1

I need to summarize an attribute of a geojson based on the map extent. I want to sum values for all features intersecting bbox. I think that I must use the Bbox filter but isn't clear for me how I can use it.

I've a simple GeoJSON with four geometry named test_data.geojson:

{
"type": "FeatureCollection",
"name": "test_data",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "id": 1, "name": "focusarea-id1", "pop": 30 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 10.224194550042373, 41.358221559689788 ], [ 10.224194550042373, 42.154498393805234 ], [ 11.816748218273265, 42.154498393805234 ], [ 11.816748218273265, 41.358221559689788 ], [ 10.224194550042373, 41.358221559689788 ] ] ] ] } },
{ "type": "Feature", "properties": { "id": 2, "name": "focusarea-id2", "pop": 20 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 11.960078048414047, 40.779593726899229 ], [ 11.960078048414047, 41.87314724575112 ], [ 13.297823129727995, 41.87314724575112 ], [ 13.297823129727995, 40.779593726899229 ], [ 11.960078048414047, 40.779593726899229 ] ] ] ] } },
{ "type": "Feature", "properties": { "id": 3, "name": "focusarea-id1", "pop": 10 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 11.519471533536832, 42.425232517404488 ], [ 11.519471533536832, 43.582488182985607 ], [ 12.8890676882154, 43.582488182985607 ], [ 12.8890676882154, 42.425232517404488 ], [ 11.519471533536832, 42.425232517404488 ] ] ] ] } },
{ "type": "Feature", "properties": { "id": 4, "name": "focusarea-id3", "pop": 40 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 13.043014542811051, 42.255360126126526 ], [ 13.043014542811051, 43.465700913981998 ], [ 13.871142450291117, 43.465700913981998 ], [ 13.871142450291117, 42.255360126126526 ], [ 13.043014542811051, 42.255360126126526 ] ] ] ] } }
]
}

I'm be able to put on the map my four rectangles using this code:

var sourceDataUrl = '{% static 'gis-data/vettori/test_data.geojson' %}';
var polygonsSource = new ol.source.Vector({
    url: sourceDataUrl,
    format: new ol.format.GeoJSON(),
});
var vectors = new ol.layer.Vector({
  source: polygonsSource,
});
map.addLayer(vectors);

var fetchFn = fetch(sourceDataUrl)
  .then(function(resp) {
    return resp.json();
  });

/// Summarize pop
fetchFn.then(function(json) {
    var features = new ol.format.GeoJSON().readFeatures(json, {
      dataProjection: 'EPSG:4326',
      featureProjection: map.getView().getProjection(),
    });

    var polygonPop = 0;
    for (var i=0; i<features.length; i++) {
      polygonPop += features[i].values_.pop;
    }
    console.log(polygonPop);

});

/// Compute the bounding box based on map extent
map.getView().on('change', function() {
    var extent3857 = map.getView().calculateExtent(map.getSize())
    var extent4326 = ol.proj.transformExtent(extent3857, 'EPSG:3857', 'EPSG:4326');
    console.log('Boundary Box 4326: '+extent4326);

});

I can compute the bounding box based on map extent but I don't understand how I can link this feature with polygonSurface.

EDIT 1 with the indications of @Mike

map.getView().on('change', function() {

    var extent = ol.proj.transformExtent(
      map.getView().calculateExtent(map.getSize()),
      'EPSG:3857',
      'EPSG:4326',
    );

    var polygonIntersection = [];

    polygonsSource.forEachFeatureIntersectingExtent(extent, function(feature) {
      console.log(feature);
      polygonIntersection.push(feature);
    });

    console.log(polygonIntersection); // response -> Array []

});

Using the method forEachFeatureIntersectingExtent I've an empty array.

  • What would the filtering algorithm be? Sum values for all features intersecting bbox? Sum values for all features completely inside bbox? Calculate actual feature surface visible inside bbox? Please edit the question and add this info. – TomazicM Jul 27 at 16:25
  • I've edit my question @TomazicM – Massimiliano Moraca Jul 27 at 16:36
  • 1
    Next question: In your code you calculate extent only when zoom changes, but what about map panning? Feature intersections with bbox change also when you pan/move the map. – TomazicM Jul 27 at 16:50
  • Oh! You pointed me out that my code is usefull only with zoom in/out. I was sure that was usefull also with pan/move. This is a problem that I've not considerd before... – Massimiliano Moraca Jul 27 at 17:04
  • 1
    If you add your features to a vector source you can use forEachFeatureIntersectingExtent openlayers.org/en/latest/apidoc/… If you only have point features it would be more efficient to use forEachFeatureInExtent or getFeaturesInExtent – Mike Jul 27 at 17:48
1

Since it looks like @Mike is not around, I'm answering this.

When you calculate current view extent, you are transforming GeoJSON source coordinates from EPSG:3857 to EPSG:4326, to use them for checking intersection with GeoJSON features. That's wrong since source coordinates are transformed automatically from original EPSG:4326 to standard view EPSG:3857 when GeoJSON is read into source.

It would be also better to use map's moveend to catch view extent change, since view's change events are called twice at every move/zoom event, once at the beginning and once at the end.

So your code could look something like:

map.on('moveend', function() {
  var extent = map.getView().calculateExtent(map.getSize());
  var polygonIntersection = [];

  polygonsSource.forEachFeatureIntersectingExtent(extent, function(feature) {
    polygonIntersection.push(feature);
  });
  
  console.log(polygonIntersection);
});
| improve this answer | |
  • Why with your code I see an array fo 8 elements instead of 4? Every time I refresh the map the array has 8 elements – Massimiliano Moraca Jul 29 at 17:28
  • Since I don't see your complete code, I can't answer your comment. I tried the above code with your data and it worked. – TomazicM Jul 29 at 17:35
  • Sorry it's a my mistake. Now I see the correct array length – Massimiliano Moraca Jul 29 at 17:45

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.