Use self-defined Leaflet identifiers to work with jsTree checkboxes

I have some hierachic structured point-layers in a GeoJSON file using jsTree (ajax) with checkboxes to add them to the map. As I have about 20.000 points structured in 2.000 nodes representing the layers I have to to it in an automated way.

My idea is to connect the jsTree id with an id in the GeoJSON, so the Node ID of the jstree corresponds with the “treeid” (, both are strings) in the GeoJSON file. The string ID’s are generated in a Database and exported as JSON. Each checkbox adds an ID assigned layer to a layergroup on the map. Unchecking should remove that particular layer. The user can activate as much checkboxes as he likes.

Based on this question I set the default _leaflet_id equal to the “treeid” to use it as an identifier for each Layer. This works basically.

Example of the GeoJSON:

var collection = {"type": "FeatureCollection","crs": {"type": "name","properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84"}},   "features": [{ "type": "Feature",
   "properties": {
     "dta_1": "Node_1",
     "treeid": '01 01 002 00001'
   "geometry": {
     "type": "Point",
     "coordinates": [38.933333, 40.816667]
   "type": "Feature",
   "properties": {
     "dta_1": "Node_2",
     "treeid": '01 01 002 00002'
   "geometry": {
     "type": "Point",
     "coordinates": [38.9551, 40.7626]

Example of the jsTree (simple JSON):

$('#data').jstree({'core': {'data': [{
     "id": "01",
     "parent": "#",
     "text": "Root"
   }, {
     "id": "01 01 002 00001",
     "parent": "01",
     "text": "Node_1"
   }, {
     "id": "01 01 002 00002",
     "parent": "01",
     "text": "Node_2"
   } ...

My checkbox code:

var group = {}; 
var layergroup =  L.layerGroup().addTo(map);
$('#data').on("check_node.jstree", function(e, data) {
            group =  L.geoJson(collection, {    
            onEachFeature: function(feature, layer) {
                           layer._leaflet_id =;},      
            filter: function(feature, layer) {
                    if ( return true}});
            group.treeid =
 /*         layergroup.eachLayer(function(layer){
            layer._leaflet_id =;
            }) */
.on("uncheck_node.jstree", function(e, data){
if (e._layers[]) layergroup.removeLayer(e);})});
//   if (layer._leaflet_id === {
//   layergroup.removeLayer(layer)}

A working fiddle is here: jsfiddle

Using the “onEachFeature” Function works fine for one point, it is removed correctly. So I thought, it works, but as you can see in the fiddle, if there are many points (Node_2) again only one point (the first one) is added to the map. (Because only the first one is assigned?)

Using the “eachLayer” method adds all points as expected, but of course the uncheck code doesn’t work. Changing to the outcommented code does not work.

Where is the point I’m missing on the “onEachfeature” Function to add all points with the same treeid?

Or the other option: How to change the uncheck code?

I need to add all points with the same id referencing a specific to a layergroup by a checkbox, unchecking it should remove them from the layergroup and the map.

Geographic Information Systems Asked by McOS on November 12, 2021

1 Answers

One Answer

I don't quite understand the intended logic of jsfiddle code, but there is definitely no need to load GeoJSON on each tree node selection/click, it can be loaded once at the beginning and then it's features iterated through when neccessary.

The other thing is that you should never modify internal Leaflet _leaflet_id property. You can only read it with getLayerId method of group layer and later use it to get desired layer with getLayer method.

In the code below (only relevant part from jsfiddle) GeoJSON features are loaded only once into featureLayer group layer, which is not added to map. Then upon tree node selection/unselecton features in featureLayer are iterated through and layer with id property that corresponds to tree node id is added/removed to layergroup layer:

var featureLayer = L.geoJson(collection);

  .on("check_node.jstree", function(e, data) {
    featureLayer.eachLayer(function (layer) {
      if ( == {

  .on("uncheck_node.jstree", function(e, data) {
      if ( == {

Answered by TomazicM on November 12, 2021

Add your own answers!

Related Questions

Identifying topology error with Javascript

0  Asked on April 26, 2021 by zhangjinzhou


Distance raster from polygon features

1  Asked on April 26, 2021 by northson


QGIS form performance

2  Asked on April 25, 2021 by lennert-de-feyter


CRSerror in geocube make_geocube

0  Asked on April 25, 2021


Using writeOGR on a list of SpatialPolygons

2  Asked on April 25, 2021 by canderson156


Ask a Question

Get help from others!

© 2021 All rights reserved.