Documentation
¶
Overview ¶
Package location is a lightweight, SDK-free, zero-dependency Go wrapper for routing, distance matrix, geocoding, and isochrone across Google, Mapbox, HERE, ESRI, TomTom, and OSRM.
It is the Go sibling of @thinwrap/location (npm) and thinwrap/location (Packagist), sharing the same normalized surface: distances in meters, durations in seconds, coordinates as {lat, lng}, geometry as Google precision-5 polylines, and a single typed *ConnectorError.
Construct an operation facade from a provider config and call its method:
r := location.NewRouting(location.GoogleConfig{APIKey: key})
res, err := r.Route(ctx, location.RoutingOptions{
Waypoints: []location.LatLng{{Lat: 40.71, Lng: -74.0}, {Lat: 41.42, Lng: -73.0}},
})
if err != nil {
var ce *location.ConnectorError
if errors.As(err, &ce) {
// ce.ProviderCode, ce.StatusCode, ce.ProviderMessage
}
}
The config type selects the provider; switching vendors is a one-line change (swap GoogleConfig for MapboxConfig, etc.). Operations a provider does not support are unrepresentable at compile time (e.g. OsrmConfig does not satisfy GeocodingConfig).
The wrapper holds no state: no caching, retries, idempotency keys, or telemetry. Bring your own HTTP client via WithHTTPClient; the default client never follows redirects (a 3xx surfaces as an error rather than silently re-sending auth headers to the redirect target).
Index ¶
- Constants
- func EncodePolyline(coords []LatLng) (string, error)
- type AutocompleteOptions
- type AutocompletePrediction
- type AutocompleteResult
- type AutocompleteStructuredFormat
- type ConnectorError
- type EsriConfig
- type EsriPathsGeometry
- type GeocodeCandidate
- type GeocodeOptions
- type GeocodeResult
- type Geocoding
- func (g *Geocoding) Autocomplete(ctx context.Context, opts AutocompleteOptions) (*AutocompleteResult, error)
- func (g *Geocoding) Geocode(ctx context.Context, opts GeocodeOptions) (*GeocodeResult, error)
- func (g *Geocoding) PlaceDetails(ctx context.Context, opts PlaceDetailsOptions) (*PlaceDetailsResult, error)
- func (g *Geocoding) ProviderID() ProviderID
- func (g *Geocoding) ReverseGeocode(ctx context.Context, opts ReverseGeocodeOptions) (*ReverseGeocodeResult, error)
- type GeocodingConfig
- type GoogleConfig
- type HTTPClient
- type HereConfig
- type HereTransportMode
- type Isochrone
- type IsochroneConfig
- type IsochroneContour
- type IsochroneMeta
- type IsochroneOptions
- type IsochroneResult
- type IsochroneType
- type LatLng
- type MapboxConfig
- type Matrix
- type MatrixCell
- type MatrixConfig
- type MatrixOptions
- type MatrixResult
- type Option
- type OsrmConfig
- type Passthrough
- type PlaceDetailsInclude
- type PlaceDetailsOptions
- type PlaceDetailsResult
- type Polygon
- type PolylineQuality
- type ProviderCode
- type ProviderID
- type ReverseGeocodeOptions
- type ReverseGeocodeResult
- type Routing
- type RoutingConfig
- type RoutingInclude
- type RoutingLeg
- type RoutingOptions
- type RoutingResult
- type SpatialReference
- type TomTomConfig
- type TrafficMode
- type TravelMode
- type Viewport
Constants ¶
const MaxIsochroneValues = 4
MaxIsochroneValues is the maximum number of contour breaks supported across all four isochrone providers, set by Mapbox's native ceiling.
Variables ¶
This section is empty.
Functions ¶
func EncodePolyline ¶
EncodePolyline encodes coordinates into a Google-format precision-5 polyline string. It returns an *ConnectorError (invalid_request) if any coordinate is non-finite.
Types ¶
type AutocompleteOptions ¶
type AutocompleteOptions struct {
Input string
// Location and Radius bias results toward a point (ignored by some providers).
Location *LatLng
Radius *float64
Language string
// CountryFilter is an optional hard filter of ISO 3166-1 alpha-2 codes, the
// same vocabulary as GeocodeOptions.CountryFilter. All five geocoders support
// one natively; each connector translates it into that vendor's parameter
// (Google includedRegionCodes, Mapbox country, TomTom countrySet, Esri
// countryCode, HERE in=countryCode with alpha-3 codes).
//
// Two provider behaviours are worth knowing. Google takes ccTLD codes rather
// than ISO — the two disagree on the United Kingdom (GB → uk), which the
// connector translates — and setting the filter also stops Google returning
// *query* predictions, so it changes which kinds of suggestion come back.
// HERE requires the filter to be accompanied by a Location.
CountryFilter []string
// SessionToken groups this keystroke with the rest of one user interaction,
// closed by the PlaceDetails call carrying the SAME value.
//
// Google-only here: Places Autocomplete is billed per SESSION when a token
// ties the keystroke requests to the details call that closes them, and per
// REQUEST when it does not — so omitting it on a keystroke-driven UI multiplies
// the bill by the number of characters typed. Google documents a v4 UUID.
//
// The wrapper holds no state and cannot correlate the calls, so generating and
// threading the value is the caller's job. Ignored by every other provider.
// (Mapbox needs the same concept but only on PlaceDetails, because its suggest
// leg generates its own token — see PlaceDetailsOptions.SessionToken.)
SessionToken string
Passthrough *Passthrough
}
AutocompleteOptions is the normalized input to Geocoding.Autocomplete.
type AutocompletePrediction ¶
type AutocompletePrediction struct {
Description string `json:"description"`
PlaceID string `json:"placeId,omitempty"`
// StructuredFormat is the prediction split into its primary and secondary
// parts, when the provider returns them as distinct fields.
//
// This is what lets a UI render the usual two-line suggestion — the place name
// above a greyed-out address — without guessing where to split Description.
// Splitting on the first comma is the workaround this replaces, and it breaks
// on names containing commas and on locales that order the address differently.
//
// Never synthesized. Non-nil only when the provider supplies a genuinely
// distinct main part: Google (structuredFormat.mainText), Mapbox (name /
// place_formatted), HERE (title / address.label), TomTom (poi.name /
// address.freeformAddress — absent for street results, which have no poi.name).
// Esri returns a single flat text field and is the genuine gap.
//
// So nil means "this provider/row has no distinct main part", and Description
// remains the thing to render.
StructuredFormat *AutocompleteStructuredFormat `json:"structuredFormat,omitempty"`
}
AutocompletePrediction is one normalized autocomplete suggestion.
type AutocompleteResult ¶
type AutocompleteResult struct {
Predictions []AutocompletePrediction `json:"predictions"`
Raw any `json:"raw"`
}
AutocompleteResult is the normalized autocomplete response.
type AutocompleteStructuredFormat ¶ added in v1.2.0
type AutocompleteStructuredFormat struct {
MainText string `json:"mainText"`
SecondaryText string `json:"secondaryText,omitempty"`
}
AutocompleteStructuredFormat is the two display parts of a prediction.
SecondaryText is empty when the provider has a main part but no address — HERE's query-type suggestions are exactly that shape, and emitting a fabricated value there would render as a blank second line.
type ConnectorError ¶
type ConnectorError struct {
// StatusCode is the HTTP status, or nil for pre-response / transport failures.
StatusCode *int
// ProviderCode is the normalized classification.
ProviderCode ProviderCode
// ProviderMessage is the vendor-supplied message (or "" when absent).
ProviderMessage string
// Message is the human-readable error message; falls back to ProviderMessage.
Message string
// Cause holds the decoded vendor body (map/slice/scalar) OR an underlying error.
Cause any
}
ConnectorError is the single typed error every operation can return. Retrieve it from a returned error with errors.As:
var ce *location.ConnectorError
if errors.As(err, &ce) { ... }
There is deliberately no top-level RetryAfterSeconds field: the raw Retry-After header rides in Cause (key "retryAfter"), and its parsed seconds are woven into ProviderMessage.
func (*ConnectorError) Error ¶
func (e *ConnectorError) Error() string
func (*ConnectorError) Unwrap ¶
func (e *ConnectorError) Unwrap() error
Unwrap exposes an underlying error cause (e.g. a transport error) to errors.Is / errors.As.
type EsriConfig ¶
EsriConfig authenticates the ESRI/ArcGIS provider. Provide exactly one of APIKey or ArcGISToken. Supports all four operations.
func (EsriConfig) ProviderID ¶
func (EsriConfig) ProviderID() ProviderID
type EsriPathsGeometry ¶
type EsriPathsGeometry struct {
Paths [][][]float64 `json:"paths"`
SpatialReference SpatialReference `json:"spatialReference"`
}
EsriPathsGeometry is the ESRI-JSON `paths` geometry object ArcGIS services accept/return. Points are [lng, lat] (ESRI's lng-first convention, opposite of GeoJSON) and the spatial reference is fixed at {wkid: 4326}.
func EncodeEsriPaths ¶
func EncodeEsriPaths(paths [][]LatLng) EsriPathsGeometry
EncodeEsriPaths converts LatLng paths into an ESRI-JSON `paths` geometry object. Each point becomes an [lng, lat] pair; the CRS is fixed at WGS-84.
type GeocodeCandidate ¶
type GeocodeCandidate struct {
FormattedAddress string `json:"formattedAddress"`
Location LatLng `json:"location"`
PlaceID string `json:"placeId,omitempty"`
Viewport *Viewport `json:"viewport,omitempty"`
}
GeocodeCandidate is one normalized geocoding result.
type GeocodeOptions ¶
type GeocodeOptions struct {
Address string
// Language is an optional BCP-47 language tag ("" = provider default).
Language string
// CountryFilter is an optional hard filter of ISO 3166-1 alpha-2 codes.
CountryFilter []string
Passthrough *Passthrough
}
GeocodeOptions is the normalized input to Geocoding.Geocode.
type GeocodeResult ¶
type GeocodeResult struct {
Candidates []GeocodeCandidate `json:"candidates"`
Raw any `json:"raw"`
}
GeocodeResult is the normalized forward-geocoding response.
type Geocoding ¶
type Geocoding struct {
// contains filtered or unexported fields
}
Geocoding is the geocoding facade (forward, reverse, autocomplete). Construct it with NewGeocoding.
func NewGeocoding ¶
func NewGeocoding(cfg GeocodingConfig, opts ...Option) *Geocoding
NewGeocoding builds a geocoding facade for the provider selected by cfg's type.
func (*Geocoding) Autocomplete ¶
func (g *Geocoding) Autocomplete(ctx context.Context, opts AutocompleteOptions) (*AutocompleteResult, error)
Autocomplete returns address predictions for a partial input.
func (*Geocoding) Geocode ¶
func (g *Geocoding) Geocode(ctx context.Context, opts GeocodeOptions) (*GeocodeResult, error)
Geocode resolves an address to candidate locations.
func (*Geocoding) PlaceDetails ¶ added in v1.2.0
func (g *Geocoding) PlaceDetails(ctx context.Context, opts PlaceDetailsOptions) (*PlaceDetailsResult, error)
PlaceDetails resolves a PlaceID from Autocomplete into a full candidate.
All five geocoding providers support it. There is no capability check because the connector interface is unexported — every possible connector is one this package built, and the compiler already requires the method.
For Mapbox, set opts.SessionToken to the same value used for the preceding Autocomplete call: Search Box bills per session, so a matching token makes suggest+retrieve one billable session instead of two.
func (*Geocoding) ProviderID ¶
func (g *Geocoding) ProviderID() ProviderID
ProviderID returns the provider this facade dispatches to.
func (*Geocoding) ReverseGeocode ¶
func (g *Geocoding) ReverseGeocode(ctx context.Context, opts ReverseGeocodeOptions) (*ReverseGeocodeResult, error)
ReverseGeocode resolves a coordinate to candidate addresses.
type GeocodingConfig ¶
type GeocodingConfig interface {
ProviderID() ProviderID
// contains filtered or unexported methods
}
GeocodingConfig is implemented by every provider config that supports geocoding (all except OSRM).
type GoogleConfig ¶
type GoogleConfig struct{ APIKey string }
GoogleConfig authenticates the Google provider. Supports routing, matrix, and geocoding.
func (GoogleConfig) ProviderID ¶
func (GoogleConfig) ProviderID() ProviderID
type HTTPClient ¶
HTTPClient is the bring-your-own HTTP seam. It is satisfied by *http.Client out of the box; inject any implementation for tracing, retries, mocking, or proxying.
type HereConfig ¶
type HereConfig struct{ APIKey string }
HereConfig authenticates the HERE provider. Supports all four operations.
func (HereConfig) ProviderID ¶
func (HereConfig) ProviderID() ProviderID
type HereTransportMode ¶
type HereTransportMode string
HereTransportMode is the HERE-narrowed transport mode. Set it on RoutingOptions / MatrixOptions to override the base TravelMode mapping; it is read only by the HERE connector and ignored by every other provider.
const ( HereCar HereTransportMode = "car" HereTruck HereTransportMode = "truck" HerePedestrian HereTransportMode = "pedestrian" HereBicycle HereTransportMode = "bicycle" HereScooter HereTransportMode = "scooter" HereTaxi HereTransportMode = "taxi" // routing only HerePrivateBus HereTransportMode = "privateBus" // routing only )
type Isochrone ¶
type Isochrone struct {
// contains filtered or unexported fields
}
Isochrone is the isochrone facade. Construct it with NewIsochrone.
func NewIsochrone ¶
func NewIsochrone(cfg IsochroneConfig, opts ...Option) *Isochrone
NewIsochrone builds an isochrone facade for the provider selected by cfg's type.
func (*Isochrone) Isochrone ¶
func (i *Isochrone) Isochrone(ctx context.Context, opts IsochroneOptions) (*IsochroneResult, error)
Isochrone computes reachable-area contours from a center point.
func (*Isochrone) ProviderID ¶
func (i *Isochrone) ProviderID() ProviderID
ProviderID returns the provider this facade dispatches to.
type IsochroneConfig ¶
type IsochroneConfig interface {
ProviderID() ProviderID
// contains filtered or unexported methods
}
IsochroneConfig is implemented by every provider config that supports isochrone (Mapbox, HERE, ESRI, TomTom).
type IsochroneContour ¶
IsochroneContour is one reachable-area band.
type IsochroneMeta ¶
type IsochroneMeta struct {
RequestCount int `json:"requestCount"`
}
IsochroneMeta carries optional metadata, present only when more than one underlying HTTP call was made (TomTom multi-band).
type IsochroneOptions ¶
type IsochroneOptions struct {
Center LatLng
Type IsochroneType
Values []float64
TravelMode TravelMode
// DepartureTime is an ISO 8601 string (note: a string, not time.Time,
// matching the sibling libraries' isochrone surface).
DepartureTime string
Passthrough *Passthrough
}
IsochroneOptions is the normalized input to Isochrone.Isochrone. Values holds 1..4 break values (seconds for time, meters for distance). TravelMode is driving/walking on the base surface; Mapbox and TomTom additionally accept Cycling (other providers reject it as unsupported_travel_mode).
type IsochroneResult ¶
type IsochroneResult struct {
Contours []IsochroneContour `json:"contours"`
Raw any `json:"raw"`
Meta *IsochroneMeta `json:"_meta,omitempty"`
}
IsochroneResult is the normalized isochrone response. Contours are sorted by Value ascending.
type IsochroneType ¶
type IsochroneType string
IsochroneType selects whether Values are interpreted as time (seconds) or distance (meters).
const ( IsochroneTime IsochroneType = "time" IsochroneDistance IsochroneType = "distance" )
type LatLng ¶
LatLng is a WGS-84 coordinate, latitude first. It is the single coordinate representation across every operation input and output.
func DecodeFlexPolyline ¶
DecodeFlexPolyline decodes a HERE flex-polyline encoded string. Altitude (the optional third dimension) is decoded and skipped. Reference: https://github.com/heremaps/flexible-polyline
func DecodePolyline ¶
DecodePolyline decodes a Google-format precision-5 polyline string.
type MapboxConfig ¶
type MapboxConfig struct{ AccessToken string }
MapboxConfig authenticates the Mapbox provider. Supports all four operations.
func (MapboxConfig) ProviderID ¶
func (MapboxConfig) ProviderID() ProviderID
type Matrix ¶
type Matrix struct {
// contains filtered or unexported fields
}
Matrix is the distance-matrix facade. Construct it with NewMatrix.
func NewMatrix ¶
func NewMatrix(cfg MatrixConfig, opts ...Option) *Matrix
NewMatrix builds a matrix facade for the provider selected by cfg's type.
func (*Matrix) Matrix ¶
func (m *Matrix) Matrix(ctx context.Context, opts MatrixOptions) (*MatrixResult, error)
Matrix computes an origins×destinations distance/duration matrix.
func (*Matrix) ProviderID ¶
func (m *Matrix) ProviderID() ProviderID
ProviderID returns the provider this facade dispatches to.
type MatrixCell ¶
type MatrixCell struct {
OriginIndex int `json:"originIndex"`
DestinationIndex int `json:"destinationIndex"`
DistanceMeters float64 `json:"distanceMeters"`
DurationSeconds float64 `json:"durationSeconds"`
}
MatrixCell is one origin×destination pairing. Results are a flat list of cells; re-pivot into a 2D grid via OriginIndex / DestinationIndex.
type MatrixConfig ¶
type MatrixConfig interface {
ProviderID() ProviderID
// contains filtered or unexported methods
}
MatrixConfig is implemented by every provider config that supports matrix.
type MatrixOptions ¶
type MatrixOptions struct {
Origins []LatLng
Destinations []LatLng
TravelMode TravelMode
AvoidTolls bool
DepartureTime *time.Time
// TransportMode is a HERE-only augmentation (see RoutingOptions).
TransportMode HereTransportMode
Passthrough *Passthrough
// TrafficMode selects whether cells are computed against live traffic. The
// zero value means no traffic.
//
// Opt-in for the same reason as on routing — and the stakes are higher here.
// Google's Route Matrix bills PER ELEMENT, so a traffic-aware 10x10 request
// moves 100 billed elements onto the Pro-tier SKU, not one. Setting
// DepartureTime alone therefore does NOT enable traffic; ask for it.
TrafficMode TrafficMode
}
MatrixOptions is the normalized input to Matrix.Matrix. TravelMode defaults to Driving when empty.
type MatrixResult ¶
type MatrixResult struct {
Cells []MatrixCell `json:"cells"`
Raw any `json:"raw"`
}
MatrixResult is the normalized distance matrix.
type Option ¶
type Option func(*facadeOptions)
Option configures a facade constructor.
func WithHTTPClient ¶
func WithHTTPClient(c HTTPClient) Option
WithHTTPClient injects a custom HTTP client (see HTTPClient). Without it, a non-redirect-following default is used.
type OsrmConfig ¶
type OsrmConfig struct {
BaseURL string
// SupportedExcludeClasses lists the exclude classes THIS OSRM build accepts —
// "toll", "ferry", "motorway".
//
// Whether a class is accepted is a property of the OPERATOR'S SERVER, not of
// OSRM, which is why it has to be declared rather than assumed. Verified live on
// two builds that answer the same request differently: exclude=toll is rejected
// with InvalidValue by the public demo build, and honoured by a self-hosted
// instance where it genuinely changed the route (138075 m / 5890 s via the toll
// road → 130421 m / 6513 s without it).
//
// Stock OSRM compiles no exclude classes, so by default the connector rejects
// AvoidTolls / AvoidFerries / AvoidHighways up front with unsupported_option —
// better than sending a request the server will bounce with an opaque
// InvalidValue. List the classes your profile was built with and the matching
// avoid-flags start working.
//
// Declared rather than probed because there is no way to ask an OSRM server what
// it supports without issuing a request that fails, and the wrapper holds no
// state to cache such a probe in.
SupportedExcludeClasses []string
}
OsrmConfig points at a self-hosted OSRM instance. BaseURL is required (there is no public OSRM host). Supports routing and matrix only.
func (OsrmConfig) ProviderID ¶
func (OsrmConfig) ProviderID() ProviderID
type Passthrough ¶
type Passthrough struct {
Body map[string]any `json:"body,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
Query map[string]string `json:"query,omitempty"`
}
Passthrough is the per-operation input escape hatch. Keys are forwarded verbatim: Body is deep-merged into the connector's request body, Headers and Query are shallow-merged. Consumer values intentionally OVERRIDE connector-set values (including auth) — there is deliberately no reserved-key protection.
type PlaceDetailsInclude ¶ added in v1.2.0
type PlaceDetailsInclude string
PlaceDetailsInclude is an opt-in token for an optional place-details output field, mirroring RoutingInclude.
const ( // IncludePlaceName populates PlaceDetailsResult.Name. // // On Google this adds displayName to the MANDATORY field mask, which selects the // Pro SKU tier — the reason it is opt-in rather than always requested. Free on // HERE/Mapbox/TomTom; unavailable on Esri. IncludePlaceName PlaceDetailsInclude = "name" )
type PlaceDetailsOptions ¶ added in v1.2.0
type PlaceDetailsOptions struct {
PlaceID string
Language string
// SessionToken closes a billable session opened by Autocomplete. Honoured by
// Mapbox and Google; ignored by every other provider.
//
// Both vendors bill the autocomplete leg per *session* rather than per request,
// and a session is only one session when every call carries the SAME token:
// - Mapbox: a suggest call plus the retrieve that follows count as ONE
// billable Search Box session. Sent as `session_token`.
// - Google: the keystroke requests plus the details call that closes them
// count as ONE session; without a token each keystroke is billed as its own
// request. Sent as `sessionToken`.
//
// Omitting it, or passing a fresh one, turns a single user interaction into
// several billed ones. The wrapper holds no state and cannot correlate the
// calls, so threading it is the caller's job.
SessionToken string
// Include names optional output fields to fetch. Empty means nothing extra.
Include []PlaceDetailsInclude
Passthrough *Passthrough
}
PlaceDetailsOptions is the input for a place-details lookup: resolve a PlaceID from an autocomplete prediction into a full candidate.
This is deliberately ONE operation rather than two. "Place details" and "geocode by place id" are the same vendor call — every provider resolves its own opaque id to the same address+coordinates payload — so splitting them would put two names on one request.
PlaceID must come from the SAME provider's Autocomplete: these ids are provider-scoped and not interchangeable.
type PlaceDetailsResult ¶ added in v1.2.0
type PlaceDetailsResult struct {
Candidate GeocodeCandidate `json:"candidate"`
// Name is the place's display name, when the provider returns one distinct from
// the formatted address (e.g. "Blue Bottle Coffee" vs its street address).
//
// Empty on providers that only return an address (Esri), and on Google unless
// IncludePlaceName was requested — its Place Details SKU tier is driven by the
// field mask, and displayName is a Pro-tier field. Note this is the OPPOSITE of
// Compute Routes, whose SKU is feature-driven: check per API, do not generalize.
Name string `json:"name,omitempty"`
Raw any `json:"raw"`
}
PlaceDetailsResult is the normalized place-details response.
It returns a full GeocodeCandidate rather than a new shape, because that is what the operation resolves to and reusing it means a caller can feed the result straight into whatever already consumes geocode candidates.
type Polygon ¶
Polygon is a GeoJSON Polygon (closed outer ring), the normalized isochrone contour geometry. Coordinates are [lng, lat] rings.
type PolylineQuality ¶ added in v1.2.0
type PolylineQuality string
PolylineQuality is the geometry fidelity of a returned polyline.
Simplified is the default because the difference is large and one-sided: measured on a single ~140km route, Mapbox returned 203 characters simplified versus 6146 full (30x), OSRM 155 versus 4873 (31x), and Google 883 versus 2565 (2.9x) — with every leg distance and duration byte-identical.
const ( // PolylineSimplified is the zero value and the default. PolylineSimplified PolylineQuality = "" // PolylineDetailed asks for the vendor's full-fidelity geometry. PolylineDetailed PolylineQuality = "detailed" )
type ProviderCode ¶
type ProviderCode string
ProviderCode is the normalized, cross-provider error classification surfaced on every *ConnectorError. The values are byte-identical across the thinwrap location siblings: 6 canonical (shared across thinwrap scopes) + 7 location-extended.
const ( // Canonical (shared across thinwrap scopes). CodeInvalidRecipient ProviderCode = "invalid_recipient" CodeRateLimited ProviderCode = "rate_limited" CodeAuthFailed ProviderCode = "auth_failed" CodeInvalidRequest ProviderCode = "invalid_request" CodeUnknown ProviderCode = "unknown" // Location-extended. CodeUnsupportedField ProviderCode = "unsupported_field" // e.g. OSRM rejecting departureTime (pre-flight) CodeUnsupportedOption ProviderCode = "unsupported_option" // e.g. OSRM rejecting avoid* flags (pre-flight) CodeUnsupportedTravelMode ProviderCode = "unsupported_travel_mode" // e.g. TomTom/ESRI Matrix rejecting cycling CodeProfileNotConfigured ProviderCode = "profile_not_configured" // OSRM missing compiled profile CodeMatrixPollingTimeout ProviderCode = "matrix_polling_timeout" // HERE/TomTom async matrix exceeded deadline // CodeNoRoute means the provider answered successfully but no route exists // between the given waypoints. Distinct from CodeInvalidRequest: the request // was well-formed, so this is a business outcome to branch on rather than a // bug to fix. // // The vendors agree on nothing here — Google answers HTTP 200 with the // "routes" key absent, HERE 200 with routes: [] plus a notices[] code, Mapbox // code: "NoRoute" on either 200 or 422, OSRM the same codes on a 400, TomTom a // 400 with detailedError.code, Esri a 200 with an in-body error.code: 400 // whose details[] name an *unlocated* stop. // // In practice it means a waypoint could not be matched to the road network: // every provider tested routes Reykjavik->Oslo via ferry, so a genuinely // disconnected network is close to unreachable. CodeNoRoute ProviderCode = "no_route" // CodeTimeout means the request exceeded the client's timeout before any // response arrived. CodeTimeout ProviderCode = "timeout" )
type ProviderID ¶
type ProviderID string
ProviderID is the stable, user-facing identifier for a location provider. The string values are byte-identical across the thinwrap location siblings (TypeScript, PHP, Go).
const ( Google ProviderID = "google" Mapbox ProviderID = "mapbox" Here ProviderID = "here" Esri ProviderID = "esri" Osrm ProviderID = "osrm" TomTom ProviderID = "tomtom" )
type ReverseGeocodeOptions ¶
type ReverseGeocodeOptions struct {
Location LatLng
Language string
Passthrough *Passthrough
}
ReverseGeocodeOptions is the normalized input to Geocoding.ReverseGeocode.
type ReverseGeocodeResult ¶
type ReverseGeocodeResult struct {
Candidates []GeocodeCandidate `json:"candidates"`
Raw any `json:"raw"`
}
ReverseGeocodeResult mirrors GeocodeResult (a list, even for providers whose reverse endpoint natively returns a single result).
type Routing ¶
type Routing struct {
// contains filtered or unexported fields
}
Routing is the routing facade. Construct it with NewRouting.
func NewRouting ¶
func NewRouting(cfg RoutingConfig, opts ...Option) *Routing
NewRouting builds a routing facade for the provider selected by cfg's type.
func (*Routing) ProviderID ¶
func (r *Routing) ProviderID() ProviderID
ProviderID returns the provider this facade dispatches to.
func (*Routing) Route ¶
func (r *Routing) Route(ctx context.Context, opts RoutingOptions) (*RoutingResult, error)
Route computes a route over the given waypoints.
type RoutingConfig ¶
type RoutingConfig interface {
ProviderID() ProviderID
// contains filtered or unexported methods
}
RoutingConfig is implemented by every provider config that supports routing.
type RoutingInclude ¶ added in v1.2.0
type RoutingInclude string
RoutingInclude is an opt-in token for an optional normalized output field.
Nothing extra is fetched unless it is named. Each token maps 1:1 onto one optional field of RoutingResult / RoutingLeg — that 1:1 rule is what keeps this from degenerating into a second Passthrough. Vendor data with no normalized field gets no token; read it from Raw.
const ( // IncludeDurationWithoutTraffic populates // RoutingLeg.DurationWithoutTrafficSeconds and // RoutingResult.TotalDurationWithoutTrafficSeconds. // // Free on Google (a field-mask entry), HERE (already inside the requested // summary) and Mapbox/OSRM (not returned at all); TomTom needs the extra // computeTravelTimeFor=all request parameter. IncludeDurationWithoutTraffic RoutingInclude = "durationWithoutTraffic" )
type RoutingLeg ¶
type RoutingLeg struct {
DistanceMeters float64 `json:"distanceMeters"`
DurationSeconds float64 `json:"durationSeconds"`
// DurationWithoutTrafficSeconds is the leg duration ignoring traffic. Non-nil
// only when IncludeDurationWithoutTraffic was requested AND the provider
// returned it natively — never synthesized, so nil is meaningful: this provider
// did not supply the value for this request.
//
// The point of having it alongside DurationSeconds is the delta: the two
// together say how much of a trip's time is congestion, which makes
// ETA-vs-baseline comparisons possible without a second request.
//
// Native on Google (staticDuration), HERE (baseDuration) and TomTom
// (noTrafficTravelTimeInSeconds). Mapbox, OSRM and Esri do not return it.
DurationWithoutTrafficSeconds *float64 `json:"durationWithoutTrafficSeconds,omitempty"`
}
RoutingLeg is one segment of a route.
type RoutingOptions ¶
type RoutingOptions struct {
Waypoints []LatLng
Optimize bool
OptimizeFixedOrigin bool
OptimizeFixedDestination bool
IsRoundTrip bool
DepartureTime *time.Time
AvoidTolls bool
AvoidFerries bool
AvoidHighways bool
TravelMode TravelMode
// TransportMode is a HERE-only augmentation; when set it overrides the
// TravelMode mapping. Ignored by all other providers.
TransportMode HereTransportMode
Passthrough *Passthrough
// PolylineQuality is the geometry fidelity of the returned Polyline. The zero
// value means simplified.
//
// A best-effort hint, not a guarantee. Google, Mapbox and OSRM honour both
// values. HERE and TomTom expose no fidelity control, and Esri offers only a
// generalization *tolerance* in map units (mapping onto some chosen tolerance
// would mean inventing a magic number), so on those three the value is silently
// ignored. That is deliberate: fidelity is cosmetic, so extra vertices cannot
// make a caller's result wrong — unlike AvoidTolls, whose silent omission WOULD
// change routing semantics and therefore errors.
PolylineQuality PolylineQuality
// TrafficMode selects whether the route is computed against live traffic. The
// zero value means no traffic.
//
// Opt-in because traffic is a billable upgrade on some providers — most
// notably Google, where it selects a Pro-tier SKU. It is therefore NOT implied
// by setting DepartureTime. Providers with no traffic control ignore it.
TrafficMode TrafficMode
// Include names optional normalized output fields to fetch. Empty means
// nothing extra is requested, so the response stays as small and as cheap as
// the provider allows.
Include []RoutingInclude
}
RoutingOptions is the normalized input to Routing.Route. Waypoints must have at least two entries. TravelMode defaults to Driving when empty.
type RoutingResult ¶
type RoutingResult struct {
Legs []RoutingLeg `json:"legs"`
TotalDistanceMeters float64 `json:"totalDistanceMeters"`
TotalDurationSeconds float64 `json:"totalDurationSeconds"`
Polyline string `json:"polyline"`
// WaypointOrder, when present, lists input waypoint indices in visiting
// order (0-based, including origin and destination). Nil when no
// optimization was requested or the vendor returned no ordering.
WaypointOrder []int `json:"waypointOrder,omitempty"`
// TotalDurationWithoutTrafficSeconds is the whole-route duration ignoring
// traffic. Same contract as RoutingLeg.DurationWithoutTrafficSeconds: opt-in
// via IncludeDurationWithoutTraffic, vendor-native only, never synthesized.
TotalDurationWithoutTrafficSeconds *float64 `json:"totalDurationWithoutTrafficSeconds,omitempty"`
Raw any `json:"raw"`
}
RoutingResult is the normalized route. Distances are meters, durations are seconds, and Polyline is a Google precision-5 encoded string.
type SpatialReference ¶
type SpatialReference struct {
Wkid int `json:"wkid"`
}
SpatialReference is the CRS wrapper in ESRI-JSON geometry. Locked to WGS-84.
type TomTomConfig ¶
type TomTomConfig struct{ APIKey string }
TomTomConfig authenticates the TomTom provider. Supports all four operations.
func (TomTomConfig) ProviderID ¶
func (TomTomConfig) ProviderID() ProviderID
type TrafficMode ¶ added in v1.2.0
type TrafficMode string
TrafficMode selects how much traffic data a route is computed against.
const ( // TrafficNone is the zero value and the default. On Google this keeps the // request on the base Essentials SKU rather than Pro. TrafficNone TrafficMode = "" // TrafficLive uses current traffic conditions where the provider supports it. TrafficLive TrafficMode = "live" )
type TravelMode ¶
type TravelMode string
TravelMode is the normalized travel mode. Providers map it to their native vocabulary; unsupported combinations surface as unsupported_travel_mode.
const ( Driving TravelMode = "driving" Walking TravelMode = "walking" Cycling TravelMode = "cycling" )
Source Files
¶
- base.go
- config.go
- coordinate.go
- doc.go
- errors.go
- esri.go
- facades.go
- geocoding.go
- google.go
- here.go
- httpclient.go
- isochrone.go
- isochrone_validate.go
- json.go
- jsonpath.go
- latlng.go
- mapbox.go
- matrix.go
- options.go
- osrm.go
- passthrough.go
- poll.go
- polyline.go
- provider.go
- routecompleteness.go
- routing.go
- tomtom.go
- util.go
- waypointorder.go