How to filter Google Maps markers by category?
Filter by user selection. Easily modifiable to any filtering logic.
Let's just dig in and start by adding Google Maps to page. We need <script>
tag to add Google Maps Javascript, another <script>
for our Javascript logic and <div>
to hold our map.
<body>
<!-- Google Maps JS -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY_HERE&callback=initialize"></script>
<!-- Our JS file -->
<script src="index.js"></script>
<!-- Map target element -->
<div id="map-canvas"></div>
</body>
Now, this won't render anything yet since map is not initialized. For this, we will add Javascript file which will hold all our logic.
Since we are loading Google Maps asynchronously, we need &callback=initialize
so that Google Maps know which function to call if it is done loading.
Now we need to add initialize
method to create map.
// index.js
let map;
/**
* Function to initialize map
*/
function initialize() {
let center = new google.maps.LatLng(52.4357808, 4.991315699999973);
let mapOptions = {
zoom: 12,
center: center
};
map = new google.maps.Map(
document.getElementById('map-canvas'),
mapOptions
);
}
And we have map showing. Feel free to edit map options as needed.
To filter markers, we obviously need markers. Let's add markers right after initializing map.
// index.js
let map;
let infowindow;
// This array will hold our markers added to map
let mapMarkers = [];
// Our markers, could be data from backend
// For example purpose, let's use predefined array of markers
// title, latitude, longitude, category
// Add as many as you want
let markers = [
['Shop 1', 52.4357808, 4.991315699999973, 'shop'],
['Card dealer 1', 52.4357808, 4.981315699999973, 'car'],
['Shop 2', 52.4555687, 5.039231599999994, 'shop'],
['Gas station 1', 52.4555687, 5.029231599999994, 'gas'],
];
/**
* Function to initialize map
*
* - Initalizes map
* - Adds markers to map
*/
function initialize() {
let center = new google.maps.LatLng(52.4357808, 4.991315699999973);
let mapOptions = {
zoom: 12,
center: center
};
// Init map
map = new google.maps.Map(
document.getElementById('map-canvas'),
mapOptions
);
// Infowindow to show marker title
// Not actually needed for filtering, but nice to have
infowindow = new google.maps.InfoWindow({
content: '',
});
// Add our markers to map
for (let i = 0; i < markers.length; i++) {
addMarkerToMap(markers[i]);
}
}
/**
* Function to add marker to map
*/
function addMarkerToMap(markerData) {
let category = markerData[3];
let title = markerData[0];
let pos = new google.maps.LatLng(markerData[1], markerData[2]);
let content = markerData[0];
let marker = new google.maps.Marker({
title: title,
position: pos,
category: category,
map: map,
});
mapMarkers.push(marker);
// Marker click listener
// Fill infowindow with marker title and zoom in to marker
google.maps.event.addListener(
marker,
'click',
(function(marker, content) {
return function() {
infowindow.setContent(content);
infowindow.open(map, marker);
map.panTo(this.getPosition());
map.setZoom(15);
};
})(marker, content)
);
}
We added addMarkerToMap
function to add marker to map, which takes marker data array as parameter. It gets used in initialize
function, iterating over every marker and calling addMarkerToMap
to add markers one by one.
Currently we are defining markers directly in our code, but in real case they would probably be loaded dynamically from backend. Logic stays the same.
For extra touch, marker click handler is added which will open infowindow showing marker title.
Lastly, we need some way for a user to interact with the map to be able to filter markers by category. For that we are adding select with categories.
<body>
...
<!-- Map target element -->
<div id="map-canvas"></div>
<!-- Select category -->
<select onchange="filterMarkersByCategory(this.value)">
<option value="">Please select a category</option>
<option value="shop">Shops</option>
<option value="gas">Gas stations</option>
<option value="car">Car dealers</option>
</select>
</body>
This <select>
element has onchange="filterMarkersByCategory(this.value)
which means if we change it's value, it will call filterMarkersByCategory
and passes selected value as parameter. This way we know which category user selected.
All we need to do now is to add filterMarkersByCategory
to change markers visibilities based on user selection.
// index.js
// ...
/**
* Function to filter markers by category
*/
function filterMarkersByCategory(category) {
for (let i = 0; i < mapMarkers.length; i++) {
let marker = mapMarkers[i];
// If is same category or category not picked
let visible = marker.category == category || category.length === 0;
marker.setVisible(visible);
}
}
google.maps.Marker
object has method setVisible
which takes boolean value. If it is true
, marker will be shown.
Feel free to play around with or fork my JSFiddle.