Skip to content

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>