MapSnippets logoMapSnippets logo

Live GPS Tracking with MapLibre GL JS

MapLibre GL JS

Simulate a moving marker by updating a GeoJSON source position in real time with setInterval.

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: [14.42, 50.08],
  zoom: 14
});
const route = [[14.410,50.090],[14.415,50.088],[14.420,50.085],[14.425,50.082],[14.430,50.080],[14.435,50.078]];
let step = 0;
map.on('load', () => {
  map.addSource('tracker', { type: 'geojson', data: { type: 'Point', coordinates: route[0] } });
  map.addLayer({ id: 'tracker-dot', type: 'circle', source: 'tracker',
    paint: { 'circle-radius': 10, 'circle-color': '#F44336', 'circle-stroke-width': 3, 'circle-stroke-color': '#fff' } });
  map.addSource('trail', { type: 'geojson', data: { type: 'LineString', coordinates: [route[0]] } });
  map.addLayer({ id: 'trail-line', type: 'line', source: 'trail',
    paint: { 'line-color': '#2196F3', 'line-width': 3, 'line-dasharray': [2, 2] } });
  const trail = [route[0]];
  setInterval(() => {
    step = (step + 1) % route.length;
    const pos = route[step];
    map.getSource('tracker').setData({ type: 'Point', coordinates: pos });
    trail.push(pos);
    map.getSource('trail').setData({ type: 'LineString', coordinates: trail });
    map.panTo(pos, { duration: 500 });
  }, 1000);
});

How it works

This example simulates a moving object by updating a GeoJSON point source on an interval. Every second, the tracker advances to the next coordinate along a predefined route, and the trail line grows behind it.

The setData() method on a GeoJSON source replaces its data completely. Because MapLibre renders sources on the GPU, updating a single point is very efficient. The map pans smoothly to follow the tracker using panTo() with a duration.

In a real application, replace the predefined route with WebSocket or API data to show live vehicle or device positions.

Key APIs

API Description Docs
source.setData() Replace GeoJSON source data maplibre.org docs
map.panTo() Smooth pan to coordinates maplibre.org docs
setInterval JavaScript timer for periodic updates MDN docs

FAQ

How do I smooth the movement between points?

Interpolate between consecutive coordinates using linear interpolation on each animation frame instead of jumping between points on a fixed interval.

Can I show the heading direction?

Add a symbol layer with icon-rotate set to the bearing calculated from consecutive positions.

Common mistakes

  • Creating a new source on every update instead of calling setData(): causes memory leaks
  • Not clearing the interval when the map is removed: use clearInterval in cleanup
  • Forgetting to wrap source/layer additions in map.on('load', ...)
auto_awesome

Build maps using MapLibre GL JS with AI

Generate code like this live gps tracking with maplibre gl js example using the MapLibre GL JS skill in your IDE.