0

I am currently working on a polygon selection tool in Openlayers 3 and am developing on the code posted here.

The above example displays the searchable layer (in this case a WFS) from when the application loads, but as my WFS layer contains 80,000+ features that I need to search against, I am trying to adapt this so that the WFS layer is only displayed once the user completes their search polygon to reduce the loading time, and features only within the bounding box of the drawn polygon are shown.

The JSTS library is then used to do a spatial intersect between the user's drawn polygon and the WFS features added to the map.

The below code works ok as it correctly displays the WFS features in the drawn polygon extent, but it isn't returning the feature's attribute(s) in the console.

I am trying to work out if this is because the layer fully isn't loaded before we try to return the feature's attributes? Do we need to include something to wait until the layer is loaded before carrying out the forEachFeatureInExtent method?

var myDrawSource = new ol.source.Vector({wrapX: false});

var myDrawVector = new ol.layer.Vector({
  source: myDrawSource,
  style: new ol.style.Style({
    fill: new ol.style.Fill({
      color: 'rgba(255, 255, 255, 0.5)'
    }),
    stroke: new ol.style.Stroke({
      color: '#ffcc33',
      width: 2
    }),
    image: new ol.style.Circle({
      radius: 7,
      fill: new ol.style.Fill({
        color: '#ffcc33'
      })
    })
  })
});

var mySelectionsSource = new ol.source.Vector({wrapX: false});

var mySelectionsVector = new ol.layer.Vector({
  source: mySelectionsSource,
  style: new ol.style.Style({
    fill: new ol.style.Fill({
      color: 'rgba(255, 0, 0, 0.5)'
    }),
    stroke: new ol.style.Stroke({
      color: 'rgba(255, 0, 0, 1)',
      width: 2
    }),
    image: new ol.style.Circle({
      radius: 7,
      fill: new ol.style.Fill({
        color: '#ffcc33'
      })
    })
  })
});

var map = new ol.Map({
  layers: [raster,myDrawVector,mySelectionsVector],
  target: 'map',
  view: new ol.View({
    projection: bng,
        resolutions: resolutions,
        center: [501776, 167214],
        zoom: 5
  })
});

var  draw = new ol.interaction.Draw({
      source: myDrawSource,
      type: "Polygon",
    });

map.addInteraction(draw);

draw.on('drawend',function(e){
myDrawSource.clear();
mySelectionsSource.clear();
var waterAreasVecSource = new ol.source.Vector({
        format: new ol.format.GeoJSON(),
        url: function() {
          var featuresExtent = e.feature.getGeometry().getExtent();
          return '../../geoserver/wfs?service=WFS&' +
              'version=1.1.0&request=GetFeature&typename=waterfeature&' +
              'outputFormat=application/json&srsname=EPSG:27700&' +
              'bbox=' + featuresExtent.join(',') + ',EPSG:27700';
        },
        strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
          maxZoom: 13
        }))
      });

var waterAreasVector = new ol.layer.Vector({
    source: waterAreasVecSource
});

map.addLayer(waterAreasVector);
var extent = e.feature.getGeometry().getExtent();
var geomA = e.feature.getGeometry();
waterAreasVecSource.forEachFeatureInExtent(extent,function(aa){
console.log("forEachFeatureInExtent",aa.get('name'));
if (polyIntersectsPoly(geomA,aa.getGeometry()) === true){
mySelectionsSource.addFeature(aa);
}
});
});


/**
* check whether the supplied polygons have any spatial interaction
* @{ol.geometry.Polygon} polygeomA 
* @{ol.geometry.Polygon} polygeomB 
* @returns {Boolean} true||false
*/
function polyIntersectsPoly(polygeomA, polygeomB) {
 var geomA = new jsts.io.GeoJSONReader().read(new ol.format.GeoJSON().writeFeatureObject(
        new ol.Feature({
            geometry: polygeomA
       })
   )
   ).geometry;
var geomB = new jsts.io.GeoJSONReader().read(new ol.format.GeoJSON().writeFeatureObject(
        new ol.Feature({
            geometry: polygeomB
        })
    )
    ).geometry;
return geomA.intersects(geomB);
};
4

