[Commits] r615 - apps/opengeo/geoexplorer/trunk/lib
commits at geoext.org
commits at geoext.org
Wed May 6 21:44:23 CEST 2009
Author: dwins
Date: 2009-05-06 21:44:23 +0200 (Wed, 06 May 2009)
New Revision: 615
Removed:
apps/opengeo/geoexplorer/trunk/lib/MassGetFeatureInfo.js
Modified:
apps/opengeo/geoexplorer/trunk/lib/GeoExplorer.js
Log:
Reimplement per-layer getfeature requests without modifying the OpenLayers control
Modified: apps/opengeo/geoexplorer/trunk/lib/GeoExplorer.js
===================================================================
--- apps/opengeo/geoexplorer/trunk/lib/GeoExplorer.js 2009-05-06 19:33:28 UTC (rev 614)
+++ apps/opengeo/geoexplorer/trunk/lib/GeoExplorer.js 2009-05-06 19:44:23 UTC (rev 615)
@@ -70,6 +70,13 @@
capGrid: null,
/**
+ * Property: popupCache
+ * {Object} An object containing references to visible popups so that
+ * we can insert responses from multiple requests.
+ */
+ popupCache: {},
+
+ /**
* Method: load
* Called at the end of construction. This initiates the sequence that
* prepares the application for use.
@@ -578,47 +585,62 @@
}
});
this.map.addControl(historyControl);
+
+ var toolGroup = "toolGroup";
// create a get feature info control
- var infoControl = new MassGetFeatureInfo({
- url: this.initialConfig.ows,
- queryVisible: true,
- singleRequest: false,
- eventListeners: {
- getfeatureinfo: this.displayPopup,
- scope: this
+ var info = {controls: []};
+ var infoButton = new Ext.Button({
+ tooltip: "Get Feature Info",
+ iconCls: "icon-getfeatureinfo",
+ toggleGroup: toolGroup,
+ enableToggle: true,
+ allowDepress: false,
+ toggleHandler: function(button, pressed) {
+ for (var i = 0, len = info.controls.length; i < len; i++){
+ if(pressed) {
+ info.controls[i].activate();
+ } else {
+ info.controls[i].deactivate();
+ }
+ }
}
- });
+ })
var updateInfo = function() {
var queryableLayers = this.mapPanel.layers.queryBy(function(x){
- return x.data.queryable;
+ return x.get("queryable");
});
- var layerObjects = [];
- queryableLayers.each(function(x){layerObjects.push(x.data.layer);});
- if (queryableLayers.length > 0) {
- infoControl.url = queryableLayers[0];
+ var map = this.mapPanel.map;
+ var gx = this;
+
+ for (var i = 0, len = info.controls.length; i < len; i++){
+ map.removeControl(info.controls[i]);
}
- infoControl.layers = layerObjects;
+ info.controls = [];
+ queryableLayers.each(function(x){
+ var control = new OpenLayers.Control.WMSGetFeatureInfo({
+ url: x.get("layer").url,
+ queryVisible: true,
+ layers: [x.get("layer")],
+ eventListeners: {
+ getfeatureinfo: function(evt) {
+ gx.displayPopup(evt, x.get("title"));
+ },
+ scope: gx
+ }
+ });
+ map.addControl(control);
+ info.controls.push(control);
+ });
};
this.mapPanel.layers.on("update", updateInfo, this);
this.mapPanel.layers.on("add", updateInfo, this);
this.mapPanel.layers.on("remove", updateInfo, this);
- this.on({
- ready: function() {
- var record = this.capabilities.getAt(0);
- if(record) {
- infoControl.layerUrls = [record.get("layer").url];
- }
- },
- scope: this
- });
- this.map.addControl(infoControl);
-
// create length measure control
var measureLength = this.createMeasureTool(
OpenLayers.Handler.Path, 'Length'
@@ -631,7 +653,6 @@
);
this.map.addControl(measureArea);
- var toolGroup = "toolGroup";
var tools = [
new Ext.Button({
text: "GeoExplorer",
@@ -662,20 +683,7 @@
},
scope: this
}),
- new Ext.Button({
- tooltip: "Get Feature Info",
- iconCls: "icon-getfeatureinfo",
- toggleGroup: toolGroup,
- enableToggle: true,
- allowDepress: false,
- toggleHandler: function(button, pressed) {
- if(pressed) {
- infoControl.activate();
- } else {
- infoControl.deactivate();
- }
- }
- }),
+ infoButton,
new MapToolSplitToggle({
tooltip: "Measure",
iconCls: "icon-measure",
@@ -847,49 +855,45 @@
return measureControl;
},
- displayPopup: function(evt){
- var items = [];
+ displayPopup: function(evt, title){
+ var popup;
+ var popupKey = evt.xy.x + "." + evt.xy.y;
- for (var i in evt.responses) {
- var html = evt.responses[i].text;
- if (html == '' || html.match(/<body>\s*<\/body>/)) {
- continue;
- }
+ if (!(popupKey in this.popupCache)) {
+ var lonlat = this.map.getLonLatFromPixel(evt.xy);
+ popup = new GeoExt.Popup({
+ title: "Feature Info",
+ lonlat: lonlat,
+ width: 250,
+ height: 300,
+ autoScroll: true,
+ listeners: {
+ close: (function(key) {
+ return function(panel){
+ delete this.popupCache[key];
+ };
+ })(popupKey),
+ scope: this
+ }
+ });
+ popup.addToMapPanel(this.mapPanel);
+ popup.show();
+ this.popupCache[popupKey] = popup;
+ } else {
+ popup = this.popupCache[popupKey];
+ }
- items.push({
- title: i,
+ var html = evt.text;
+ if (!(html == '' || html.match(/<body>\s*<\/body>/))) {
+ popup.add({
+ title: title,
html: html,
autoScroll: true,
collapsible: true
});
}
- if (items.length == 0) {
- return;
- }
-
- if (items.length == 1) {
- items[0].collapsible = false;
- }
-
-
- var lonlat = this.map.getLonLatFromPixel(evt.xy);
- var win = new GeoExt.Popup({
- title: "Feature Info",
- lonlat: lonlat,
- width: 250,
- height: 300,
- autoScroll: true,
- items: [new Ext.Panel({
- //width: 250,
- //height: 300,
- //enableTabScroll: true,
- //activeTab: 0,
- items: items
- })]
- });
- win.addToMapPanel(this.mapPanel);
- win.show();
+ popup.doLayout();
},
Deleted: apps/opengeo/geoexplorer/trunk/lib/MassGetFeatureInfo.js
===================================================================
--- apps/opengeo/geoexplorer/trunk/lib/MassGetFeatureInfo.js 2009-05-06 19:33:28 UTC (rev 614)
+++ apps/opengeo/geoexplorer/trunk/lib/MassGetFeatureInfo.js 2009-05-06 19:44:23 UTC (rev 615)
@@ -1,478 +0,0 @@
-
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
- * full text of the license. */
-
-
-/**
- * @requires OpenLayers/Control.js
- * @requires OpenLayers/Handler/Click.js
- * @requires OpenLayers/Handler/Hover.js
- * @requires OpenLayers/Request.js
- */
-
-/**
- * Class: OpenLayers.Control.WMSGetFeatureInfo
- * The WMSGetFeatureInfo control uses a WMS query to get information about a point on the map. The
- * information may be in a display-friendly format such as HTML, or a machine-friendly format such
- * as GML, depending on the server's capabilities and the client's configuration. This control
- * handles click or hover events, attempts to parse the results using an OpenLayers.Format, and
- * fires a 'getfeatureinfo' event with the click position, the raw body of the response, and an
- * array of features if it successfully read the response.
- *
- * Inherits from:
- * - <OpenLayers.Control>
- */
-MassGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
-
- /**
- * APIProperty: hover
- * {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
- * sets the feature_count parameter on WMS GetFeatureInfo
- * requests.
- */
- maxFeatures: 10,
-
- /**
- * Property: layers
- * {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. Default is false.
- */
- queryVisible: false,
-
- /**
- * Property: singleRequest
- * {Boolean} if true, aggregate requests to the same service into a single
- * request with multiple LAYERs specified. Otherwise, issue one http
- * request per layer. Default is true.
- */
- singleRequest: true,
-
- /**
- * Property: url
- * {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
- * {String} The mimetype to request from the server
- */
- infoFormat: 'text/html',
-
- /**
- * Property: vendorParams
- * {Object} Additional parameters that will be added to the request, for
- * WMS implementations that support them. This could e.g. look like
- * (start code)
- * {
- * radius: 5
- * }
- * (end)
- */
- vendorParams: {},
-
- /**
- * Property: format
- * {<OpenLayers.Format>} A format for parsing GetFeatureInfo responses.
- * Default is <OpenLayers.Format.WMSGetFeatureInfo>.
- */
- 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
- * {Object} Additional options for the handlers used by this control, e.g.
- * (start code)
- * {
- * "click": {delay: 100},
- * "hover": {delay: 300}
- * }
- * (end)
- */
- handlerOptions: null,
-
- /**
- * Property: handler
- * {Object} Reference to the <OpenLayers.Handler> for this control
- */
- handler: null,
-
- /**
- * Property: hoverRequest
- * {<OpenLayers.Request>} contains the currently running hover request
- * (if any).
- */
- hoverRequest: null,
-
- /**
- * Constant: EVENT_TYPES
- *
- * 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.WMSGetFeatureInfo>
- *
- * Parameters:
- * options - {Object}
- */
- initialize: function(options) {
- // concatenate events specific to vector with those from the base
- this.EVENT_TYPES =
- MassGetFeatureInfo.prototype.EVENT_TYPES.concat(
- OpenLayers.Control.prototype.EVENT_TYPES
- );
-
- options = options || {};
- options.handlerOptions = options.handlerOptions || {};
-
- OpenLayers.Control.prototype.initialize.apply(this, [options]);
-
- if(!this.format) {
- this.format = new OpenLayers.Format.WMSGetFeatureInfo(
- options.formatOptions
- );
- }
-
- if (this.hover) {
- this.handler = new OpenLayers.Handler.Hover(
- this, {
- 'move': this.cancelHover,
- 'pause': this.getInfoForHover
- },
- OpenLayers.Util.extend(this.handlerOptions.hover || {}, {
- 'delay': 250
- }));
- } else {
- this.handler = new OpenLayers.Handler.Click(this,
- {click: this.getInfoForClick}, this.handlerOptions.click || {});
- }
- },
-
- /**
- * Method: activate
- * Activates the control.
- *
- * Returns:
- * {Boolean} The control was effectively activated.
- */
- activate: function () {
- if (!this.active) {
- this.handler.activate();
- }
- return OpenLayers.Control.prototype.activate.apply(
- this, arguments
- );
- },
-
- /**
- * Method: deactivate
- * Deactivates the control.
- *
- * Returns:
- * {Boolean} The control was effectively deactivated.
- */
- deactivate: function () {
- return OpenLayers.Control.prototype.deactivate.apply(
- this, arguments
- );
- },
-
- /**
- * Method: getInfoForClick
- * Called on click
- *
- * Parameters:
- * evt - {<OpenLayers.Event>}
- */
- getInfoForClick: function(evt) {
- // Set the cursor to "wait" to tell the user we're working on their
- // click.
- OpenLayers.Element.addClass(this.map.viewPortDiv, "olCursorWait");
- this.request(evt.xy, {});
- },
-
- /**
- * Method: getInfoForHover
- * Pause callback for the hover handler
- *
- * Parameters:
- * evt - {Object}
- */
- getInfoForHover: function(evt) {
- this.request(evt.xy, {hover: true});
- },
-
- /**
- * Method: cancelHover
- * Cancel callback for the hover handler
- */
- cancelHover: function() {
- if (this.hoverRequest) {
- this.hoverRequest.abort();
- this.hoverRequest = null;
- }
- },
-
- /**
- * Method: findLayers
- * Internal method to get the layers, independent of whether we are
- * inspecting the map or using a client-provided array
- */
- findLayers: function() {
-
- var layers = [];
-
- 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 - {<OpenLayers.Pixel>} The position on the map where the
- * mouse event occurred.
- * options - {Object} additional options for this method.
- *
- * Valid options:
- * - *hover* {Boolean} true if we do the request for the hover handler
- */
- request: function(clickPosition, options) {
- options = options || {};
- var layerNames = [];
- 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, ""));
- }
- }
- }
-
- var baseRequestParams = OpenLayers.Util.applyDefaults({
- service: "WMS",
- version: "1.1.0",
- request: "GetFeatureInfo",
- 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);
-
- if (this.singleRequest) {
- var layerRequestParams = OpenLayers.Util.applyDefaults({
- layers: layerNames,
- query_layers: layerNames,
- styles: styleNames
- }, baseRequestParams);
-
- var wmsOptions = {
- url: this.url,
- params: layerRequestParams,
- callback: function (request) {
- this.handleResponse(clickPosition, request);
- },
- scope: this
- };
-
- var response = OpenLayers.Request.GET(wmsOptions);
-
- if (options.hover === true) {
- this.hoverRequest = response.priv;
- }
- } else {
- var requestFuncs = [];
- var results = {};
-
- for (var i = 0, len = layerNames.length; i < len; i++) {
- var layerRequestParams = OpenLayers.Util.applyDefaults({
- layers: layerNames[i],
- query_layers: layerNames[i],
- styles: styleNames[i]
- }, baseRequestParams);
-
- requestFuncs.push((function(url, params){
- return (function(done) {
- var wmsOptions = {
- url: this.url,
- params: params,
- callback: function(request) {
- results[params.layers] =
- this.handlePartialResponse(clickPosition, request);
- done();
- },
- scope: this};
-
- OpenLayers.Request.GET(wmsOptions);
- });})(this.url, layerRequestParams));
- }
-
- Viewer.prototype.dispatch.call(this, requestFuncs, function() {
- OpenLayers.Element.removeClass(this.map.viewPortDiv, "olCursorWait");
- this.events.triggerEvent('getfeatureinfo', {
- responses: results,
- xy: clickPosition
- });
- });
- }
- } else {
- // Reset the cursor.
- OpenLayers.Element.removeClass(this.map.viewPortDiv, "olCursorWait");
- }
- },
-
- handlePartialResponse: function(xy, request) {
- var doc = request.responseXML;
- if(!doc || !doc.documentElement) {
- doc = request.responseText;
- }
-
- var features = this.format.read(doc);
-
- return {
- text: request.responseText,
- features: features,
- request: request
- }
- },
-
- /**
- * Method: handleResponse
- * Handler for the GetFeatureInfo response.
- *
- * Parameters:
- * xy - {<OpenLayers.Pixel>} The position on the map where the
- * mouse event occurred.
- * request - {XMLHttpRequest} The request object.
- */
- 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: request.responseText,
- features: features,
- request: request,
- xy: xy
- });
-
- // Reset the cursor.
- OpenLayers.Element.removeClass(this.map.viewPortDiv, "olCursorWait");
- },
-
- /**
- * Method: setMap
- * Set the map property for the control.
- *
- * Parameters:
- * map - {<OpenLayers.Map>}
- */
- setMap: function(map) {
- this.handler.setMap(map);
- OpenLayers.Control.prototype.setMap.apply(this, arguments);
- },
-
- CLASS_NAME: "MassGetFeatureInfo"
-});
More information about the Commits
mailing list