diff --git a/examples/proxy.cgi b/examples/proxy.cgi index 1d2818f27a..21c7590ab4 100755 --- a/examples/proxy.cgi +++ b/examples/proxy.cgi @@ -22,7 +22,7 @@ allowedHosts = ['www.openlayers.org', 'openlayers.org', 'www.openstreetmap.org', 'sample.azavea.com', 'v2.suite.opengeo.org', 'v-swe.uni-muenster.de:8080', 'vmap0.tiles.osgeo.org', 'www.openrouteservice.org', - 'maps.wien.gv.at'] + 'maps.wien.gv.at','msgsoc.mapgears.com'] method = os.environ["REQUEST_METHOD"] diff --git a/examples/utfgrid_twogrids.js b/examples/utfgrid_twogrids.js index c9cb4980e9..b4780591ec 100644 --- a/examples/utfgrid_twogrids.js +++ b/examples/utfgrid_twogrids.js @@ -52,7 +52,7 @@ var controls = { }), move_both: new OpenLayers.Control.UTFGrid({ callback: callback, - layers: null, // same as all map.layers + layers: [population,bioregions], handlerMode: "move" }) }; diff --git a/examples/utfgridwms.html b/examples/utfgridwms.html new file mode 100644 index 0000000000..23781c43a6 --- /dev/null +++ b/examples/utfgridwms.html @@ -0,0 +1,113 @@ + + + + + + + + + + + + +

OpenLayers UTFGridWMS Demo

+ +
+ wms, layer, singletile +
+

+ This page demonstrates the use of the OpenLayers UTFGridWMS. +

+ +
+ +
+

 

+

This exemple demostrates the use of UTFGridWMS. It allows high interaction maps with WMS. It can be used with the same functionalities that UTFGrid has.

+
+ + diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index 4bf92e758a..b2f9de4917 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -183,6 +183,7 @@ "OpenLayers/Layer/Boxes.js", "OpenLayers/Layer/XYZ.js", "OpenLayers/Layer/UTFGrid.js", + "OpenLayers/Layer/UTFGridWMS.js", "OpenLayers/Layer/OSM.js", "OpenLayers/Layer/Bing.js", "OpenLayers/Layer/TMS.js", diff --git a/lib/OpenLayers/Control/UTFGrid.js b/lib/OpenLayers/Control/UTFGrid.js index 799320110f..c0d233dadc 100644 --- a/lib/OpenLayers/Control/UTFGrid.js +++ b/lib/OpenLayers/Control/UTFGrid.js @@ -229,7 +229,7 @@ OpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, { var layer; for (var i=candidates.length-1; i>=0; --i) { layer = candidates[i]; - if (layer instanceof OpenLayers.Layer.UTFGrid ) { + if (layer instanceof OpenLayers.Layer.UTFGrid || OpenLayers.Layer.UTFGridWMS) { layers.push(layer); } } diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 296674343f..c10d7c690a 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -857,6 +857,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { this.grid[0] = []; } + // store the resolution of the grid + this.gridResolution = this.getServerResolution(); + var tile = this.grid[0][0]; if (!tile) { tile = this.addTile(tileBounds, px); @@ -870,9 +873,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { //remove all but our single tile this.removeExcessTiles(1,1); - - // store the resolution of the grid - this.gridResolution = this.getServerResolution(); }, /** diff --git a/lib/OpenLayers/Layer/UTFGridWMS.js b/lib/OpenLayers/Layer/UTFGridWMS.js new file mode 100644 index 0000000000..85418af09e --- /dev/null +++ b/lib/OpenLayers/Layer/UTFGridWMS.js @@ -0,0 +1,278 @@ +/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for + * full list of contributors). Published under the 2-clause BSD license. + * See license.txt in the OpenLayers distribution or repository for the + * full text of the license. */ + + +/** + * @requires OpenLayers/Layer/WMS.js + * @requires OpenLayers/Tile/UTFGrid.js + * @requires OpenLayers/Control/UTFGrid.js + */ + +/** + * Class: OpenLayers.Layer.UTFGridWMS + * This Layer reads from UTFGrid WMS data sources. Since UTFGrids are + * essentially JSON-based ASCII art with attached attributes, they are not + * visibly rendered. In order to use them in the map, you must add a + * control as well.xw + * + * Inherits from: + * - + */ +OpenLayers.Layer.UTFGridWMS = OpenLayers.Class(OpenLayers.Layer.WMS, { + + /** + * Constant: DEFAULT_PARAMS + * {Object} Hashtable of default parameter key/value pairs + */ + DEFAULT_PARAMS: { service: "WMS", + version: "1.1.1", + request: "GetMap", + styles: "", + format: "application/json" + }, + + /** + * APIProperty: isBaseLayer + * {Boolean} Default is false for UTFGridWMS layer + */ + isBaseLayer: false, + + /** + * APIProperty: encodeBBOX + * {Boolean} Should the BBOX commas be encoded? The WMS spec says 'no', + * but some services want it that way. Default false. + */ + encodeBBOX: false, + + /** + * Property: useJSONP + * {Boolean} + * Should we use a JSONP script approach instead of a standard AJAX call? + * + * Set to true for using utfgrids from another server. + * Avoids same-domain policy restrictions. + * Note that this only works if the server accepts + * the callback GET parameter and dynamically + * wraps the returned json in a function call. + * + * Default is false + */ + useJSONP: false, + + /** + * Property: yx + * {Object} Keys in this object are EPSG codes for which the axis order + * is to be reversed (yx instead of xy, LatLon instead of LonLat), with + * true as value. This is only relevant for WMS versions >= 1.3.0, and + * only if yx is not set in for the + * used projection. + */ + yx: {}, + + /** + * Property: tileClass + * {} The tile class to use for this layer. + * Defaults is . + */ + tileClass: OpenLayers.Tile.UTFGrid, + + /** + * Constructor: OpenLayers.Layer.UTFGridWMS + * Create a new UTFGridWMS layer object + * + * Parameters: + * name - {String} A name for the layer + * url - {String} Base url for the WMS + * (e.g. http://wms.jpl.nasa.gov/wms.cgi) + * params - {Object} An object with key/value pairs representing the + * GetMap query string parameters and parameter values. + * options - {Object} Hashtable of extra options to tag onto the layer. + * These options include all properties listed above, plus the ones + * inherited from superclasses. + */ + initialize: function(name, url, params, options) { + var newArguments = []; + //uppercase params + params = OpenLayers.Util.upperCaseObject(params); + if (parseFloat(params.VERSION) >= 1.3 && !params.EXCEPTIONS) { + params.EXCEPTIONS = "INIMAGE"; + } + newArguments.push(name, url, params, options); + OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments); + OpenLayers.Util.applyDefaults(this.params, OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)); + + this.tileOptions = OpenLayers.Util.extend({ + utfgridResolution: this.utfgridResolution + }, this.tileOptions); + }, + + /** + * Method: createBackBuffer + * The UTFGrid cannot create a back buffer, so this method is overriden. + */ + createBackBuffer: function() {}, + + /** + * Method: clone + * Create a clone of this layer + * + * Returns: + * {} An exact clone of this layer + */ + clone: function (obj) { + + if (obj == null) { + obj = new OpenLayers.Layer.UTFGridWMS(this.name, + this.url, + this.params, + this.getOptions()); + } + + //get all additions from superclasses + obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]); + + return obj; + }, + + /** + * APIMethod: reverseAxisOrder + * Returns true if the axis order is reversed for the WMS version and + * projection of the layer. + * + * Returns: + * {Boolean} true if the axis order is reversed, false otherwise. + */ + reverseAxisOrder: function() { + var projCode = this.projection.getCode(); + return parseFloat(this.params.VERSION) >= 1.3 && + !!(this.yx[projCode] || OpenLayers.Projection.defaults[projCode].yx); + }, + + /** + * Method: getURL + * Return a GetMap query string for this layer + * + * Parameters: + * bounds - {} A bounds representing the bbox for the + * request. + * + * Returns: + * {String} A string with the layer's url and parameters and also the + * passed-in bounds and appropriate tile size specified as + * parameters. + */ + getURL: function (bounds) { + bounds = this.adjustBounds(bounds); + var imageSize = this.getImageSize(bounds); + var newParams = {}; + // WMS 1.3 introduced axis order + var reverseAxisOrder = this.reverseAxisOrder(); + newParams.BBOX = this.encodeBBOX ? + bounds.toBBOX(null, reverseAxisOrder) : + bounds.toArray(reverseAxisOrder); + newParams.WIDTH = imageSize.w; + newParams.HEIGHT = imageSize.h; + var requestString = this.getFullRequestString(newParams); + return requestString; + }, + + /** + * APIMethod: mergeNewParams + * Catch changeParams and uppercase the new params to be merged in + * before calling changeParams on the super class. + * + * Once params have been changed, the tiles will be reloaded with + * the new parameters. + * + * Parameters: + * newParams - {Object} Hashtable of new params to use + */ + mergeNewParams:function(newParams) { + var upperParams = OpenLayers.Util.upperCaseObject(newParams); + var newArguments = [upperParams]; + return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this, + newArguments); + }, + + /** + * APIMethod: getFullRequestString + * Combine the layer's url with its params and these newParams. + * + * Add the SRS parameter from projection -- this is probably + * more eloquently done via a setProjection() method, but this + * works for now and always. + * + * Parameters: + * newParams - {Object} + * altUrl - {String} Use this as the url instead of the layer's url + * + * Returns: + * {String} + */ + getFullRequestString:function(newParams, altUrl) { + var mapProjection = this.map.getProjectionObject(); + var projectionCode = this.projection && this.projection.equals(mapProjection) ? + this.projection.getCode() : + mapProjection.getCode(); + var value = (projectionCode == "none") ? null : projectionCode; + if (parseFloat(this.params.VERSION) >= 1.3) { + this.params.CRS = value; + } else { + this.params.SRS = value; + } + + if (typeof this.params.TRANSPARENT == "boolean") { + newParams.TRANSPARENT = this.params.TRANSPARENT ? "TRUE" : "FALSE"; + } + + return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply( + this, arguments); + }, + + /** + * APIProperty: getFeatureInfo + * Get details about a feature associated with a map location. The object + * returned will have id and data properties. If the given location + * doesn't correspond to a feature, null will be returned. + * + * Parameters: + * location - {} map location + * + * Returns: + * {Object} Object representing the feature id and UTFGrid data + * corresponding to the given map location. Returns null if the given + * location doesn't hit a feature. + */ + getFeatureInfo:function(location) { + var info = null; + var tileInfo = this.getTileData(location); + if (tileInfo && tileInfo.tile) { + info = tileInfo.tile.getFeatureInfo(tileInfo.i, tileInfo.j); + } + return info; + }, + + /** + * APIMethod: getFeatureId + * Get the identifier for the feature associated with a map location. + * + * Parameters: + * location - {} map location + * + * Returns: + * {String} The feature identifier corresponding to the given map location. + * Returns null if the location doesn't hit a feature. + */ + getFeatureId: function(location) { + var id = null; + var info = this.getTileData(location); + if (info.tile) { + id = info.tile.getFeatureId(info.i, info.j); + } + return id; + }, + + CLASS_NAME: "OpenLayers.Layer.UTFGridWMS" +});