0

I have a webapp that displays many markers on a map that are loaded dynamically when the user moves the map around. I call an API with the bounds and get back a list of markers.

The current solution

<l-map v-if="showMap" :zoom="zoom" :center="center" @update:bounds="boundsUpdated" style="height: 100%">
    <l-tile-layer :url="url" :attribution="attribution"/>
    <l-marker v-for="marker in markers" :key="marker.id" :lat-lng="marker.coordinates" >
      <l-icon
          icon-url="https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png">
      </l-icon>
    </l-marker>
</l-map>

...

mounted() {
    let thisClass = this;
    EventBus.$on('new_markers', function (payLoad) {
      for (const marker of payLoad) {
        thisClass.markerMap[marker.id] = marker;
      }
      thisClass.markers = Object.values(thisClass.markerMap)
    });
  },

Based on how slow it is to render the markers and how hot my laptop gets, I assume it is rendering all the markers every time.

My question

How to load with leaflet only the markers that are new in the list of markers and not the entire list every time?

Paul Fournel
  • 10,807
  • 9
  • 40
  • 68
  • `only the markers that are not yet in the list of markers` if they're not in the list of markers, where are they? – Jaromanda X Oct 08 '20 at 09:05
  • I updated my question to be more precise. From the API I get different markers based on the zoom level, and the bounds. This is why I think I would be more efficient to only add to the map the new markers. – Paul Fournel Oct 08 '20 at 09:39

1 Answers1

0

I assume it is rendering all the markers every time -> Have you tried to console.log markers to see how many items are inside ?

If you want to display on the map just the markers that are new to the markers array, what you could do is changing v-for="marker in markers" to v-for="marker in lastMarkers with lastMakers being a computed property returning only the last items, like so:

lastMarkers() {
 return this.markers.slice(this.lastMarkerIndex);
}

now you need to update lastMarkerIndex in your EventBus callback function just before assigning Object.values(thisClass.markerMap) to thisClass.markers

And to get rid of thisClass and use this instead you can just use an arrow function for your callback, instead of function (payload)

So to sum up your EventBus listener could look like this :

EventBus.$on('new_markers', (payload) => {
  for (const marker of payload) {
    this.markerMap[marker.id] = marker;
  }
  this.lastMarkerIndex = this.markers.length - 1;
  this.markers = Object.values(this.markerMap)
});

This is how I would do but I guess there are a lot of different ways to achieve what you want.

Dharman
  • 30,962
  • 25
  • 85
  • 135
hnrd
  • 265
  • 1
  • 4
  • 13