source: Dev/branches/rest-dojo-ui/client/dojox/geo/openlayers/Map.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 17.1 KB
Line 
1define(["dojo/_base/kernel",
2                                "dojo/_base/declare",
3                                "dojo/_base/lang",
4                                "dojo/_base/array",
5                                "dojo/_base/json",
6                                "dojo/_base/html",
7                                "dojox/main",
8                                "dojox/geo/openlayers/TouchInteractionSupport",
9                                "dojox/geo/openlayers/Layer",
10                                "dojox/geo/openlayers/Patch"], function(dojo, declare, lang, array, json, html, dojox, TouchInteractionSupport,
11                                                                                                                                                                                                Layer, Patch){
12
13        dojo.experimental("dojox.geo.openlayers.Map");
14
15        lang.getObject("geo.openlayers", true, dojox);
16
17        dojox.geo.openlayers.BaseLayerType = {
18                //      summary:
19                //              Defines the base layer types to be used at Map construction time or
20                //              with the setBaseLayerType function.
21                //      description:
22                //              This object defines the base layer types to be used at Map construction
23                //              time or with the setBaseLayerType function.
24                //      OSM: String
25                //              The Open Street Map base layer type selector.
26                OSM : "OSM",
27                //      WMS: String
28                //              The Web Map Server base layer type selector.
29                WMS : "WMS",
30                //      GOOGLE: String
31                //              The Google base layer type selector.
32                GOOGLE : "Google",
33                //      VIRTUAL_EARTH: String
34                //              The Virtual Earth base layer type selector.
35                VIRTUAL_EARTH : "VirtualEarth",
36                //      BING: String
37                //              Same as Virtual Earth
38                BING : "VirtualEarth",
39                //      YAHOO: String
40                //              The Yahoo base layer type selector.
41                YAHOO : "Yahoo",
42                //      ARCGIS: String
43                //              The ESRI ARCGis base layer selector.
44                ARCGIS : "ArcGIS"
45        };
46
47        dojox.geo.openlayers.EPSG4326 = new OpenLayers.Projection("EPSG:4326");
48
49        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;
50        dojox.geo.openlayers.parseDMS = function(v, toDecimal){
51                //      summary:
52                //              Parses the specified string and returns degree minute second or decimal degree.
53                //      description:
54                //              Parses the specified string and returns degree minute second or decimal degree.
55                //      v: String
56                //              The string to parse
57                //      toDecimal: Boolean
58                //              Specifies if the result should be returned in decimal degrees or in an array
59                //              containg the degrees, minutes, seconds values.
60                //      returns: Float | Array
61                //              the parsed value in decimal degrees or an array containing the degrees, minutes, seconds values.
62
63                var res = re.exec(v);
64                if (res == null || res.length < 5)
65                        return parseFloat(v);
66                var d = parseFloat(res[1]);
67                var m = parseFloat(res[2]);
68                var s = parseFloat(res[3]);
69                var nsew = res[5];
70                if (toDecimal) {
71                        var lc = nsew.toLowerCase();
72                        var dd = d + (m + s / 60.0) / 60.0;
73                        if (lc == "w" || lc == "s")
74                                dd = -dd;
75                        return dd;
76                }
77                return [d, m, s, nsew];
78        };
79
80        Patch.patchGFX();
81
82        return declare("dojox.geo.openlayers.Map", null, {
83                //      summary:
84                //              A map viewer based on the OpenLayers library.
85                //
86                //      description:
87                //              The `dojox.geo.openlayers.Map` object allows to view maps from various map providers.
88                //              It encapsulates  an `OpenLayers.Map` object on which most operations are delegated.
89                //              GFX layers can be added to display GFX georeferenced shapes as well as Dojo widgets.
90                //              Parameters can be passed as argument at construction time to define the base layer
91                //              type and the base layer parameters such as url or options depending on the type
92                //              specified. These parameters can be any of :
93                //      <br />
94                //      _baseLayerType_: type of the base layer. Can be any of
95                //     
96                //      * `dojox.geo.openlayers.BaseLayerType.OSM`: Open Street Map base layer
97                //      * `dojox.geo.openlayers.BaseLayerType.WMS`: Web Map Service layer
98                //      * `dojox.geo.openlayers.BaseLayerType.GOOGLE`: Google layer
99                //      * `dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH`: Virtual Earth layer
100                //      * `dojox.geo.openlayers.BaseLayerType.BING`: Bing layer
101                //      * `dojox.geo.openlayers.BaseLayerType.YAHOO`: Yahoo layer
102                //      * `dojox.geo.openlayers.BaseLayerType.ARCGIS`: ESRI ArgGIS layer
103                //
104                //      Note that access to commercial server such as Google, Virtual Earth or Yahoo may need specific licencing.
105                //
106                //      The parameters value also include :
107                //
108                //      * `baseLayerName`: The name of the base layer.
109                //      * `baseLayerUrl`: Some layer may need an url such as Web Map Server
110                //      * `baseLayerOptions`: Addtional specific options passed to OpensLayers layer, 
111                //      such as The list of layer to display, for Web Map Server layer.
112                //
113                //      example:
114                //
115                //      |       var map = new dojox.geo.openlayers.widget.Map(div, {
116                //      |               baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM,
117                //      |               baseLayerName : 'Open Street Map Layer'
118                //      |       });
119
120                //      summary:
121                //              The underlying OpenLayers.Map object.
122                //              Should be accessed on read mode only.
123                olMap : null,
124
125                _tp : null,
126
127                constructor : function(div, options){
128                        //      summary:
129                        //              Constructs a new Map object
130                        if (!options)
131                                options = {};
132
133                        div = html.byId(div);
134
135                        this._tp = {
136                                x : 0,
137                                y : 0
138                        };
139
140                        var opts = options.openLayersMapOptions;
141
142                        if (!opts) {
143                                opts = {
144                                        controls : [new OpenLayers.Control.ScaleLine({
145                                                maxWidth : 200
146                                        }), new OpenLayers.Control.Navigation()]
147                                };
148                        }
149                        if (options.accessible) {
150                                var kbd = new OpenLayers.Control.KeyboardDefaults();
151                                if (!opts.controls)
152                                        opts.controls = [];
153                                opts.controls.push(kbd);
154                        }
155                        var baseLayerType = options.baseLayerType;
156                        if (!baseLayerType)
157                                baseLayerType = dojox.geo.openlayers.BaseLayerType.OSM;
158
159                        html.style(div, {
160                                width : "100%",
161                                height : "100%",
162                                dir : "ltr"
163                        });
164
165                        var map = new OpenLayers.Map(div, opts);
166                        this.olMap = map;
167
168                        this._layerDictionary = {
169                                olLayers : [],
170                                layers : []
171                        };
172
173                        if (options.touchHandler)
174                                this._touchControl = new TouchInteractionSupport(map);
175
176                        var base = this._createBaseLayer(options);
177                        this.addLayer(base);
178
179                        this.initialFit(options);
180                },
181
182                initialFit : function(params){
183                        var o = params.initialLocation;
184                        if (!o)
185                                o = [-160, 70, 160, -70];
186                        this.fitTo(o);
187                },
188
189                setBaseLayerType : function(
190                /* dojox.geo.openlayers.Map.BaseLayerType */type){
191                        //      summary:
192                        //              Set the base layer type, replacing the existing base layer
193                        //      type: dojox.geo.openlayers.BaseLayerType
194                        //              base layer type
195                        //      returns: OpenLayers.Layer
196                        //              The newly created layer.
197                        if (type == this.baseLayerType)
198                                return null;
199
200                        var o = null;
201                        if (typeof type == "string") {
202                                o = {
203                                        baseLayerName : type,
204                                        baseLayerType : type
205                                };
206                                this.baseLayerType = type;
207                        } else if (typeof type == "object") {
208                                o = type;
209                                this.baseLayerType = o.baseLayerType;
210                        }
211                        var bl = null;
212                        if (o != null) {
213                                bl = this._createBaseLayer(o);
214                                if (bl != null) {
215                                        var olm = this.olMap;
216                                        var ob = olm.getZoom();
217                                        var oc = olm.getCenter();
218                                        var recenter = !!oc && !!olm.baseLayer && !!olm.baseLayer.map;
219
220                                        if (recenter) {
221                                                var proj = olm.getProjectionObject();
222                                                if (proj != null)
223                                                        oc = oc.transform(proj, dojox.geo.openlayers.EPSG4326);
224                                        }
225                                        var old = olm.baseLayer;
226                                        if (old != null) {
227                                                var l = this._getLayer(old);
228                                                this.removeLayer(l);
229                                        }
230                                        if (bl != null)
231                                                this.addLayer(bl);
232                                        if (recenter) {
233                                                proj = olm.getProjectionObject();
234                                                if (proj != null)
235                                                        oc = oc.transform(dojox.geo.openlayers.EPSG4326, proj);
236                                                olm.setCenter(oc, ob);
237                                        }
238                                }
239                        }
240                        return bl;
241                },
242
243                getBaseLayerType : function(){
244                        //      summary:
245                        //              Retrieves the base layer type.
246                        //      returns: dojox.geo.openlayers.BaseLayerType
247                        //              The current base layer type.
248                        return this.baseLayerType;
249                },
250
251                getScale : function(geodesic){
252                        //      summary:
253                        //              Returns the current scale
254                        //      geodesic: Boolean
255                        //              Tell if geodesic calculation should be performed. If set to
256                        //              true, the scale will be calculated based on the horizontal size of the
257                        //              pixel in the center of the map viewport.
258                        //      returns: Number
259                        //              The current scale.
260                        var scale;
261                        var om = this.olMap;
262                        if (geodesic) {
263                                var units = om.getUnits();
264                                if (!units) {
265                                        return null;
266                                }
267                                var inches = OpenLayers.INCHES_PER_UNIT;
268                                scale = (om.getGeodesicPixelSize().w || 0.000001) * inches["km"] * OpenLayers.DOTS_PER_INCH;
269                        } else {
270                                scale = om.getScale();
271                        }
272                        return scale;
273                },
274
275                getOLMap : function(){
276                        //      summary:
277                        //              gets the underlying OpenLayers map object.
278                        //      returns : OpenLayers.Map
279                        //              The underlying OpenLayers map object.
280                        return this.olMap;
281                },
282
283                _createBaseLayer : function(params){
284                        //      summary:
285                        //              Creates the base layer.
286                        //      tags:
287                        //              private
288                        var base = null;
289                        var type = params.baseLayerType;
290                        var url = params.baseLayerUrl;
291                        var name = params.baseLayerName;
292                        var options = params.baseLayerOptions;
293
294                        if (!name)
295                                name = type;
296                        if (!options)
297                                options = {};
298                        switch (type) {
299                                case dojox.geo.openlayers.BaseLayerType.OSM:
300                                        options.transitionEffect = "resize";
301                                        //                              base = new OpenLayers.Layer.OSM(name, url, options);
302                                        base = new Layer(name, {
303                                                olLayer : new OpenLayers.Layer.OSM(name, url, options)
304                                        });
305                                break;
306                                case dojox.geo.openlayers.BaseLayerType.WMS:
307                                        if (!url) {
308                                                url = "http://labs.metacarta.com/wms/vmap0";
309                                                if (!options.layers)
310                                                        options.layers = "basic";
311                                        }
312                                        base = new Layer(name, {
313                                                olLayer : new OpenLayers.Layer.WMS(name, url, options, {
314                                                        transitionEffect : "resize"
315                                                })
316                                        });
317                                break;
318                                case dojox.geo.openlayers.BaseLayerType.GOOGLE:
319                                        base = new Layer(name, {
320                                                olLayer : new OpenLayers.Layer.Google(name, options)
321                                        });
322                                break;
323                                case dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH:
324                                        base = new Layer(name, {
325                                                olLayer : new OpenLayers.Layer.VirtualEarth(name, options)
326                                        });
327                                break;
328                                case dojox.geo.openlayers.BaseLayerType.YAHOO:
329                                        //                              base = new OpenLayers.Layer.Yahoo(name);
330                                        base = new Layer(name, {
331                                                olLayer : new OpenLayers.Layer.Yahoo(name, options)
332                                        });
333                                break;
334                                case dojox.geo.openlayers.BaseLayerType.ARCGIS:
335                                        if (!url)
336                                                url = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/export";
337                                        base = new Layer(name, {
338                                                olLayer : new OpenLayers.Layer.ArcGIS93Rest(name, url, options, {})
339                                        });
340
341                                break;
342                        }
343
344                        if (base == null) {
345                                if (type instanceof OpenLayers.Layer)
346                                        base = type;
347                                else {
348                                        options.transitionEffect = "resize";
349                                        base = new Layer(name, {
350                                                olLayer : new OpenLayers.Layer.OSM(name, url, options)
351                                        });
352                                        this.baseLayerType = dojox.geo.openlayers.BaseLayerType.OSM;
353                                }
354                        }
355
356                        return base;
357                },
358
359                removeLayer : function(/* dojox.geo.openlayers.Layer */layer){
360                        //      summary:
361                        //              Remove the specified layer from the map.
362                        //      layer: dojox.geo.openlayers.Layer
363                        //              The layer to remove from the map.
364                        var om = this.olMap;
365                        var i = array.indexOf(this._layerDictionary.layers, layer);
366                        if (i > 0)
367                                this._layerDictionary.layers.splice(i, 1);
368                        var oll = layer.olLayer;
369                        var j = array.indexOf(this._layerDictionary.olLayers, oll);
370                        if (j > 0)
371                                this._layerDictionary.olLayers.splice(i, j);
372                        om.removeLayer(oll, false);
373                },
374
375                layerIndex : function(/* dojox.geo.openlayers.Layer */layer, index){
376                        //      summary:
377                        //              Set or retrieve the layer index.
378                        //      description:
379                        //              Set or get the layer index, that is the z-order of the layer.
380                        //              if the index parameter is provided, the layer index is set to
381                        //              this value. If the index parameter is not provided, the index of
382                        //              the layer is returned.
383                        //      index: undefined | int
384                        //              index of the layer
385                        //      returns: int
386                        //              the index of the layer.
387                        var olm = this.olMap;
388                        if (!index)
389                                return olm.getLayerIndex(layer.olLayer);
390                        //olm.raiseLayer(layer.olLayer, index);
391                        olm.setLayerIndex(layer.olLayer, index);
392
393                        this._layerDictionary.layers.sort(function(l1, l2){
394                                return olm.getLayerIndex(l1.olLayer) - olm.getLayerIndex(l2.olLayer);
395                        });
396                        this._layerDictionary.olLayers.sort(function(l1, l2){
397                                return olm.getLayerIndex(l1) - olm.getLayerIndex(l2);
398                        });
399
400                        return index;
401                },
402
403                addLayer : function(/* dojox.geo.openlayers.Layer */layer){
404                        //      summary:
405                        //              Add the specified layer to the map.
406                        //      layer: dojox.geo.openlayer.Layer
407                        //              The layer to add to the map.
408                        layer.dojoMap = this;
409                        var om = this.olMap;
410                        var ol = layer.olLayer;
411                        this._layerDictionary.olLayers.push(ol);
412                        this._layerDictionary.layers.push(layer);
413                        om.addLayer(ol);
414                        layer.added();
415                },
416
417                _getLayer : function(/*OpenLayer.Layer */ol){
418                        //      summary:
419                        //              Retrieve the dojox.geo.openlayer.Layer from the OpenLayer.Layer
420                        //      tags:
421                        //              private
422                        var i = array.indexOf(this._layerDictionary.olLayers, ol);
423                        if (i != -1)
424                                return this._layerDictionary.layers[i];
425                        return null;
426                },
427
428                getLayer : function(property, value){
429                        //      summary:
430                        //              Returns the layer whose property matches the value.
431                        //      property: String
432                        //              The property to check
433                        //      value: Object
434                        //              The value to match
435                        //      returns: dojox.geo.openlayer.Layer | Array
436                        //              The layer(s) matching the property's value. Since multiple layers
437                        //              match the property's value the return value is an array.
438                        //      example:
439                        //              var layers = map.getLayer("name", "Layer Name");
440                        var om = this.olMap;
441                        var ols = om.getBy("layers", property, value);
442                        var ret = new Array(); //[];
443                        array.forEach(ols, function(ol){
444                                ret.push(this._getLayer(ol));
445                        }, this);
446                        return ret;
447                },
448
449                getLayerCount : function(){
450                        //      summary:
451                        //              Returns the count of layers of this map.
452                        //      returns: int
453                        //              The number of layers of this map.
454                        var om = this.olMap;
455                        if (om.layers == null)
456                                return 0;
457                        return om.layers.length;
458                },
459
460                fitTo : function(o){
461                        //      summary:
462                        //              Fits the map on a point,or an area
463                        //      description:
464                        //              Fits the map on the point or extent specified as parameter.
465                        //      o: Object
466                        //              Object with key values fit parameters or a JSON string.
467                        //      example:
468                        //              Examples of arguments passed to the fitTo function :
469                        //      |       null
470                        //              The map is fit on full extent
471                        //
472                        //      |       {
473                        //      |       bounds : [ulx, uly, lrx, lry]
474                        //      |       }
475                        //              The map is fit on the specified bounds expressed as decimal degrees latitude and longitude.
476                        //              The bounds are defined with their upper left and lower right corners coordinates.
477                        //
478                        //      |       {
479                        //      |       position : [longitude, latitude],
480                        //      |       extent : degrees
481                        //      |       }
482                        //              The map is fit on the specified position showing the extent <extent> around
483                        //              the specified center position.
484
485                        var map = this.olMap;
486                        var from = dojox.geo.openlayers.EPSG4326;
487
488                        if (o == null) {
489                                var c = this.transformXY(0, 0, from);
490                                map.setCenter(new OpenLayers.LonLat(c.x, c.y));
491                                return;
492                        }
493                        var b = null;
494                        if (typeof o == "string")
495                                var j = json.fromJson(o);
496                        else
497                                j = o;
498                        var ul;
499                        var lr;
500                        if (j.hasOwnProperty("bounds")) {
501                                var a = j.bounds;
502                                b = new OpenLayers.Bounds();
503                                ul = this.transformXY(a[0], a[1], from);
504                                b.left = ul.x;
505                                b.top = ul.y;
506                                lr = this.transformXY(a[2], a[3], from);
507                                b.right = lr.x;
508                                b.bottom = lr.y;
509                        }
510                        if (b == null) {
511                                if (j.hasOwnProperty("position")) {
512                                        var p = j.position;
513                                        var e = j.hasOwnProperty("extent") ? j.extent : 1;
514                                        if (typeof e == "string")
515                                                e = parseFloat(e);
516                                        b = new OpenLayers.Bounds();
517                                        ul = this.transformXY(p[0] - e, p[1] + e, from);
518                                        b.left = ul.x;
519                                        b.top = ul.y;
520                                        lr = this.transformXY(p[0] + e, p[1] - e, from);
521                                        b.right = lr.x;
522                                        b.bottom = lr.y;
523                                }
524                        }
525                        if (b == null) {
526                                if (o.length == 4) {
527                                        b = new OpenLayers.Bounds();
528                                        // TODO Choose the correct method
529                                        if (false) {
530                                                b.left = o[0];
531                                                b.top = o[1];
532
533                                                b.right = o[2];
534                                                b.bottom = o[3];
535                                        } else {
536                                                ul = this.transformXY(o[0], o[1], from);
537                                                b.left = ul.x;
538                                                b.top = ul.y;
539                                                lr = this.transformXY(o[2], o[3], from);
540                                                b.right = lr.x;
541                                                b.bottom = lr.y;
542                                        }
543                                }
544                        }
545                        if (b != null) {
546                                map.zoomToExtent(b, true);
547                        }
548                },
549
550                transform : function(p, from, to){
551                        //      summary:
552                        //              Transforms the point passed as argument, expressed in the <em>from</em>
553                        //              coordinate system to the map coordinate system.
554                        //      description:
555                        //              Transforms the point passed as argument without modifying it. The point is supposed to be expressed
556                        //              in the <em>from</em> coordinate system and is transformed to the map coordinate system.
557                        //      p : Object {x, y}
558                        //              The point to transform
559                        //      from: OpenLayers.Projection
560                        //              The projection in which the point is expressed.
561                        return this.transformXY(p.x, p.y, from, to);
562                },
563
564                transformXY : function(x, y, from, to){
565                        //      summary
566                        //              Transforms the coordinates passed as argument, expressed in the <em>from</em>
567                        //              coordinate system to the map coordinate system.
568                        //      description:
569                        //              Transforms the coordinates passed as argument. The coordinate are supposed to be expressed
570                        //              in the <em>from</em> coordinate system and are transformed to the map coordinate system.
571                        //      x : Number
572                        //              The longitude coordinate to transform.
573                        //      y : Number
574                        //              The latitude coordinate to transform.
575                        //      from: OpenLayers.Projection
576                        //              The projection in which the point is expressed.
577
578                        var tp = this._tp;
579                        tp.x = x;
580                        tp.y = y;
581                        if (!from)
582                                from = dojox.geo.openlayers.EPSG4326;
583                        if (!to)
584                                to = this.olMap.getProjectionObject();
585                        tp = OpenLayers.Projection.transform(tp, from, to);
586                        return tp;
587                }
588
589        });
590
591});
Note: See TracBrowser for help on using the repository browser.