/* Copyright (c) 2006-2013 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/Request/XMLHttpRequest.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.MapGuide2 = OpenLayers.Class(OpenLayers.Layer.Grid, {
|
|
/**
|
* APIProperty: isBaseLayer
|
* {Boolean} Treat this layer as a base layer. Default is true.
|
**/
|
isBaseLayer: true,
|
|
/**
|
* APIProperty: useHttpTile
|
* {Boolean} use a tile cache exposed directly via a webserver rather than the
|
* via mapguide server. This does require extra configuration on the Mapguide Server,
|
* and will only work when singleTile is false. The url for the layer must be set to the
|
* webserver path rather than the Mapguide mapagent.
|
* See http://trac.osgeo.org/mapguide/wiki/CodeSamples/Tiles/ServingTilesViaHttp
|
**/
|
useHttpTile: false,
|
|
/**
|
* APIProperty: singleTile
|
* {Boolean} use tile server or request single tile image.
|
**/
|
singleTile: false,
|
|
/**
|
* APIProperty: useOverlay
|
* {Boolean} flag to indicate if the layer should be retrieved using
|
* GETMAPIMAGE (default) or using GETDYNAMICOVERLAY requests.
|
**/
|
useOverlay: false,
|
|
/**
|
* APIProperty: useAsyncOverlay
|
* {Boolean} indicates if the MapGuide site supports the asynchronous
|
* GETDYNAMICOVERLAY requests which is available in MapGuide Enterprise 2010
|
* and MapGuide Open Source v2.0.3 or higher. The newer versions of MG
|
* is called asynchronously, allows selections to be drawn separately from
|
* the map and offers styling options.
|
*
|
* With older versions of MapGuide, set useAsyncOverlay=false. Note that in
|
* this case a synchronous AJAX call is issued and the mapname and session
|
* parameters must be used to initialize the layer, not the mapdefinition
|
* parameter. Also note that this will issue a synchronous AJAX request
|
* before the image request can be issued so the users browser may lock
|
* up if the MG Web tier does not respond in a timely fashion.
|
**/
|
useAsyncOverlay: true,
|
|
/**
|
* 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',
|
clip: '1',
|
version: '1.0.0'
|
},
|
|
/**
|
* Constant: OVERLAY_PARAMS
|
* {Object} Hashtable of default parameter key/value pairs for untiled layer
|
*/
|
OVERLAY_PARAMS: {
|
operation: 'GETDYNAMICMAPOVERLAYIMAGE',
|
format: 'PNG',
|
locale: 'en',
|
clip: '1',
|
version: '2.0.0'
|
},
|
|
/**
|
* Constant: FOLDER_PARAMS
|
* {Object} Hashtable of parameter key/value pairs which describe
|
* the folder structure for tiles as configured in the mapguide
|
* serverconfig.ini section [TileServiceProperties]
|
*/
|
FOLDER_PARAMS: {
|
tileColumnsPerFolder: 30,
|
tileRowsPerFolder: 30,
|
format: 'png',
|
querystring: null
|
},
|
|
/**
|
* Property: defaultSize
|
* {<OpenLayers.Size>} Tile size as produced by MapGuide server
|
**/
|
defaultSize: new OpenLayers.Size(300,300),
|
|
/**
|
* Property: tileOriginCorner
|
* {String} MapGuide tile server uses top-left as tile origin
|
**/
|
tileOriginCorner: "tl",
|
|
/**
|
* Constructor: OpenLayers.Layer.MapGuide
|
* Create a new Mapguide layer, either tiled or untiled.
|
*
|
* For tiled layers, the 'groupName' and 'mapDefinition' values
|
* must be specified as parameters in the constructor.
|
*
|
* For untiled base layers, specify either combination of 'mapName' and
|
* 'session', or 'mapDefinition' and 'locale'.
|
*
|
* For older versions of MapGuide and overlay layers, set useAsyncOverlay
|
* to false and in this case mapName and session are required parameters
|
* for the constructor.
|
*
|
* NOTE: MapGuide OS uses a DPI value and degrees to meters conversion
|
* factor that are different than the defaults used in OpenLayers,
|
* so these must be adjusted accordingly in your application.
|
* See the MapGuide example for how to set these values for MGOS.
|
*
|
* 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 server. 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 - {Object} 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));
|
}
|
|
if (options && options.useOverlay!=null) {
|
this.useOverlay = options.useOverlay;
|
}
|
|
//initialize for untiled layers
|
if (this.singleTile) {
|
if (this.useOverlay) {
|
OpenLayers.Util.applyDefaults(
|
this.params,
|
this.OVERLAY_PARAMS
|
);
|
if (!this.useAsyncOverlay) {
|
this.params.version = "1.0.0";
|
}
|
} else {
|
OpenLayers.Util.applyDefaults(
|
this.params,
|
this.SINGLE_TILE_PARAMS
|
);
|
}
|
} else {
|
//initialize for tiled layers
|
if (this.useHttpTile) {
|
OpenLayers.Util.applyDefaults(
|
this.params,
|
this.FOLDER_PARAMS
|
);
|
} else {
|
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.getOptions());
|
}
|
//get all additions from superclasses
|
obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
|
|
return obj;
|
},
|
|
/**
|
* 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.getSize();
|
|
if (this.singleTile) {
|
|
//set up the call for GETMAPIMAGE or GETDYNAMICMAPOVERLAY with
|
//dynamic map parameters
|
var center_prim= new OpenLayers.LonLat(center.lon,center.lat);
|
center_prim.transform(this.map.projection,this.projection);
|
var thismapScale=this.map.getScale();
|
var swapXY=false;
|
|
var metersPerUnit = 111319.4908; //value returned from mapguide
|
var inPerUnit = OpenLayers.INCHES_PER_UNIT.m * metersPerUnit;
|
OpenLayers.INCHES_PER_UNIT["dd"] = inPerUnit;
|
OpenLayers.INCHES_PER_UNIT["degrees"] = inPerUnit;
|
OpenLayers.DOTS_PER_INCH = 96;
|
var params = {
|
setdisplaydpi: OpenLayers.DOTS_PER_INCH,
|
setdisplayheight: mapSize.h *this.ratio*0.9,
|
setdisplaywidth: mapSize.w *this.ratio*0.9,
|
setviewcenterx:(swapXY? center_prim.lat:center_prim.lon),
|
setviewcentery:(swapXY? center_prim.lon:center_prim.lat),
|
setviewscale: thismapScale
|
};
|
|
if (this.useOverlay && !this.useAsyncOverlay) {
|
//first we need to call GETVISIBLEMAPEXTENT to set the extent
|
var getVisParams = {};
|
getVisParams = OpenLayers.Util.extend(getVisParams, params);
|
getVisParams.operation = "GETVISIBLEMAPEXTENT";
|
getVisParams.version = "1.0.0";
|
getVisParams.session = this.params.session;
|
getVisParams.mapName = this.params.mapName;
|
getVisParams.format = 'text/xml';
|
url = this.getFullRequestString( getVisParams );
|
|
OpenLayers.Request.GET({url: url, async: false});
|
}
|
//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);
|
|
if (this.useHttpTile){
|
url = this.getImageFilePath(
|
{
|
tilecol: colidx,
|
tilerow: rowidx,
|
scaleindex: this.resolutions.length - this.map.zoom - 1
|
});
|
|
} else {
|
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.getParameters(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: getImageFilePath
|
* special handler to request mapguide tiles from an http exposed tilecache
|
*
|
* Parameters:
|
* altUrl - {String} Alternative base URL to use.
|
*
|
* Returns:
|
* {String} A string with the url for the tile image
|
*/
|
getImageFilePath: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;
|
|
var tileRowGroup = "";
|
var tileColGroup = "";
|
|
if (newParams.tilerow < 0) {
|
tileRowGroup = '-';
|
}
|
|
if (newParams.tilerow == 0 ) {
|
tileRowGroup += '0';
|
} else {
|
tileRowGroup += Math.floor(Math.abs(newParams.tilerow/this.params.tileRowsPerFolder)) * this.params.tileRowsPerFolder;
|
}
|
|
if (newParams.tilecol < 0) {
|
tileColGroup = '-';
|
}
|
|
if (newParams.tilecol == 0) {
|
tileColGroup += '0';
|
} else {
|
tileColGroup += Math.floor(Math.abs(newParams.tilecol/this.params.tileColumnsPerFolder)) * this.params.tileColumnsPerFolder;
|
}
|
|
var tilePath = '/S' + Math.floor(newParams.scaleindex)
|
+ '/' + this.params.basemaplayergroupname
|
+ '/R' + tileRowGroup
|
+ '/C' + tileColGroup
|
+ '/' + (newParams.tilerow % this.params.tileRowsPerFolder)
|
+ '_' + (newParams.tilecol % this.params.tileColumnsPerFolder)
|
+ '.' + this.params.format;
|
|
if (this.params.querystring) {
|
tilePath += "?" + this.params.querystring;
|
}
|
|
requestString += tilePath;
|
return requestString;
|
},
|
|
CLASS_NAME: "OpenLayers.Layer.MapGuide2"
|
});
|