Skip to content

Both copy text to your clipboard — Build with AI copies a setup prompt to paste into Claude Code, Cursor, Codex or Copilot; Copy page as Markdown copies this page to paste into a chat. How it works

Add Multiple Geometries from One GeoJSON Source

Use one GeoJSON source containing mixed geometry types and render each type in its own layer using geometry type filters.

Key Concept: Geometry Type Filter

Use ['==', ['geometry-type'], 'Point'] to target specific geometry types from a shared source:

javascript
// Single source with mixed geometries
map.addSource('mixed', {
  type: 'geojson',
  data: {
    type: 'FeatureCollection',
    features: [
      { type: 'Feature', geometry: { type: 'Point', coordinates: [0, 0] }, properties: {} },
      { type: 'Feature', geometry: { type: 'LineString', coordinates: [[0,0],[1,1]] }, properties: {} },
      { type: 'Feature', geometry: { type: 'Polygon', coordinates: [[[0,0],[1,0],[1,1],[0,0]]] }, properties: {} }
    ]
  }
});

// Render only Points
map.addLayer({
  id: 'points', type: 'circle', source: 'mixed',
  filter: ['==', ['geometry-type'], 'Point'],
  paint: { 'circle-radius': 8, 'circle-color': '#3b82f6' }
});

// Render only Lines
map.addLayer({
  id: 'lines', type: 'line', source: 'mixed',
  filter: ['==', ['geometry-type'], 'LineString'],
  paint: { 'line-color': '#ef4444', 'line-width': 3 }
});

// Render only Polygons
map.addLayer({
  id: 'polygons', type: 'fill', source: 'mixed',
  filter: ['==', ['geometry-type'], 'Polygon'],
  paint: { 'fill-color': '#22c55e', 'fill-opacity': 0.3 }
});

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: [5, 48], zoom: 4 });
      map.on('load', () => {
        map.addSource('mixed', {
          type: 'geojson',
          data: {
            type: 'FeatureCollection',
            features: [
              { type: 'Feature', properties: {}, geometry: { type: 'Point', coordinates: [2.35, 48.85] } },
              { type: 'Feature', properties: {}, geometry: { type: 'LineString', coordinates: [[2.35, 48.85], [-0.12, 51.50]] } },
              { type: 'Feature', properties: {}, geometry: { type: 'Polygon', coordinates: [[[0, 46], [15, 46], [15, 54], [0, 54], [0, 46]]] } }
            ]
          }
        });
        map.addLayer({ id: 'fills', type: 'fill', source: 'mixed', filter: ['==', ['geometry-type'], 'Polygon'], paint: { 'fill-color': '#3b82f6', 'fill-opacity': 0.2 } });
        map.addLayer({ id: 'lines', type: 'line', source: 'mixed', filter: ['==', ['geometry-type'], 'LineString'], paint: { 'line-color': '#ef4444', 'line-width': 3 } });
        map.addLayer({ id: 'points', type: 'circle', source: 'mixed', filter: ['==', ['geometry-type'], 'Point'], paint: { 'circle-radius': 8, 'circle-color': '#22c55e' } });
      });
    </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 mixedData = {
  type: 'FeatureCollection',
  features: [
    { type: 'Feature', properties: {}, geometry: { type: 'Point', coordinates: [2.35, 48.85] } },
    { type: 'Feature', properties: {}, geometry: { type: 'LineString', coordinates: [[2.35, 48.85], [-0.12, 51.50]] } },
    { type: 'Feature', properties: {}, geometry: { type: 'Polygon', coordinates: [[[0, 46], [15, 46], [15, 54], [0, 54], [0, 46]]] } }
  ]
};

const MultipleGeometries = () => {
  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: [5, 48], zoom: 4 });
    map.current.on('load', () => {
      map.current.addSource('mixed', { type: 'geojson', data: mixedData });
      map.current.addLayer({ id: 'fills', type: 'fill', source: 'mixed', filter: ['==', ['geometry-type'], 'Polygon'], paint: { 'fill-color': '#3b82f6', 'fill-opacity': 0.2 } });
      map.current.addLayer({ id: 'lines', type: 'line', source: 'mixed', filter: ['==', ['geometry-type'], 'LineString'], paint: { 'line-color': '#ef4444', 'line-width': 3 } });
      map.current.addLayer({ id: 'points', type: 'circle', source: 'mixed', filter: ['==', ['geometry-type'], 'Point'], paint: { 'circle-radius': 8, 'circle-color': '#22c55e' } });
    });
    return () => { map.current?.remove(); map.current = null; };
  }, []);

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

export default MultipleGeometries;

For more information, visit the MapMetrics GitHub repository.