Skip to content

Style Lines with a Data-Driven Property ​

Change line color and width based on feature data properties using MapMetrics GL expressions.

Lines are styled by speed property: 🔴 fast highway · 🟡 medium road · 🟢 slow street

How It Works ​

Use MapMetrics GL expressions in layer paint properties to read feature properties and apply styles dynamically.

Color by Property Value ​

match expression — exact value matching ​

javascript
'line-color': [
  'match', ['get', 'type'],
  'highway', '#ef4444',   // red for highways
  'road',    '#eab308',   // yellow for roads
  'street',  '#22c55e',   // green for streets
  '#94a3b8'               // default (gray)
]

step expression — numeric ranges ​

javascript
'line-color': [
  'step', ['get', 'speed'],
  '#22c55e',    // default (speed < 60)
  60,  '#eab308', // speed >= 60
  100, '#ef4444'  // speed >= 100
]

interpolate expression — smooth gradient ​

javascript
'line-color': [
  'interpolate', ['linear'], ['get', 'speed'],
  0,   '#22c55e',   // green at 0 km/h
  60,  '#eab308',   // yellow at 60 km/h
  130, '#ef4444'    // red at 130 km/h
]

Width by Property ​

javascript
'line-width': [
  'interpolate', ['linear'], ['get', 'speed'],
  0,   1,    // thin at slow speed
  130, 8     // thick at high speed
]

Complete Example ​

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <link href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css" rel="stylesheet" />
    <script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>
    <style>#map { height: 500px; width: 100%; }</style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      const map = new mapmetricsgl.Map({
        container: 'map',
        style: '<StyleFile_URL_with_Token>',
        center: [2.349902, 48.852966],
        zoom: 5
      });

      map.on('load', () => {
        map.addSource('roads', {
          type: 'geojson',
          data: {
            type: 'FeatureCollection',
            features: [
              {
                type: 'Feature',
                properties: { name: 'Highway', type: 'highway', speed: 130 },
                geometry: { type: 'LineString', coordinates: [[2.35, 48.85], [5.0, 47.5]] }
              },
              {
                type: 'Feature',
                properties: { name: 'Road', type: 'road', speed: 80 },
                geometry: { type: 'LineString', coordinates: [[2.35, 48.85], [2.5, 47.0]] }
              },
              {
                type: 'Feature',
                properties: { name: 'Street', type: 'street', speed: 30 },
                geometry: { type: 'LineString', coordinates: [[2.35, 48.85], [1.0, 49.5]] }
              }
            ]
          }
        });

        map.addLayer({
          id: 'roads-layer',
          type: 'line',
          source: 'roads',
          paint: {
            'line-color': [
              'step', ['get', 'speed'],
              '#22c55e', 60, '#eab308', 100, '#ef4444'
            ],
            'line-width': [
              'match', ['get', 'type'],
              'highway', 5, 'road', 3, 'street', 1.5, 2
            ]
          }
        });
      });
    </script>
  </body>
</html>
jsx
import React, { useEffect, useRef } from 'react';
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';

const roadsData = {
  type: 'FeatureCollection',
  features: [
    { type: 'Feature', properties: { name: 'Highway', type: 'highway', speed: 130 },
      geometry: { type: 'LineString', coordinates: [[2.35, 48.85], [5.0, 47.5]] } },
    { type: 'Feature', properties: { name: 'Road', type: 'road', speed: 80 },
      geometry: { type: 'LineString', coordinates: [[2.35, 48.85], [2.5, 47.0]] } },
    { type: 'Feature', properties: { name: 'Street', type: 'street', speed: 30 },
      geometry: { type: 'LineString', coordinates: [[2.35, 48.85], [1.0, 49.5]] } },
  ]
};

const DataDrivenLines = () => {
  const mapContainer = useRef(null);
  const map = useRef(null);

  useEffect(() => {
    if (map.current) return;

    map.current = new mapmetricsgl.Map({
      container: mapContainer.current,
      style: '<StyleFile_URL_with_Token>',
      center: [2.349902, 48.852966],
      zoom: 5
    });

    map.current.on('load', () => {
      map.current.addSource('roads', { type: 'geojson', data: roadsData });

      map.current.addLayer({
        id: 'roads-layer',
        type: 'line',
        source: 'roads',
        paint: {
          'line-color': ['step', ['get', 'speed'], '#22c55e', 60, '#eab308', 100, '#ef4444'],
          'line-width': ['match', ['get', 'type'], 'highway', 5, 'road', 3, 'street', 1.5, 2]
        }
      });
    });

    return () => { map.current?.remove(); map.current = null; };
  }, []);

  return <div ref={mapContainer} style={{ height: '500px', width: '100%' }} />;
};

export default DataDrivenLines;

For more information, visit the MapMetrics GitHub repository.