ANPR camera's map

by PhilQ

HTML

<!DOCTYPE html>
<html>
	<head>
		<title>ANPR cameras map</title>
		<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
	</head>
	<body>

		<div id="map"></div>
		
		<div id="legend"><h3>Legend</h3></div>

		<div id="search">
			<span class="material-icons md-24">search</span>
			<input type="text" id="search_input" placeholder="Search location" value="">
		</div>

		<button id="btn-current-location" title="Pan to Current Location" class="custom-icon-button"><span class="material-icons">gps_fixed</span></button>

		<button id="btn-last-view" title="Back to Last View" class="custom-icon-button"><span class="material-icons">undo</span></button>

		<!-- See:
			https://developers.google.com/maps/documentation/javascript/overview?hl=nl
			https://developers.google.com/maps/documentation/javascript/reference?hl=nl
		-->
		<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
		<script async src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly&channel=2&language=nl"></script>
		<!--<script async
			src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
		</script>-->

		<!-- See: https://googlemaps.github.io/js-markerclusterer/classes/MarkerClusterer.html#algorithm -->
		<script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>
		
		<!--
			Zendmasten zie: https://antennekaart.nl/kaart/5g?lat=52.22359335&lng=5.42175293&zoom=9
		-->
</body>
</html>

SCSS

@import url("https://fonts.googleapis.com/icon?family=Material+Icons");
.material-icons {
	font-family: 'Material Icons';
	font-weight: normal;
	font-style: normal;
	font-size: 24px;  /* Preferred icon size */
	display: inline-block;
	line-height: 1;
	text-transform: none;
	letter-spacing: normal;
	word-wrap: normal;
	white-space: nowrap;
	direction: ltr;

	/* Support for all WebKit browsers. */
	-webkit-font-smoothing: antialiased;

	/* Support for Safari and Chrome. */
	text-rendering: optimizeLegibility;

	/* Support for Firefox. */
	-moz-osx-font-smoothing: grayscale;

	/* Support for IE. */
	font-feature-settings: 'liga';
}

*, ::before, ::after {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

html,
body {
	overflow: hidden;
	height: 100%;
}

/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */
#map {
	height: 100%;
}

.custom-map-control-button {
	background-color: #fff;
	border: 0;
	border-radius: 2px;
	box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
	margin: 10px;
	padding: 0 0.5em;
	font: 400 18px Roboto, Arial, sans-serif;
	overflow: hidden;
	height: 40px;
	cursor: pointer;

	&:hover, &:focus {
		background: #ebebeb;
	}
}

.custom-icon-button {
	background-color: #fff;
	border: 0;
	border-radius: 2px;
	box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
	text-transform: none;
	appearance: none;
	user-select: none;
	overflow: hidden;
	width: 40px;
	height: 40px;
	cursor: pointer;
	color: #666;

	&:hover, &:focus, &:active {
		color: #111;
		//background: #ebebeb;
	}
}

.margin-t { margin-top: 10px; }
.margin-b { margin-bottom: 10px; }
.margin-l { margin-left: 10px; }
.margin-r { margin-right: 10px; }

#search {
	margin-top: 10px;

	span {
		position: absolute;
		top: 8px;
		left: 8px;
		pointer-events: none;
		color: #5f6368;
	}

	input {
		background-color: #fff;
		border: 0;
		border-radius: 2px;
		box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
		text-transform: none;
		appearance: none;
		outline:...

JavaScript

// Politie
// Locatienaam, Eenheid, Plaats, Gemeente, Latitude, Longitude, Reden 1, Reden 2, Reden 3, Reden 4
let anpr_politie = [
	["05 Alexanderplein-Noord", "Amsterdam", "Amsterdam", "Amsterdam", 52.3635, 4.92636, "X", "X", "X", "X"],
	["05 Amstelveenseweg", "Amsterdam", "Amsterdam", "Amsterdam", 52.341661, 4.857801, "X", "X", "X", "X"],
	["05 Beethovenstraat", "Amsterdam", "Amsterdam", "Amsterdam", 52.340353, 4.876962, "X", "X", "X", "X"],
	["05 Bos en Lommerplein", "Amsterdam", "Amsterdam", "Amsterdam", 52.377696, 4.845056, "X", "X", "X", "X"],
	["05 Cornelis Douwesweg", "Amsterdam", "Amsterdam", "Amsterdam", 52.409112, 4.887743, "X", "X", "X", "X"],
	["05 Cruquiuskade-West", "Amsterdam", "Amsterdam", "Amsterdam", 52.3675, 4.92818, "X", "X", "X", "X"],
	["05 Europaboulevard", "Amsterdam", "Amsterdam", "Amsterdam", 52.339878, 4.892393, "X", "X", "X", "X"],
	["05 Gooiseweg", "Amsterdam", "Amsterdam", "Amsterdam", 52.339922, 4.937583, "X", "X", "X", "X"],
	["05 Haarlemmerweg", "Amsterdam", "Amsterdam", "Amsterdam", 52.384926, 4.847145, "X", "X", "X", "X"],
	["05 Heemstedestraat", "Amsterdam", "Amsterdam", "Amsterdam", 52.351496, 4.843625, "X", "X", "X", "X"],
	["05 Hendrikje Stoffelstraat", "Amsterdam", "Amsterdam", "Amsterdam", 52.3563, 4.84345, "X", "X", "X", "X"],
	["05 Henk Sneevlietweg", "Amsterdam", "Amsterdam", "Amsterdam", 52.345894, 4.845361, "X", "X", "X", "X"],
	["05 IJtunnel-Zuid", "Amsterdam", "Amsterdam", "Amsterdam", 52.38664, 4.9026, "X", "X", "X", "X"],
	["05 Jan Evertsenstraat", "Amsterdam", "Amsterdam", "Amsterdam", 52.369274, 4.844718, "X", "X", "X", "X"],
	["05 Jan van Galenstraat", "Amsterdam", "Amsterdam", "Amsterdam", 52.3721, 4.844403, "X", "X", "X", "X"],
	["05 Koekjesbrug-Oost", "Amsterdam", "Amsterdam", "Amsterdam", 52.3664, 4.88177, "X", "X", "X", "X"],
	["05 KortesGravensanderstr-Noord", "Amsterdam", "Amsterdam", "Amsterdam", 52.36196, 4.90325, "X", "X", "X", "X"],
	["05 Leidseplein-Oost", "Amsterdam", "Amsterdam", "Amsterdam",...