Filter within a Layer
This example shows how to filter a layer based on user input using setFilter(). Download the earthquake sample data.
NPM module setup
npm install --save @maptiler/sdk
import { Map, MapStyle, config } from '@maptiler/sdk';
import '@maptiler/sdk/dist/maptiler-sdk.css';
config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';
const data = {};
const map = new Map({
container: 'map',
style: MapStyle.DATAVIZ.DARK,
center: [-156.6, 44],
zoom: 1.6,
});
map.on('load', async function () {
await maptilersdk.helpers.addPoint(map, {
layerId: 'earthquakes',
data: 'YOUR_MAPTILER_DATASET_ID_HERE',
pointColor: '#FB3A1B',
pointRadius: 40
});
});
document.getElementById('nav-filter').addEventListener('change', (e) => {
let filterOnValue = ['all'];
let operator = '==';
switch (e.target.id) {
/// example: `map.setFilter("earthquakes", ["any", [">", "felt", 16.0]])`
case 'felt':
operatorFelt = document.getElementById('operator-felt');
felt = document.getElementById('range-felt');
operator = operatorFelt.value;
// eslint-disable-next-line no-unused-expressions
e.target.checked ? data.felt = Number(felt.value) : delete data['felt'];
break;
/// example: `map.setFilter("earthquakes", ["any", [">", "mag", 5.0]])`
case 'mag':
operatorMag = document.getElementById('operator-mag');
mag = document.getElementById('range-mag');
operator = operatorMag.value;
// eslint-disable-next-line no-unused-expressions
e.target.checked ? data.mag = Number(mag.value) : delete data['mag'];
break;
/// example: `map.setFilter("earthquakes", ["any", [">", "tsunami", 0]])`
case 'tsunami':
// eslint-disable-next-line @typescript-eslint/quotes
tsunami = document.querySelector("input[type='radio'][name=tsunami]:checked");
operator = '==';
// eslint-disable-next-line no-unused-expressions
e.target.checked ? data.tsunami = Number(tsunami.value) : delete data['tsunami'];
break;
default:
console.log('default');
}
filterOnValue = Object.keys(data);
mapLibreFilterSpread = ['all', ...filterOnValue.map(id => [operator, id, data[id]])];
mapLibreFilter = mapLibreFilterSpread;
document.getElementById('filter-result').textContent = JSON.stringify(mapLibreFilter);
map.setFilter('earthquakes', mapLibreFilter);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex">
<title>Filter within a Layer | NPM example</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<style>
.map-overlay {
font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
position: absolute;
width: 31.8%;
top: 0;
left: 0;
padding: 10px;
}
.map-overlay .map-overlay-inner {
background-color: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
border-radius: 3px;
padding: 10px;
margin-bottom: 10px;
}
.map-overlay input {
margin: 2px;
}
input[type=number] {
width: 25%
}
#filter-result {
font-size: 8px;
font-family: "Courier New";
}
</style>
<div id="map"></div>
<div class="map-overlay top">
<div class="map-overlay-inner">
<nav id="nav-filter">
<fieldset>
<legend>🫨 Earthquake <code>felt</code>?</legend>
<div>
<input id="felt" type="checkbox" />
<label for="felt">Apply <code>felt</code> Filter</label>
<div>
<div>
<label for="operator-select">Operator:</label>
<select name="operator" id="operator-felt">
<option value=">">></option>
<option value="==" selected>==</option>
<option value="<"><</option>
</select>
<br>
<label for="range">Felt:</label>
<input type="number" id="range-felt" name="range" value="4" min="1.0" max="10000" />
</div>
</div>
</fieldset>
<fieldset>
<legend>📈 Magnitude</legend>
<div>
<input id="mag" type="checkbox" />
<label for="mag">Apply <code>magnitude</code> Filter</label>
<div>
<div>
<label for="operator-select">Operator:</label>
<select name="operator" id="operator-mag">
<option value=">">></option>
<option value="==" selected>==</option>
<option value="<"><</option>
</select>
<br>
<label for="range">Magnitude:</label>
<input type="number" id="range-mag" name="range" value="2.71" min="0.0" max="100" />
</div>
</div>
</fieldset>
<fieldset>
<legend>🌊 Tsunami (0 or 1)</legend>
<input id="tsunami" type="checkbox" /> <label>Apply <code>tsunami</code> filter</label>
<div id="radio-tsunamis">
<input type="radio" id="t0" name="tsunami" value="0" /><label>0</label>
<input type="radio" id="t1" name="tsunami" value="1" /><label>1</label>
</div>
</fieldset>
</nav>
<hr />
<div id='filter-result'>["all"]</div>
</div>
</div>
<script type="module" src="./main.js"></script>
</body>
</html>
body {margin: 0; padding: 0;}
#map {position: absolute; top: 0; bottom: 0; width: 100%;}
Related examples
Point layer colored and sized according to a property (point helper)
ExamplesStyle point layer by property using point helper.