//>>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 : //
// _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 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 from // 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 from 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 from // coordinate system to the map coordinate system. // description: // Transforms the coordinates passed as argument. The coordinate are supposed to be expressed // in the from 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; } }); });