[GIS] Loop over features of a GeoJSON object from CartoDB

cartogeojsonjavascriptleafletloop

I have just little knowledge about HTML and JavaScript. Nevertheless I was playing, copying and pasting around with Leaflet and CartoDB.

I want to display the features GeoJson in a table. This is what I tried.

var map = L.map('map').setView([51.0, 10.0], 6);

var base = {
"S/W" : L.TileLayer.provider('OpenStreetMap.BlackAndWhite'),
"TOP":  L.TileLayer.provider('Thunderforest.OpenCycleMap'),
"OpenStreetMap": L.TileLayer.provider('OpenStreetMap.Mapnik')
};


window.backupAlert = window.alert;
window.alert = function () {return true};
var alle = L.cartoDB('http://leak-my-brain.cartodb.com/api/v2/sql?q=SELECT * FROM jobsnew', {
pointToLayer: function(feature, latlng) {
return L.marker(latlng, {
icon: L.icon({
iconSize: [4, 4],
iconAnchor: [0, 0],
popupAnchor: [0, 0],
iconUrl: "http://www.zoowelt.org/wp-content/uploads/2013/02/viv_point.png"
})
})
},
 onEachFeature: function(feature, layer) {
layer.bindPopup('<strong>' + feature.properties.title + '</strong><br>' + feature.properties.kw);
}
});

map.addLayer(base.OpenStreetMap); 
map.addLayer(alle);


map.on( "zoomend", function( e ) {
    console.log( "zoom level is " + map.getZoom())
}); //zur ausgabe des Zoomlevels in der Konsole
var layersControl = L.control.layers(base,alle); 
layersControl.addTo(map);  
for (var key in alle._layers) {
  if (alle._layers.hasOwnProperty(key)) {
    backupAlert("hi comment");
  }
};
function writeTable() {
    var out = '';
    for (var row=0; row<1000; row++) {
    if ( typeof(alle._layers[row])=='undefined') continue;
        out += '<tr>' 
        + '<td>' + alle._layers[row].feature.properties.title + '</td>' + 
        + '<td>' + alle._layers[row].feature.properties.kw + '</td>' 
        + '</tr>'
     }      
     document.write(out);
 };

This somehow works but there are some issues. The main problem is that the indices in the alle are not starting at 0 and they are not increasing by the step size of 1.

Best Answer

You can loop over a L.LayerGroup using eachLayer in Leaflet. A L.cartoDB object is a specialized L.GeoJSON object which in turn is a specialized layer group.

Each feature, a geometry, in stored in a layer. The properties you want to display can be fetched from the features of the layers we are looping over.

var out = '';
result.eachLayer(function(layer){
    out += '<tr>';
    out += '    <td>' + layer.feature.properties.title + '</td>';
    out += '    <td>' + layer.feature.properties.kw    + '</td>';
    out += '</tr>';
});

But notice that creating the L.cartoDB object takes some time for the database query. And since this is done asynchronously, you have to wait for the result in code.

Sadly, as far as I found out, there is no way to pass a callback to handle the result as it returns. Here is a short lineup how to perform the task without the help of CartoDB. I am not going to explain this in more detail since it goes beyond the actual question and you would need to dig into technologies like JavaScript, PHP, SQL, GeoJSON and AJAX first.

  • use a JavaScript framework like jQuery for the AJAX request which allows you to specify a callback function to process the data as it returns
  • use a server side language like PHP to connect to the database, query the data from it, encode it to GeoJSON and output that
  • in the JavaSCript callback do both, create a Leaflet GeoJSON layer to display the result on the map, and loop over the GeoJSON object to append rows for each feature to the table