Geographic Information Systems Asked by Massimiliano Moraca on August 3, 2020
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.
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);
});
Correct answer by TomazicM on August 3, 2020
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP