Working with a dynamic GeoJson data - is this the best way to do it?

1,281 views
Skip to first unread message

DaveF63

unread,
Dec 5, 2015, 5:02:06 PM12/5/15
to Leaflet
Hi

This routine works as expected, but I'm unsure if it's the most efficient code. (Note this code is stripped down - In the full code I add custom markers so pointToLayer is required)

On running the routine I'm downloading both nodes & polygon data for 'pubs' using Overpass from the OSM database; then converting it to GeoJson. I want to display a marker at all the node locations & at the centre of the polygons. I also want the boundary of the polygon to be displayed.

From code you can see I'm using the .addto(map) method three times to achieve this, First within the pointoLayer function to place node markers, the second in the onEachFeature function for polygons & the last call is to display the boundary.

This, to my naive eyes appears overkill, but all seem necessary. Is there better/quicker method?

I'm aware of the 'center' output option for Overpass which returns the polygon centre coordinates, but I'm guessing that downloading from the web is slower than running javascript. Am I correct in this assumption?

Cheers
Dave F.        

<script>
       
var osmMap = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')
       
var map = L.map('map', {layers: [osmMap]});
        map
.setView([51.37659,-2.35406], 17)
       
       
var coords = '[bbox:51.37615,-2.3549,51.37683,-2.35272]'
       
var tag1 = '["amenity"="pub"]'
       
var output = ';);out body;>;out skel qt;'    
       
var query = '?data=' + coords + ';(node'+ tag1 +';way'+ tag1 + output;
               
        $
.get('http://overpass-api.de/api/interpreter' + query, function (osmDataAsXml) {

       
// ******** Pubs **********        
        L
.geoJson(osmtogeojson(osmDataAsXml), {
          pointToLayer
: function (feature, latlng) {
           L
.marker(latlng).addTo(map)    
         
},

         
// Get polygon bounds, center of it & place marker there
          onEachFeature
: function (feature, layer) {
           
if (feature.geometry.type === 'Polygon') {
              L
.marker(layer.getBounds().getCenter()).addTo(map)
           
}
         
}    
       
}).addTo(map);    
     
});
   
</script>

ghybs

unread,
Dec 7, 2015, 1:11:16 AM12/7/15
to Leaflet
Hi,

There is no issue in the absolute adding layers multiple times to the same map.
The map makes sure it does not process multiple times layers that are already there.

Please note that the function you pass to `pointToLayer` should return a layer (marker), that will be included into the GeoJSON Layer Group being built.
If I copy-paste your code as-is, it breaks because of this.
Since those markers are added into the GeoJSON Layer Group (which you add to the map in the end), you no longer need to add them directly to the map.

As for your center markers, there is no issue computing them Client side rather than requesting them to OSM, since anyway you want the full polygon as well.
Regarding speed, it might not be as simple saying which technique is better, as it would depend on your connectivity and CPU power.
I do not think requesting an extra coordinate pair per polygon would hurt that much, though.

Instead of adding the computed center directly to the map, you could store it into a temporary Layer Group that you add to your GeoJSON Layer Group at the end.
That way, the "centers" are part of that Group as well.
E.g. you can switch it on/off through the Layers Control, and all related layers (markers, polygons, center markers) will be turned on/off accordingly.

Demo: http://jsfiddle.net/ve2huzxw/79/

var layersControl = L.control.layers(null, null, {
  collapsed
: false
}).addTo(map);


$
.get('http://overpass-api.de/api/interpreter' + query, function(osmDataAsXml) {

 
 
var tempLayerGroup = L.layerGroup();

 
// ******** Pubs **********        
 
var myLayerGroup = L.geoJson(osmtogeojson(osmDataAsXml), {
    pointToLayer
: function(feature, latlng) {
     
//L.marker(latlng).addTo(map);
     
return L.marker(latlng); // pointToLayer should return a layer (marker) that will be included in this GeoJSON Layer Group.

   
},

   
// Get polygon bounds, center of it & place marker there

    onEachFeature
: function(feature, layer) {

     
if (feature.geometry.type === 'Polygon') {

        L
.marker(layer.getBounds().getCenter()).addTo(tempLayerGroup); // The created marker is added to a temporary Layer Group.
     
}
   
}
 
}).addTo(map);
 
  myLayerGroup
.addLayer(tempLayerGroup); // Nest the temporary Layer Group with all center markers into the GeoJSON Layer Group, so that they are part of it / they are switched on/off together.
 
  layersControl
.addOverlay(myLayerGroup, "Pubs"); // Toggling on/off the GeoJSON Layer Group adds/removes all markers, polygons and center markers.
});

DaveF63

unread,
Dec 10, 2015, 10:09:29 AM12/10/15
to Leaflet
Hi ghybs
Thanks for the reply.

Firstly, where did you obtain the reference to osmtogeojson.js? I tried loading:
https://raw.githubusercontent.com/tyrasd/osmtogeojson/gh-pages/osmtogeojson.js

but got this error message: 'Github is not a CDN, using it as such will cause issues with loading the file. Do you still wish to it?'


"If I copy-paste your code as-is, it breaks because of this."
The <snip> is a routine I'm rebuilding using Leaflet 1.0 b1:

http://cdn.leafletjs.com/leaflet-1.0.0-b1/leaflet.css
http://cdn.leafletjs.com/leaflet-1.0.0-b1/leaflet.js

If I use 0.7* on the <snip> it doesn't display the polygon & only two of the threes markers. Unsure if this is an issue, or intended practice.

Excuse my Javascript ignorance, but in your fiddle you've no reference to jQuery. I thought that ($ in the code) did a httpget request for the data. Where is it getting the data from?

In my full routine I use a LayerControl:  http://jsfiddle.net/9cp2c28o/13/

Is there a specific reason you use '.addTo(map);' instead of 'map.addLayer(myLayerGroup);'?

Cheers
Dave F.

Stinky McGhee

unread,
Dec 11, 2015, 4:35:03 PM12/11/15
to Leaflet




Firstly, where did you obtain the reference to osmtogeojson.js? I tried loading:
https://raw.githubusercontent.com/tyrasd/osmtogeojson/gh-pages/osmtogeojson.js


Simply change that url to:

and that should do the trick.
Reply all
Reply to author
Forward
0 new messages