Touching up WMSGetFeatureInfo. Requests are now sent out with correct case on request parameter. Requests are only sent out if there are layers to query. The control has a single format with configurable options. Requests can be made in cases where layer url differs from control url. The control url property is optional. In cases where it is not provided, the url of the first eligible layer will be used. Tests pass and example works (for the first time) in IE as well.
git-svn-id: http://svn.openlayers.org/trunk/openlayers@9300 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -26,42 +26,49 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* APIProperty: hover
|
||||
* {Boolean} Send WMS request on mouse moves. This will cause the
|
||||
* "hoverfeature" and "outfeature" events to be triggered.
|
||||
* {Boolean} Send GetFeatureInfo requests when mouse stops moving.
|
||||
* Default is false.
|
||||
*/
|
||||
hover: false,
|
||||
|
||||
/**
|
||||
* APIProperty: maxFeatures
|
||||
* {Integer} maximum number of features to return from a WMS query. This
|
||||
* has the same effect as the feature_count parameter on WMS GetFeatureInfo
|
||||
* requests. Will be ignored for box selections.
|
||||
* {Integer} Maximum number of features to return from a WMS query. This
|
||||
* sets the feature_count parameter on WMS GetFeatureInfo
|
||||
* requests.
|
||||
*/
|
||||
maxFeatures: 10,
|
||||
|
||||
/**
|
||||
* Property: layers
|
||||
* {<Array(OpenLayers.Layer.WMS>} The Layer objects for which to find
|
||||
* feature info. If omitted, search all WMS layers from the map whose url
|
||||
* is the same as the one in this control's configuration. See the
|
||||
* <queryVisible> property
|
||||
* {Array(<OpenLayers.Layer.WMS>)} The layers to query for feature info.
|
||||
* If omitted, all map WMS layers with a url that matches this <url> or
|
||||
* <layerUrl> will be considered.
|
||||
*/
|
||||
layers: null,
|
||||
|
||||
/**
|
||||
* Property: queryVisible
|
||||
* {Boolean} If true, filter out hidden layers when searching the map for
|
||||
* layers to query. If an explicit layers parameter is set, then this does
|
||||
* nothing.
|
||||
* layers to query. Default is false.
|
||||
*/
|
||||
queryVisible: false,
|
||||
|
||||
/**
|
||||
* Property: url
|
||||
* {String} The URL of the WMS service to use.
|
||||
* {String} The URL of the WMS service to use. If not provided, the url
|
||||
* of the first eligible layer will be used.
|
||||
*/
|
||||
url: null,
|
||||
|
||||
/**
|
||||
* Property: layerUrls
|
||||
* {Array(String)} Optional list of urls for layers that should be queried.
|
||||
* This can be used when the layer url differs from the url used for
|
||||
* making GetFeatureInfo requests (in the case of a layer using cached
|
||||
* tiles).
|
||||
*/
|
||||
layerUrls: null,
|
||||
|
||||
/**
|
||||
* Property: infoFormat
|
||||
@@ -79,20 +86,21 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
* }
|
||||
* (end)
|
||||
*/
|
||||
vendorParams: {},
|
||||
|
||||
vendorParams: {},
|
||||
|
||||
/**
|
||||
* Property: formats
|
||||
* An object mapping from mime-types to OL Format objects to use when
|
||||
* parsing GFI responses. The default mapping is
|
||||
* (start code)
|
||||
* {
|
||||
* 'application/vnd.ogc.gml': new OpenLayers.Format.WMSGetFeatureInfo()
|
||||
* }
|
||||
* (end)
|
||||
* An object provided here will extend the default mapping.
|
||||
* Property: format
|
||||
* {<OpenLayers.Format>} A format for parsing GetFeatureInfo responses.
|
||||
* Default is <OpenLayers.Format.WMSGetFeatureInfo>.
|
||||
*/
|
||||
formats: null,
|
||||
format: null,
|
||||
|
||||
/**
|
||||
* Property: formatOptions
|
||||
* {Object} Optional properties to set on the format (if one is not provided
|
||||
* in the <format> property.
|
||||
*/
|
||||
formatOptions: null,
|
||||
|
||||
/**
|
||||
* APIProperty: handlerOptions
|
||||
@@ -122,24 +130,23 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
/**
|
||||
* Constant: EVENT_TYPES
|
||||
*
|
||||
* Supported event types:
|
||||
* - *getfeatureinfo* Triggered when a GetFeatureInfo response is received.
|
||||
* The event object has a text property with:
|
||||
* text: a string containing the body of the response,
|
||||
* features: an array of the parsed features, if parsing succeeded.
|
||||
* xy: the position of the mouse click or hover event that
|
||||
* triggered the request
|
||||
* Supported event types (in addition to those from <OpenLayers.Control>):
|
||||
* getfeatureinfo - Triggered when a GetFeatureInfo response is received.
|
||||
* The event object has a *text* property with the body of the
|
||||
* response (String), a *features* property with an array of the
|
||||
* parsed features, an *xy* property with the position of the mouse
|
||||
* click or hover event that triggered the request, and a *request*
|
||||
* property with the request itself.
|
||||
*/
|
||||
EVENT_TYPES: ["getfeatureinfo"],
|
||||
|
||||
/**
|
||||
* Constructor: <OpenLayers.Control.SelectFeature>
|
||||
* Constructor: <OpenLayers.Control.WMSGetFeatureInfo>
|
||||
*
|
||||
* Parameters:
|
||||
* url - {String}
|
||||
* options - {Object}
|
||||
*/
|
||||
initialize: function(url, options) {
|
||||
initialize: function(options) {
|
||||
// concatenate events specific to vector with those from the base
|
||||
this.EVENT_TYPES =
|
||||
OpenLayers.Control.WMSGetFeatureInfo.prototype.EVENT_TYPES.concat(
|
||||
@@ -150,13 +157,12 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
options.handlerOptions = options.handlerOptions || {};
|
||||
|
||||
OpenLayers.Control.prototype.initialize.apply(this, [options]);
|
||||
this.url = url;
|
||||
this.layers = options.layers;
|
||||
|
||||
this.formats = OpenLayers.Util.extend({
|
||||
'application/vnd.ogc.gml': new OpenLayers.Format.WMSGetFeatureInfo()
|
||||
}, options.formats);
|
||||
|
||||
|
||||
if(!this.format) {
|
||||
this.format = new OpenLayers.Format.WMSGetFeatureInfo(
|
||||
options.formatOptions
|
||||
);
|
||||
}
|
||||
|
||||
if (this.hover) {
|
||||
this.handler = new OpenLayers.Handler.Hover(
|
||||
@@ -241,32 +247,65 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
/**
|
||||
* Method: findLayers
|
||||
* Internal method to get the layers, independent of whether we are
|
||||
* inspecting the map or using a client-provided array
|
||||
* inspecting the map or using a client-provided array
|
||||
*/
|
||||
findLayers: function() {
|
||||
if (this.layers) return this.layers;
|
||||
|
||||
var layers = [];
|
||||
|
||||
for (var i = 0, len = this.map.layers.length; i < len; i++) {
|
||||
var mapLayer = this.map.layers[i];
|
||||
if (mapLayer instanceof OpenLayers.Layer.WMS
|
||||
&& mapLayer.url === this.url
|
||||
&& (!this.queryVisible || mapLayer.getVisibility())) {
|
||||
|
||||
layers.push(mapLayer);
|
||||
|
||||
var candidates = this.layers || this.map.layers;
|
||||
var layer, url;
|
||||
for(var i=0, len=candidates.length; i<len; ++i) {
|
||||
layer = candidates[i];
|
||||
if(layer instanceof OpenLayers.Layer.WMS &&
|
||||
(!this.queryVisible || layer.getVisibility())) {
|
||||
url = layer.url instanceof Array ? layer.url[0] : layer.url;
|
||||
// if the control was not configured with a url, set it
|
||||
// to the first layer url
|
||||
if(!this.url) {
|
||||
this.url = url;
|
||||
}
|
||||
if(this.urlMatches(url)) {
|
||||
layers.push(layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return layers;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: urlMatches
|
||||
* Test to see if the provided url matches either the control <url> or one
|
||||
* of the <layerUrls>.
|
||||
*
|
||||
* Parameters:
|
||||
* url - {String} The url to test.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The provided url matches the control <url> or one of the
|
||||
* <layerUrls>.
|
||||
*/
|
||||
urlMatches: function(url) {
|
||||
var matches = OpenLayers.Util.isEquivalentUrl(this.url, url);
|
||||
if(!matches && this.layerUrls) {
|
||||
for(var i=0, len=this.layerUrls.length; i<len; ++i) {
|
||||
if(OpenLayers.Util.isEquivalentUrl(this.layerUrls[i], url)) {
|
||||
matches = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: request
|
||||
* Sends a GetFeatureInfo request to the WMS
|
||||
*
|
||||
* Parameters:
|
||||
* clickPosition - The position on the map where the mouse event occurred
|
||||
* clickPosition - {<OpenLayers.Pixel>} The position on the map where the
|
||||
* mouse event occurred.
|
||||
* options - {Object} additional options for this method.
|
||||
*
|
||||
* Valid options:
|
||||
@@ -278,77 +317,79 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
|
||||
var styleNames = [];
|
||||
|
||||
var layers = this.findLayers();
|
||||
if(layers.length > 0) {
|
||||
|
||||
for (var i = 0, len = layers.length; i < len; i++) {
|
||||
layerNames = layerNames.concat(layers[i].params.LAYERS);
|
||||
// in the event of a WMS layer bundling multiple layers but not
|
||||
// specifying styles,we need the same number of commas to specify
|
||||
// the default style for each of the layers. We can't just leave it
|
||||
// blank as we may be including other layers that do specify styles.
|
||||
if (layers[i].params.STYLES) {
|
||||
styleNames = styleNames.concat(layers[i].params.STYLES);
|
||||
} else {
|
||||
if (layers[i].params.LAYERS instanceof Array) {
|
||||
styleNames = styleNames.concat(new Array(layers[i].params.LAYERS.length));
|
||||
} else { // Assume it's a String
|
||||
styleNames = styleNames.concat(layers[i].params.LAYERS.replace(/[^,]/g, ""));
|
||||
for (var i = 0, len = layers.length; i < len; i++) {
|
||||
layerNames = layerNames.concat(layers[i].params.LAYERS);
|
||||
// in the event of a WMS layer bundling multiple layers but not
|
||||
// specifying styles,we need the same number of commas to specify
|
||||
// the default style for each of the layers. We can't just leave it
|
||||
// blank as we may be including other layers that do specify styles.
|
||||
if (layers[i].params.STYLES) {
|
||||
styleNames = styleNames.concat(layers[i].params.STYLES);
|
||||
} else {
|
||||
if (layers[i].params.LAYERS instanceof Array) {
|
||||
styleNames = styleNames.concat(new Array(layers[i].params.LAYERS.length));
|
||||
} else { // Assume it's a String
|
||||
styleNames = styleNames.concat(layers[i].params.LAYERS.replace(/[^,]/g, ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var wmsOptions = {
|
||||
url: this.url,
|
||||
params: OpenLayers.Util.applyDefaults({
|
||||
service: "WMS",
|
||||
version: "1.1.0",
|
||||
request: 'getfeatureinfo',
|
||||
layers: layerNames,
|
||||
query_layers: layerNames,
|
||||
styles: styleNames,
|
||||
bbox: this.map.getExtent().toBBOX(),
|
||||
srs: this.map.getProjection(),
|
||||
feature_count: this.maxFeatures,
|
||||
x: clickPosition.x,
|
||||
y: clickPosition.y,
|
||||
height: this.map.getSize().h,
|
||||
width: this.map.getSize().w,
|
||||
info_format: this.infoFormat
|
||||
}, this.vendorParams),
|
||||
callback: this.handleResponse,
|
||||
scope: OpenLayers.Util.extend({
|
||||
xy: clickPosition
|
||||
}, this)
|
||||
};
|
||||
|
||||
var response = OpenLayers.Request.GET(wmsOptions);
|
||||
|
||||
if (options.hover === true) {
|
||||
this.hoverRequest = response.priv;
|
||||
|
||||
var wmsOptions = {
|
||||
url: this.url,
|
||||
params: OpenLayers.Util.applyDefaults({
|
||||
service: "WMS",
|
||||
version: "1.1.0",
|
||||
request: "GetFeatureInfo",
|
||||
layers: layerNames,
|
||||
query_layers: layerNames,
|
||||
styles: styleNames,
|
||||
bbox: this.map.getExtent().toBBOX(),
|
||||
srs: this.map.getProjection(),
|
||||
feature_count: this.maxFeatures,
|
||||
x: clickPosition.x,
|
||||
y: clickPosition.y,
|
||||
height: this.map.getSize().h,
|
||||
width: this.map.getSize().w,
|
||||
info_format: this.infoFormat
|
||||
}, this.vendorParams),
|
||||
callback: function(request) {
|
||||
this.handleResponse(clickPosition, request);
|
||||
},
|
||||
scope: this
|
||||
};
|
||||
|
||||
var response = OpenLayers.Request.GET(wmsOptions);
|
||||
|
||||
if (options.hover === true) {
|
||||
this.hoverRequest = response.priv;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: handleResponse
|
||||
* Handler for the GetFeatureInfo response. Will be called in an extended
|
||||
* scope of this instance plus an xy property with the click position.
|
||||
*
|
||||
* Handler for the GetFeatureInfo response.
|
||||
*
|
||||
* Parameters:
|
||||
* response - {Object}
|
||||
* xy - {<OpenLayers.Pixel>} The position on the map where the
|
||||
* mouse event occurred.
|
||||
* request - {XMLHttpRequest} The request object.
|
||||
*/
|
||||
handleResponse: function(response) {
|
||||
var features;
|
||||
var fmt = this.formats[
|
||||
response.getResponseHeader("Content-type").split(";")[0]
|
||||
];
|
||||
if (fmt) {
|
||||
features = fmt.read(response.responseXml ||
|
||||
response.responseText);
|
||||
handleResponse: function(xy, request) {
|
||||
|
||||
var doc = request.responseXML;
|
||||
if(!doc || !doc.documentElement) {
|
||||
doc = request.responseText;
|
||||
}
|
||||
var features = this.format.read(doc);
|
||||
|
||||
this.events.triggerEvent("getfeatureinfo", {
|
||||
text: response.responseText,
|
||||
text: request.responseText,
|
||||
features: features,
|
||||
xy: this.xy
|
||||
request: request,
|
||||
xy: xy
|
||||
});
|
||||
|
||||
// Reset the cursor.
|
||||
|
||||
Reference in New Issue
Block a user