Add support for MapGuide Open Source layers in OpenLayers. Great work by
Mike Adair on following this one through. Includes example, tests, code, etc. r=me (Closes #995) git-svn-id: http://svn.openlayers.org/trunk/openlayers@6368 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
332
lib/OpenLayers/Layer/MapGuide.js
Normal file
332
lib/OpenLayers/Layer/MapGuide.js
Normal file
@@ -0,0 +1,332 @@
|
||||
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
|
||||
* licence. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Ajax.js
|
||||
* @requires OpenLayers/Layer/Grid.js
|
||||
*
|
||||
* Class: OpenLayers.Layer.MapGuide
|
||||
* Instances of OpenLayers.Layer.MapGuide are used to display
|
||||
* data from a MapGuide OS instance.
|
||||
*
|
||||
* Inherits from:
|
||||
* - <OpenLayers.Layer.Grid>
|
||||
*/
|
||||
OpenLayers.Layer.MapGuide = OpenLayers.Class(OpenLayers.Layer.Grid, {
|
||||
|
||||
/**
|
||||
* APIProperty: isBaseLayer
|
||||
* {Boolean} Treat this layer as a base layer. Default is true.
|
||||
**/
|
||||
isBaseLayer: true,
|
||||
|
||||
/**
|
||||
* APIProperty: singleTile
|
||||
* {Boolean} use tile server or request single tile image. Note that using
|
||||
* singleTile *and* isBaseLayer false is *not recommend*: it uses synchronous
|
||||
* XMLHttpRequests to load tiles, and this will *lock up users browsers*
|
||||
* during requests.
|
||||
**/
|
||||
singleTile: false,
|
||||
|
||||
/**
|
||||
* Constant: TILE_PARAMS
|
||||
* {Object} Hashtable of default parameter key/value pairs for tiled layer
|
||||
*/
|
||||
TILE_PARAMS: {
|
||||
operation: 'GETTILEIMAGE',
|
||||
version: '1.2.0'
|
||||
},
|
||||
|
||||
/**
|
||||
* Constant: SINGLE_TILE_PARAMS
|
||||
* {Object} Hashtable of default parameter key/value pairs for untiled layer
|
||||
*/
|
||||
SINGLE_TILE_PARAMS: {
|
||||
operation: 'GETMAPIMAGE',
|
||||
format: 'PNG',
|
||||
locale: 'en',
|
||||
version: '1.0.0'
|
||||
},
|
||||
|
||||
/**
|
||||
* Property: defaultSize
|
||||
* {<OpenLayers.Size>} Tile size as produced by MapGuide server
|
||||
**/
|
||||
defaultSize: new OpenLayers.Size(300,300),
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Layer.MapGuide
|
||||
* Create a new Mapguide layer, either tiled or untiled.
|
||||
*
|
||||
* For tiled layers, the 'groupName' and 'mapDefnition' options
|
||||
* must be specified as options.
|
||||
*
|
||||
* For untiled layers, specify either combination of 'mapName' and
|
||||
* 'session', or 'mapDefinition' and 'locale'.
|
||||
*
|
||||
* Parameters:
|
||||
* name - {String} Name of the layer displayed in the interface
|
||||
* url - {String} Location of the MapGuide mapagent executable
|
||||
* (e.g. http://localhost:8008/mapguide/mapagent/mapagent.fcgi)
|
||||
* params - {Object} hashtable of additional parameters to use. Some
|
||||
* parameters may require additional code on the serer. The ones that
|
||||
* you may want to use are:
|
||||
* - mapDefinition - {String} The MapGuide resource definition
|
||||
* (e.g. Library://Samples/Gmap/Maps/gmapTiled.MapDefinition)
|
||||
* - locale - Locale setting
|
||||
* (for untiled overlays layers only)
|
||||
* - mapName - {String} Name of the map as stored in the MapGuide session.
|
||||
* (for untiled layers with a session parameter only)
|
||||
* - session - { String} MapGuide session ID
|
||||
* (for untiled overlays layers only)
|
||||
* - basemaplayergroupname - {String} GroupName for tiled MapGuide layers only
|
||||
* - format - Image format to be returned (for untiled overlay layers only)
|
||||
* - showLayers - {String} A comma separated list of GUID's for the
|
||||
* layers to display eg: 'cvc-xcv34,453-345-345sdf'.
|
||||
* - hideLayers - {String} A comma separated list of GUID's for the
|
||||
* layers to hide eg: 'cvc-xcv34,453-345-345sdf'.
|
||||
* - showGroups - {String} A comma separated list of GUID's for the
|
||||
* groups to display eg: 'cvc-xcv34,453-345-345sdf'.
|
||||
* - hideGroups - {String} A comma separated list of GUID's for the
|
||||
* groups to hide eg: 'cvc-xcv34,453-345-345sdf'
|
||||
* - selectionXml - {String} A selection xml string Some server plumbing
|
||||
* is required to read such a value.
|
||||
* options - {Ojbect} Hashtable of extra options to tag onto the layer;
|
||||
* will vary depending if tiled or untiled maps are being requested
|
||||
*/
|
||||
initialize: function(name, url, params, options) {
|
||||
|
||||
OpenLayers.Layer.Grid.prototype.initialize.apply(this, arguments);
|
||||
|
||||
// unless explicitly set in options, if the layer is transparent,
|
||||
// it will be an overlay
|
||||
if (options == null || options.isBaseLayer == null) {
|
||||
this.isBaseLayer = ((this.transparent != "true") &&
|
||||
(this.transparent != true));
|
||||
}
|
||||
|
||||
//initialize for untiled layers
|
||||
if (this.singleTile) {
|
||||
OpenLayers.Util.applyDefaults(
|
||||
this.params,
|
||||
this.SINGLE_TILE_PARAMS
|
||||
);
|
||||
} else {
|
||||
//initialize for tiled layers
|
||||
OpenLayers.Util.applyDefaults(
|
||||
this.params,
|
||||
this.TILE_PARAMS
|
||||
);
|
||||
this.setTileSize(this.defaultSize);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: clone
|
||||
* Create a clone of this layer
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Layer.MapGuide>} An exact clone of this layer
|
||||
*/
|
||||
clone: function (obj) {
|
||||
if (obj == null) {
|
||||
obj = new OpenLayers.Layer.MapGuide(this.name,
|
||||
this.url,
|
||||
this.params,
|
||||
this.options);
|
||||
}
|
||||
//get all additions from superclasses
|
||||
obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: addTile
|
||||
* Creates a tile, initializes it, and adds it to the layer div.
|
||||
*
|
||||
* Parameters:
|
||||
* bounds - {<OpenLayers.Bounds>}
|
||||
*
|
||||
* Returns:
|
||||
* {<OpenLayers.Tile.Image>} The added OpenLayers.Tile.Image
|
||||
*/
|
||||
addTile:function(bounds,position) {
|
||||
return new OpenLayers.Tile.Image(this, position, bounds,
|
||||
null, this.tileSize);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getURL
|
||||
* Return a query string for this layer
|
||||
*
|
||||
* Parameters:
|
||||
* bounds - {<OpenLayers.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) {
|
||||
var url;
|
||||
var center = bounds.getCenterLonLat();
|
||||
var mapSize = this.map.getCurrentSize();
|
||||
|
||||
if (this.singleTile) {
|
||||
//set up the call for GETMAPIMAGE or GETDYNAMICMAPOVERLAY
|
||||
var params = {};
|
||||
params.setdisplaydpi = OpenLayers.DOTS_PER_INCH;
|
||||
params.setdisplayheight = mapSize.h*this.ratio;
|
||||
params.setdisplaywidth = mapSize.w*this.ratio;
|
||||
params.setviewcenterx = center.lon;
|
||||
params.setviewcentery = center.lat;
|
||||
params.setviewscale = this.map.getScale();
|
||||
|
||||
if (!this.isBaseLayer) {
|
||||
// in this case the main image operation is remapped to this
|
||||
this.params.operation = "GETDYNAMICMAPOVERLAYIMAGE";
|
||||
|
||||
//but we first need to call GETVISIBLEMAPEXTENT to set the extent
|
||||
var getVisParams = {};
|
||||
getVisParams.operation = "GETVISIBLEMAPEXTENT";
|
||||
getVisParams.version = "1.0.0";
|
||||
getVisParams.session = this.params.session;
|
||||
getVisParams.mapName = this.params.mapName;
|
||||
getVisParams.format = 'text/xml';
|
||||
getVisParams = OpenLayers.Util.extend(getVisParams, params);
|
||||
|
||||
new OpenLayers.Ajax.Request(this.url,
|
||||
{ parameters: getVisParams,
|
||||
method: 'get',
|
||||
asynchronous: false //must be synchronous call to return control here
|
||||
});
|
||||
}
|
||||
|
||||
//construct the full URL
|
||||
url = this.getFullRequestString( params );
|
||||
} else {
|
||||
|
||||
//tiled version
|
||||
var currentRes = this.map.getResolution();
|
||||
var colidx = Math.floor((bounds.left-this.maxExtent.left)/currentRes);
|
||||
colidx = Math.round(colidx/this.tileSize.w);
|
||||
var rowidx = Math.floor((this.maxExtent.top-bounds.top)/currentRes);
|
||||
rowidx = Math.round(rowidx/this.tileSize.h);
|
||||
|
||||
url = this.getFullRequestString(
|
||||
{
|
||||
tilecol: colidx,
|
||||
tilerow: rowidx,
|
||||
scaleindex: this.resolutions.length - this.map.zoom - 1
|
||||
});
|
||||
}
|
||||
|
||||
return url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getFullRequestString
|
||||
* getFullRequestString on MapGuide layers is special, because we
|
||||
* do a regular expression replace on ',' in parameters to '+'.
|
||||
* This is why it is subclassed here.
|
||||
*
|
||||
* Parameters:
|
||||
* altUrl - {String} Alternative base URL to use.
|
||||
*
|
||||
* Returns:
|
||||
* {String} A string with the layer's url appropriately encoded for MapGuide
|
||||
*/
|
||||
getFullRequestString:function(newParams, altUrl) {
|
||||
// use layer's url unless altUrl passed in
|
||||
var url = (altUrl == null) ? this.url : altUrl;
|
||||
|
||||
// if url is not a string, it should be an array of strings,
|
||||
// in which case we will randomly select one of them in order
|
||||
// to evenly distribute requests to different urls.
|
||||
if (typeof url == "object") {
|
||||
url = url[Math.floor(Math.random()*url.length)];
|
||||
}
|
||||
// requestString always starts with url
|
||||
var requestString = url;
|
||||
|
||||
// create a new params hashtable with all the layer params and the
|
||||
// new params together. then convert to string
|
||||
var allParams = OpenLayers.Util.extend({}, this.params);
|
||||
allParams = OpenLayers.Util.extend(allParams, newParams);
|
||||
// ignore parameters that are already in the url search string
|
||||
var urlParams = OpenLayers.Util.upperCaseObject(
|
||||
OpenLayers.Util.getArgs(url));
|
||||
for(var key in allParams) {
|
||||
if(key.toUpperCase() in urlParams) {
|
||||
delete allParams[key];
|
||||
}
|
||||
}
|
||||
var paramsString = OpenLayers.Util.getParameterString(allParams);
|
||||
|
||||
/* MapGuide needs '+' seperating things like bounds/height/width.
|
||||
Since typically this is URL encoded, we use a slight hack: we
|
||||
depend on the list-like functionality of getParameterString to
|
||||
leave ',' only in the case of list items (since otherwise it is
|
||||
encoded) then do a regular expression replace on the , characters
|
||||
to '+' */
|
||||
paramsString = paramsString.replace(/,/g, "+");
|
||||
|
||||
if (paramsString != "") {
|
||||
var lastServerChar = url.charAt(url.length - 1);
|
||||
if ((lastServerChar == "&") || (lastServerChar == "?")) {
|
||||
requestString += paramsString;
|
||||
} else {
|
||||
if (url.indexOf('?') == -1) {
|
||||
//serverPath has no ? -- add one
|
||||
requestString += '?' + paramsString;
|
||||
} else {
|
||||
//serverPath contains ?, so must already have paramsString at the end
|
||||
requestString += '&' + paramsString;
|
||||
}
|
||||
}
|
||||
}
|
||||
return requestString;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: calculateGridLayout
|
||||
* Generate parameters for the grid layout. This
|
||||
*
|
||||
* Parameters:
|
||||
* bounds - {<OpenLayers.Bound>}
|
||||
* extent - {<OpenLayers.Bounds>}
|
||||
* resolution - {Number}
|
||||
*
|
||||
* Returns:
|
||||
* Object containing properties tilelon, tilelat, tileoffsetlat,
|
||||
* tileoffsetlat, tileoffsetx, tileoffsety
|
||||
*/
|
||||
calculateGridLayout: function(bounds, extent, resolution) {
|
||||
var tilelon = resolution * this.tileSize.w;
|
||||
var tilelat = resolution * this.tileSize.h;
|
||||
|
||||
var offsetlon = bounds.left - extent.left;
|
||||
var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;
|
||||
var tilecolremain = offsetlon/tilelon - tilecol;
|
||||
var tileoffsetx = -tilecolremain * this.tileSize.w;
|
||||
var tileoffsetlon = extent.left + tilecol * tilelon;
|
||||
|
||||
var offsetlat = extent.top - bounds.top + tilelat;
|
||||
var tilerow = Math.floor(offsetlat/tilelat) - this.buffer;
|
||||
var tilerowremain = tilerow - offsetlat/tilelat;
|
||||
var tileoffsety = tilerowremain * this.tileSize.h;
|
||||
var tileoffsetlat = extent.top - tilelat*tilerow;
|
||||
|
||||
return {
|
||||
tilelon: tilelon, tilelat: tilelat,
|
||||
tileoffsetlon: tileoffsetlon, tileoffsetlat: tileoffsetlat,
|
||||
tileoffsetx: tileoffsetx, tileoffsety: tileoffsety
|
||||
}
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Layer.MapGuide"
|
||||
});
|
||||
Reference in New Issue
Block a user