dimfeld / svelte-maplibre

Svelte bindings for the MapLibre mapping library
https://svelte-maplibre.vercel.app
MIT License
283 stars 34 forks source link

Anyone know how to dynamically add data to the map AFTER component creation? #102

Closed wx007 closed 7 months ago

wx007 commented 7 months ago

I'm attempting to add new points to a HeatmapLayer as new coordinates arrive from the server. In vanilla Maplibre I can do this:

map.getSource('earthquakes').setData(earthquakeData);

which would overwrite the existing map data with the augmented data.

Using svelte-maplibe Im having trouble figuring out how to go about this. I didn't see any examples covering this on the examples page. Any help is appreciated.

Thanks!

dimfeld commented 7 months ago

You just update the data that you’re passing into the GeoJSON source. Keep in mind that normal Svelte reactivity rules apply so just doing an array push won’t trigger an update.

wx007 commented 7 months ago

Thank you for your quick response! It's working now. I forgot Svelte reactivity is triggered by assignment, not array / object mutation.

For the benefit of anyone new to Svelte and SK (like me), this is what worked:

<script>

    let heatmapData = {
        type: "FeatureCollection",
        features: []
     }

    . . .

    // Your function to receive a single geolocation record from the server 
    // and assign it to the "inbound" variable goes here

    . . .

    // drop new data into a Feature template
    let newHeatmapDataPoint = {
        type: "Feature",
        geometry: {
            type: "Point",
            coordinates: [ inbound.lon, inbound.lat ]  // required
        },
        properties: {
            id: inbound.id,
            time: inbound.date,
            mag: inbound.magnitude  // required
         }
     }

    heatmapData.features.push( newHeatmapDataPoint )  // all records kept here
    heatmapData = heatmapData  // <---- force Svelte to push updated heatmapData to GeoJSON component  

</script>

<MapLibre ... >
    <GeoJSON id="myheatmap" bind:data={ heatmapData }>
dimfeld commented 7 months ago

Glad you got it working! :)