Create and style clusters
Use TrackAsia 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://unpkg.com/trackasia-gl@1.0.5/dist/trackasia-gl.js"></script><link href="https://unpkg.com/trackasia-gl@1.0.5/dist/trackasia-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>var map = new trackasiagl.Map({container: 'map',style: 'https://maps.track-asia.com/styles/v1/streets.json?key=public_key',center: [-103.59179687498357, 40.66995747013945],zoom: 3}); map.on('load', function () {// 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://docs.track-asia.com/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 (https://docs.track-asia.com/style/#expressions-step)// 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': ['DIN Pro Regular', 'Arial Unicode MS 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', function (e) {var features = map.queryRenderedFeatures(e.point, {layers: ['clusters']});var clusterId = features[0].properties.cluster_id;map.getSource('earthquakes').getClusterExpansionZoom(clusterId,function (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', function (e) {var coordinates = e.features[0].geometry.coordinates.slice();var mag = e.features[0].properties.mag;var 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 trackasiagl.Popup().setLngLat(coordinates).setHTML('magnitude: ' + mag + '<br>Was there a tsunami?: ' + tsunami).addTo(map);}); map.on('mouseenter', 'clusters', function () {map.getCanvas().style.cursor = 'pointer';});map.on('mouseleave', 'clusters', function () {map.getCanvas().style.cursor = '';});});</script> </body></html>