Files
Xpress-rider/docs/MAPS.md
2026-08-12 10:50:45 +05:30

4.3 KiB

Maps & routing

Fully open source, no API key, no account, no card.

Concern Technology Cost
Rendering MapLibre GL (BSD) free
Tiles OpenFreeMap — OSM data, MIT free, no key, no limits
Routing OSRM (BSD) free, self-hostable

There is no dependency on Google Maps: no Maps SDK, no Directions API, no com.google.android.geo.API_KEY in the manifest, and no credential of any kind shipped in the app.

Why

Google's mobile Maps SDK is free and unlimited — the bill came from the Directions API at $5 per 1,000 requests above a 10,000/month free tier. Two things made it worse: the multi-stop screen issued one Directions call per route segment, and the API key was hardcoded in five places (including AndroidManifest.xml), unrestricted because the routing calls went out from the device as web-service requests.

Commercial alternatives were considered and rejected because they all want an account and a payment method. The open-source stack has neither.

Configuration

Nothing is required to run the app — the defaults work out of the box:

flutter run

Both endpoints are overridable at build time, so production can point at self-hosted infrastructure without a code change:

flutter build apk \
  --dart-define=OSRM_BASE_URL=https://osrm.your-domain.in \
  --dart-define=MAP_STYLE_URL=https://tiles.your-domain.in/styles/liberty

Before production, stand up your own OSRM. The default (routing.openstreetmap.de) is the FOSSGIS community server — free and keyless, but donation-funded with a fair-use policy that a delivery fleet would abuse. See deploy/osrm/README.md; the Coimbatore region needs only a 0.52 GB extract.

Tiles do not need self-hosting — OpenFreeMap's public instance has no key and no request limits, and permits commercial use under MIT with attribution (which MapLibre renders automatically).

Layout

File Role
lib/services/maps/map_config.dart Tile style + routing endpoints
lib/services/maps/routing_service.dart OSRM client, polyline decoding, response cache
lib/services/maps/map_marker_icons.dart Canvas-drawn marker bitmaps (MapLibre has no built-in pins)
lib/services/maps/nearle_map.dart The NearleMap widget — declarative markers/polylines over MapLibre

Provider choice is confined to the first two files. The four map screens talk only to NearleMap and RoutingService, so swapping backends again would not touch UI code.

OSRM notes

  • Coordinates go in the URL path as lon,lat — the reverse of most APIs.
  • overview=full&geometries=polyline returns an encoded polyline at precision 5. OSRM's polyline6 option is precision 6; pass precision: 6 to decodePolyline if you ever switch.
  • _parse() is deliberately tolerant — plain-number or {"value": n} distances, several geometry key names, GeoJSON LineString — so a proxy or an OSRM-compatible alternative (Valhalla, GraphHopper) drops in without changes.

Cost controls

These mattered when routing was billed and still cut latency and load:

  • One call per route, not per leg. The multi-stop screen passes intermediate stops as additional coordinates in a single OSRM request. It previously issued one request per consecutive pair, so an N-stop route cost N calls every time the screen opened.
  • Response cache. RoutingService caches by origin/destination rounded to ~11 m for 30 minutes, so repeated quotes for the same delivery reuse one call.
  • Rendering makes no routing calls at all.

Known gaps vs. the old Google implementation

  • Info windows. MapLibre has no info-window concept. Marker taps still fire (NearleMapMarker.onTap drives the customer sheet on the multi-stop screen), but the old tap-to-show-title bubbles are gone.
  • Traffic and 3D buildings. trafficEnabled / buildingsEnabled on the navigation screen had no MapLibre equivalent and were dropped. OSRM has no live-traffic model either — ETAs are free-flow estimates.
  • Turn-by-turn navigation is unchanged. It still hands off to whatever navigation app is installed via a google.navigation: / maps URL intent. That is an OS intent, not an API — no key, no SDK, no billing.