Skip to content

About

Live Mapbox route map + driver location + geofenced arrival check for React Native / Expo

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

React Native Route Map Example

A small, runnable Expo app showing how to build a live Mapbox map with a route line, stop pins, and a "you are here" driver dot in React Native — plus a second screen for a geofenced arrival check (is the driver inside a radius around a target location?).

This is a cleaned-up extract of a real feature built for Sarvika's Supply Chain Management mobile app (last-mile delivery tracking). The business logic (facility names, delivery workflow, backend wiring) has been stripped out; the Mapbox mechanics — the actually reusable, non-obvious part — are kept intact. Use this as a starting point whenever a project needs "a live map with a route and a moving location marker" instead of re-solving the same problems from scratch.

What's in here

File Demonstrates
src/components/LiveRouteMap.tsx Full route + "active leg" polylines with a gradient/glow style, stop pins that declutter when close together, direction-arrow chips, camera auto-fit, a live driver position
src/components/GeofencedMapPreview.tsx A radius-based geofence rendered as a real GeoJSON circle (Mapbox has no meters-based circle primitive), with in-range/out-of-range styling
src/components/CurrentLocationDot.tsx A reusable pulsing "you are here" marker
src/utils/polyline6.ts Decoding a polyline6-encoded route geometry (the format Mapbox Directions / most routing APIs return) into coordinates
src/utils/geo.ts Haversine distance + generating a real-world-meters circle polygon for the geofence
metro.config.js Two Metro gotchas specific to @rnmapbox/maps (see below)

Run it, then use src/screens/RouteMapDemoScreen.tsx and src/screens/GeofenceDemoScreen.tsx as the "how do I wire this up" reference.

Prerequisites

  • A Mapbox account and a public access token (starts with pk.) — free tier is enough for this demo.
  • @rnmapbox/maps is a native module. This is not an Expo Go app — Expo Go doesn't include Mapbox's native code. You need a custom dev client (already wired up here via the expo-dev-client plugin) or a full expo run:android / expo run:ios build.
  • Depending on your Mapbox SDK version and platform, you may also need a Mapbox secret downloads token (different from the public access token) configured for the native Android/iOS build to even fetch the SDK. This wasn't required by the source app's current setup, but check @rnmapbox/maps' own install docs for your exact version if the native build fails to pull dependencies.

Setup

npm install
cp .env.example .env
# edit .env and paste in your Mapbox public access token

Then either:

npx expo run:android   # builds a real dev client + installs it
npx expo run:ios

or, if you already have a dev client build installed on a device/simulator:

npx expo start

npx expo start --web also works, but only for layout — see the web fallback note below.

Non-obvious things this sample already solved for you

  • Android: a Mapbox MapView inside a ScrollView fights the outer scroll gesture for touches. react-native-gesture-handler's Gesture.Native() does not resolve this for @rnmapbox/maps's MapView. LiveRouteMap exposes onTouchStart/onTouchEnd so the parent screen can disable its own ScrollView while a finger is on the map — see RouteMapDemoScreen.tsx for the wiring.
  • Camera.bounds silently no-ops if you fit bounds before the native MapView has taken on its real layout size (fails with "map size is {24, 24}" on-device, with no retry). Both map components gate the first <Camera> fit on onDidFinishLoadingMap, which only fires after layout has already happened — simpler than a manual onLayout size check.
  • No real-world-meters circle primitive. CircleLayer's radius is in screen pixels, not meters, so it zooms wrong. geo.ts's circlePolygon() generates an actual GeoJSON polygon ring instead, fed through ShapeSource + FillLayer/LineLayer.
  • @rnmapbox/maps has no web build worth using. Its web bundle doesn't export ShapeSource/LineLayer/PointAnnotation at all, and pulls in a mapbox-gl CSS file Metro can't load. Both map components render a static text fallback on Platform.OS === 'web' instead of crashing, and metro.config.js stubs out the mapbox-gl/.css imports so the web bundle can even compile in the first place.
  • Stop pins that sit too close together get pushed apart (scaled to how zoomed-out the current route is, not a fixed distance), and direction-arrow chips are placed one per route leg, at that leg's own midpoint, ranked by real length and capped at a handful so they land on the stretches that actually benefit from one rather than clustering near the start — both in LiveRouteMap.tsx.

What's deliberately left out

  • Navigation between the two demo screens is a plain useState toggle in App.tsx, not a routing library — add @react-navigation yourself if your project needs real navigation.
  • No backend/routing-API integration. src/mock/sampleRoute.ts builds a fake route with a tiny local encodePolyline6() helper just so the demo exercises the same decode path production data would go through — a real app would get this string from Mapbox Directions or its own routing service instead.

About

Live Mapbox route map + driver location + geofenced arrival check for React Native / Expo

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages