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.

<!DOCTYPE html>
<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="" rel="stylesheet">
<script src=""></script>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
.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;
<div id="map"></div>
<div id="map-overlay" class="map-overlay"></div>
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 the source to query. In this example we're using
// county polygons uploaded as vector tiles.
map.addSource('counties', {
'type': 'vector',
'url': 'mapbox://mapbox.82pkq93d'
// Add transparent county polygons
// for default display.
'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)'
); // Place polygons under labels.
// Add filled county polygons
// for highlighted display.
'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', '']
); // 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',]
// Render found features in an overlay.
overlay.innerHTML = '';
// Total the populations of all features.
var populationSum = relatedFeatures.reduce(function (
) {
return memo +;
var title = document.createElement('strong');
title.textContent = +
' (' +
relatedFeatures.length +
' found)';
var population = document.createElement('div');
population.textContent =
'Total population: ' + populationSum.toLocaleString();
overlay.appendChild(population); = 'block';
// Add features with the same county name
// to the highlighted layer.
map.setFilter('counties-highlighted', [
// Display a popup with the name of the county.
map.on('mouseleave', 'counties', function () {
map.getCanvas().style.cursor = '';
map.setFilter('counties-highlighted', ['in', 'COUNTY', '']); = 'none';