1 votos

Filtrar la geometría en función de la extensión del mapa mediante OpenLayers

Necesito resumir un atributo de un geojson basado en la extensión del mapa. Quiero sumar los valores de todas las características que se cruzan con el bbox. Creo que debo utilizar el Filtro Bbox pero no me queda claro cómo puedo utilizarlo.

Tengo un simple GeoJSON con cuatro geometrías llamadas 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 ] ] ] ] } }
]
}

Soy capaz de poner en el mapa mis cuatro rectángulos usando este código:

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);

});

Puedo calcular el cuadro delimitador basado en la extensión del mapa, pero no entiendo cómo puedo vincular esta característica con polygonSurface .

EDIT 1 con las indicaciones de @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 []

});

Utilizando el método forEachFeatureIntersectingExtent Tengo un array vacío.

1voto

hood Puntos 16

Como parece que @Mike no está por aquí, respondo a esto.

Cuando se calcula la extensión de la vista actual, se transforman las coordenadas de origen GeoJSON de EPSG:3857 a EPSG:4326 para utilizarlos en la comprobación de la intersección con las características GeoJSON. Esto es incorrecto, ya que las coordenadas de origen se transforman automáticamente a partir del EPSG:4326 a la vista estándar EPSG:3857 cuando se lee GeoJSON en la fuente.

También sería mejor utilizar el mapa de moveend para captar el cambio de extensión de la vista, ya que el change son llamados dos veces en cada evento de movimiento/zoom, una al principio y otra al final.

Así que tu código podría ser algo así:

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

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

  console.log(polygonIntersection);
});

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X