diff --git a/tomtom/example/route/main.go b/tomtom/example/route/main.go index b1aab762..bdb645bb 100644 --- a/tomtom/example/route/main.go +++ b/tomtom/example/route/main.go @@ -13,14 +13,13 @@ func main() { // Example 1: Calculate a simple route traffic := false routeRequest := &tomtom.CalculateRouteRequest{ - Params: tomtom.CalculateRouteParams{ - VersionNumber: 1, - Locations: "52.50931,13.42936:52.50274,13.43872", - ContentType: "json", - Traffic: &traffic, - TravelMode: "car", - RouteType: "fastest", + 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) diff --git a/tomtom/route.go b/tomtom/route.go index 6b1a0f3e..eeb83374 100644 --- a/tomtom/route.go +++ b/tomtom/route.go @@ -3,120 +3,71 @@ package tomtom import ( "fmt" "net/url" - "strconv" + "strings" "github.com/google/go-querystring/query" ) // CalculateRouteRequest combines both path parameters and POST body type CalculateRouteRequest struct { - Params CalculateRouteParams - PostData *CalculateRoutePostData + // 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) } -// BuildURL builds the URL for the Calculate Route request -func (req *CalculateRouteRequest) BuildURL(apiKey string) (string, error) { - baseURL := fmt.Sprintf("%s/routing/%d/calculateRoute/%s/%s", - BaseURL, - req.Params.VersionNumber, - req.Params.Locations, - req.Params.ContentType) - - // Add query parameters - query := url.Values{} - query.Add("key", apiKey) - - // Add all the query parameters if they're set - if req.Params.MaxAlternatives != nil { - query.Add("maxAlternatives", strconv.Itoa(*req.Params.MaxAlternatives)) - } - - if req.Params.AlternativeType != "" { - query.Add("alternativeType", req.Params.AlternativeType) - } - - if req.Params.MinDeviationDistance != nil { - query.Add("minDeviationDistance", strconv.Itoa(*req.Params.MinDeviationDistance)) - } - - if req.Params.MinDeviationTime != nil { - query.Add("minDeviationTime", strconv.Itoa(*req.Params.MinDeviationTime)) - } - - if req.Params.InstructionsType != "" { - query.Add("instructionsType", req.Params.InstructionsType) - } - - if req.Params.Language != "" { - query.Add("language", req.Params.Language) - } - - if req.Params.ComputeBestOrder != nil { - query.Add("computeBestOrder", strconv.FormatBool(*req.Params.ComputeBestOrder)) - } - - if req.Params.RouteRepresentation != "" { - query.Add("routeRepresentation", req.Params.RouteRepresentation) - } - - if req.Params.ComputeTravelTimeFor != "" { - query.Add("computeTravelTimeFor", req.Params.ComputeTravelTimeFor) - } - - if req.Params.VehicleHeading != nil { - query.Add("vehicleHeading", strconv.Itoa(*req.Params.VehicleHeading)) - } - - for _, sectionType := range req.Params.SectionType { - query.Add("sectionType", sectionType) - } - - if req.Params.IncludeTollPaymentTypes != "" { - query.Add("includeTollPaymentTypes", req.Params.IncludeTollPaymentTypes) - } - - if req.Params.Callback != "" { - query.Add("callback", req.Params.Callback) - } - - if req.Params.Report != "" { - query.Add("report", req.Params.Report) - } - - if req.Params.DepartAt != "" { - query.Add("departAt", req.Params.DepartAt) - } - - if req.Params.ArriveAt != "" { - query.Add("arriveAt", req.Params.ArriveAt) - } - - if req.Params.RouteType != "" { - query.Add("routeType", req.Params.RouteType) - } - - if req.Params.Traffic != nil { - query.Add("traffic", strconv.FormatBool(*req.Params.Traffic)) - } - - for _, avoid := range req.Params.Avoid { - query.Add("avoid", avoid) - } - - if req.Params.TravelMode != "" { - query.Add("travelMode", req.Params.TravelMode) - } - - // Add other parameters similarly... - // Too many to list all here, but the pattern is the same - - return baseURL + "?" + query.Encode(), nil -} - // CalculateRoute sends a route calculation request to TomTom API func (c *TomTom) CalculateRoute(req *CalculateRouteRequest) (*CalculateRouteResponse, error) { /*url, err := req.BuildURL(c.APIKey) @@ -135,7 +86,7 @@ func (c *TomTom) CalculateRoute(req *CalculateRouteRequest) (*CalculateRouteResp resp, err := c.client.R(). //SetQueryParamsFromValues(query). SetResult(&result). - SetPathParam("locations", req.Params.Locations). + SetPathParam("locations", locationString(req.Locations)). SetPathParam("urlBase", c.urlBase). SetQueryParam("key", c.APIKey). Get("https://{urlBase}/routing/1/calculateRoute/{locations}/json") @@ -148,3 +99,24 @@ func (c *TomTom) CalculateRoute(req *CalculateRouteRequest) (*CalculateRouteResp 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/types.go b/tomtom/types.go index c4ee008e..17d2c88b 100644 --- a/tomtom/types.go +++ b/tomtom/types.go @@ -10,11 +10,11 @@ import ( // Base URLs and API constants const ( - BaseURL = "https://api.tomtom.com" + BaseURL = "https://api.tomtom.com" + RouteTypeFastest = "fastest" + TravelModeCar = "car" ) -// Common structs - // Coordinates represents latitude and longitude values type Coordinates struct { Latitude string `json:"latitude" xml:"latitude,attr"` @@ -44,66 +44,6 @@ type Client struct { HTTPClient *http.Client } -// CalculateRoute API structures - -// CalculateRouteParams holds the parameters for the Calculate Route API -type CalculateRouteParams struct { - // Path parameters - VersionNumber int - Locations string - ContentType string // "json" or "jsonp" - - // 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 -} - // CalculateRoutePostData represents the POST body for Calculate Route API type CalculateRoutePostData struct { SupportingPoints []SupportingPoint `json:"supportingPoints,omitempty" xml:"supportingPoints>supportingPoint,omitempty"` @@ -153,9 +93,8 @@ type CalculateRouteResponse struct { // CalculateReachableRangeParams holds the parameters for the Calculate Reachable Range API type CalculateReachableRangeParams struct { // Path parameters - VersionNumber int - Origin string - ContentType string // "json" or "jsonp" + Origin string + ContentType string // "json" or "jsonp" // Query parameters FuelBudgetInLiters *float64 @@ -232,7 +171,6 @@ type CalculateReachableRangeResponse struct { func (req *CalculateReachableRangeRequest) BuildURL(apiKey string) (string, error) { baseURL := fmt.Sprintf("%s/routing/%d/calculateReachableRange/%s/%s", BaseURL, - req.Params.VersionNumber, req.Params.Origin, req.Params.ContentType)