Skip to content

Feature Interaction

Add hover and click interactions to GeoJSON features using mousemove, mouseleave, and click events with setFilter.

<!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%; }
            #info {
                position: absolute;
                top: 20px;
                left: 20px;
                background: white;
                padding: 12px 18px;
                border-radius: 8px;
                box-shadow: 0 2px 10px rgba(0,0,0,0.15);
                font-family: sans-serif;
                font-size: 14px;
                z-index: 1;
                max-width: 250px;
            }
            #info strong { color: #18345c; }
        </style>
    </head>
    <body>
        <div id="map"></div>
        <div id="info">Hover over a circle to highlight it. Click to see details.</div>
        <script>
            const map = new smartmapsgl.Map({
                apiKey: "[INSERT API-KEY]",
                container: "map",
                center: { lat: 48.78, lng: 9.18 },
                zoom: 11,
                style: smartmapsgl.MapStyle.ESSENTIAL
            });

            const locations = {
                type: "FeatureCollection",
                features: [
                    { type: "Feature", geometry: { type: "Point", coordinates: [9.1829, 48.7758] }, properties: { name: "Stuttgart Mitte", population: 635911 } },
                    { type: "Feature", geometry: { type: "Point", coordinates: [9.2205, 48.7784] }, properties: { name: "Bad Cannstatt", population: 72000 } },
                    { type: "Feature", geometry: { type: "Point", coordinates: [9.1068, 48.7443] }, properties: { name: "Vaihingen", population: 45000 } },
                    { type: "Feature", geometry: { type: "Point", coordinates: [9.1514, 48.8107] }, properties: { name: "Zuffenhausen", population: 38000 } },
                    { type: "Feature", geometry: { type: "Point", coordinates: [9.2472, 48.7920] }, properties: { name: "Fellbach", population: 46000 } }
                ]
            };

            map.on("load", () => {
                map.addSource("locations", { type: "geojson", data: locations });

                map.addLayer({
                    id: "locations-circle",
                    type: "circle",
                    source: "locations",
                    paint: {
                        "circle-radius": ["interpolate", ["linear"], ["get", "population"], 30000, 12, 600000, 35],
                        "circle-color": "#18345c",
                        "circle-opacity": 0.7,
                        "circle-stroke-width": 2,
                        "circle-stroke-color": "#ffffff"
                    }
                });

                map.addLayer({
                    id: "locations-hover",
                    type: "circle",
                    source: "locations",
                    paint: {
                        "circle-radius": ["interpolate", ["linear"], ["get", "population"], 30000, 15, 600000, 40],
                        "circle-color": "#f6b80c",
                        "circle-opacity": 0.9,
                        "circle-stroke-width": 3,
                        "circle-stroke-color": "#ffffff"
                    },
                    filter: ["==", ["get", "name"], ""]
                });

                // Hover effect
                map.on("mousemove", "locations-circle", (e) => {
                    map.getCanvas().style.cursor = "pointer";
                    if (e.features.length > 0) {
                        map.setFilter("locations-hover", ["==", ["get", "name"], e.features[0].properties.name]);
                    }
                });

                map.on("mouseleave", "locations-circle", () => {
                    map.getCanvas().style.cursor = "";
                    map.setFilter("locations-hover", ["==", ["get", "name"], ""]);
                });

                // Click interaction
                map.on("click", "locations-circle", (e) => {
                    const props = e.features[0].properties;
                    document.getElementById("info").innerHTML =
                        `<strong>${props.name}</strong><br>Population: ${props.population.toLocaleString()}`;
                });
            });
        </script>
    </body>
</html>