Friday, 5 October 2018

OpenLayers load WFS vector layer: how to check whether all features are returned from server?


My app takes several seconds to return all features of a WFS layer from server, I am wondering whether there is a way to check whether all features are returned in coding, so that we can add a loading-mask...



In other words, how do you check whether a WFS request is successful or not?


Code sample:


var newEventLayer = new OpenLayers.Layer.Vector
(
'test'
, { "strategies":
[new OpenLayers.Strategy.BBOX()
, new OpenLayers.Strategy.Refresh({ "force": true })
]
, "protocol": new OpenLayers.Protocol.WFS(

{ "version": '1.0.0'
, "srsName": 'EPSG:4326'
, "url": '/geoserver/ows?service=WFS'
, "featureType": 'XXX'
, "featureNS": 'XXXX'
, "geometryName": 'GEOM'
})
}
);


map.addLayer(newEventLayer);

Answer



Assuming your are using OpenLayers.Protocol.WFS, then you have something like this and you can provide a callback when you call the read operation on the protocol:


The call back has an OpenLayers.Protocol.Response object. This object has an error property that will let you know of any errors.


    var protocol = new OpenLayers.Protocol.WFS({
version: "1.1.0",
url: xxx
featurePrefix: xxx
featureType: xxx
featureNS: xxx

geometryName: xxx
// defaultFilter: searchFilter,
srsName: xxx
});

var response = protocol.read({
maxFeatures: 100,
callback: _CallBack
});


function _CallBack (resp) {
console.log(resp);
console.log(resp.error);
});

enter image description here



The problem with supplying the protocol in the layer constructor is that you don't get the chance to call .read() yourself and the opportunity to provide your own callback to monitor the response because the layer does it for you.


So if you want to monitor the results you're going to have to create the layer and protocol separate so you can call the .read() whenever you click the "search" button for example. Then when you get the results you add those features to the layer newEventLayer.addFeatures(resp.features);


var newEventLayer = new OpenLayers.Layer.Vector('test');

map.addLayer(newEventLayer);
var protocol = new OpenLayers.Protocol.WFS({
version: "1.1.0",
url: xxx,
featurePrefix: xxx,
featureType: xxx,
featureNS: xxx,
geometryName: xxx,
defaultFilter: new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.AND,

filters: getMyFilter()
}),
srsName: xxx
});

var response = protocol.read({
maxFeatures: 100,
callback: _CallBack
});


function _CallBack (resp) {
newEventLayer.addFeatures(resp.features);
});


Try this if _callBack is not called:


var _CallBack = function (resp) {
newEventLayer.addFeatures(resp.features);
});
var response = protocol.read({

maxFeatures: 100,
callback: _CallBack
});


You are right, i have removed the strategy from the layer constructor. You are going to have to specify your filter separately or in the protocol constructor as I have it above. But you're going to have build a search filter anyway if you want to search your WFS service by attributes, date/time, etc. Or did you only want to rely on the BBox Strategy (give me EVERYTHING in the BBOX)? If so then just set up a filter for that and call the protocol.read() on the map extentchange event. After all, that's all the strategy does. But that's seperate question which I, or others can help you with.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...