Add MapGuide untiled map support to ol3.

This adds a new ol.source.MapGuide class that is initialized with an options object that can contain the following values:
 - projection: The projection of the Map Definition in EPSG format
 - url: The mapagent URL
 - useOverlay: Determines whether the GETMAPIMAGE (false) or GETDYNAMICMAPOVERLAYIMAGE (true) will be used for requesting the map image. When using GETMAPIMAGE, you must include a valid MAPDEFINITION parameter in the 'params' option property. When using GETDYNAMICMAPOVERLAYIMAGE, you must include a valid SESSION and MAPNAME parameters in the 'params' option property.
 - metersPerUnit: A required value used for calculating the map scale needed by the image request. This value can be calculated using the MapGuide Web API or obtained through the new CREATERUNTIMEMAP operation in MapGuide Open Source 2.6
 - params: A set of key-value pairs to append to the mapagent request
 - extent: The bounds of the layer

An example is included to demonstrate this new layer source. Like ol2, this example uses the MapGuide Server on data.mapguide.com
This commit is contained in:
Jackie Ng
2013-11-06 00:14:57 +11:00
parent fdad53c619
commit 60825f0f99
5 changed files with 227 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="../css/ol.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
<title>MapGuide untiled example</title>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<h4 id="title">MapGuide untiled example</h4>
<p id="shortdesc">Example of a untiled MapGuide map.</p>
<div id="docs">
<p>See the <a href="mapguide-untiled.js" target="_blank">mapguide-untiled.js source</a> to see how this is done.</p>
</div>
<div id="tags">mapguide</div>
</div>
</div>
</div>
<script src="loader.js?id=mapguide-untiled" type="text/javascript"></script>
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
</body>
</html>

View File

@@ -0,0 +1,39 @@
goog.require('ol.Map');
goog.require('ol.RendererHint');
goog.require('ol.View2D');
goog.require('ol.layer.Image');
goog.require('ol.source.MapGuide');
var mdf = 'Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition';
var agentUrl =
'http://data.mapguide.com/mapguide/mapagent/mapagent.fcgi?USERNAME=Anonymous';
var bounds = [
-87.865114442365922,
43.665065564837931,
-87.595394059497067,
43.823852564430069
];
var map = new ol.Map({
layers: [
new ol.layer.Image({
source: new ol.source.MapGuide({
projection: 'EPSG:4326',
url: agentUrl,
useOverlay: false,
metersPerUnit: 111319.4908, //value returned from mapguide
params: {
MAPDEFINITION: mdf,
FORMAT: 'PNG'
},
extent: bounds
})
})
],
renderer: ol.RendererHint.CANVAS,
target: 'map',
view: new ol.View2D({
center: [-87.7302542509315, 43.744459064634],
projection: 'EPSG:4326',
zoom: 12
})
});

View File

@@ -578,6 +578,18 @@
* @todo stability experimental
*/
/**
* @typedef {Object} ol.source.MapGuideOptions
* @property {string} url The mapagent url
* @property {number} metersPerUnit The meters-per-unit value
* @property {ol.Extent|undefined} extent Extent.
* @property {boolean} useOverlay If true, will use GETDYNAMICMAPOVERLAYIMAGE
* @property {ol.proj.ProjectionLike} projection Projection.
* @property {Array.<number>|undefined} resolutions Resolutions. If specified,
* requests will be made for these resolutions only.
* @property {Object} params additional parameters
*/
/**
* @typedef {Object} ol.source.MapQuestOptions
* @property {ol.TileLoadFunctionType|undefined} tileLoadFunction Optional

View File

@@ -0,0 +1 @@
@exportSymbol ol.source.MapGuide

View File

@@ -0,0 +1,125 @@
goog.provide('ol.source.MapGuide');
goog.require('goog.object');
goog.require('goog.uri.utils');
goog.require('ol.ImageUrlFunction');
goog.require('ol.extent');
goog.require('ol.source.Image');
/**
* @constructor
* @extends {ol.source.Image}
* @param {ol.source.MapGuideOptions} options Options.
*/
ol.source.MapGuide = function(options) {
var imageUrlFunction = goog.isDef(options.url) ?
ol.ImageUrlFunction.createFromParamsFunction(
options.url,
options.params,
goog.bind(this.getUrl, this)) :
ol.ImageUrlFunction.nullImageUrlFunction;
/**
* @private
* @type {number}
*/
this.metersPerUnit_ = options.metersPerUnit;
/**
* @private
* @type {boolean}
*/
this.useOverlay_ = options.useOverlay;
/**
* @private
* @type {ol.Image}
*/
this.image_ = null;
goog.base(this, {
extent: options.extent,
projection: options.projection,
resolutions: options.resolutions,
imageUrlFunction: imageUrlFunction
});
};
goog.inherits(ol.source.MapGuide, ol.source.Image);
/**
* @inheritDoc
*/
ol.source.MapGuide.prototype.getImage =
function(extent, resolution, projection) {
resolution = this.findNearestResolution(resolution);
var image = this.image_;
if (!goog.isNull(image) &&
image.getResolution() == resolution &&
ol.extent.containsExtent(image.getExtent(), extent)) {
return image;
}
extent = extent.slice();
ol.extent.scaleFromCenter(extent, 1.0); //this.ratio_);
var width = (extent[2] - extent[0]) / resolution;
var height = (extent[3] - extent[1]) / resolution;
var size = [width, height];
this.image_ = this.createImage(extent, resolution, size, projection);
return this.image_;
};
/**
* @param {ol.Extent} extent The map extents
* @param {ol.Size} size the viewport size
* @return {number} The computed map scale
*/
ol.source.MapGuide.prototype.getScale = function(extent, size) {
var mcsW = extent[2] - extent[0];
var mcsH = extent[3] - extent[1];
var devW = size[0];
var devH = size[1];
var dpi = 96;
var mpu = this.metersPerUnit_;
var mpp = 0.0254 / dpi;
var scale = 0.0;
if (devH * mcsW > devW * mcsH)
scale = mcsW * mpu / (devW * mpp); //width-limited
else
scale = mcsH * mpu / (devH * mpp); //height-limited
return scale;
};
/**
* @param {string} baseUrl The mapagent url.
* @param {Object.<string, string|number>} params Request parameters.
* @param {ol.Extent} extent Extent.
* @param {ol.Size} size Size.
* @param {ol.proj.Projection} projection Projection.
* @return {string} The mapagent map image request URL.
*/
ol.source.MapGuide.prototype.getUrl =
function(baseUrl, params, extent, size, projection) {
var scale = this.getScale(extent, size);
var baseParams = {
'OPERATION': this.useOverlay_ ? 'GETDYNAMICMAPOVERLAYIMAGE' : 'GETMAPIMAGE',
'VERSION': '2.0.0',
'LOCALE': 'en',
'CLIENTAGENT': 'ol.source.MapGuide source',
'CLIP': '1',
'SETDISPLAYDPI': 96,
'SETDISPLAYWIDTH': Math.round(size[0]),
'SETDISPLAYHEIGHT': Math.round(size[1]),
'SETVIEWSCALE': scale,
'SETVIEWCENTERX': (extent[0] + extent[2]) / 2,
'SETVIEWCENTERY': (extent[1] + extent[3]) / 2
};
goog.object.extend(baseParams, params);
return goog.uri.utils.appendParamsFromMap(baseUrl, baseParams);
};