Area by rectangle
This example demonstrates an interactive map using the Smartmaps API to display dynamic boundary data. As the user navigates the map, it automatically fetches and renders boundary information for the current view, with clickable regions that display additional details in a popup.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.smartmaps.cloud/packages/smartmaps/smartmaps-gl/v2/umd/smartmaps-gl.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
html,
body,
#map {
height: 100%;
}
#loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(255, 255, 255, 0.8);
padding: 10px;
border-radius: 5px;
display: none;
z-index: 999;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="loading">Loading...</div>
<script>
const apiKey = 'INSERT API-KEY';
const map = new smartmapsgl.Map({
apiKey,
container: "map",
center: { lat: 49.02164948779226, lng: 8.439330018049352 },
zoom: 5,
style: smartmapsgl.MapStyle.AUTO
});
let currentBounds = null;
let debounceTimer;
function debounce(func, delay) {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(func, delay);
}
function boundsChanged(newBounds) {
if (!currentBounds) return true;
const currentNE = currentBounds.getNorthEast();
const currentSW = currentBounds.getSouthWest();
const newNE = newBounds.getNorthEast();
const newSW = newBounds.getSouthWest();
return currentNE.lat !== newNE.lat || currentNE.lng !== newNE.lng ||
currentSW.lat !== newSW.lat || currentSW.lng !== newSW.lng;
}
function searchBoundaries() {
const bounds = map.getBounds();
const northEast = bounds.getNorthEast();
const southWest = bounds.getSouthWest();
const url = `https://area.smartmaps.cloud/api/v2/Boundaries/rectangle?apiKey=${apiKey}`;
const requestBody = {
level: 2,
zoom: Math.round(map.getZoom()),
reduceGeometry: 0.01,
boundingBox: {
northEast: {
latitude: northEast.lat,
longitude: northEast.lng
},
southWest: {
latitude: southWest.lat,
longitude: southWest.lng
}
}
};
// Show loading indicator
document.getElementById('loading').style.display = 'block';
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
updateMap(data);
})
.catch(error => {
console.error('Error loading GeoJSON:', error);
alert('Error loading geodata. Please try again later.');
})
.finally(() => {
// Hide loading indicator
document.getElementById('loading').style.display = 'none';
});
}
function updateMap(data) {
if (!map.getSource('geojson-source')) {
map.addSource('geojson-source', {
'type': 'geojson',
'data': data
});
map.addLayer({
'id': 'geojson-layer',
'type': 'fill',
'source': 'geojson-source',
'layout': {},
'paint': {
'fill-color': '#18345c',
'fill-opacity': 0.6,
}
});
map.addLayer({
'id': 'geojson-outline-layer',
'type': 'line',
'source': 'geojson-source',
'layout': {},
'paint': {
'line-color': '#ffffff',
'line-width': 3
}
});
} else {
map.getSource('geojson-source').setData(data);
}
}
map.on('load', () => {
currentBounds = map.getBounds();
searchBoundaries();
map.on('moveend', () => {
const newBounds = map.getBounds();
if (boundsChanged(newBounds)) {
currentBounds = newBounds;
debounce(searchBoundaries, 100);
}
});
map.on('click', 'geojson-layer', (e) => {
if (e.features && e.features.length > 0) {
const coordinates = e.lngLat;
const feature = e.features[0];
const name = feature.properties.name;
new smartmapsgl.Popup()
.setLngLat(coordinates)
.setHTML(`<strong>Name:</strong> ${name}`)
.addTo(map);
}
});
map.on('mouseenter', 'geojson-layer', () => {
map.getCanvas().style.cursor = 'pointer';
});
map.on('mouseleave', 'geojson-layer', () => {
map.getCanvas().style.cursor = '';
});
});
</script>
</body>
</html>