Skip to content

Instantly share code, notes, and snippets.

@malwoodsantoro
Last active March 4, 2022 04:29
Show Gist options
  • Save malwoodsantoro/9a7313401e7853e7c909c6781cadfa28 to your computer and use it in GitHub Desktop.
Save malwoodsantoro/9a7313401e7853e7c909c6781cadfa28 to your computer and use it in GitHub Desktop.
Filter clusters using filter source param
<!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">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#menu {
position: absolute;
background: #90eebf;
padding: 20px;
font-family: 'Open Sans', sans-serif;
font-size: 20px;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="menu">
<h3>Magnitude</h3>
<div>
<input type="radio" id="all" name="rtoggle" value="true" checked="">
<label for="true">All</label>
</div>
<div>
<input type="radio" id="less than 5" name="rtoggle" value="false">
<label for="false">
< 5</label>
</div>
<div>
<input type="radio" id="greater than 5" name="rtoggle" value="false">
<label for="false">> 5</label>
</div>
</div>
<script>
// less than 5, 5 - 7, greater than 7, all
mapboxgl.accessToken = 'pk.eyJ1IjoibWFsLXdvb2QiLCJhIjoiY2oyZ2t2em50MDAyMzJ3cnltMDFhb2NzdiJ9.X-D4Wvo5E5QxeP7K_I3O8w';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v10',
center: [-103.59179687498357, 40.66995747013945],
zoom: 0
});
map.on('load', function () {
var currentSource = 'earthquakes';
addNewClusterSource = (sourceID, filter) => {
map.addSource(sourceID, {
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)
filter: filter
});
}
addNewClusterSource(currentSource, '')
addNewClusterLayers = (sourceID) => {
map.addLayer({
id: 'clusters',
type: 'circle',
source: sourceID,
filter: ['has', 'point_count'],
paint: {
'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: sourceID,
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: sourceID,
filter: ['!', ['has', 'point_count']],
paint: {
'circle-color': '#11b4da',
'circle-radius': 4,
'circle-stroke-width': 1,
'circle-stroke-color': '#fff'
}
});
}
addNewClusterLayers('earthquakes')
// inspect a cluster on click
map.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 mapboxgl.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 = '';
});
var magnitudeFilters = document.getElementById('menu');
var inputs = magnitudeFilters.getElementsByTagName('input');
function switchMagnitudeFilter(option) {
map.removeLayer('clusters')
map.removeLayer('unclustered-point')
map.removeLayer('cluster-count')
map.removeSource(currentSource);
var magnitudeButton = option.target.id;
if (magnitudeButton === 'less than 5') {
currentSource = 'less-than-five'
filter = ['<', ["get", "mag"], 5]
} else if (magnitudeButton === 'greater than 5') {
currentSource = 'greater-than-five'
filter = ['>', ["get", "mag"], 5]
currentSource = 'greater-than-five'
} else {
currentSource = 'all'
filter = ''
}
addNewClusterSource(currentSource, filter);
addNewClusterLayers(currentSource);
}
for (var i = 0; i < inputs.length; i++) {
inputs[i].onclick = switchMagnitudeFilter;
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment