Using WFS with filters, I was able to contruct a filter that retrieves info for the selection only. My code is as shown below:
select = new OpenLayers.Layer.Vector("Selection")
selectCtrl = new OpenLayers.Control.SelectFeature(select, {
clickout: false, toggle: false,
multiple: false, hover: false,
toggleKey: "ctrlKey",
multipleKey: "shiftKey",
box: true
});
map.addControl(selectCtrl);
selectCtrl.activate();
select.events.on({
'beforefeatureadded': function(event) {
},
'featureselected': function(event) {
var geometry900913 = event.feature.geometry;
var geometry = geometry900913.transform(new OpenLayers.Projection("900913"), new OpenLayers.Projection("EPSG:4326"));
var filter = getGeometryFilter(getWkt(geometry));
var wpsRequestData = getWPSRequestData(filter);
sendWPSRequest(wpsRequestData);
return false;
},
'featureunselected': function(feature) {
}
});
map.addLayers([select]);
map.addControl(new OpenLayers.Control.EditingToolbar(select));
In this, I'm using WPS chained with WFS(with filter containing info about the selected geometry). From the code above, getGeometryFilter(getWkt(geometry))
parses my geometry into WKT format, and constructs a valid filter. The filter is shown below:
function getGeometryFilter(polygon) {
var filter =
'<ogc:Filter>' +
'<ogc:Intersects>' +
'<ogc:PropertyName>the_geom</ogc:PropertyName>' +
'<ogc:Function name="collectGeometries">' +
'<ogc:Function name="queryCollection">' +
'<ogc:Literal>ws:layer_2</ogc:Literal>' +
'<ogc:Literal>the_geom</ogc:Literal>' +
'<ogc:Literal>INTERSECTS(the_geom,' + polygon + ')</ogc:Literal>' +
'</ogc:Function>' +
'</ogc:Function>' +
'</ogc:Intersects>' +
'</ogc:Filter>';
return filter;
}
In my case, I was calculating population for the selected region. So, I constructed a gs:Aggregate
request using the WPS request builder
. I then passed the filter above to it. This is done in the getWPSRequestData(filter)
method. This method is trivial if you use the WPS Request Builder.
My actual request is sent in the sendWPSRequest(wpsRequestData);
function. Its details are shown below:
function sendWPSRequest(wpsRequestData) {
var request = new OpenLayers.Request.POST({
url: WPS_HOST,
data: wpsRequestData,
headers: {
"Content-Type": "text/xml;charset=utf-8"
},
callback: function (response) {
var gmlParser = new OpenLayers.Format.GML();
var xmlSum = gmlParser.read(response.responseText);
parsePopulation(response.responseText);
},
failure: function (response) {
alert("Something went wrong in the request");
}
});
}
I'm sending my request via POST, and using OpenLayers.Format.GML
class to deal with the GML response.
Thanks to @iant for his comments with regards to proj4js, I've now got the mapping sorted. My mapfile uses a "EPSG:27700" for the map and layer projections (as posted originally). Within the calls to OpenLayers I now explicitly set the projection and displayProjection as below:
var mymap = new OpenLayers.Map({ div: "map",
layers: [
new OpenLayers.Layer.Vector("County", {
isBaseLayer: true,
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:27700"),
strategies: [new OpenLayers.Strategy.BBOX()],
protocol: new OpenLayers.Protocol.WFS({
url: "http://localhost/cgi-bin/mapserv.exe?map=C:/DevProjects/fgsv2/mapfile.map",
version: "1.0.0",
featureType: "County",
featurePrefix:"ms",
featureNS: "http://mapserver.gis.umn.edu/mapserver"
})
})
],center: [400000, 300000],zoom:10});
The XML Post now references "EPSG:900913" as the SRSName for the box used to query the data. The XML now references "EPSG:27700" when returning the coordinates of the features.
Best Answer
I'd suggest checking this openlayers example: getfeatureinfo-control. It shows the feature info in a table on the page. Putting it into a popup should be easy changing some lines in the javascript.
In general openlayers.org/dev/examples/ is a good resource for openlayers code snippets.