1
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2
* licence. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3
* full text of the license. */
6
* @requires OpenLayers/Request/XMLHttpRequest.js
7
* @requires OpenLayers/Layer/Grid.js
11
* Class: OpenLayers.Layer.MapGuide
12
* Instances of OpenLayers.Layer.MapGuide are used to display
13
* data from a MapGuide OS instance.
16
* - <OpenLayers.Layer.Grid>
18
OpenLayers.Layer.MapGuide = OpenLayers.Class(OpenLayers.Layer.Grid, {
21
* APIProperty: isBaseLayer
22
* {Boolean} Treat this layer as a base layer. Default is true.
27
* APIProperty: singleTile
28
* {Boolean} use tile server or request single tile image. Note that using
29
* singleTile *and* isBaseLayer false is *not recommend*: it uses synchronous
30
* XMLHttpRequests to load tiles, and this will *lock up users browsers*
31
* during requests if the server fails to respond.
36
* Constant: TILE_PARAMS
37
* {Object} Hashtable of default parameter key/value pairs for tiled layer
40
operation: 'GETTILEIMAGE',
45
* Constant: SINGLE_TILE_PARAMS
46
* {Object} Hashtable of default parameter key/value pairs for untiled layer
49
operation: 'GETMAPIMAGE',
57
* Property: defaultSize
58
* {<OpenLayers.Size>} Tile size as produced by MapGuide server
60
defaultSize: new OpenLayers.Size(300,300),
63
* Constructor: OpenLayers.Layer.MapGuide
64
* Create a new Mapguide layer, either tiled or untiled.
66
* For tiled layers, the 'groupName' and 'mapDefinition' values
67
* must be specified as parameters in the constructor.
69
* For untiled base layers, specify either combination of 'mapName' and
70
* 'session', or 'mapDefinition' and 'locale'.
72
* For untiled overlay layers (singleTile=true and isBaseLayer=false),
73
* mapName and session are required parameters for the Layer constructor.
74
* Also NOTE: untiled overlay layers issues a synchronous AJAX request
75
* before the image request can be issued so the users browser may lock
76
* up if the MG Web tier does not respond in a timely fashion.
78
* NOTE: MapGuide OS uses a DPI value and degrees to meters conversion
79
* factor that are different than the defaults used in OpenLayers,
80
* so these must be adjusted accordingly in your application.
81
* See the MapGuide example for how to set these values for MGOS.
84
* name - {String} Name of the layer displayed in the interface
85
* url - {String} Location of the MapGuide mapagent executable
86
* (e.g. http://localhost:8008/mapguide/mapagent/mapagent.fcgi)
87
* params - {Object} hashtable of additional parameters to use. Some
88
* parameters may require additional code on the server. The ones that
89
* you may want to use are:
90
* - mapDefinition - {String} The MapGuide resource definition
91
* (e.g. Library://Samples/Gmap/Maps/gmapTiled.MapDefinition)
92
* - locale - Locale setting
93
* (for untiled overlays layers only)
94
* - mapName - {String} Name of the map as stored in the MapGuide session.
95
* (for untiled layers with a session parameter only)
96
* - session - { String} MapGuide session ID
97
* (for untiled overlays layers only)
98
* - basemaplayergroupname - {String} GroupName for tiled MapGuide layers only
99
* - format - Image format to be returned (for untiled overlay layers only)
100
* - showLayers - {String} A comma separated list of GUID's for the
101
* layers to display eg: 'cvc-xcv34,453-345-345sdf'.
102
* - hideLayers - {String} A comma separated list of GUID's for the
103
* layers to hide eg: 'cvc-xcv34,453-345-345sdf'.
104
* - showGroups - {String} A comma separated list of GUID's for the
105
* groups to display eg: 'cvc-xcv34,453-345-345sdf'.
106
* - hideGroups - {String} A comma separated list of GUID's for the
107
* groups to hide eg: 'cvc-xcv34,453-345-345sdf'
108
* - selectionXml - {String} A selection xml string Some server plumbing
109
* is required to read such a value.
110
* options - {Ojbect} Hashtable of extra options to tag onto the layer;
111
* will vary depending if tiled or untiled maps are being requested
113
initialize: function(name, url, params, options) {
115
OpenLayers.Layer.Grid.prototype.initialize.apply(this, arguments);
117
// unless explicitly set in options, if the layer is transparent,
118
// it will be an overlay
119
if (options == null || options.isBaseLayer == null) {
120
this.isBaseLayer = ((this.transparent != "true") &&
121
(this.transparent != true));
124
//initialize for untiled layers
125
if (this.singleTile) {
126
OpenLayers.Util.applyDefaults(
128
this.SINGLE_TILE_PARAMS
132
//initialize for tiled layers
133
OpenLayers.Util.applyDefaults(
137
this.setTileSize(this.defaultSize);
143
* Create a clone of this layer
146
* {<OpenLayers.Layer.MapGuide>} An exact clone of this layer
148
clone: function (obj) {
150
obj = new OpenLayers.Layer.MapGuide(this.name,
155
//get all additions from superclasses
156
obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
163
* Creates a tile, initializes it, and adds it to the layer div.
166
* bounds - {<OpenLayers.Bounds>}
167
* position - {<OpenLayers.Pixel>}
170
* {<OpenLayers.Tile.Image>} The added OpenLayers.Tile.Image
172
addTile:function(bounds,position) {
173
return new OpenLayers.Tile.Image(this, position, bounds,
174
null, this.tileSize);
179
* Return a query string for this layer
182
* bounds - {<OpenLayers.Bounds>} A bounds representing the bbox
186
* {String} A string with the layer's url and parameters and also
187
* the passed-in bounds and appropriate tile size specified
190
getURL: function (bounds) {
192
var center = bounds.getCenterLonLat();
193
var mapSize = this.map.getCurrentSize();
195
if (this.singleTile) {
196
//set up the call for GETMAPIMAGE or GETDYNAMICMAPOVERLAY
198
params.setdisplaydpi = OpenLayers.DOTS_PER_INCH;
199
params.setdisplayheight = mapSize.h*this.ratio;
200
params.setdisplaywidth = mapSize.w*this.ratio;
201
params.setviewcenterx = center.lon;
202
params.setviewcentery = center.lat;
203
params.setviewscale = this.map.getScale();
205
if (!this.isBaseLayer) {
206
// in this case the main image operation is remapped to this
207
this.params.operation = "GETDYNAMICMAPOVERLAYIMAGE";
209
//but we first need to call GETVISIBLEMAPEXTENT to set the extent
210
var getVisParams = {};
211
getVisParams = OpenLayers.Util.extend(getVisParams, params);
212
getVisParams.operation = "GETVISIBLEMAPEXTENT";
213
getVisParams.version = "1.0.0";
214
getVisParams.session = this.params.session;
215
getVisParams.mapName = this.params.mapName;
216
getVisParams.format = 'text/xml';
217
url = this.getFullRequestString( getVisParams );
219
OpenLayers.Request.GET({url: url, async: false});
222
//construct the full URL
223
url = this.getFullRequestString( params );
227
var currentRes = this.map.getResolution();
228
var colidx = Math.floor((bounds.left-this.maxExtent.left)/currentRes);
229
colidx = Math.round(colidx/this.tileSize.w);
230
var rowidx = Math.floor((this.maxExtent.top-bounds.top)/currentRes);
231
rowidx = Math.round(rowidx/this.tileSize.h);
233
url = this.getFullRequestString(
237
scaleindex: this.resolutions.length - this.map.zoom - 1
245
* Method: getFullRequestString
246
* getFullRequestString on MapGuide layers is special, because we
247
* do a regular expression replace on ',' in parameters to '+'.
248
* This is why it is subclassed here.
251
* altUrl - {String} Alternative base URL to use.
254
* {String} A string with the layer's url appropriately encoded for MapGuide
256
getFullRequestString:function(newParams, altUrl) {
257
// use layer's url unless altUrl passed in
258
var url = (altUrl == null) ? this.url : altUrl;
260
// if url is not a string, it should be an array of strings,
261
// in which case we will randomly select one of them in order
262
// to evenly distribute requests to different urls.
263
if (typeof url == "object") {
264
url = url[Math.floor(Math.random()*url.length)];
266
// requestString always starts with url
267
var requestString = url;
269
// create a new params hashtable with all the layer params and the
270
// new params together. then convert to string
271
var allParams = OpenLayers.Util.extend({}, this.params);
272
allParams = OpenLayers.Util.extend(allParams, newParams);
273
// ignore parameters that are already in the url search string
274
var urlParams = OpenLayers.Util.upperCaseObject(
275
OpenLayers.Util.getArgs(url));
276
for(var key in allParams) {
277
if(key.toUpperCase() in urlParams) {
278
delete allParams[key];
281
var paramsString = OpenLayers.Util.getParameterString(allParams);
283
/* MapGuide needs '+' seperating things like bounds/height/width.
284
Since typically this is URL encoded, we use a slight hack: we
285
depend on the list-like functionality of getParameterString to
286
leave ',' only in the case of list items (since otherwise it is
287
encoded) then do a regular expression replace on the , characters
289
paramsString = paramsString.replace(/,/g, "+");
291
if (paramsString != "") {
292
var lastServerChar = url.charAt(url.length - 1);
293
if ((lastServerChar == "&") || (lastServerChar == "?")) {
294
requestString += paramsString;
296
if (url.indexOf('?') == -1) {
297
//serverPath has no ? -- add one
298
requestString += '?' + paramsString;
300
//serverPath contains ?, so must already have paramsString at the end
301
requestString += '&' + paramsString;
305
return requestString;
309
* Method: calculateGridLayout
310
* Generate parameters for the grid layout. This
313
* bounds - {<OpenLayers.Bound>}
314
* extent - {<OpenLayers.Bounds>}
315
* resolution - {Number}
318
* Object containing properties tilelon, tilelat, tileoffsetlat,
319
* tileoffsetlat, tileoffsetx, tileoffsety
321
calculateGridLayout: function(bounds, extent, resolution) {
322
var tilelon = resolution * this.tileSize.w;
323
var tilelat = resolution * this.tileSize.h;
325
var offsetlon = bounds.left - extent.left;
326
var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;
327
var tilecolremain = offsetlon/tilelon - tilecol;
328
var tileoffsetx = -tilecolremain * this.tileSize.w;
329
var tileoffsetlon = extent.left + tilecol * tilelon;
331
var offsetlat = extent.top - bounds.top + tilelat;
332
var tilerow = Math.floor(offsetlat/tilelat) - this.buffer;
333
var tilerowremain = tilerow - offsetlat/tilelat;
334
var tileoffsety = tilerowremain * this.tileSize.h;
335
var tileoffsetlat = extent.top - tilelat*tilerow;
338
tilelon: tilelon, tilelat: tilelat,
339
tileoffsetlon: tileoffsetlon, tileoffsetlat: tileoffsetlat,
340
tileoffsetx: tileoffsetx, tileoffsety: tileoffsety
344
CLASS_NAME: "OpenLayers.Layer.MapGuide"