Skip to content

teritorio/maplibre-gl-teritorio-cluster

Repository files navigation

MapLibre GL Teritorio Cluster

Render native MapLibre GL JS clusters as HTML marker.

Renders:

  • HTML cluster
  • HTML Unfolded cluster defined by a minimum leaves and min / max zoom threshold
  • Pin Marker on feature click

Allow visualization and interaction with all markers, even when superposed. Can display and interact with small cluster without the need to zoom or uncluster.

See the Demo page.

alt text

Usage

Install as a dependency

yarn add @teritorio/maplibre-gl-teritorio-cluster

Or use it from CDN

<script type="module" src="https://unpkg.com/@teritorio/maplibre-gl-teritorio-cluster/dist/maplibre-gl-teritorio-cluster.js"></script>

Warning

Set your GeoJson source with clusterMaxZoom: 22 in order to let the plugin handle cluster/individual marker rendering across all zoom level

import { TeritorioCluster } from '@teritorio/maplibre-gl-teritorio-cluster'
import { Map } from 'maplibre-gl'

const map = new Map({
  container: 'map',
  style: {
    version: 8,
    name: 'Empty Style',
    metadata: { 'maputnik:renderer': 'mlgljs' },
    sources: {
      points: {
        type: 'geojson',
        cluster: true,
        clusterRadius: 80,
        clusterMaxZoom: 22, // Required
        data: {
          type: 'FeatureCollection',
          features: [
            {
              type: 'Feature',
              properties: { id: 1 },
              geometry: { type: 'Point', coordinates: [0, 0] }
            },
            {
              type: 'Feature',
              properties: { id: 2 },
              geometry: { type: 'Point', coordinates: [0, 1] }
            }
          ]
        }
      }
    },
    glyphs: 'https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf',
    layers: [
      {
        id: 'cluster',
        type: 'circle',
        source: 'points'
      }
    ],
    id: 'muks8j3'
  }
})

map.on('load', () => {
  const teritorioCluster = new TeritorioCluster(map, 'points', options)

  // Get feature click event
  teritorioCluster.addEventListener('click', (e) => {
    console.log(e.detail.selectedFeature)
  })
})

// Create whatever HTML element you want as Cluster
function clusterRender(element, props) {}

// Create whatever HTML element you want as individual Marker
function markerRender(element, feature, markerSize) {}

// Create whatever HTML element you want as Pin Marker
function pinMarkerRender(coords, offset) {}

API

TeritorioCluster

Create a new Maplibre GL JS plugin for feature (cluster / individual marker) rendering

Parameters

Name Type Description Required Default value
map Map The Map object represents the map on your page
sourceId string The ID of the source. Should be a vector source, preferably of type GeoJSON and not vector tiles
options object Options to configure the plugin undefined

Options

Name Type Description Required Default value
clusterMaxZoom number Maximal zoom level at which we force the rendering of the Unfolded Cluster 17
clusterMinZoom number Minimal zoom level at which we force the rendering of the Unfolded Cluster 0
clusterRenderFn (element: HTMLDivElement, props: MapGeoJSONFeature['properties']): void Cluster render function src/utils/helpers.ts/clusterRenderDefault()
fitBoundsOptions FitBoundsOptions Options for Map#fitBounds method { padding: 20 }
initialFeature MapGeoJSONFeature Feature to select on initial rendering undefined
markerRenderFn (element: HTMLDivElement, feature: MapGeoJSONFeature, markerSize: number): void Individual Marker render function src/utils/helpers.ts/markerRenderDefault()
markerSize number (in px) Size of Marker 24
unfoldedClusterRenderFn (parent: HTMLDivElement, items: MapGeoJSONFeature[], markerSize: number, renderMarker: (feature: MapGeoJSONFeature) => HTMLDivElement, clickHandler: (e: Event, feature: MapGeoJSONFeature) => void) => void Unfolded Cluster render function src/utils/helpers.ts/unfoldedClusterRenderSmart()
unfoldedClusterRenderSmart Mix between Circular and HexaShape shape Unfolded Cluster render function - - -
unfoldedClusterRenderGrid Grid shape Unfolded Cluster render function function - - -
unfoldedClusterRenderCircle Circular shape Unfolded Cluster render function function - - -
unfoldedClusterRenderHexaGrid HexaGrid shape Unfolded Cluster render function function - - -
unfoldedClusterMaxLeaves number Unfolded Cluster max leaves number 7
pinMarkerRenderFn (coords: LngLatLike, offset: Point): Marker Pin Marker render function src/utils/helpers.ts/pinMarkerRenderDefault()

Methods

Name Type Description
addEventListener ('feature-click', (e: Event) => void) Listen to feature click and return a MapGeoJSONFeature from e.detail.selectedFeature for external control.
resetSelectedFeature () => void Remove selected feature and associated Pin Marker
setBoundsOptions (options: FitBoundsOptions) => void Update Map's visible area
setSelectedFeature (feature: MapGeoJSONFeature) => void Set selected feature and display Pin Marker on top of it

Dev

Install dependencies

yarn install

Serve the demo page

yarn dev

Requirements

Requires maplibre-gl-js >= v4.0.0.

Contribution

Please see the contribution guide.

Author

Teritorio