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:
Tim Schaub
2009-04-15 23:44:29 +00:00
parent cd815bc2a2
commit d54440b0e9
4 changed files with 354 additions and 179 deletions

View File

@@ -5,39 +5,75 @@
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" /> <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
<link rel="stylesheet" href="style.css" type="text/css" /> <link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css"> <style type="text/css">
ul, li { padding-left: 0px; margin-left: 0px; } ul, li {
padding-left: 0px;
margin-left: 0px;
list-style: none;
}
#info {
position: absolute;
top: 6em;
left: 550px;
}
#info table td {
border:1px solid #ddd;
border-collapse: collapse;
margin: 0;
padding: 0;
font-size: 90%;
padding: .2em .1em;
background:#fff;
}
#info table th{
padding:.2em .2em;
text-transform: uppercase;
font-weight: bold;
background: #eee;
}
tr.odd td {
background:#eee;
}
table.featureInfo caption {
text-align:left;
font-size:100%;
font-weight:bold;
text-transform:uppercase;
padding:.2em .2em;
}
</style> </style>
<script defer="defer" type="text/javascript"> <script defer="defer" type="text/javascript">
OpenLayers.ProxyHost = "/dev/examples/proxy.cgi?url="; OpenLayers.ProxyHost = "/proxy/?url=";
var map, infocontrols, vegetation, highlightlayer; var map, infocontrols, water, highlightlayer;
function load() { function load() {
map = new OpenLayers.Map('map', { map = new OpenLayers.Map('map', {
maxExtent: new OpenLayers.Bounds(143.834,-43.648,148.479,-39.573) maxExtent: new OpenLayers.Bounds(143.834,-43.648,148.479,-39.573)
}); });
var roads = new OpenLayers.Layer.WMS("State Boundaries", var political = new OpenLayers.Layer.WMS("State Boundaries",
"http://demo.opengeo.org/geoserver/wms", "http://demo.opengeo.org/geoserver/wms",
{'layers': 'topp:tasmania_state_boundaries', transparent: true, format: 'image/png'}, {'layers': 'topp:tasmania_state_boundaries', transparent: true, format: 'image/gif'},
{isBaseLayer: true} {isBaseLayer: true}
); );
var natural = new OpenLayers.Layer.WMS("Roads", var roads = new OpenLayers.Layer.WMS("Roads",
"http://demo.opengeo.org/geoserver/wms", "http://demo.opengeo.org/geoserver/wms",
{'layers': 'topp:tasmania_roads', transparent: true, format: 'image/png'}, {'layers': 'topp:tasmania_roads', transparent: true, format: 'image/gif'},
{isBaseLayer: false} {isBaseLayer: false}
); );
var points = new OpenLayers.Layer.WMS("Cities", var cities = new OpenLayers.Layer.WMS("Cities",
"http://demo.opengeo.org/geoserver/wms", "http://demo.opengeo.org/geoserver/wms",
{'layers': 'topp:tasmania_cities', transparent: true, format: 'image/png'}, {'layers': 'topp:tasmania_cities', transparent: true, format: 'image/gif'},
{isBaseLayer: false} {isBaseLayer: false}
); );
vegetation = new OpenLayers.Layer.WMS("Bodies of Water", water = new OpenLayers.Layer.WMS("Bodies of Water",
"http://demo.opengeo.org/geoserver/wms", "http://demo.opengeo.org/geoserver/wms",
{'layers': 'topp:tasmania_water_bodies', transparent: true, format: 'image/png'}, {'layers': 'topp:tasmania_water_bodies', transparent: true, format: 'image/gif'},
{isBaseLayer: false} {isBaseLayer: false}
); );
@@ -48,25 +84,27 @@
); );
infoControls = { infoControls = {
click: new OpenLayers.Control.WMSGetFeatureInfo('http://demo.opengeo.org/geoserver/wms', { click: new OpenLayers.Control.WMSGetFeatureInfo({
url: 'http://demo.opengeo.org/geoserver/wms',
title: 'Identify features by clicking', title: 'Identify features by clicking',
layers: [vegetation], layers: [water],
queryVisible: true queryVisible: true
}), }),
hover: new OpenLayers.Control.WMSGetFeatureInfo('http://demo.opengeo.org/geoserver/wms', { hover: new OpenLayers.Control.WMSGetFeatureInfo({
url: 'http://demo.opengeo.org/geoserver/wms',
title: 'Identify features by clicking', title: 'Identify features by clicking',
layers: [vegetation], layers: [water],
hover: true, hover: true,
// defining a custom format here // defining a custom format options here
formats: {'application/vnd.ogc.gml': new OpenLayers.Format.GML({ formatOptions: {
typeName: 'water_bodies', typeName: 'water_bodies',
featureNS: 'http://www.openplans.org/topp' featureNS: 'http://www.openplans.org/topp'
})}, },
queryVisible: true queryVisible: true
}) })
} }
map.addLayers([roads, natural, points, vegetation, highlightLayer]); map.addLayers([political, roads, cities, water, highlightLayer]);
for (var i in infoControls) { for (var i in infoControls) {
infoControls[i].events.register("getfeatureinfo", this, showInfo); infoControls[i].events.register("getfeatureinfo", this, showInfo);
map.addControl(infoControls[i]); map.addControl(infoControls[i]);
@@ -84,7 +122,7 @@
highlightLayer.addFeatures(evt.features); highlightLayer.addFeatures(evt.features);
highlightLayer.redraw(); highlightLayer.redraw();
} else { } else {
$('nodeList').innerHTML = evt.text; $('responseText').innerHTML = evt.text;
} }
} }
@@ -110,7 +148,7 @@
for (var key in infoControls) { for (var key in infoControls) {
var control = infoControls[key]; var control = infoControls[key];
if (element.value == 'Specified') { if (element.value == 'Specified') {
control.layers = [vegetation]; control.layers = [water];
} else { } else {
control.layers = null; control.layers = null;
} }
@@ -126,15 +164,13 @@
<div id="tags"></div> <div id="tags"></div>
<p id="shortdesc"> <p id="shortdesc">
Demonstrates the WMSGetFeatureInfo control for fetching information about a position from WMS. Demonstrates the WMSGetFeatureInfo control for fetching information about a position from WMS (via GetFeatureInfo request).
</p> </p>
<a id="permalink" href="">Permalink</a><br /> <div id="info">
<h1>Tasmania</h1>
<div style="float:right;width:28%"> <p>Click on the map to get feature info.</p>
<h1 style="font-size:1.3em;">Tasmania</h1> <div id="responseText">
<p style="font-size:.8em;">Click on the map to get feature info.</p>
<div id="nodeList">
</div> </div>
</div> </div>
<div id="map" class="smallmap"></div> <div id="map" class="smallmap"></div>
@@ -169,12 +205,12 @@
<li> <li>
<input type="radio" name="layerSelection" value="Specified" id="Specified" <input type="radio" name="layerSelection" value="Specified" id="Specified"
onclick="toggleLayers(this);" checked="checked" /> onclick="toggleLayers(this);" checked="checked" />
<label for="html">Get Vegetation info</label> <label for="Specified">Get water body info</label>
</li> </li>
<li> <li>
<input type="radio" name="layerSelection" value="Auto" id="Auto" <input type="radio" name="layerSelection" value="Auto" id="Auto"
onclick="toggleLayers(this);" /> onclick="toggleLayers(this);" />
<label for="">Get info for visible layers</label> <label for="Auto">Get info for visible layers</label>
</li> </li>
</ul> </ul>
</body> </body>

View File

@@ -26,42 +26,49 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
/** /**
* APIProperty: hover * APIProperty: hover
* {Boolean} Send WMS request on mouse moves. This will cause the * {Boolean} Send GetFeatureInfo requests when mouse stops moving.
* "hoverfeature" and "outfeature" events to be triggered.
* Default is false. * Default is false.
*/ */
hover: false, hover: false,
/** /**
* APIProperty: maxFeatures * APIProperty: maxFeatures
* {Integer} maximum number of features to return from a WMS query. This * {Integer} Maximum number of features to return from a WMS query. This
* has the same effect as the feature_count parameter on WMS GetFeatureInfo * sets the feature_count parameter on WMS GetFeatureInfo
* requests. Will be ignored for box selections. * requests.
*/ */
maxFeatures: 10, maxFeatures: 10,
/** /**
* Property: layers * Property: layers
* {<Array(OpenLayers.Layer.WMS>} The Layer objects for which to find * {Array(<OpenLayers.Layer.WMS>)} The layers to query for feature info.
* feature info. If omitted, search all WMS layers from the map whose url * If omitted, all map WMS layers with a url that matches this <url> or
* is the same as the one in this control's configuration. See the * <layerUrl> will be considered.
* <queryVisible> property
*/ */
layers: null, layers: null,
/** /**
* Property: queryVisible * Property: queryVisible
* {Boolean} If true, filter out hidden layers when searching the map for * {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 * layers to query. Default is false.
* nothing.
*/ */
queryVisible: false, queryVisible: false,
/** /**
* Property: url * 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, 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 * Property: infoFormat
@@ -79,20 +86,21 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
* } * }
* (end) * (end)
*/ */
vendorParams: {}, vendorParams: {},
/** /**
* Property: formats * Property: format
* An object mapping from mime-types to OL Format objects to use when * {<OpenLayers.Format>} A format for parsing GetFeatureInfo responses.
* parsing GFI responses. The default mapping is * Default is <OpenLayers.Format.WMSGetFeatureInfo>.
* (start code)
* {
* 'application/vnd.ogc.gml': new OpenLayers.Format.WMSGetFeatureInfo()
* }
* (end)
* An object provided here will extend the default mapping.
*/ */
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 * APIProperty: handlerOptions
@@ -122,24 +130,23 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
/** /**
* Constant: EVENT_TYPES * Constant: EVENT_TYPES
* *
* Supported event types: * Supported event types (in addition to those from <OpenLayers.Control>):
* - *getfeatureinfo* Triggered when a GetFeatureInfo response is received. * getfeatureinfo - Triggered when a GetFeatureInfo response is received.
* The event object has a text property with: * The event object has a *text* property with the body of the
* text: a string containing the body of the response, * response (String), a *features* property with an array of the
* features: an array of the parsed features, if parsing succeeded. * parsed features, an *xy* property with the position of the mouse
* xy: the position of the mouse click or hover event that * click or hover event that triggered the request, and a *request*
* triggered the request * property with the request itself.
*/ */
EVENT_TYPES: ["getfeatureinfo"], EVENT_TYPES: ["getfeatureinfo"],
/** /**
* Constructor: <OpenLayers.Control.SelectFeature> * Constructor: <OpenLayers.Control.WMSGetFeatureInfo>
* *
* Parameters: * Parameters:
* url - {String}
* options - {Object} * options - {Object}
*/ */
initialize: function(url, options) { initialize: function(options) {
// concatenate events specific to vector with those from the base // concatenate events specific to vector with those from the base
this.EVENT_TYPES = this.EVENT_TYPES =
OpenLayers.Control.WMSGetFeatureInfo.prototype.EVENT_TYPES.concat( OpenLayers.Control.WMSGetFeatureInfo.prototype.EVENT_TYPES.concat(
@@ -150,13 +157,12 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
options.handlerOptions = options.handlerOptions || {}; options.handlerOptions = options.handlerOptions || {};
OpenLayers.Control.prototype.initialize.apply(this, [options]); OpenLayers.Control.prototype.initialize.apply(this, [options]);
this.url = url;
this.layers = options.layers; if(!this.format) {
this.format = new OpenLayers.Format.WMSGetFeatureInfo(
this.formats = OpenLayers.Util.extend({ options.formatOptions
'application/vnd.ogc.gml': new OpenLayers.Format.WMSGetFeatureInfo() );
}, options.formats); }
if (this.hover) { if (this.hover) {
this.handler = new OpenLayers.Handler.Hover( this.handler = new OpenLayers.Handler.Hover(
@@ -241,32 +247,65 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
/** /**
* Method: findLayers * Method: findLayers
* Internal method to get the layers, independent of whether we are * 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() { findLayers: function() {
if (this.layers) return this.layers;
var layers = []; var layers = [];
for (var i = 0, len = this.map.layers.length; i < len; i++) { var candidates = this.layers || this.map.layers;
var mapLayer = this.map.layers[i]; var layer, url;
if (mapLayer instanceof OpenLayers.Layer.WMS for(var i=0, len=candidates.length; i<len; ++i) {
&& mapLayer.url === this.url layer = candidates[i];
&& (!this.queryVisible || mapLayer.getVisibility())) { if(layer instanceof OpenLayers.Layer.WMS &&
(!this.queryVisible || layer.getVisibility())) {
layers.push(mapLayer); 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; 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 * Method: request
* Sends a GetFeatureInfo request to the WMS * Sends a GetFeatureInfo request to the WMS
* *
* Parameters: * 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. * options - {Object} additional options for this method.
* *
* Valid options: * Valid options:
@@ -278,77 +317,79 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
var styleNames = []; var styleNames = [];
var layers = this.findLayers(); var layers = this.findLayers();
if(layers.length > 0) {
for (var i = 0, len = layers.length; i < len; i++) { for (var i = 0, len = layers.length; i < len; i++) {
layerNames = layerNames.concat(layers[i].params.LAYERS); layerNames = layerNames.concat(layers[i].params.LAYERS);
// in the event of a WMS layer bundling multiple layers but not // in the event of a WMS layer bundling multiple layers but not
// specifying styles,we need the same number of commas to specify // 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 // 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. // blank as we may be including other layers that do specify styles.
if (layers[i].params.STYLES) { if (layers[i].params.STYLES) {
styleNames = styleNames.concat(layers[i].params.STYLES); styleNames = styleNames.concat(layers[i].params.STYLES);
} else { } else {
if (layers[i].params.LAYERS instanceof Array) { if (layers[i].params.LAYERS instanceof Array) {
styleNames = styleNames.concat(new Array(layers[i].params.LAYERS.length)); styleNames = styleNames.concat(new Array(layers[i].params.LAYERS.length));
} else { // Assume it's a String } else { // Assume it's a String
styleNames = styleNames.concat(layers[i].params.LAYERS.replace(/[^,]/g, "")); styleNames = styleNames.concat(layers[i].params.LAYERS.replace(/[^,]/g, ""));
}
} }
} }
}
var wmsOptions = {
var wmsOptions = { url: this.url,
url: this.url, params: OpenLayers.Util.applyDefaults({
params: OpenLayers.Util.applyDefaults({ service: "WMS",
service: "WMS", version: "1.1.0",
version: "1.1.0", request: "GetFeatureInfo",
request: 'getfeatureinfo', layers: layerNames,
layers: layerNames, query_layers: layerNames,
query_layers: layerNames, styles: styleNames,
styles: styleNames, bbox: this.map.getExtent().toBBOX(),
bbox: this.map.getExtent().toBBOX(), srs: this.map.getProjection(),
srs: this.map.getProjection(), feature_count: this.maxFeatures,
feature_count: this.maxFeatures, x: clickPosition.x,
x: clickPosition.x, y: clickPosition.y,
y: clickPosition.y, height: this.map.getSize().h,
height: this.map.getSize().h, width: this.map.getSize().w,
width: this.map.getSize().w, info_format: this.infoFormat
info_format: this.infoFormat }, this.vendorParams),
}, this.vendorParams), callback: function(request) {
callback: this.handleResponse, this.handleResponse(clickPosition, request);
scope: OpenLayers.Util.extend({ },
xy: clickPosition scope: this
}, this) };
};
var response = OpenLayers.Request.GET(wmsOptions);
var response = OpenLayers.Request.GET(wmsOptions);
if (options.hover === true) {
if (options.hover === true) { this.hoverRequest = response.priv;
this.hoverRequest = response.priv; }
} }
}, },
/** /**
* Method: handleResponse * Method: handleResponse
* Handler for the GetFeatureInfo response. Will be called in an extended * Handler for the GetFeatureInfo response.
* scope of this instance plus an xy property with the click position. *
*
* Parameters: * Parameters:
* response - {Object} * xy - {<OpenLayers.Pixel>} The position on the map where the
* mouse event occurred.
* request - {XMLHttpRequest} The request object.
*/ */
handleResponse: function(response) { handleResponse: function(xy, request) {
var features;
var fmt = this.formats[ var doc = request.responseXML;
response.getResponseHeader("Content-type").split(";")[0] if(!doc || !doc.documentElement) {
]; doc = request.responseText;
if (fmt) {
features = fmt.read(response.responseXml ||
response.responseText);
} }
var features = this.format.read(doc);
this.events.triggerEvent("getfeatureinfo", { this.events.triggerEvent("getfeatureinfo", {
text: response.responseText, text: request.responseText,
features: features, features: features,
xy: this.xy request: request,
xy: xy
}); });
// Reset the cursor. // Reset the cursor.

View File

@@ -77,14 +77,18 @@ OpenLayers.Format.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Format.XML, {
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]); data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
} }
var root = data.documentElement; var root = data.documentElement;
var scope = this; if(root) {
var read = this["read_" + root.nodeName]; var scope = this;
if(read) { var read = this["read_" + root.nodeName];
result = read.call(this, root); if(read) {
result = read.call(this, root);
} else {
// fall-back to GML since this is a common output format for WMS
// GetFeatureInfo responses
result = new OpenLayers.Format.GML((this.options ? this.options : {})).read(data);
}
} else { } else {
// fall-back to GML since this is a common output format for WMS result = data;
// GetFeatureInfo responses
result = new OpenLayers.Format.GML((this.options ? this.options : {})).read(data);
} }
return result; return result;
}, },

View File

@@ -2,37 +2,40 @@
<head> <head>
<script src="../../lib/OpenLayers.js"></script> <script src="../../lib/OpenLayers.js"></script>
<script type="text/javascript"> <script type="text/javascript">
function test_WMSGetFeatureInfo_constructor(t) {
t.plan(4); function test_initialize(t) {
t.plan(5);
var options = { var options = {
layers: 'ns:type', url: 'http://localhost/wms',
formats: {"application/vnd.ogc.gml": "foo"} layers: ["foo"],
formatOptions: {
foo: "bar"
}
}; };
var layer = "bar"; var control = new OpenLayers.Control.WMSGetFeatureInfo(options);
var control = new OpenLayers.Control.WMSGetFeatureInfo('http://localhost/wms', options);
t.ok(control instanceof OpenLayers.Control.WMSGetFeatureInfo, t.ok(control instanceof OpenLayers.Control.WMSGetFeatureInfo,
"new OpenLayers.Control.WMSGetFeatureInfo returns an instance"); "new OpenLayers.Control.WMSGetFeatureInfo returns an instance");
t.eq(control.url, 'http://localhost/wms', t.eq(control.url, 'http://localhost/wms',
"constructor sets url correctly"); "constructor sets url correctly");
t.eq(control.layers, "ns:type", t.eq(control.layers, ["foo"],
"constructor sets options correctly on feature handler" "constructor layers"
); );
t.eq(control.formats["application/vnd.ogc.gml"], "foo", 'Custom format passed through properly'); t.ok(control.format instanceof OpenLayers.Format.WMSGetFeatureInfo, "format created");
t.eq(control.format.foo, "bar", "format options used")
} }
function test_Control_WMSGetFeatureInfo_destroy(t) { function test_destroy(t) {
t.plan(2); t.plan(2);
var map = new OpenLayers.Map("map"); var map = new OpenLayers.Map("map");
var click = new OpenLayers.Control.WMSGetFeatureInfo('http://localhost/wms', { var click = new OpenLayers.Control.WMSGetFeatureInfo({
layers: 'ns:type', url: 'http://localhost/wms',
featureNS: 'http://localhost/ns', layers: ["foo"]
featureType: 'type'
}); });
var hover = new OpenLayers.Control.WMSGetFeatureInfo('http://localhost/wms', { var hover = new OpenLayers.Control.WMSGetFeatureInfo({
layers: 'ns:type', url: 'http://localhost/wms',
featureNS: 'http://localhost/ns', layers: ["foo"],
featureType: 'type',
hover: true hover: true
}); });
@@ -48,7 +51,7 @@
hover.destroy(); hover.destroy();
} }
function test_Control_WMSGetFeatureInfo_click(t) { function test_click(t) {
t.plan(4); t.plan(4);
var map = new OpenLayers.Map('map'); var map = new OpenLayers.Map('map');
@@ -68,15 +71,17 @@
control.getInfoForHover({xy: {x: 50, y: 50}}); control.getInfoForHover({xy: {x: 50, y: 50}});
} }
function test_Control_WMSGetFeatureInfo_activate(t) { function test_activate(t) {
t.plan(4); t.plan(4);
var map = new OpenLayers.Map("map"); var map = new OpenLayers.Map("map");
var click = new OpenLayers.Control.WMSGetFeatureInfo('http://localhost/wms', { var click = new OpenLayers.Control.WMSGetFeatureInfo({
url: 'http://localhost/wms',
featureType: 'type', featureType: 'type',
featureNS: 'http://localhost/ns', featureNS: 'http://localhost/ns',
layers: 'ns:type' layers: 'ns:type'
}); });
var hover = new OpenLayers.Control.WMSGetFeatureInfo('http://localhost/wms', { var hover = new OpenLayers.Control.WMSGetFeatureInfo({
url: 'http://localhost/wms',
featureType: 'type', featureType: 'type',
featureNS: 'http://localhost/ns', featureNS: 'http://localhost/ns',
layers: 'ns:type', layers: 'ns:type',
@@ -96,15 +101,17 @@
"hover handler is active after activating control"); "hover handler is active after activating control");
} }
function test_Control_WMSGetFeatureInfo_deactivate(t) { function test_deactivate(t) {
t.plan(2); t.plan(2);
var map = new OpenLayers.Map("map"); var map = new OpenLayers.Map("map");
var click = new OpenLayers.Control.WMSGetFeatureInfo("http://localhost/wms", { var click = new OpenLayers.Control.WMSGetFeatureInfo({
url: 'http://localhost/wms',
featureType: 'type', featureType: 'type',
featureNS: 'http://localhost/ns', featureNS: 'http://localhost/ns',
layers: 'ns:type' layers: 'ns:type'
}); });
var hover = new OpenLayers.Control.WMSGetFeatureInfo("http://localhost/wms", { var hover = new OpenLayers.Control.WMSGetFeatureInfo({
url: 'http://localhost/wms',
featureType: 'type', featureType: 'type',
featureNS: 'http://localhost/ns', featureNS: 'http://localhost/ns',
layers: 'ns:type' layers: 'ns:type'
@@ -130,8 +137,8 @@
// Verify that things work all right when we combine different types for the STYLES and LAYERS // Verify that things work all right when we combine different types for the STYLES and LAYERS
// params in the WMS Layers involved // params in the WMS Layers involved
function test_Control_WMSGetFeatureInfo_MixedParams(t) { function test_mixedParams(t) {
t.plan(1); t.plan(2);
var map = new OpenLayers.Map("map", { var map = new OpenLayers.Map("map", {
getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));} getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}
} }
@@ -155,7 +162,7 @@
layers: "a,b,c,d" layers: "a,b,c,d"
}); });
var click = new OpenLayers.Control.WMSGetFeatureInfo("http://localhost/wms", { var click = new OpenLayers.Control.WMSGetFeatureInfo({
featureType: 'type', featureType: 'type',
featureNS: 'ns', featureNS: 'ns',
layers: [a, b, c, d] layers: [a, b, c, d]
@@ -163,17 +170,104 @@
map.addControl(click); map.addControl(click);
var log = {};
var _request = OpenLayers.Request.GET; var _request = OpenLayers.Request.GET;
OpenLayers.Request.GET = function(options) { OpenLayers.Request.GET = function(options) {
t.eq( log.options = options;
options.params.styles.join(","), "a,b,c,d,a,b,c,d,,,,,,,,",
"Styles merged correctly"
);
}; };
click.activate(); click.activate();
click.getInfoForClick({xy: {x: 50, y: 50}}); click.getInfoForClick({xy: {x: 50, y: 50}});
OpenLayers.Request.GET = _request; OpenLayers.Request.GET = _request;
t.eq(
log.options && log.options.url,
"http://localhost/wms",
"url from first layer used"
);
t.eq(
log.options && log.options.params.styles.join(","),
"a,b,c,d,a,b,c,d,,,,,,,,",
"Styles merged correctly"
);
}
function test_urlMatches(t) {
t.plan(5);
var control = new OpenLayers.Control.WMSGetFeatureInfo({
url: "http://host/wms?one=1&two=2"
});
t.ok(!control.urlMatches("foo"), "doesn't match garbage");
t.ok(control.urlMatches("http://host:80/wms?two=2&one=1"), "matches equivalent url");
// give the control more urls to match from
control.layerUrls = ["http://a.host/wms", "http://b.host/wms"];
t.ok(control.urlMatches("http://host:80/wms?two=2&one=1"), "still matches equivalent url");
t.ok(control.urlMatches("http://a.host:80/wms"), "matches equivalent of first of layerUrls");
t.ok(control.urlMatches("http://b.host:80/wms"), "matches equivalent of second of layerUrls");
}
function test_layerUrls(t) {
t.plan(4);
var map = new OpenLayers.Map({
div: "map",
getExtent: function() {
return new OpenLayers.Bounds(-180,-90,180,90);
}
});
var a = new OpenLayers.Layer.WMS(
null, "http://a.mirror/wms", {layers: "a"}
);
var b = new OpenLayers.Layer.WMS(
null, "http://b.mirror/wms", {layers: "b"}
);
var c = new OpenLayers.Layer.WMS(
null, ["http://c.mirror/wms", "http://d.mirror/wms"], {layers: "c"}
);
var control = new OpenLayers.Control.WMSGetFeatureInfo({
url: "http://host/wms",
layers: [a, b, c]
});
map.addControl(control);
control.activate();
// log calls to GET
var log;
var _request = OpenLayers.Request.GET;
OpenLayers.Request.GET = function(options) {
log.options = options;
};
// control url doesn't match layer urls, no request issued
log = {};
control.getInfoForClick({xy: {x: 50, y: 50}});
t.ok(!log.options, "no url match, no request issued");
// give control a list of urls to match
log = {};
control.layerUrls = ["http://a.mirror/wms", "http://b.mirror/wms"];
control.getInfoForClick({xy: {x: 50, y: 50}});
t.eq(log.options && log.options.url, "http://host/wms", "some match, request issued");
t.eq(log.options && log.options.params["query_layers"].join(","), "a,b", "selected layers queried");
// show that a layer can be matched if it has a urls array itself (first needs to be matched)
log = {};
control.layerUrls = ["http://c.mirror/wms"];
control.getInfoForClick({xy: {x: 50, y: 50}});
t.eq(log.options && log.options.params["query_layers"].join(","), "c", "layer with urls array can be queried");
// clean up
OpenLayers.Request.GET = _request;
map.destroy();
} }
</script> </script>