593 lines
17 KiB
JavaScript
593 lines
17 KiB
JavaScript
//>>built
|
|
define("dojox/geo/openlayers/Map", ["dojo/_base/kernel",
|
|
"dojo/_base/declare",
|
|
"dojo/_base/lang",
|
|
"dojo/_base/array",
|
|
"dojo/_base/json",
|
|
"dojo/_base/html",
|
|
"dojox/main",
|
|
"dojox/geo/openlayers/TouchInteractionSupport",
|
|
"dojox/geo/openlayers/Layer",
|
|
"dojox/geo/openlayers/Patch"], function(dojo, declare, lang, array, json, html, dojox, TouchInteractionSupport,
|
|
Layer, Patch){
|
|
|
|
dojo.experimental("dojox.geo.openlayers.Map");
|
|
|
|
lang.getObject("geo.openlayers", true, dojox);
|
|
|
|
dojox.geo.openlayers.BaseLayerType = {
|
|
// summary:
|
|
// Defines the base layer types to be used at Map construction time or
|
|
// with the setBaseLayerType function.
|
|
// description:
|
|
// This object defines the base layer types to be used at Map construction
|
|
// time or with the setBaseLayerType function.
|
|
// OSM: String
|
|
// The Open Street Map base layer type selector.
|
|
OSM : "OSM",
|
|
// WMS: String
|
|
// The Web Map Server base layer type selector.
|
|
WMS : "WMS",
|
|
// GOOGLE: String
|
|
// The Google base layer type selector.
|
|
GOOGLE : "Google",
|
|
// VIRTUAL_EARTH: String
|
|
// The Virtual Earth base layer type selector.
|
|
VIRTUAL_EARTH : "VirtualEarth",
|
|
// BING: String
|
|
// Same as Virtual Earth
|
|
BING : "VirtualEarth",
|
|
// YAHOO: String
|
|
// The Yahoo base layer type selector.
|
|
YAHOO : "Yahoo",
|
|
// ARCGIS: String
|
|
// The ESRI ARCGis base layer selector.
|
|
ARCGIS : "ArcGIS"
|
|
};
|
|
|
|
dojox.geo.openlayers.EPSG4326 = new OpenLayers.Projection("EPSG:4326");
|
|
|
|
var re = /^\s*(\d{1,3})[D°]\s*(\d{1,2})[M']\s*(\d{1,2}\.?\d*)\s*(S|"|'')\s*([NSEWnsew]{0,1})\s*$/i;
|
|
dojox.geo.openlayers.parseDMS = function(v, toDecimal){
|
|
// summary:
|
|
// Parses the specified string and returns degree minute second or decimal degree.
|
|
// description:
|
|
// Parses the specified string and returns degree minute second or decimal degree.
|
|
// v: String
|
|
// The string to parse
|
|
// toDecimal: Boolean
|
|
// Specifies if the result should be returned in decimal degrees or in an array
|
|
// containg the degrees, minutes, seconds values.
|
|
// returns: Float | Array
|
|
// the parsed value in decimal degrees or an array containing the degrees, minutes, seconds values.
|
|
|
|
var res = re.exec(v);
|
|
if (res == null || res.length < 5)
|
|
return parseFloat(v);
|
|
var d = parseFloat(res[1]);
|
|
var m = parseFloat(res[2]);
|
|
var s = parseFloat(res[3]);
|
|
var nsew = res[5];
|
|
if (toDecimal) {
|
|
var lc = nsew.toLowerCase();
|
|
var dd = d + (m + s / 60.0) / 60.0;
|
|
if (lc == "w" || lc == "s")
|
|
dd = -dd;
|
|
return dd;
|
|
}
|
|
return [d, m, s, nsew];
|
|
};
|
|
|
|
Patch.patchGFX();
|
|
|
|
return declare("dojox.geo.openlayers.Map", null, {
|
|
// summary:
|
|
// A map viewer based on the OpenLayers library.
|
|
//
|
|
// description:
|
|
// The `dojox.geo.openlayers.Map` object allows to view maps from various map providers.
|
|
// It encapsulates an `OpenLayers.Map` object on which most operations are delegated.
|
|
// GFX layers can be added to display GFX georeferenced shapes as well as Dojo widgets.
|
|
// Parameters can be passed as argument at construction time to define the base layer
|
|
// type and the base layer parameters such as url or options depending on the type
|
|
// specified. These parameters can be any of :
|
|
// <br />
|
|
// _baseLayerType_: type of the base layer. Can be any of
|
|
//
|
|
// * `dojox.geo.openlayers.BaseLayerType.OSM`: Open Street Map base layer
|
|
// * `dojox.geo.openlayers.BaseLayerType.WMS`: Web Map Service layer
|
|
// * `dojox.geo.openlayers.BaseLayerType.GOOGLE`: Google layer
|
|
// * `dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH`: Virtual Earth layer
|
|
// * `dojox.geo.openlayers.BaseLayerType.BING`: Bing layer
|
|
// * `dojox.geo.openlayers.BaseLayerType.YAHOO`: Yahoo layer
|
|
// * `dojox.geo.openlayers.BaseLayerType.ARCGIS`: ESRI ArgGIS layer
|
|
//
|
|
// Note that access to commercial server such as Google, Virtual Earth or Yahoo may need specific licencing.
|
|
//
|
|
// The parameters value also include :
|
|
//
|
|
// * `baseLayerName`: The name of the base layer.
|
|
// * `baseLayerUrl`: Some layer may need an url such as Web Map Server
|
|
// * `baseLayerOptions`: Addtional specific options passed to OpensLayers layer,
|
|
// such as The list of layer to display, for Web Map Server layer.
|
|
//
|
|
// example:
|
|
//
|
|
// | var map = new dojox.geo.openlayers.widget.Map(div, {
|
|
// | baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM,
|
|
// | baseLayerName : 'Open Street Map Layer'
|
|
// | });
|
|
|
|
// summary:
|
|
// The underlying OpenLayers.Map object.
|
|
// Should be accessed on read mode only.
|
|
olMap : null,
|
|
|
|
_tp : null,
|
|
|
|
constructor : function(div, options){
|
|
// summary:
|
|
// Constructs a new Map object
|
|
if (!options)
|
|
options = {};
|
|
|
|
div = html.byId(div);
|
|
|
|
this._tp = {
|
|
x : 0,
|
|
y : 0
|
|
};
|
|
|
|
var opts = options.openLayersMapOptions;
|
|
|
|
if (!opts) {
|
|
opts = {
|
|
controls : [new OpenLayers.Control.ScaleLine({
|
|
maxWidth : 200
|
|
}), new OpenLayers.Control.Navigation()]
|
|
};
|
|
}
|
|
if (options.accessible) {
|
|
var kbd = new OpenLayers.Control.KeyboardDefaults();
|
|
if (!opts.controls)
|
|
opts.controls = [];
|
|
opts.controls.push(kbd);
|
|
}
|
|
var baseLayerType = options.baseLayerType;
|
|
if (!baseLayerType)
|
|
baseLayerType = dojox.geo.openlayers.BaseLayerType.OSM;
|
|
|
|
html.style(div, {
|
|
width : "100%",
|
|
height : "100%",
|
|
dir : "ltr"
|
|
});
|
|
|
|
var map = new OpenLayers.Map(div, opts);
|
|
this.olMap = map;
|
|
|
|
this._layerDictionary = {
|
|
olLayers : [],
|
|
layers : []
|
|
};
|
|
|
|
if (options.touchHandler)
|
|
this._touchControl = new TouchInteractionSupport(map);
|
|
|
|
var base = this._createBaseLayer(options);
|
|
this.addLayer(base);
|
|
|
|
this.initialFit(options);
|
|
},
|
|
|
|
initialFit : function(params){
|
|
var o = params.initialLocation;
|
|
if (!o)
|
|
o = [-160, 70, 160, -70];
|
|
this.fitTo(o);
|
|
},
|
|
|
|
setBaseLayerType : function(
|
|
/* dojox.geo.openlayers.Map.BaseLayerType */type){
|
|
// summary:
|
|
// Set the base layer type, replacing the existing base layer
|
|
// type: dojox.geo.openlayers.BaseLayerType
|
|
// base layer type
|
|
// returns: OpenLayers.Layer
|
|
// The newly created layer.
|
|
if (type == this.baseLayerType)
|
|
return null;
|
|
|
|
var o = null;
|
|
if (typeof type == "string") {
|
|
o = {
|
|
baseLayerName : type,
|
|
baseLayerType : type
|
|
};
|
|
this.baseLayerType = type;
|
|
} else if (typeof type == "object") {
|
|
o = type;
|
|
this.baseLayerType = o.baseLayerType;
|
|
}
|
|
var bl = null;
|
|
if (o != null) {
|
|
bl = this._createBaseLayer(o);
|
|
if (bl != null) {
|
|
var olm = this.olMap;
|
|
var ob = olm.getZoom();
|
|
var oc = olm.getCenter();
|
|
var recenter = !!oc && !!olm.baseLayer && !!olm.baseLayer.map;
|
|
|
|
if (recenter) {
|
|
var proj = olm.getProjectionObject();
|
|
if (proj != null)
|
|
oc = oc.transform(proj, dojox.geo.openlayers.EPSG4326);
|
|
}
|
|
var old = olm.baseLayer;
|
|
if (old != null) {
|
|
var l = this._getLayer(old);
|
|
this.removeLayer(l);
|
|
}
|
|
if (bl != null)
|
|
this.addLayer(bl);
|
|
if (recenter) {
|
|
proj = olm.getProjectionObject();
|
|
if (proj != null)
|
|
oc = oc.transform(dojox.geo.openlayers.EPSG4326, proj);
|
|
olm.setCenter(oc, ob);
|
|
}
|
|
}
|
|
}
|
|
return bl;
|
|
},
|
|
|
|
getBaseLayerType : function(){
|
|
// summary:
|
|
// Retrieves the base layer type.
|
|
// returns: dojox.geo.openlayers.BaseLayerType
|
|
// The current base layer type.
|
|
return this.baseLayerType;
|
|
},
|
|
|
|
getScale : function(geodesic){
|
|
// summary:
|
|
// Returns the current scale
|
|
// geodesic: Boolean
|
|
// Tell if geodesic calculation should be performed. If set to
|
|
// true, the scale will be calculated based on the horizontal size of the
|
|
// pixel in the center of the map viewport.
|
|
// returns: Number
|
|
// The current scale.
|
|
var scale;
|
|
var om = this.olMap;
|
|
if (geodesic) {
|
|
var units = om.getUnits();
|
|
if (!units) {
|
|
return null;
|
|
}
|
|
var inches = OpenLayers.INCHES_PER_UNIT;
|
|
scale = (om.getGeodesicPixelSize().w || 0.000001) * inches["km"] * OpenLayers.DOTS_PER_INCH;
|
|
} else {
|
|
scale = om.getScale();
|
|
}
|
|
return scale;
|
|
},
|
|
|
|
getOLMap : function(){
|
|
// summary:
|
|
// gets the underlying OpenLayers map object.
|
|
// returns : OpenLayers.Map
|
|
// The underlying OpenLayers map object.
|
|
return this.olMap;
|
|
},
|
|
|
|
_createBaseLayer : function(params){
|
|
// summary:
|
|
// Creates the base layer.
|
|
// tags:
|
|
// private
|
|
var base = null;
|
|
var type = params.baseLayerType;
|
|
var url = params.baseLayerUrl;
|
|
var name = params.baseLayerName;
|
|
var options = params.baseLayerOptions;
|
|
|
|
if (!name)
|
|
name = type;
|
|
if (!options)
|
|
options = {};
|
|
switch (type) {
|
|
case dojox.geo.openlayers.BaseLayerType.OSM:
|
|
options.transitionEffect = "resize";
|
|
// base = new OpenLayers.Layer.OSM(name, url, options);
|
|
base = new Layer(name, {
|
|
olLayer : new OpenLayers.Layer.OSM(name, url, options)
|
|
});
|
|
break;
|
|
case dojox.geo.openlayers.BaseLayerType.WMS:
|
|
if (!url) {
|
|
url = "http://labs.metacarta.com/wms/vmap0";
|
|
if (!options.layers)
|
|
options.layers = "basic";
|
|
}
|
|
base = new Layer(name, {
|
|
olLayer : new OpenLayers.Layer.WMS(name, url, options, {
|
|
transitionEffect : "resize"
|
|
})
|
|
});
|
|
break;
|
|
case dojox.geo.openlayers.BaseLayerType.GOOGLE:
|
|
base = new Layer(name, {
|
|
olLayer : new OpenLayers.Layer.Google(name, options)
|
|
});
|
|
break;
|
|
case dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH:
|
|
base = new Layer(name, {
|
|
olLayer : new OpenLayers.Layer.VirtualEarth(name, options)
|
|
});
|
|
break;
|
|
case dojox.geo.openlayers.BaseLayerType.YAHOO:
|
|
// base = new OpenLayers.Layer.Yahoo(name);
|
|
base = new Layer(name, {
|
|
olLayer : new OpenLayers.Layer.Yahoo(name, options)
|
|
});
|
|
break;
|
|
case dojox.geo.openlayers.BaseLayerType.ARCGIS:
|
|
if (!url)
|
|
url = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/export";
|
|
base = new Layer(name, {
|
|
olLayer : new OpenLayers.Layer.ArcGIS93Rest(name, url, options, {})
|
|
});
|
|
|
|
break;
|
|
}
|
|
|
|
if (base == null) {
|
|
if (type instanceof OpenLayers.Layer)
|
|
base = type;
|
|
else {
|
|
options.transitionEffect = "resize";
|
|
base = new Layer(name, {
|
|
olLayer : new OpenLayers.Layer.OSM(name, url, options)
|
|
});
|
|
this.baseLayerType = dojox.geo.openlayers.BaseLayerType.OSM;
|
|
}
|
|
}
|
|
|
|
return base;
|
|
},
|
|
|
|
removeLayer : function(/* dojox.geo.openlayers.Layer */layer){
|
|
// summary:
|
|
// Remove the specified layer from the map.
|
|
// layer: dojox.geo.openlayers.Layer
|
|
// The layer to remove from the map.
|
|
var om = this.olMap;
|
|
var i = array.indexOf(this._layerDictionary.layers, layer);
|
|
if (i > 0)
|
|
this._layerDictionary.layers.splice(i, 1);
|
|
var oll = layer.olLayer;
|
|
var j = array.indexOf(this._layerDictionary.olLayers, oll);
|
|
if (j > 0)
|
|
this._layerDictionary.olLayers.splice(i, j);
|
|
om.removeLayer(oll, false);
|
|
},
|
|
|
|
layerIndex : function(/* dojox.geo.openlayers.Layer */layer, index){
|
|
// summary:
|
|
// Set or retrieve the layer index.
|
|
// description:
|
|
// Set or get the layer index, that is the z-order of the layer.
|
|
// if the index parameter is provided, the layer index is set to
|
|
// this value. If the index parameter is not provided, the index of
|
|
// the layer is returned.
|
|
// index: undefined | int
|
|
// index of the layer
|
|
// returns: int
|
|
// the index of the layer.
|
|
var olm = this.olMap;
|
|
if (!index)
|
|
return olm.getLayerIndex(layer.olLayer);
|
|
//olm.raiseLayer(layer.olLayer, index);
|
|
olm.setLayerIndex(layer.olLayer, index);
|
|
|
|
this._layerDictionary.layers.sort(function(l1, l2){
|
|
return olm.getLayerIndex(l1.olLayer) - olm.getLayerIndex(l2.olLayer);
|
|
});
|
|
this._layerDictionary.olLayers.sort(function(l1, l2){
|
|
return olm.getLayerIndex(l1) - olm.getLayerIndex(l2);
|
|
});
|
|
|
|
return index;
|
|
},
|
|
|
|
addLayer : function(/* dojox.geo.openlayers.Layer */layer){
|
|
// summary:
|
|
// Add the specified layer to the map.
|
|
// layer: dojox.geo.openlayer.Layer
|
|
// The layer to add to the map.
|
|
layer.dojoMap = this;
|
|
var om = this.olMap;
|
|
var ol = layer.olLayer;
|
|
this._layerDictionary.olLayers.push(ol);
|
|
this._layerDictionary.layers.push(layer);
|
|
om.addLayer(ol);
|
|
layer.added();
|
|
},
|
|
|
|
_getLayer : function(/*OpenLayer.Layer */ol){
|
|
// summary:
|
|
// Retrieve the dojox.geo.openlayer.Layer from the OpenLayer.Layer
|
|
// tags:
|
|
// private
|
|
var i = array.indexOf(this._layerDictionary.olLayers, ol);
|
|
if (i != -1)
|
|
return this._layerDictionary.layers[i];
|
|
return null;
|
|
},
|
|
|
|
getLayer : function(property, value){
|
|
// summary:
|
|
// Returns the layer whose property matches the value.
|
|
// property: String
|
|
// The property to check
|
|
// value: Object
|
|
// The value to match
|
|
// returns: dojox.geo.openlayer.Layer | Array
|
|
// The layer(s) matching the property's value. Since multiple layers
|
|
// match the property's value the return value is an array.
|
|
// example:
|
|
// var layers = map.getLayer("name", "Layer Name");
|
|
var om = this.olMap;
|
|
var ols = om.getBy("layers", property, value);
|
|
var ret = new Array(); //[];
|
|
array.forEach(ols, function(ol){
|
|
ret.push(this._getLayer(ol));
|
|
}, this);
|
|
return ret;
|
|
},
|
|
|
|
getLayerCount : function(){
|
|
// summary:
|
|
// Returns the count of layers of this map.
|
|
// returns: int
|
|
// The number of layers of this map.
|
|
var om = this.olMap;
|
|
if (om.layers == null)
|
|
return 0;
|
|
return om.layers.length;
|
|
},
|
|
|
|
fitTo : function(o){
|
|
// summary:
|
|
// Fits the map on a point,or an area
|
|
// description:
|
|
// Fits the map on the point or extent specified as parameter.
|
|
// o: Object
|
|
// Object with key values fit parameters or a JSON string.
|
|
// example:
|
|
// Examples of arguments passed to the fitTo function :
|
|
// | null
|
|
// The map is fit on full extent
|
|
//
|
|
// | {
|
|
// | bounds : [ulx, uly, lrx, lry]
|
|
// | }
|
|
// The map is fit on the specified bounds expressed as decimal degrees latitude and longitude.
|
|
// The bounds are defined with their upper left and lower right corners coordinates.
|
|
//
|
|
// | {
|
|
// | position : [longitude, latitude],
|
|
// | extent : degrees
|
|
// | }
|
|
// The map is fit on the specified position showing the extent <extent> around
|
|
// the specified center position.
|
|
|
|
var map = this.olMap;
|
|
var from = dojox.geo.openlayers.EPSG4326;
|
|
|
|
if (o == null) {
|
|
var c = this.transformXY(0, 0, from);
|
|
map.setCenter(new OpenLayers.LonLat(c.x, c.y));
|
|
return;
|
|
}
|
|
var b = null;
|
|
if (typeof o == "string")
|
|
var j = json.fromJson(o);
|
|
else
|
|
j = o;
|
|
var ul;
|
|
var lr;
|
|
if (j.hasOwnProperty("bounds")) {
|
|
var a = j.bounds;
|
|
b = new OpenLayers.Bounds();
|
|
ul = this.transformXY(a[0], a[1], from);
|
|
b.left = ul.x;
|
|
b.top = ul.y;
|
|
lr = this.transformXY(a[2], a[3], from);
|
|
b.right = lr.x;
|
|
b.bottom = lr.y;
|
|
}
|
|
if (b == null) {
|
|
if (j.hasOwnProperty("position")) {
|
|
var p = j.position;
|
|
var e = j.hasOwnProperty("extent") ? j.extent : 1;
|
|
if (typeof e == "string")
|
|
e = parseFloat(e);
|
|
b = new OpenLayers.Bounds();
|
|
ul = this.transformXY(p[0] - e, p[1] + e, from);
|
|
b.left = ul.x;
|
|
b.top = ul.y;
|
|
lr = this.transformXY(p[0] + e, p[1] - e, from);
|
|
b.right = lr.x;
|
|
b.bottom = lr.y;
|
|
}
|
|
}
|
|
if (b == null) {
|
|
if (o.length == 4) {
|
|
b = new OpenLayers.Bounds();
|
|
// TODO Choose the correct method
|
|
if (false) {
|
|
b.left = o[0];
|
|
b.top = o[1];
|
|
|
|
b.right = o[2];
|
|
b.bottom = o[3];
|
|
} else {
|
|
ul = this.transformXY(o[0], o[1], from);
|
|
b.left = ul.x;
|
|
b.top = ul.y;
|
|
lr = this.transformXY(o[2], o[3], from);
|
|
b.right = lr.x;
|
|
b.bottom = lr.y;
|
|
}
|
|
}
|
|
}
|
|
if (b != null) {
|
|
map.zoomToExtent(b, true);
|
|
}
|
|
},
|
|
|
|
transform : function(p, from, to){
|
|
// summary:
|
|
// Transforms the point passed as argument, expressed in the <em>from</em>
|
|
// coordinate system to the map coordinate system.
|
|
// description:
|
|
// Transforms the point passed as argument without modifying it. The point is supposed to be expressed
|
|
// in the <em>from</em> coordinate system and is transformed to the map coordinate system.
|
|
// p : Object {x, y}
|
|
// The point to transform
|
|
// from: OpenLayers.Projection
|
|
// The projection in which the point is expressed.
|
|
return this.transformXY(p.x, p.y, from, to);
|
|
},
|
|
|
|
transformXY : function(x, y, from, to){
|
|
// summary
|
|
// Transforms the coordinates passed as argument, expressed in the <em>from</em>
|
|
// coordinate system to the map coordinate system.
|
|
// description:
|
|
// Transforms the coordinates passed as argument. The coordinate are supposed to be expressed
|
|
// in the <em>from</em> coordinate system and are transformed to the map coordinate system.
|
|
// x : Number
|
|
// The longitude coordinate to transform.
|
|
// y : Number
|
|
// The latitude coordinate to transform.
|
|
// from: OpenLayers.Projection
|
|
// The projection in which the point is expressed.
|
|
|
|
var tp = this._tp;
|
|
tp.x = x;
|
|
tp.y = y;
|
|
if (!from)
|
|
from = dojox.geo.openlayers.EPSG4326;
|
|
if (!to)
|
|
to = this.olMap.getProjectionObject();
|
|
tp = OpenLayers.Projection.transform(tp, from, to);
|
|
return tp;
|
|
}
|
|
|
|
});
|
|
|
|
});
|