maps

package
v0.38.18 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package maps wires same-origin reverse-proxies that let the SPA reach self-hosted map services (Valhalla for routing + map matching, an nginx-served PMTiles bundle for vector basemaps) through the existing rivolt origin and session cookie.

Why proxy instead of CORS-on-the-upstream:

  • Most upstreams (Valhalla, the tile nginx) have no native CORS. nginx can be configured for it, but exposing each upstream behind its own ingress + cert burns hostnames for what is effectively the SPA's own data path.
  • Proxying through the rivolt API keeps drive maps same-origin, reuses the existing auth middleware (routes are mounted inside the requireUser group), and lets us add per-user rate limits later without touching the cluster.
  • The frontend code change shrinks to "swap base URL"; no CORS preflight handling, no second fetch credential mode.

The proxy is intentionally dumb: it forwards every request path unchanged to the upstream. Path-prefix stripping is done at mount time via http.StripPrefix in api.go, so this package only handles host rewrite and credential scrubbing.

Index

Constants

View Source
const MaxTileResponse = 2 << 20

MaxTileResponse is the most a single tile read may carry. Real reads are a header, a directory or one tile (the largest in the 19 GB basemap is 344 KiB); 2 MiB leaves room, and anything bigger is an upstream answering something other than the byte range that was asked for.

Variables

View Source
var ErrInvalidURL = errors.New("maps: base URL must include scheme and host")

ErrInvalidURL is returned when a configured base URL parses but is missing a scheme or host. Treated as fatal at startup so a typo in RIVOLT_VALHALLA_BASE_URL / RIVOLT_TILES_BASE_URL fails fast instead of silently dropping every drive map back to public CDNs.

View Source
var ErrNoRoute = errors.New("valhalla: no route found")

ErrNoRoute means Valhalla found no road route between the locations (a location in the ocean, or islands with no ferry). It is the caller's input, not a service failure.

Functions

func AllowTiles added in v0.37.5

func AllowTiles(next http.Handler) http.Handler

AllowTiles admits only GET/HEAD of a single top-level *.pmtiles file (Range requests are plain GETs). Directory listings, nested paths and any other file on the tile server are refused. Whatever is admitted goes through guardTiles, so a GET can only ever be answered with a bounded byte range.

func AllowValhalla added in v0.37.5

func AllowValhalla(next http.Handler) http.Handler

AllowValhalla admits only what the SPA uses: POST /route and POST /trace_route. Everything else (isochrone, matrix, expansion, status, any GET) is refused before it reaches Valhalla.

func NewProxy

func NewProxy(baseURL string) (http.Handler, error)

NewProxy builds a reverse-proxy handler that forwards to baseURL. The empty string returns (nil, nil) - callers (api.New) treat nil as "feature off" and skip mounting the route.

baseURL is typically a cluster-internal Service address ("http://valhalla.valhalla.svc.cluster.local", "http://tiles.tiles.svc.cluster.local").

Types

type Route added in v0.37.0

type Route struct {
	Legs []RouteLeg
}

Route is a Valhalla route through an ordered list of locations.

type RouteLeg added in v0.37.0

type RouteLeg struct {
	LengthMeters float64
	TimeSec      float64
	// Shape is the leg's road geometry as (lat, lon) pairs.
	Shape [][2]float64
}

RouteLeg is one leg of a Route: from one location to the next.

type RouteOpts added in v0.37.0

type RouteOpts struct {
	AvoidTolls    bool
	AvoidFerries  bool
	AvoidHighways bool
}

RouteOpts are the routing preferences Route honours.

type Valhalla

type Valhalla struct {
	HTTP    *http.Client
	BaseURL string
}

Valhalla is a thin server-to-server client for the in-cluster Valhalla routing service. It exists alongside the same-origin reverse proxy (NewProxy in this package) — the proxy is for the SPA, this client is for backend code that wants a routing answer directly without going through the user-facing HTTP path.

Today the only consumer is the live recorder's GPS-gap fill: when the WS feed drops fixes for several seconds, we ask Valhalla what road-level path is most likely between the last good fix and the new one, and splice that shape into the drive polyline so the rendered trace doesn't contain a straight-line shortcut across whatever the car actually drove.

func NewValhalla

func NewValhalla(baseURL string) *Valhalla

NewValhalla returns a client pointed at baseURL. Empty baseURL returns nil — callers must nil-check and skip the feature.

func (*Valhalla) Enabled

func (v *Valhalla) Enabled() bool

Enabled reports whether the client is configured.

func (*Valhalla) Route added in v0.37.0

func (v *Valhalla) Route(ctx context.Context, locs [][2]float64, opts RouteOpts) (Route, error)

Route asks Valhalla for the auto route through locs (lat, lon pairs, at least two, every one a stop so each gap is its own leg) in one request, and returns per-leg length, time and shape. It sits beside RouteShape, which stays as it is.

func (*Valhalla) RouteShape

func (v *Valhalla) RouteShape(ctx context.Context, from, to [2]float64) ([][2]float64, error)

RouteShape returns the on-road shape between two points as a sequence of (lat, lon) pairs, derived from a Valhalla /route call with auto costing. Used by the recorder to fill GPS-lag gaps with a plausible road-snapped path. The returned slice INCLUDES the requested endpoints (Valhalla always echoes them as the first/last shape vertex).

The context's deadline bounds the upstream call. Callers should pass a tight timeout (a few hundred ms) — if Valhalla can't answer quickly it's better to fall back to a straight line than to delay the live recorder.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL