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