1 回答 1

2

提供的小提琴中有几个错误。每次drawend触发事件时添加一层是错误的。而是在启动时添加一个 vactor 层,然后在其上添加/删除功能。这是一个工作代码。和小提琴 检查控制台以查看功能属性的日志记录。

var raster = new ol.layer.Tile({
  source: new ol.source.OSM({})
});

var myDrawSource = new ol.source.Vector({wrapX: false});

var myDrawVector = new ol.layer.Vector({
  source: myDrawSource,
  style: new ol.style.Style({
    fill: new ol.style.Fill({
      color: 'rgba(255, 255, 255, 0.5)'
    }),
    stroke: new ol.style.Stroke({
      color: '#ffcc33',
      width: 2
    }),
    image: new ol.style.Circle({
      radius: 7,
      fill: new ol.style.Fill({
        color: '#ffcc33'
      })
    })
  })
});

var mySelectionsSource = new ol.source.Vector({wrapX: false});

var mySelectionsVector = new ol.layer.Vector({
  source: mySelectionsSource,
  style: new ol.style.Style({
    fill: new ol.style.Fill({
      color: 'rgba(255, 0, 0, 0.5)'
    }),
    stroke: new ol.style.Stroke({
      color: 'rgba(255, 0, 0, 1)',
      width: 2
    }),
    image: new ol.style.Circle({
      radius: 7,
      fill: new ol.style.Fill({
        color: '#ffcc33'
      })
    })
  })
});

var map = new ol.Map({
  layers: [raster, myDrawVector,mySelectionsVector],
  target: 'map',
  view: new ol.View({
    center: [-8908887.277395891, 5381918.072437216],
    maxZoom: 19,
    zoom: 12
  })
});


var  draw = new ol.interaction.Draw({
      source: myDrawSource,
      type: "Polygon",
    });

map.addInteraction(draw);

//just clear featutes and add back those falling within drawn polygon
//you need an ajax request and new ol.format.WFS to parse the feats 
draw.on('drawend',function(e){
var extent = e.feature.getGeometry().getExtent();
var geomA = e.feature.getGeometry();

myDrawSource.clear();
mySelectionsSource.clear();
$.ajax('http://demo.opengeo.org/geoserver/wfs', {
            type: 'GET',
            data: {
                service: 'WFS',
                version: '1.1.0',
                request: 'GetFeature',
                typename: 'water_areas',
                srsname: 'EPSG:3857',
                bbox: extent.join(',') + ',EPSG:3857'
            }
        }).done(function(resp){
        var formatWFS = new ol.format.WFS();
        var featuresInExtent = formatWFS.readFeatures(resp);
        var featuresOnDrawPoly = new Array();
        for (var i=0;i<featuresInExtent.length;i++){       
        var geomB = featuresInExtent[i].getGeometry();
          if (polyIntersectsPoly(geomA,geomB)===true){
          featuresOnDrawPoly.push(featuresInExtent[i])
          }
        }
        mySelectionsSource.addFeatures(featuresOnDrawPoly);
        //here you may iterate and get the attributes of those falling within the draw polygon
        for (var z=0;z<featuresOnDrawPoly.length;z++){
        console.log("feature landuse is ======", featuresOnDrawPoly[z].get('landuse'));
        }
        }).fail(function () {
        alert("fail loading layer!!!")
        });

})





/**
* check whether the supplied polygons have any spatial interaction
* @{ol.geometry.Polygon} polygeomA 
* @{ol.geometry.Polygon} polygeomB 
* @returns {Boolean} true||false
*/
function polyIntersectsPoly(polygeomA, polygeomB) {
 var geomA = new jsts.io.GeoJSONReader().read(new ol.format.GeoJSON().writeFeatureObject(
        new ol.Feature({
            geometry: polygeomA
       })
   )
   ).geometry;
var geomB = new jsts.io.GeoJSONReader().read(new ol.format.GeoJSON().writeFeatureObject(
        new ol.Feature({
            geometry: polygeomB
        })
    )
    ).geometry;
return geomA.intersects(geomB);
};
于 2016-03-17T14:25:02.147 回答