Search code examples
mapsmapboxgeojson

How to add markers via GeoJSON to an existing layer, without having to reset it


I'm using mapbox.

I have a layer that contains my markers:

 map = L.mapbox.map(id, map_id...)
 map.featureLayer # this is the layer containing all my markers

What I want is to add markers to this layer without removing the existing ones. But I don't want to just create a marker via L.mapbox.Marker, I want to add them via GeoJSON, because I want to add custom properties to it.

I tried to create a new featureLayer, add the GeoJSON of my new markers via setGeoJSON, then add this layer to the existing one. If I do that, my custom filter (setFilter) isn't applied to this sub layer.

Another idea would be to create another layer, add the json to it via setGeoJSON, then iterate over its markers and add them to the existing featureLayer. Is that a possibility?

How can I add markers via GeoJSON to an existing layer?


Solution

  • You could try something like this, it depends on two functions inherited from L.LayerGroup called removeLayer & addLayer:

    // Create featurelayer and add it to the map
    var featureLayer1 = L.mapbox.featureLayer(mapid).addTo(map);
    
    // Create another featurelayer, don't add it to the map
    var featureLayer2 = L.mapbox.featureLayer(mapid);
    
    // Wait until ready
    featureLayer2.on('ready', function () {
        // Loop over the layers in the layer
        featureLayer2.eachLayer(function (layer) {
            // Remove them from this layer, this is important because a layer
            // (marker, polygon etc) can't be present in two layers at once
            featureLayer2.removeLayer(layer);
            // Add them to the other layer
            featureLayer1.addLayer(layer);
        }
    });
    

    Personally i'de call that a quick hack. I'de rather use L.GeoJSON which has a addData method, which can add features or featurescollections without removing the already added features.

    // Creates empty GeoJSON layer
    var geojson = L.geoJson().addTo(map);
    
    // Creates GeoJSON layer with initial data
    var geojson = L.geoJson(geojsonObject).addTo(map);
    
    // Add data afterwards
    geojson.addData(geojsonObject);
    

    I can't make up from the code where you are getting you initial data, if it's the features from a mapbox map, you could load them like this:

    // Create a featureLayer which loads your features
    var featureLayer = L.mapbox.featureLayer('examples.map-zr0njcqy');
    
    // Create empty geojson layer
    var geojsonLayer = L.geoJson().addTo(map); 
    
    // Wait until everything is loaded 
    featureLayer.on('ready', function() {
        // Turn layer's features back into geojson
        var features = featureLayer.getGeoJSON();
        // Add features to geojsonLayer
        geojsonLayer.addData(features);
    });
    
    // Now you can add more data afterwards
    geojsonLayer.addData(moreFeatures);
    

    You can also fetch them using a single request with jQuery for instance:

    $.getJSON('http://a.tiles.mapbox.com/v4/MAPID/features.json?access_token=TOKEN', function (data) {
        geojson.addData(data);
    });
    

    You can use filtering with L.GeoJSON in pretty much the same way:

    L.geoJSON(data, {
        'filter': function (feature) {
            //return true or false
        }
    }).addTo(map);
    

    Reference: http://leafletjs.com/reference.html#geojson

    Tutorial: http://leafletjs.com/examples/geojson.html

    Normally i would create an example on Plunker to demonstrate but they're down today, so i'm unable to create a testcase. Did the code above quickly from memory and can't test it so forgive me if i've made any errors.