Create and style clusters
Use NMaps GL JS' built-in functions to visualize points as clusters.
<!DOCTYPE html><html><head><meta charset="utf-8" /><title>Create and style clusters</title><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /><script src="https://cdn.ndrive.com/nmapsgl/v.1.6.8/nmaps-gl.js"></script><link href="https://cdn.ndrive.com/nmapsgl/v.1.6.8/nmaps-gl.css" rel="stylesheet" /><style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; }</style></head><body><div id="map"></div> <script> // TO MAKE THE MAP APPEAR YOU MUST ADD YOUR ACCESS TOKEN nmapsgl.accessToken = '<your access token here>'; const map = new nmapsgl.Map({container: 'map',style: 'Dark',center: [-103.59179687498357, 40.66995747013945],zoom: 3}); map.on('load', () => {// Add a new source from our GeoJSON data and// set the 'cluster' option to true. GL-JS will// add the point_count property to your source data.map.addSource('earthquakes', {type: 'geojson',// Point to GeoJSON data. This example visualizes all M1.0+ earthquakes// from 12/22/15 to 1/21/16 as logged by USGS' Earthquake hazards program.data: 'https://nmaps-gl.ndrive.com/nmaps-gl-js/assets/earthquakes.geojson',cluster: true,clusterMaxZoom: 14, // Max zoom to cluster points onclusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)}); map.addLayer({id: 'clusters',type: 'circle',source: 'earthquakes',filter: ['has', 'point_count'],paint: {// Use step expressions with three steps to implement three types of circles:// * Blue, 20px circles when point count is less than 100// * Yellow, 30px circles when point count is between 100 and 750// * Pink, 40px circles when point count is greater than or equal to 750'circle-color': ['step',['get', 'point_count'],'#51bbd6',100,'#f1f075',750,'#f28cb1'],'circle-radius': ['step',['get', 'point_count'],20,100,30,750,40]}}); map.addLayer({id: 'cluster-count',type: 'symbol',source: 'earthquakes',filter: ['has', 'point_count'],layout: {'text-field': '{point_count_abbreviated}','text-font': ['Open Sans Regular'],'text-size': 12}}); map.addLayer({id: 'unclustered-point',type: 'circle',source: 'earthquakes',filter: ['!', ['has', 'point_count']],paint: {'circle-color': '#11b4da','circle-radius': 4,'circle-stroke-width': 1,'circle-stroke-color': '#fff'}}); // inspect a cluster on clickmap.on('click', 'clusters', (e) => {const features = map.queryRenderedFeatures(e.point, {layers: ['clusters']});const clusterId = features[0].properties.cluster_id;map.getSource('earthquakes').getClusterExpansionZoom(clusterId,(err, zoom) => {if (err) return; map.easeTo({center: features[0].geometry.coordinates,zoom: zoom});});}); // When a click event occurs on a feature in// the unclustered-point layer, open a popup at// the location of the feature, with// description HTML from its properties.map.on('click', 'unclustered-point', (e) => {const coordinates = e.features[0].geometry.coordinates.slice();const mag = e.features[0].properties.mag;let tsunami; if (e.features[0].properties.tsunami === 1) {tsunami = 'yes';} else {tsunami = 'no';} // Ensure that if the map is zoomed out such that// multiple copies of the feature are visible, the// popup appears over the copy being pointed to.while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;} new nmapsgl.Popup().setLngLat(coordinates).setHTML('magnitude: ' + mag + '<br>Was there a tsunami?: ' + tsunami).addTo(map);}); map.on('mouseenter', 'clusters', () => {map.getCanvas().style.cursor = 'pointer';});map.on('mouseleave', 'clusters', () => {map.getCanvas().style.cursor = '';});});</script> </body></html>