All docsMapbox GL JSExamplesHighlight features containing similar data

Highlight features containing similar data

In this example, a user can hover their cursor over any county in the United States, and the map highlights other U.S. counties with a matching name, displays a popup with the name of the county at the cursor location, and displays an HTML overlay with summary information.

The example first uses addSource to add county polygons from a vector tileset. Then it uses addLayer to add two fill layers using that source. The layer for the default display has transparent county polygons, and the layer for the highlighted display has filled county polygons.

To add interactivity, the example uses mousemove to get the first county feature that the mouse is now over. Then it uses querySourceFeatures to create a list of county features that match the name of the current county. Then it uses that list to get the total population and create the overlay. To create the illusion of highlighted polygons, it uses setFilter to update the filter that is applied to the highlighted layer, allowing the matching counties to be visible.

Use a custom tileset

This example uses U.S. county data uploaded to Mapbox as a vector tileset. This data is not updated or maintained and should not be used in production applications.

If you're interested in creating an application that uses U.S. county data, you can download a Shapefile from census.gov's data portal and upload it to Mapbox Studio's Tilesets page.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Highlight features containing similar data</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%; }
</style>
</head>
<body>
<style>
.map-overlay {
font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
background-color: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
border-radius: 3px;
position: absolute;
width: 25%;
top: 10px;
left: 10px;
padding: 10px;
display: none;
}
</style>
<div id="map"></div>
<div id="map-overlay" class="map-overlay"></div>
<script>
// TO MAKE THE MAP APPEAR YOU MUST
// ADD YOUR ACCESS TOKEN FROM
// https://account.mapbox.com
mapboxgl.accessToken = '<your access token here>';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-98, 38.88],
minZoom: 2,
zoom: 3
});
var overlay = document.getElementById('map-overlay');
// Create a popup, but don't add it to the map yet.
var popup = new mapboxgl.Popup({
closeButton: false
});
map.on('load', function () {
// Add a custom vector tileset source. The tileset used in
// this example contains a feature for every county in the U.S.
// Each county contains four properties. For example:
// {
// COUNTY: "Uintah County",
// FIPS: 49047,
// median-income: 62363,
// population: 34576
// }
map.addSource('counties', {
'type': 'vector',
'url': 'mapbox://mapbox.82pkq93d'
});
// Add transparent county polygons
// for default display.
map.addLayer(
{
'id': 'counties',
'type': 'fill',
'source': 'counties',
'source-layer': 'original',
'paint': {
'fill-outline-color': 'rgba(0,0,0,0.1)',
'fill-color': 'rgba(0,0,0,0.1)'
}
},
'settlement-label'
); // Place polygons under labels.
// Add filled county polygons
// for highlighted display.
map.addLayer(
{
'id': 'counties-highlighted',
'type': 'fill',
'source': 'counties',
'source-layer': 'original',
'paint': {
'fill-outline-color': '#484896',
'fill-color': '#6e599f',
'fill-opacity': 0.75
},
// Display none by adding a
// filter with an empty string.
'filter': ['in', 'COUNTY', '']
},
'settlement-label'
); // Place polygons under labels.
map.on('mousemove', 'counties', function (e) {
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = 'pointer';
// Use the first found feature.
var feature = e.features[0];
// Query the counties layer visible in the map.
// Use filter to collect only results
// with the same county name.
var relatedFeatures = map.querySourceFeatures('counties', {
sourceLayer: 'original',
filter: ['in', 'COUNTY', feature.properties.COUNTY]
});
// Render found features in an overlay.
overlay.innerHTML = '';
// Total the populations of all features.
var populationSum = relatedFeatures.reduce(function (
memo,
feature
) {
return memo + feature.properties.population;
},
0);
var title = document.createElement('strong');
title.textContent =
feature.properties.COUNTY +
' (' +
relatedFeatures.length +
' found)';
var population = document.createElement('div');
population.textContent =
'Total population: ' + populationSum.toLocaleString();
overlay.appendChild(title);
overlay.appendChild(population);
overlay.style.display = 'block';
// Add features with the same county name
// to the highlighted layer.
map.setFilter('counties-highlighted', [
'in',
'COUNTY',
feature.properties.COUNTY
]);
// Display a popup with the name of the county.
popup
.setLngLat(e.lngLat)
.setText(feature.properties.COUNTY)
.addTo(map);
});
map.on('mouseleave', 'counties', function () {
map.getCanvas().style.cursor = '';
popup.remove();
map.setFilter('counties-highlighted', ['in', 'COUNTY', '']);
overlay.style.display = 'none';
});
});
</script>
</body>
</html>