1

I have a Leaflet map where I am adding the features from a GeoJSON file. I am able to filter the features depending on the properties in the GeoJSON.

I am writing out the same giant block of code each time I add a layer and just changing the variables. I leave off the .addTo(map) and load it later from the layerControl by clicking on a checkbox.

I wrote a function that filters and adds the layers. But it only works if I add it to the map on load -- addTo(map) inside the function. Which loads it with initial paint of the map. I want to add it later, using the checkboxes in the L.control.layers menu.

I've tried several different approaches, removing the .addTo(map) from the function and adding it to the end of the function call. I've also tried calling the function from within the L.control.layers group. I left some comments in the snippet and some comments on what I have tried after the snippet. I may be going about this all wrong.

Here is what I have:

var grayscale = new L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}', {attribution: 'Tiles © Esri — Esri, DeLorme, NAVTEQ', maxZoom: 16 })
var mapOptions = {
     center: [44.2457, -116.9228],
     zoom: 14,
                 layers: [grayscale]
 }

var dog1 = new L.marker([44.2441, -116.9228]).bindPopup('This is just a placeholder.')

map = new L.Map("map", mapOptions);

// ========  function call
var fence2 = newFeature('red', 'fence')
//console.log(fence2) returns 'undefined' but it appears on the map?!
var dog = newFeature('red', 'dog')
// var dog4 = newFeature('blue', 'dog').addTo(map) // with .addTo(map) removed in the function -- nope!

// layercontrol
var baseMaps = {
"Grayscale": grayscale,
};
var overlayMaps = {
"new L.marker dog": dog1,
"not from function": groups.dogs,
"add function feature here after load": dog1   
};
L.control.layers(baseMaps, overlayMaps, { collapsed:false }).addTo(map);
function newFeature(eColor, group){
L.geoJson(myGeoJson, {
 filter: function(feature, layer) {
   return (feature.properties.farm === "Kerner" && feature.properties.group === group);
 },
 onEachFeature: function(feature, layer) {
 layer.bindPopup('farm: ' + feature.properties.farm + '<br />Notes: ' +                                    
feature.properties.description)},

style: function (feature) {
        return {
            color: eColor,
            weight: 3,
            opacity: 1,
            dashArray: 4
        }
  }
    // !!!only works if I add to map here inside the function
    // !!! adds the layer on load
  }).addTo(map)
  //})
  }

If I remove the .addTo(map) from the function and add it when I call the function:

var dog = newFeature('red', 'dog').addTo(map) 

results in this error:

Uncaught TypeError: Cannot read properties of undefined (reading 'addTo')"

Even if the function generates a visible layer, if I add the var to a L.control.layer it breaks the layer control.

var overlayMaps = {

"kerner": fence2 //  the L.control disappears from the map.
 // console - Uncaught TypeError: Cannot read properties of undefined (reading 'setZIndex')

All fine with

.addTo(map)

called like this:

var dog = newFeature('red', 'dog')

inside the function. But that is not the result I am looking for.

Here is a working, but not as needed, concept jsfiddle

and a sample of the geojson. No surprises there.

var myGeoJson = [{
"type": "FeatureCollection",
"features": [
    {
        "type": "Feature",
        "geometry": {
            "type": "LineString",
            "coordinates": [
                [
                    -116.921847,
                    44.245915
                ],
                [
                    -116.921986,
                    44.245442
                ],
                [
                    -116.922721,
                    44.245423
                ]
            ]
        },
        "properties": {
            "name": "Calf Pasture",
            "farm": "Kerner",
            "description": "pasture fence N end.",
            "group": "fence"
        }
    },{
        "type": "Feature",
        "geometry": {
            "type": "LineString",
            "coordinates": [
                [
                    -116.915847,
                    44.243915
                ],
                [
                    -116.915986,
                    44.243442
                ],
                [
                    -116.916721,
                    44.243423
                ]
            ]
        },
        "properties": {
            "name": "Other Pasture",
            "farm": "Kerner",
            "description": "other pasture fence S end.",
            "group": "fence"
        }
    },{
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": 
                [-116.9210, 44.2450]
        },
        "properties": {
            "name": "foodo",
            "farm": "Kerner",
            "description": "another dog yet.",
            "group": "dog"
        }
    }
    ]
    }];
4
  • @Cody Gray I don't unterstand why you have migrated this question to gis.stackexchange ... Do you want to migrate all 12000 leaflet questions from stackoverflow to gis.stackexchange ? Mar 23, 2022 at 12:42
  • @FalkeDesign this is where I intended to post it. Simple as that. Thank you.
    – grantiago
    Mar 23, 2022 at 13:36
  • @TomazicM gone.
    – grantiago
    Mar 23, 2022 at 18:03
  • 1
    The GIS Stack Exchange welcomes focused questions about Leaflet.
    – PolyGeo
    Mar 23, 2022 at 18:57

1 Answer 1

1

There is just one small mistake in your code.

In the function newFeature(eColor, group) you are not returning created layer, so any use of the function result fails.

Code should look something like this:

function newFeature(eColor, group){
  var vectorLayer = L.geoJson(myGeoJson, {
    filter: function(feature, layer) {
      return (feature.properties.farm === "Kerner" && feature.properties.group === group);
    },
    onEachFeature: function(feature, layer) {
      layer.bindPopup('farm: ' + feature.properties.farm + '<br />Notes: ' +                                    
      feature.properties.description)
    },
    style: function (feature) {
      return {
        color: eColor,
        weight: 3,
        opacity: 1,
        dashArray: 4
      }
    }
  });
  return(vectorLayer);  // added function return value
}

var dog = newFeature('red', 'dog').addTo(map);
var fence2 = newFeature('red', 'fence');

var overlayMaps = {
  "kerner": fence2
};

L.control.layers(baseMaps, overlayMaps, {collapsed: false}).addTo(map);

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.