2

I'd like to click on a button in a sidebar outside a Leaflet map and remove a marker associated with that button. But when I bulk add data through L.geoJSON, the function appears to not create individual variables for markers, making it impossible to simply use .remove(map) on that variable / marker.

The geoJSON looks like this:

var places = {"type": "FeatureCollection", "features": [{"id": "0", "type": "Feature", "properties": {"WIKIPEDIA": "Beni Department"}, "geometry": {"type": "Point", "coordinates": [-65.683972, -15.43334]}}, {"id": "1", "type": "Feature", "properties": {"WIKIPEDIA": "Bluefish Caves"}, "geometry": {"type": "Point", "coordinates": [-140.518611, 64.135278]}}]}

I've tried dynamically associating a variable with each marker by doing this:

  geojson = L.geoJSON(places, {
      pointToLayer: function (feature, latlng) {
          var "_" + String(feature.id) + "_" = L.circleMarker(latlng, geojsonMarkerOptions);
          return L.circleMarker(latlng, geojsonMarkerOptions);
      }
  }).addTo(map);

But that gives me a SyntaxError: missing variable name.

2 Answers 2

3

All layers in leaflet have a unique "leaflet id" which is accessible via L.stamp(layer).
You can create an array/object that connects feature.id and the unique L.stamp, and use it to interact with the markers from the sidebar, without using window variables.
With such an object, you can remove/interact with specific layers, based on their unique leaflet id via the geojson featurefroup - use the geojson featuregroup to get the layer by it's stamp.

Example:

let mapIdObj = {};
let geojson = L.geoJSON(places, {
    pointToLayer: function (feature, latlng) {          
        return L.circleMarker(latlng, geojsonMarkerOptions);
    }, 
    onEachFeature: function (feature, layer) { 
        mapIdObj[feature.id] = L.stamp(layer);
    }
}).addTo(map);

//Remove a specific layer based on external feature.id (as id)
map.removeLayer(geojson.getLayer(mapIdObj[id]))
3
  • Thank you. To confirm, you would use one of the properties (eg, feature.properties.name) because feature.id will simply returned undefined, yes?
    – zadrozny
    Aug 17, 2020 at 0:38
  • @zadrozny - yes, I was following your example. Using a property from feature.properties is the proper way.
    – NettaB
    Aug 17, 2020 at 7:26
  • Thanks for confirming. And thanks for your answer!
    – zadrozny
    Aug 17, 2020 at 22:29
0

I'd like to know if there's a better way, but this works:

  geojson = L.geoJSON(places, {
      pointToLayer: function (feature, latlng) {
          window["_" + String(feature.id) + "_"] = L.circleMarker(latlng, geojsonMarkerOptions);
          return window["_" + String(feature.id) + "_"] 
      }
  }).addTo(map);

This allow me to run window["_" + String(feature.id) + "_"].remove(map);

Code based on this answer.

3
  • There are many ways how to achieve that. Since it's working, why are you not satisfied with this one. How would you define "better"?
    – TomazicM
    Aug 12, 2020 at 19:36
  • See @NettaB's answer above. Better = baked-in / native.
    – zadrozny
    Aug 17, 2020 at 22:30
  • 1
    Yes, with this criteria accepted answer is probably the best way. What's useful to know is that layer automatically gets Leaflet id, but only after it's added to the map. In the accepted answer Leaflet id is created by user code at the time GeoJSON layer creation, and when layer is later added to the map, already created is is retained and no new id is created.
    – TomazicM
    Aug 18, 2020 at 8:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.