Skip to content

Instantly share code, notes, and snippets.

@malwoodsantoro
Created May 17, 2021 19:34
Show Gist options
  • Save malwoodsantoro/3498c341a48719783dd499ed6cc3f034 to your computer and use it in GitHub Desktop.
Save malwoodsantoro/3498c341a48719783dd499ed6cc3f034 to your computer and use it in GitHub Desktop.
Show polygon around clustered points on hover
<!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://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.css" rel="stylesheet" />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
<script src='https://unpkg.com/@turf/turf@6.3.0/turf.min.js'></script>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoibWFsLXdvb2QiLCJhIjoiY2oyZ2t2em50MDAyMzJ3cnltMDFhb2NzdiJ9.X-D4Wvo5E5QxeP7K_I3O8w';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v10',
center: [-118.19831, 33.19266],
zoom: 6
});
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.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson",
cluster: true,
clusterMaxZoom: 14, // Max zoom to cluster points on
clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
});
map.addLayer({
id: "clusters",
type: "circle",
source: "earthquakes",
filter: ["has", "point_count"],
paint: {
"circle-color": [
"step",
["get", "point_count"],
"#51bbd6",
100,
"#f1f075",
750,
"#f28cb1"
],
"circle-radius": [
"step",
["get", "point_count"],
20,
50,
30,
300,
40
]
}
});
map.addLayer({
id: "cluster-count",
type: "symbol",
source: "earthquakes",
filter: ["has", "point_count"],
layout: {
"text-field": "{point_count_abbreviated}",
"text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
"text-size": 12
}
});
map.addLayer({
id: "unclustered-point",
type: "circle",
source: "earthquakes",
filter: ["all", ["!", ["has", "point_count"]], ['<', ['number', ['get', 'mag']], 3]],
paint: {
"circle-color": "#11b4da",
"circle-radius": 4,
"circle-stroke-width": 1,
"circle-stroke-color": "#fff"
}
});
var popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
// inspect a cluster on click
map.on('mouseenter', 'clusters', function (e) {
map.getCanvas().style.cursor = 'pointer';
var features = map.queryRenderedFeatures(e.point, { layers: ['clusters'] });
var coordinates = e.features[0].geometry.coordinates.slice();
var clusterId = features[0].properties.cluster_id,
point_count = features[0].properties.point_count,
clusterSource = map.getSource('earthquakes');
// Get all points under a cluster
clusterSource.getClusterLeaves(clusterId, point_count, 0, function (err, aFeatures) {
var turfPointArray = [];
aFeatures.forEach((feature) => {
turfPointArray.push(turf.point([feature.geometry.coordinates[0], feature.geometry.coordinates[1]]))
})
var features = turf.featureCollection(turfPointArray);
var convex = turf.convex(features);
map.addSource('bbox', {
'type': 'geojson',
'data': convex
});
map.addLayer({
'id': 'fill',
'type': 'fill',
'source': 'bbox', // reference the data source
'paint': {
'fill-color': '#93E9BE', // blue color fill
'fill-opacity': 0.5
}
});
map.addLayer({
'id': 'outline',
'type': 'line',
'source': 'bbox',
'paint': {
'line-color': '#93E9BE',
'line-width': 5
}
});
})
});
map.on('mouseleave', 'clusters', function () {
map.getCanvas().style.cursor = '';
map.removeLayer('outline');
map.removeLayer('fill');
map.removeSource('bbox');
popup.remove();
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment