1

How do I add WFS when using the Leaflet.Control.Tree by jjimenezshaw plugin?

Without using the control tree plugins, I can to make the call from Geoserver through Ajax and display my data on the map in this way.

var owsrootUrl = 'http://localhost:8080/geoserver/city.urban/ows';

var defaultParameters = {
service : 'WFS',
version : '2.0',
request : 'GetFeature',
typeName : 'city.urban:streets_city',
outputFormat : 'text/javascript',
format_options : 'callback:getJson',
SrsName : 'EPSG:4326'
};


var parameters = L.Util.extend(defaultParameters);
var URL = owsrootUrl + L.Util.getParamString(parameters);

var WFSLayer = null;
var ajax = $.ajax({
url :URL,
dataType : 'jsonp',
jsonpCallback : 'getJson',
success : function (response) {
    WFSLayer = L.geoJson(response, {
        style: function (feature) {
            return {
                stroke: true,
                fillColor: '#B04173',
                fillOpacity: 2,
                color: '#000000',
                weight: 1,

            };
        
      
        }
    }).addTo(map);
   }
  });

Now, I am able to insert the WMS in the control layer tree, but I have some problem with my WFS. How can I solve this? This is my first webmap and I don't know if there is any error.

PS: I've enabled CORS on GeoServer.

 <style type="text/css">
     html, body {width: 100%; height: 100%; margin: 0; }
  #map {width: 100%; height: 100%; }
 </style>
 </head>

 <body>

<div id="map"></div>
<link rel="stylesheet" href="src/css/L.Control.Layers.Tree.css" crossorigin=""/>
<script src="src/plugins/L.Control.Layers.Tree.js"></script>




<script type="text/javascript">
var center = [41.72707235373704, 13.004139599641844];



var BING_KEY = 'MY_KEY'
var binglayer= L.tileLayer.bing(BING_KEY)



//insert wms
var boundaries = L.tileLayer.wms('http://localhost:8080/geoserver/city.urban/wms', {
layers: 'city.urban:administrative_boundaries',
format: 'image/png',
transparent: true,
});





var osm = L.tileLayer(
        '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        {attribution: '© OpenStreetMap contributors'}
    );

    var osmBw = L.tileLayer(
        'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png',
        {attribution: '© OpenStreetMap contributors'}
    );

    var thunderAttr = {attribution: '© OpenStreetMap contributors. Tiles courtesy of Andy Allan'}
    var transport = L.tileLayer(
        '//{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png',
        thunderAttr
    );

    var cycle = L.tileLayer(
        '//{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png',
        thunderAttr
    );



    var stadiadark = L.tileLayer('https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y} 
   {r}.png', {
    attribution: '&copy; <a href="https://stadiamaps.com/">Stadia Maps</a>, &copy; <a 
    href="https://openmaptiles.org/">OpenMapTiles</a> &copy; <a 
    href="http://openstreetmap.org">OpenStreetMap</a> contributors'}
    );

 
 
 var map = L.map('map', {
   renderer: L.canvas(),
   layers: [osm],
   center: center,
   zoom: 13
 });
 

 // add leaflet-geoman controls with some options to the map  
 map.pm.addControls({  
 position: 'topleft',  
 drawCircle: false,  
 });  



 L.control.scale().addTo(map);

//insert baselayers 

 var baseTree = {
        label: 'BaseLayers',
        noShow: true,
        children: [
            {
                label: 'OpenStreeMap',
                
                children: [
                    {label: 'OpenStreetMap Standard', layer: osm},
                ]
            },
            {
                label: 'Stadia Basemaps',
                children: [
                    {label: 'Stadia Alidade Smooth Dark', layer: stadiadark},
                ]
            },
            {
                label: 'Thunder',
                children: [
                    {label: 'Cycle', layer: cycle},
                    {label: 'Transport', layer: transport},
                ]
                
            },
            {  
                         label: 'Bing',
                         children: [
                        {label: 'Bing Satellite', layer: binglayer}
                         ]
                     },
                    ]
                    };                  
            

 //overlays
 
        var overlaysTree = {
label: 'City',
selectAllCheckbox: 'Un/select all',
children: [
    {
        
        label: 'Data',
        selectAllCheckbox: true,
        children: [
            {
                label: 'Testgroup',
                selectAllCheckbox: true,
                children: [
                    { label: 'Boundaries', layer: boundaries },
                    {label: 'Streets', layer: streets} ----> HERE I WANT TO PUT MY WFS
                    
                ]
            },
            /* ... */
            
        ]
    }
]
}
          

        //control options
       
        var lay = L.control.layers.tree(baseTree, overlaysTree,
        {
            namedToggle: true,
            selectorBack: false,
            closedSymbol: '&#8862; &#x1f5c0;',
            openedSymbol: '&#8863; &#x1f5c1;',
            collapseAll: 'Collapse all',
            expandAll: 'Expand all',
            collapsed: false,
        });
        
        

    lay.addTo(map).collapseTree().expandSelected().collapseTree(true);
    L.DomEvent.on(L.DomUtil.get('onlysel'), 'click', function() {
        lay.collapseTree(true).expandSelected(true);

    });

    
    
      


   </script>
   </body>
   </html>
10
  • 1
    Can you please describe more in detail "but I have some problem with my WFS"? What do you mean by "I don't know if there is any error"? Have you looked in browser debugger console and network section? – TomazicM Feb 3 at 9:26
  • I meant to say that I don't really understand how to insert the WFS within the group of layers I'm interested in. I mean, is there something I need to add to make it clear where the final result of the WFS call should go or is there another way to make the WFS call in the case of this plugin? – Matteo Ruggieri Feb 3 at 9:39
  • You say you have no problems inserting WMS layer, but have some problems with WFS. As far as layers are concerned, there is no difference between WMS or WFS layer when including them in the control, all you need is layer object. Or is your question really about how to create WFS layer? – TomazicM Feb 3 at 10:38
  • 1
    Just put `{label: 'My WFS layer', layer: WFSLayer}. – TomazicM Feb 3 at 13:38
  • 1
    Reason for this is probably the fact that you are creating WFS layer async with AJAX and so at the time of tree control creation layer is not available yet. – TomazicM Feb 3 at 16:50
1

The cause of your problem with WFS layer is that layer object initially has NULL value. Since actual layer is created async via AJAX, layer does not exist at the time of Leaflet tree control creation and as a consequence you get mentioned error.

Solution for this is to initially create an empty GeoJSON layer, and then fill it with data async and add to map:

var WFSLayer = L.geoJson(null, {
  style: function (feature) {
    return {
      stroke: true,
      fillColor: '#B04173',
      fillOpacity: 2,
      color: '#000000',
      weight: 1,
    };
  }
});

var ajax = $.ajax({
  url: URL,
  dataType: 'jsonp',
  jsonpCallback: 'getJson',
  success: function (response) {
    WFSLayer.addData(response);
    WFSLayer.addTo(map);
  }
});
2
  • It works like a charm! one point is not enough to thank you for your help. Can I ask you one more thing? In case of a second request for a new WFS do I need to change something in the callback part? Because I'm creating a new request from scratch, I can see everything in the layer control (including Check/unchek Box) but the WFS doesn't appear. I'm reading this and it sounds like a very similar problem to mine link – Matteo Ruggieri Feb 4 at 7:39
  • 1
    GIS SE site has policy of focused questions, which means one question per question. If you have a new question, please post it as a separate question. – TomazicM Feb 4 at 8:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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