MapSnippets logoMapSnippets logo

Display a Route with MapLibre GL JS

MapLibre GL JS

Display a driving route between two points using the OSRM routing API and a GeoJSON line layer in MapLibre GL JS.

progress_activityLoading map...
const map = new maplibregl.Map({
  container: 'map',
  style: 'https://api.maptiler.com/maps/streets-v4/style.json?key=YOUR_MAPTILER_KEY',
  center: [2.35, 48.86],
  zoom: 12
});
map.addControl(new maplibregl.NavigationControl());
const start = [2.3364, 48.8606], end = [2.2945, 48.8584];
map.on('load', async () => {
  const url = `https://router.project-osrm.org/route/v1/driving/${start[0]},${start[1]};${end[0]},${end[1]}?overview=full&geometries=geojson`;
  const res = await fetch(url);
  const data = await res.json();
  if (!data.routes.length) return;
  map.addSource('route', { type: 'geojson', data: { type: 'Feature', geometry: data.routes[0].geometry } });
  map.addLayer({ id: 'route-line', type: 'line', source: 'route',
    layout: { 'line-join': 'round', 'line-cap': 'round' },
    paint: { 'line-color': '#2196F3', 'line-width': 5 } });
  new maplibregl.Marker({ color: '#4CAF50' }).setLngLat(start).setPopup(new maplibregl.Popup().setText('Start: Louvre')).addTo(map);
  new maplibregl.Marker({ color: '#F44336' }).setLngLat(end).setPopup(new maplibregl.Popup().setText('End: Eiffel Tower')).addTo(map);
  const coords = data.routes[0].geometry.coordinates;
  const bounds = coords.reduce((b, c) => b.extend(c), new maplibregl.LngLatBounds(coords[0], coords[0]));
  map.fitBounds(bounds, { padding: 60 });
});

How it works

MapTiler does not provide a routing API, so this example uses the free OSRM (Open Source Routing Machine) demo server. The OSRM API returns a route as GeoJSON geometry that MapLibre renders directly as a line layer.

The URL format is router.project-osrm.org/route/v1/driving/{lng1},{lat1};{lng2},{lat2} with overview=full&geometries=geojson to get the complete route as GeoJSON. OSRM supports driving, cycling, and walking profiles.

After receiving the route, fitBounds frames the entire route on screen with padding. Start and end markers show the origin and destination.

Key APIs

API Description Docs
OSRM Route API Calculate driving routes project-osrm.org/docs
map.fitBounds() Frame a bounding box maplibre.org docs
LngLatBounds.extend() Expand bounds to include a point maplibre.org docs

FAQ

Can I use a different routing profile?

Yes. Replace driving in the URL with cycling or walking for different transport modes.

Why not use MapTiler for routing?

MapTiler does not offer a routing, isochrone, or distance matrix API. OSRM is a reliable open-source alternative.

Is the OSRM demo server suitable for production?

No. The demo server at router.project-osrm.org is for testing only. For production, host your own OSRM instance or use a commercial routing provider.

Common mistakes

  • Using MapTiler API for routing: it does not exist; use OSRM instead
  • Forgetting geometries=geojson in the OSRM URL: the default format is polyline, not GeoJSON
  • Swapping lat and lng in the OSRM URL: OSRM uses lng,lat order like GeoJSON
auto_awesome

Build maps using MapLibre GL JS with AI

Generate code like this display a route with maplibre gl js example using the MapLibre GL JS skill in your IDE.