diff --git a/CLEANUP.md b/CLEANUP.md index fb9f1de9..305b3ec0 100644 --- a/CLEANUP.md +++ b/CLEANUP.md @@ -169,14 +169,9 @@ The map-locator, address-suggestion, and photo-upload functionality has Vue equi --- -## 5. TomTom Integration — Unused +## 5. TomTom Integration — Removed ✅ -**Status:** The `tomtom/` directory contains a TomTom routing/geocoding client. It is not imported by any file outside the `tomtom/` directory. Stadia Maps is now used for geocoding and tiles. - -### 5a. Remove TomTom entirely - -- `tomtom/` — entire directory -- `tomtom/example/` — example code +*(Completed 2026-05-09: `tomtom/` directory removed — zero imports outside itself, Stadia Maps is now the geocoding/tile provider)* --- @@ -295,7 +290,7 @@ Empty placeholder file. Remove. ## Priority Summary 1. **High impact, low effort:** - - Remove `tomtom/` (unused, no imports) + - ~~Remove `tomtom/` (unused, no imports)~~ ✅ - Remove `build.js` (dead, replaced by Vite) - Remove commented-out routes in `sync/routes.go` and `rmo/routes.go` - Remove `query.go` commented-out code diff --git a/tomtom/.air.toml b/tomtom/.air.toml deleted file mode 100644 index 7c5738f8..00000000 --- a/tomtom/.air.toml +++ /dev/null @@ -1,52 +0,0 @@ -root = "." -testdata_dir = "testdata" -tmp_dir = "tmp" - -[build] - args_bin = [] - bin = "./tmp/main" - cmd = "go build -o ./tmp/main ./example/geocode-and-route" - delay = 1000 - exclude_dir = ["assets", "tmp", "vendor", "testdata"] - exclude_file = [] - exclude_regex = ["_test.go"] - exclude_unchanged = false - follow_symlink = false - full_bin = "" - include_dir = [] - include_ext = ["go", "tpl", "tmpl", "html"] - include_file = [] - kill_delay = "0s" - log = "build-errors.log" - poll = false - poll_interval = 0 - post_cmd = [] - pre_cmd = [] - rerun = false - rerun_delay = 500 - send_interrupt = false - stop_on_error = true - -[color] - app = "" - build = "yellow" - main = "magenta" - runner = "green" - watcher = "cyan" - -[log] - main_only = false - silent = false - time = false - -[misc] - clean_on_exit = false - -[proxy] - app_port = 0 - enabled = false - proxy_port = 0 - -[screen] - clear_on_rebuild = false - keep_scroll = true diff --git a/tomtom/example/geocode-and-route/main.go b/tomtom/example/geocode-and-route/main.go deleted file mode 100644 index 0780d493..00000000 --- a/tomtom/example/geocode-and-route/main.go +++ /dev/null @@ -1,61 +0,0 @@ -package main - -import ( - "log" - - "github.com/Gleipnir-Technology/nidus-sync/tomtom" -) - -func main() { - client := tomtom.NewClient() - - // Example 1: Geocode a series of addresses - waypoints := []string{ - "1737 W Houston Ave, Visalia, CA 93291", - "1138 W Prescott Ave, Visalia, CA 93291", - "3228 W Clinton Ct, Visalia, CA 93291", - "3800 N Mendonca St, Visalia, CA 93291", - } - coords := make([]tomtom.Point, 0) - for _, wp := range waypoints { - geocode, err := client.Geocode(wp) - if err != nil { - log.Fatal("Failed to geocode '%s': %w", wp, err) - } - if len(geocode.Results) == 0 { - log.Fatal("Failed to get any results for '%s'", wp) - } - result := geocode.Results[0] - coords = append(coords, result.Position.AsPoint()) - log.Printf("Geocoded %s to %f, %f", wp, result.Position.Longitude, result.Position.Latitude) - } - // Example 2: Calculate a simple route through them - traffic := false - routeRequest := &tomtom.CalculateRouteRequest{ - Locations: coords, - Traffic: &traffic, - TravelMode: tomtom.TravelModeCar, - RouteType: tomtom.RouteTypeFastest, - } - - //client.SetDebug(true) - routeResp, err := client.CalculateRoute(routeRequest) - if err != nil { - log.Fatal(err) - } - - all_points := make([]tomtom.Point, 0) - all_stops := make([]tomtom.Point, 0) - for i, route := range routeResp.Routes { - s := route.Summary - log.Printf("%d: %d meters, %d seconds, %s traffic delay", i, s.LengthInMeters, s.TravelTimeInSeconds, s.TrafficDelayInSeconds) - for _, leg := range route.Legs { - all_stops = append(all_stops, leg.Points[0]) - all_points = append(all_points, leg.Points...) - } - } - lines := tomtom.PolylineToGeoJSON(all_points) - log.Printf("%s", lines) - stops := tomtom.PolylineToGeoJSON(all_stops) - log.Printf("%s", stops) -} diff --git a/tomtom/example/route-gps/main.go b/tomtom/example/route-gps/main.go deleted file mode 100644 index de222f36..00000000 --- a/tomtom/example/route-gps/main.go +++ /dev/null @@ -1,31 +0,0 @@ -package main - -import ( - "fmt" - "log" - - "github.com/Gleipnir-Technology/nidus-sync/tomtom" -) - -func main() { - client := tomtom.NewClient() - - // Example 1: Calculate a simple route - traffic := false - routeRequest := &tomtom.CalculateRouteRequest{ - Locations: []tomtom.Point{ - tomtom.P(52.50931, 13.42936), - tomtom.P(52.50274, 13.43872), - }, - Traffic: &traffic, - TravelMode: tomtom.TravelModeCar, - RouteType: tomtom.RouteTypeFastest, - } - - routeResp, err := client.CalculateRoute(routeRequest) - if err != nil { - log.Fatal(err) - } - - fmt.Printf("Route distance: %d meters\n", routeResp.Routes[0].Summary.LengthInMeters) -} diff --git a/tomtom/geocode.go b/tomtom/geocode.go deleted file mode 100644 index 17b7947e..00000000 --- a/tomtom/geocode.go +++ /dev/null @@ -1,96 +0,0 @@ -package tomtom - -import ( - "fmt" -) - -type PointShort struct { - Latitude float64 `json:"lat"` - Longitude float64 `json:"lon"` -} - -func (ps PointShort) AsPoint() Point { - return Point(ps) -} - -type GeocodeResult struct { - Type string `json:"type"` - ID string `json:"id"` - Score float64 `json:"score"` - Dist float64 `json:"dist"` - MatchConfidence MatchConfidence `json:"matchConfidence"` - Address Address `json:"address"` - Position PointShort `json:"position"` - Viewport Viewport `json:"viewport"` - EntryPoints []EntryPoint `json:"entryPoints"` -} - -// MatchConfidence represents the confidence score for a match -type MatchConfidence struct { - Score float64 `json:"score"` -} - -// Address contains detailed address information -type Address struct { - StreetNumber string `json:"streetNumber"` - StreetName string `json:"streetName"` - Municipality string `json:"municipality"` - CountrySecondarySubdivision string `json:"countrySecondarySubdivision"` - CountrySubdivision string `json:"countrySubdivision"` - CountrySubdivisionName string `json:"countrySubdivisionName"` - CountrySubdivisionCode string `json:"countrySubdivisionCode"` - PostalCode string `json:"postalCode"` - ExtendedPostalCode string `json:"extendedPostalCode"` - CountryCode string `json:"countryCode"` - Country string `json:"country"` - CountryCodeISO3 string `json:"countryCodeISO3"` - FreeformAddress string `json:"freeformAddress"` - LocalName string `json:"localName"` -} - -// Viewport defines a geographic bounding box -type Viewport struct { - TopLeftPoint PointShort `json:"topLeftPoint"` - BtmRightPoint PointShort `json:"btmRightPoint"` -} - -// EntryPoint contains information about a point of entry to a location -type EntryPoint struct { - Type string `json:"type"` - Position PointShort `json:"position"` -} -type GeocodeSummary struct { - Query string `json:"query"` - QueryType string `json:"queryType"` - QueryTime uint `json:"queryTime"` - NumResults uint `json:"numResults"` - Offset uint `json:"offset"` - TotalResults uint `json:"totalResults"` - FuzzyLevel uint `json:"fuzzyLevel"` - GeoBias PointShort `json:"geoBias"` -} -type GeocodeResponse struct { - Summary GeocodeSummary `json:"summary"` - Results []GeocodeResult `json:"results"` -} - -// CalculateRoute sends a route calculation request to TomTom API -func (c *TomTom) Geocode(address string) (*GeocodeResponse, error) { - var result GeocodeResponse - - resp, err := c.client.R(). - SetResult(&result). - SetPathParam("address", address). - SetPathParam("urlBase", c.urlBase). - SetQueryParam("key", c.APIKey). - SetQueryParam("storeResult", "false"). - Get("https://{urlBase}/search/2/geocode/{address}.json") - if err != nil { - return nil, fmt.Errorf("calculate route get: %w", err) - } - if !resp.IsSuccess() { - return nil, fmt.Errorf("calculate route status: %d", resp.Status) - } - - return &result, nil -} diff --git a/tomtom/geojson.go b/tomtom/geojson.go deleted file mode 100644 index 0879acae..00000000 --- a/tomtom/geojson.go +++ /dev/null @@ -1,27 +0,0 @@ -package tomtom - -import ( - "fmt" - "strings" -) - -// Convert a slice of points to GeoJSON -func PolylineToGeoJSON(polyline []Point) string { - var sb strings.Builder - - sb.WriteString(`{"type":"LineString","coordinates":[`) - - for i, point := range polyline { - // IMPORTANT: GeoJSON uses [longitude, latitude] order! - sb.WriteString(fmt.Sprintf("[%g,%g]", point.Longitude, point.Latitude)) - - // Add comma if not the last point - if i < len(polyline)-1 { - sb.WriteString(",") - } - } - - sb.WriteString("]}") - - return sb.String() -} diff --git a/tomtom/route.go b/tomtom/route.go deleted file mode 100644 index ae0534bc..00000000 --- a/tomtom/route.go +++ /dev/null @@ -1,126 +0,0 @@ -package tomtom - -import ( - "fmt" - "net/url" - "strings" - - "github.com/google/go-querystring/query" -) - -// CalculateRouteRequest combines both path parameters and POST body -type CalculateRouteRequest struct { - // Path parameters - Locations Locations - - // Query parameters - MaxAlternatives *int - AlternativeType string - MinDeviationDistance *int - MinDeviationTime *int - InstructionsType string - Language string - ComputeBestOrder *bool - RouteRepresentation string - ComputeTravelTimeFor string - VehicleHeading *int - SectionType []string - IncludeTollPaymentTypes string - Callback string - Report string - DepartAt string - ArriveAt string - RouteType string - Traffic *bool - Avoid []string - TravelMode string - Hilliness string - Windingness string - VehicleMaxSpeed *int - VehicleWeight *int - VehicleAxleWeight *int - VehicleNumberOfAxles *int - VehicleLength *float64 - VehicleWidth *float64 - VehicleHeight *float64 - VehicleCommercial *bool - VehicleLoadType []string - VehicleAdrTunnelRestrictionCode string - VehicleHasElectricTollCollectionTransponder string - VehicleEngineType string - ConstantSpeedConsumptionInLitersPerHundredkm string - CurrentFuelInLiters *float64 - AuxiliaryPowerInLitersPerHour *float64 - FuelEnergyDensityInMJoulesPerLiter *float64 - AccelerationEfficiency *float64 - DecelerationEfficiency *float64 - UphillEfficiency *float64 - DownhillEfficiency *float64 - ConsumptionInkWhPerkmAltitudeGain *float64 - RecuperationInkWhPerkmAltitudeLoss *float64 - ConstantSpeedConsumptionInkWhPerHundredkm string - CurrentChargeInkWh *float64 - MaxChargeInkWh *float64 - AuxiliaryPowerInkW *float64 -} - -func (sgr CalculateRouteRequest) toQueryParams() (url.Values, error) { - return query.Values(sgr) -} - -type CalculateRouteResponse struct { - Routes []Route `json:"routes"` -} - -// CalculateRoute sends a route calculation request to TomTom API -func (c *TomTom) CalculateRoute(req *CalculateRouteRequest) (*CalculateRouteResponse, error) { - /*url, err := req.BuildURL(c.APIKey) - if err != nil { - return nil, err - }*/ - - var result CalculateRouteResponse - /* - query, err := req.toQueryParams() - if err != nil { - return nil, fmt.Errorf("structured geocode query: %w", err) - } - */ - - resp, err := c.client.R(). - //SetQueryParamsFromValues(query). - SetResult(&result). - SetPathParam("locations", locationString(req.Locations)). - SetPathParam("urlBase", c.urlBase). - SetQueryParam("key", c.APIKey). - Get("https://{urlBase}/routing/1/calculateRoute/{locations}/json") - if err != nil { - return nil, fmt.Errorf("calculate route get: %w", err) - } - if !resp.IsSuccess() { - return nil, fmt.Errorf("calculate route status: %d", resp.Status) - } - - return &result, nil -} - -func P(lat, lng float64) Point { - return Point{ - Latitude: lat, - Longitude: lng, - } -} - -type Locations = []Point - -func locationString(locations Locations) string { - var sb strings.Builder - for i, p := range locations { - if i == 0 { - sb.WriteString(fmt.Sprintf("%f,%f", p.Latitude, p.Longitude)) - } else { - sb.WriteString(fmt.Sprintf(":%f,%f", p.Latitude, p.Longitude)) - } - } - return sb.String() -} diff --git a/tomtom/routing.go b/tomtom/routing.go deleted file mode 100644 index ef66c0bb..00000000 --- a/tomtom/routing.go +++ /dev/null @@ -1 +0,0 @@ -package tomtom diff --git a/tomtom/tomtom.go b/tomtom/tomtom.go deleted file mode 100644 index 0d529bb0..00000000 --- a/tomtom/tomtom.go +++ /dev/null @@ -1,37 +0,0 @@ -package tomtom - -import ( - "os" - - "resty.dev/v3" -) - -type TomTom struct { - APIKey string - - client *resty.Client - urlBase string -} - -func NewClient() *TomTom { - api_key := os.Getenv("TOMTOM_API_KEY") - r := resty.New() - return &TomTom{ - APIKey: api_key, - client: r, - urlBase: "api.tomtom.com", - } -} - -func (s *TomTom) Close() { - s.client.Close() -} - -func (s *TomTom) SetDebug(enabled bool) { - s.client.Close() - if enabled { - s.client = resty.New().SetDebug(true) - } else { - s.client = resty.New().SetDebug(false) - } -} diff --git a/tomtom/types.go b/tomtom/types.go deleted file mode 100644 index 29d48bdb..00000000 --- a/tomtom/types.go +++ /dev/null @@ -1,235 +0,0 @@ -package tomtom - -import ( - "encoding/json" - "fmt" - "net/http" - "net/url" - "strings" -) - -// Base URLs and API constants -const ( - BaseURL = "https://api.tomtom.com" - RouteTypeFastest = "fastest" - TravelModeCar = "car" -) - -// Coordinates represents latitude and longitude values -type Coordinates struct { - Latitude string `json:"latitude" xml:"latitude,attr"` - Longitude string `json:"longitude" xml:"longitude,attr"` -} - -// Rectangle represents a geographic rectangle -type Rectangle struct { - SouthWestCorner Coordinates `json:"southWestCorner" xml:"southWestCorner"` - NorthEastCorner Coordinates `json:"northEastCorner" xml:"northEastCorner"` -} - -// AvoidAreas represents areas to avoid in routing -type AvoidAreas struct { - Rectangles []Rectangle `json:"rectangles" xml:"rectangles>rectangle"` -} - -// SupportingPoint represents a supporting point in the route calculation -type SupportingPoint struct { - Latitude string `json:"latitude" xml:"latitude,attr"` - Longitude string `json:"longitude" xml:"longitude,attr"` -} - -// Client represents a TomTom API client -type Client struct { - APIKey string - HTTPClient *http.Client -} - -// CalculateRoutePostData represents the POST body for Calculate Route API -type CalculateRoutePostData struct { - SupportingPoints []SupportingPoint `json:"supportingPoints,omitempty" xml:"supportingPoints>supportingPoint,omitempty"` - AvoidVignette []string `json:"avoidVignette,omitempty" xml:"avoidVignette,omitempty"` - AllowVignette []string `json:"allowVignette,omitempty" xml:"allowVignette,omitempty"` - AvoidAreas *AvoidAreas `json:"avoidAreas,omitempty" xml:"avoidAreas,omitempty"` -} - -// Route response structures - These would need to be completed based on actual API response -type Summary struct { - LengthInMeters int `json:"lengthInMeters"` - TravelTimeInSeconds int `json:"travelTimeInSeconds"` - TrafficDelayInSeconds int `json:"trafficDelayInSeconds"` - DepartureTime string `json:"departureTime"` - ArrivalTime string `json:"arrivalTime"` - FuelConsumptionInLiters float64 `json:"fuelConsumptionInLiters,omitempty"` - ElectricEnergyConsumptionInkWh float64 `json:"electricEnergyConsumptionInkWh,omitempty"` -} - -type Point struct { - Latitude float64 `json:"latitude"` - Longitude float64 `json:"longitude"` -} - -type Leg struct { - Summary Summary `json:"summary"` - Points []Point `json:"points,omitempty"` -} - -type Route struct { - Summary Summary `json:"summary"` - Legs []Leg `json:"legs,omitempty"` -} - -// CalculateReachableRange API structures - -// CalculateReachableRangeParams holds the parameters for the Calculate Reachable Range API -type CalculateReachableRangeParams struct { - // Path parameters - Origin string - ContentType string // "json" or "jsonp" - - // Query parameters - FuelBudgetInLiters *float64 - EnergyBudgetInkWh *float64 - TimeBudgetInSec *float64 - Callback string - Report string - DepartAt string - ArriveAt string - RouteType string - Traffic *bool - Avoid []string - TravelMode string - Hilliness string - Windingness string - VehicleMaxSpeed *int - VehicleWeight *int - VehicleAxleWeight *int - VehicleNumberOfAxles *int - VehicleLength *float64 - VehicleWidth *float64 - VehicleHeight *float64 - VehicleCommercial *bool - VehicleLoadType []string - VehicleAdrTunnelRestrictionCode string - VehicleHasElectricTollCollectionTransponder string - VehicleEngineType string - ConstantSpeedConsumptionInLitersPerHundredkm string - CurrentFuelInLiters *float64 - AuxiliaryPowerInLitersPerHour *float64 - FuelEnergyDensityInMJoulesPerLiter *float64 - AccelerationEfficiency *float64 - DecelerationEfficiency *float64 - UphillEfficiency *float64 - DownhillEfficiency *float64 - ConsumptionInkWhPerkmAltitudeGain *float64 - RecuperationInkWhPerkmAltitudeLoss *float64 - ConstantSpeedConsumptionInkWhPerHundredkm string - CurrentChargeInkWh *float64 - MaxChargeInkWh *float64 - AuxiliaryPowerInkW *float64 -} - -// CalculateReachableRangePostData represents the POST body for Calculate Reachable Range API -type CalculateReachableRangePostData struct { - AvoidVignette []string `json:"avoidVignette,omitempty" xml:"avoidVignette,omitempty"` - AllowVignette []string `json:"allowVignette,omitempty" xml:"allowVignette,omitempty"` - AvoidAreas *AvoidAreas `json:"avoidAreas,omitempty" xml:"avoidAreas,omitempty"` -} - -// CalculateReachableRangeRequest combines both path parameters and POST body -type CalculateReachableRangeRequest struct { - Params CalculateReachableRangeParams - PostData *CalculateReachableRangePostData -} - -// Reachable Range response structures -type Polygon struct { - Exterior []Point `json:"exterior"` - Interior [][]Point `json:"interior,omitempty"` -} - -type CalculateReachableRangeResponse struct { - Polygon Polygon `json:"polygon"` - Summary struct { - DistanceLimit float64 `json:"distanceLimit,omitempty"` - TimeLimit int `json:"timeLimit,omitempty"` - FuelConsumptionLimit float64 `json:"fuelConsumptionLimit,omitempty"` - EnergyConsumptionLimit float64 `json:"energyConsumptionLimit,omitempty"` - } `json:"summary"` -} - -// BuildURL builds the URL for the Calculate Reachable Range request -func (req *CalculateReachableRangeRequest) BuildURL(apiKey string) (string, error) { - baseURL := fmt.Sprintf("%s/routing/%d/calculateReachableRange/%s/%s", - BaseURL, - req.Params.Origin, - req.Params.ContentType) - - // Add query parameters - query := url.Values{} - query.Add("key", apiKey) - - if req.Params.FuelBudgetInLiters != nil { - query.Add("fuelBudgetInLiters", fmt.Sprintf("%f", *req.Params.FuelBudgetInLiters)) - } - - if req.Params.EnergyBudgetInkWh != nil { - query.Add("energyBudgetInkWh", fmt.Sprintf("%f", *req.Params.EnergyBudgetInkWh)) - } - - if req.Params.TimeBudgetInSec != nil { - query.Add("timeBudgetInSec", fmt.Sprintf("%f", *req.Params.TimeBudgetInSec)) - } - - // Add other parameters similarly... - - return baseURL + "?" + query.Encode(), nil -} - -// Client methods for executing requests - -// CalculateReachableRange sends a reachable range calculation request to TomTom API -func (c *Client) CalculateReachableRange(req *CalculateReachableRangeRequest) (*CalculateReachableRangeResponse, error) { - url, err := req.BuildURL(c.APIKey) - if err != nil { - return nil, err - } - - var response CalculateReachableRangeResponse - var httpReq *http.Request - - if req.PostData != nil { - // POST request - jsonData, err := json.Marshal(req.PostData) - if err != nil { - return nil, err - } - httpReq, err = http.NewRequest("POST", url, strings.NewReader(string(jsonData))) - if err != nil { - return nil, err - } - httpReq.Header.Set("Content-Type", "application/json") - } else { - // GET request - httpReq, err = http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - } - - resp, err := c.HTTPClient.Do(httpReq) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("API error: %s", resp.Status) - } - - err = json.NewDecoder(resp.Body).Decode(&response) - if err != nil { - return nil, err - } - - return &response, nil -}