Project

General

Profile

Download (21.3 KB) Statistics
| Branch: | Tag: | Revision:
1
//see also https://github.com/geetarista/jquery-plugin-template/blob/master/jquery.plugin-template.js
2

    
3
/**
4
 * Expected dom structure:
5
 *  '<div class="ahah-content" rel="'.$cdm_proxy_url.'"><span class="loading">Loading ....</span></div>';
6
 */
7
(function($, document, window, undefined) {
8

    
9
  $.fn.cdm_openlayers_map = function(mapserverBaseUrl, mapserverVersion, options) {
10

    
11
    var opts = $.extend({},$.fn.cdm_openlayers_map.defaults, options);
12

    
13
    return this.each(function(){
14
      this.cdmOpenlayersMap = new CdmOpenLayers.Map($(this), mapserverBaseUrl, mapserverVersion, opts);
15
      this.cdmOpenlayersMap.init();
16
     }); // END each
17

    
18
  }; // END cdm_openlayers_map
19

    
20
})(jQuery, document, window, undefined);
21

    
22
(function($){
23
    $.fn.cdm_openlayers_map.defaults = {  // set up default options
24
        legendPosition:  null,      // 1,2,3,4,5,6 = display a legend in the corner specified by the number
25
        distributionOpacity: 0.75,
26
        legendOpacity: 0.75,
27
        boundingBox: "-180,-90,180,90",
28
        showLayerSwitcher: false,
29
        baseLayerNames: ["osgeo_vmap0"],
30
        defaultBaseLayerName: 'osgeo_vmap0',
31
        maxZoom: 4,
32
        minZoom: 0,
33
        /**
34
         * allows the map to display parts of the layers which are outside
35
         * the maxExtent if the aspect ratio of the map and of the baselayer
36
         * are not equal
37
         */
38
        displayOutsideMaxExtent: true,
39
        customWMSBaseLayerData: {
40
            name: "Euro+Med",
41
            url: "http://edit.africamuseum.be/geoserver/topp/wms",
42
            params: {layers: "topp:em_tiny_jan2003", format:"image/png", tiled: true},
43
            projection: "EPSG:7777777",
44
            maxExtent: "-1600072.75, -1800000, 5600000, 5850093",
45
            unit: 'm'
46
        }
47
    };
48
})(jQuery);
49

    
50

    
51

    
52
/**************************************************************************
53
 *                          CdmOpenLayers
54
 **************************************************************************/
55
(function() {
56

    
57
/**
58
 * The CdmOpenLayers namespace definition
59
 */
60
window.CdmOpenLayers  = (function () {
61

    
62
    var projections = {
63
            epsg_4326: new OpenLayers.Projection("EPSG:4326"),
64
            epsg_900913: new OpenLayers.Projection("EPSG:900913"),
65
            epsg_3857:  new OpenLayers.Projection("EPSG:3857")
66
    };
67
    var mapExtends = {
68
        epsg_4326: new OpenLayers.Bounds(-180, -90, 180, 90),
69
        epsg_900913: new OpenLayers.Bounds(-180, -90, 180, 90),
70
        epsg_3857: new OpenLayers.Bounds(-180, -90, 180, 90)
71
    };
72
    // transform epsg_900913 to units meter
73
    mapExtends.epsg_900913.transform(projections.epsg_4326, projections.epsg_900913);
74
    mapExtends.epsg_3857.transform(projections.epsg_4326, projections.epsg_3857);
75

    
76
    // make public by returning an object
77
    return {
78
            projections: projections,
79
            mapExtends: mapExtends,
80
            getLayerByName: function(layerName){} // initially empty fuction, will be populated by openlayers_layers.js
81
    };
82

    
83
})(); // end of namespace definition for CdmOpenLayers
84

    
85
  /**
86
   * The CdmOpenLayers.Map constructor
87
   * @param mapElement
88
   * @param mapserverBaseUrl
89
   * @param mapserverVersion
90
   * @param options
91
   * @returns
92
   */
93
window.CdmOpenLayers.Map = function(mapElement, mapserverBaseUrl, mapserverVersion, options){
94

    
95
    var mapServicePath = '/edit_wp5';
96

    
97
    // firebug console stub (avoids errors if firebug is not active)
98
    if(typeof console === "undefined") {
99
        console = { log: function() { } };
100
    }
101

    
102

    
103
    var legendImgSrc = null;
104

    
105
    var map = null;
106

    
107
    var infoElement = null;
108

    
109
    var dataBounds = null;
110

    
111
    var baseLayers = [];
112
    var defaultBaseLayer = null;
113

    
114
    var mapHeight = mapElement.height();
115
    var mapWidth = mapElement.width();
116

    
117
    var defaultControls = [
118
             new OpenLayers.Control.PanZoom(),
119
             new OpenLayers.Control.Navigation({zoomWheelEnabled: false, handleRightClicks:true, zoomBoxKeyMask: OpenLayers.Handler.MOD_CTRL})
120
           ];
121

    
122
//    var dataProj = new OpenLayers.Projection("EPSG:4326");
123

    
124
    var dataLayerOptions = {
125
        isBaseLayer: false,
126
        displayInLayerSwitcher: true
127
    };
128

    
129
    var layerByNameMap = {
130
        tdwg1: 'topp:tdwg_level_1',
131
        tdwg2: 'topp:tdwg_level_2',
132
        tdwg3: 'topp:tdwg_level_3',
133
        tdwg4: 'topp:tdwg_level_4'
134
    };
135

    
136
    /**
137
     *
138
     */
139
    this.init = function(){ // public function
140

    
141
      createLayers(options.baseLayerNames, options.defaultBaseLayerName, options.customWMSBaseLayerData);
142

    
143
      initMap();
144

    
145
      // -- Distribution Layer --
146
      var mapServiceRequest;
147
      var distributionQuery = mapElement.attr('distributionQuery');
148

    
149
      if(distributionQuery !== undefined){
150
        if(typeof legendPosition == 'number'){
151
          distributionQuery = mergeQueryStrings(distributionQuery, 'legend=1&mlp=' + options.legendPosition);
152
        }
153

    
154
        distributionQuery = mergeQueryStrings(distributionQuery, 'callback=?');
155
        var legendFormatQuery = mapElement.attr('legendFormatQuery');
156
        if(legendFormatQuery !== undefined){
157
          legendImgSrc = mergeQueryStrings('/GetLegendGraphic?SERVICE=WMS&VERSION=1.1.1', legendFormatQuery);
158
        }
159

    
160
        mapServiceRequest = mapserverBaseUrl + mapServicePath + '/' + mapserverVersion + '/areas.php?' + distributionQuery;
161

    
162
        jQuery.ajax({
163
            url: mapServiceRequest,
164
            dataType: "jsonp",
165
            success: function(data){
166
              addDataLayer(data);
167
            }
168
          });
169
      }
170

    
171
      // -- Occurrence Layer --
172
      var occurrenceQuery = mapElement.attr('occurrenceQuery');
173
      if(occurrenceQuery !== undefined){
174
//        if(typeof legendPosition == 'number'){
175
//          occurrenceQuery = mergeQueryStrings(distributionQuery, 'legend=1&mlp=' + options.legendPosition);
176
//        }
177

    
178
        occurrenceQuery = mergeQueryStrings(occurrenceQuery, 'callback=?');
179
//        var legendFormatQuery = mapElement.attr('legendFormatQuery');
180
//        if(legendFormatQuery !== undefined){
181
//          legendImgSrc = mergeQueryStrings('/GetLegendGraphic?SERVICE=WMS&VERSION=1.1.1', legendFormatQuery);
182
//        }
183

    
184
        mapServiceRequest = mapserverBaseUrl + mapServicePath + '/' + mapserverVersion + '/points.php?' + occurrenceQuery;
185

    
186
        jQuery.ajax({
187
            url: mapServiceRequest,
188
            dataType: "jsonp",
189
            success: function(data){
190
              addDataLayer(data);
191
            }
192
          });
193
      }
194

    
195

    
196
    };
197

    
198
    /**
199
     * public function
200
     */
201
    this.registerEvents = function(events){
202
        for (var key in events) {
203
            if (events.hasOwnProperty(key)) {
204
                map.events.register(key, map , events[key]);
205
            }
206
        }
207
    };
208

    
209
    /**
210
     * public function
211
     */
212
    this.getMap = function(){
213
        return map;
214
    };
215

    
216
    /**
217
     * Prints info on the current map into the jQuery element
218
     * as set in the options (options.infoElement)
219
     * public function
220
     *
221
     * @param jQuery $element
222
     */
223
    this.printInfo = function(){
224

    
225
        var mapExtendDegree = map.getExtent().clone();
226
        mapExtendDegree.transform(map.baseLayer.projection, CdmOpenLayers.projections.epsg_4326);
227

    
228
        var info = "<dl>";
229
        info += "<dt>zoom:<dt><dd>" + map.getZoom() + "</dd>";
230
        info += "<dt>map resolution:<dt><dd>" + map.getResolution() + "</dd>";
231
        info += "<dt>map max resolution:<dt><dd>" + map.getMaxResolution() + "</dd>";
232
        info += "<dt>map scale:<dt><dd>" + map.getScale() + "</dd>";
233
        info += "<dt>map extent bbox:<dt><dd>" + map.getExtent().toBBOX() + " (" + mapExtendDegree.toBBOX() + ")</dd>";
234
        info += "<dt>map maxExtent bbox:<dt><dd>" + map.getMaxExtent().toBBOX() + "</dd>";
235
        info += "<dt>baselayer projection:<dt><dd>" + map.baseLayer.projection.getCode() + "</dd>";
236
        info += "</dl>";
237

    
238
        if(infoElement == null){
239
            infoElement = jQuery('<div class="map_info"></div>');
240
            mapElement.parent().after(infoElement);
241
        }
242
        infoElement.html(info);
243
    };
244

    
245
    /**
246
     * Initialize the Openlayers Map with the base layer
247
     */
248
    var initMap = function(){
249

    
250

    
251
      if(options.showLayerSwitcher === true){
252
          defaultControls.push(new OpenLayers.Control.LayerSwitcher({'ascending':false}));
253
      }
254

    
255
//      var maxExtentByAspectRatio = cropBoundsToAspectRatio(defaultBaseLayer.maxExtent, mapWidth/mapHeight);
256
      var maxResolution = null;
257
      // gmaps has no maxExtent at this point, need to check for null
258
      if(defaultBaseLayer.maxExtent != null){
259
          maxResolution = Math[(options.displayOutsideMaxExtent ? 'max' : 'min')](
260
                      defaultBaseLayer.maxExtent.getWidth() / mapWidth,
261
                      defaultBaseLayer.maxExtent.getHeight() / mapHeight
262
                    );
263
      }
264
      console.log("mapOptions.maxResolution: " + maxResolution);
265
      console.log("mapOptions.restrictedExtent: " + defaultBaseLayer.maxExtent);
266

    
267
      map = new OpenLayers.Map(
268
          "openlayers_map",
269
          {
270
              // defines the map ui elements and interaction features
271
              controls: defaultControls,
272

    
273
              // maxResolution determines the lowest zoom level and thus places the map
274
              // in its maximum extent into the available view port so that no additinal
275
              // gutter is visible and no parts of the map are hidden
276
              // see http://trac.osgeo.org/openlayers/wiki/SettingZoomLevels
277
              // IMPORTANT!!!
278
              // the maxResulution set here will be overwritten if the baselayers maxResolution
279
              // it is set
280
              maxResolution: maxResolution,
281

    
282
              // setting restrictedExtent the the maxExtent prevents from panning the
283
              // map out of its bounds
284
              restrictedExtent: defaultBaseLayer.maxExtent,
285
//              maxExtent: defaultBaseLayer.maxExtent,
286

    
287
             // Setting the map.fractionalZoom property to true allows zooming to an arbitrary level
288
             // (between the min and max resolutions).
289
             // fractional tiles are not supported by XYZ layers like OSM so this option would
290
             // however break the tile retrieval for OSM (e.g.: tile for frational zoom level
291
             // 1.2933333333333332 = http://b.tile.openstreetmap.org/1.2933333333333332/1/0.png)
292
             // fractionalZoom: 1,
293

    
294
              eventListeners: options.eventListeners
295

    
296
          }
297
      );
298

    
299
      //add the base layers
300
      map.addLayers(baseLayers);
301
      map.setBaseLayer(defaultBaseLayer);
302

    
303
      // calculate the bounds to zoom to
304
      zoomToBounds = zoomToBoundsFor(options.boundingBox, defaultBaseLayer);
305
      zoomToBounds = cropBoundsToAspectRatio(zoomToBounds, map.getSize().w / map.getSize().h);
306
      console.log("zoomToBounds: " + zoomToBounds);
307

    
308
      // zoom to the extent of the bbox
309
      map.zoomToExtent(zoomToBounds, true);
310

    
311
      // readjust if the zoom level is out side of the min max
312
//      if(map.getZoom() > options.maxZoom){
313
//        map.zoomTo(options.maxZoom);
314
//      } else if(map.getZoom() < options.minZoom){
315
//        map.zoomTo(options.minZoom);
316
//      }
317

    
318
    };
319

    
320
    /**
321
     * add a distribution layer
322
     */
323
    var addDataLayer = function(mapResponseObj){
324

    
325
      var layer;
326
      // add additional layers, get them from the mapResponseObj
327
      if(mapResponseObj !== undefined){
328
        if(mapResponseObj.points_sld !== undefined){
329
          // it is a response from the points.php
330

    
331
        var geoserverUri;
332
        if(mapResponseObj.geoserver) {
333
          geoserverUri = mapResponseObj.geoserver;
334
        } else {
335
          // it is an old servive which is not providing the corresponding geoserver URI, so we guess it
336
          geoserverUri = mapserverBaseUrl + "/geoserver/wms";
337
        }
338

    
339
        //TODO points_sld should be renamed to sld in response + fill path to sld should be given
340
          layer = new OpenLayers.Layer.WMS.Untiled(
341
              'points',
342
              geoserverUri,
343
              {layers: 'topp:rest_points' ,transparent:"true", format:"image/png"},
344
              dataLayerOptions );
345

    
346
          var sld = mapResponseObj.points_sld;
347
          if(sld.indexOf("http://") !== 0){
348
            // it is an old servive which is not providing the full sdl URI, so we guess it
349
            //  http://edit.africamuseum.be/synthesys/www/v1/sld/
350
            //  http://edit.br.fgov.be/synthesys/www/v1/sld/
351
            sld =  mapserverBaseUrl + "/synthesys/www/v1/sld/" + sld;
352

    
353
          }
354

    
355
          layer.params.SLD = sld;
356
          map.addLayers([layer]);
357

    
358
        } else {
359
          // it is a response from the areas.php
360
          for ( var i in mapResponseObj.layers) {
361
          var layerData = mapResponseObj.layers[i];
362

    
363
            layer = new OpenLayers.Layer.WMS(
364
                layerData.tdwg,
365
                mapResponseObj.geoserver + "/wms",
366
                {layers: layerByNameMap[layerData.tdwg] ,transparent:"true", format:"image/png"},
367
                dataLayerOptions );
368
            layer.params.SLD = layerData.sld;
369
            layer.setOpacity(options.distributionOpacity);
370
            map.addLayers([layer]);
371

    
372
          }
373

    
374
        }
375

    
376
        // zoom to the required area
377
        if(mapResponseObj.bbox !== undefined){
378
          var newBounds =  OpenLayers.Bounds.fromString( mapResponseObj.bbox );
379
          newBounds.transform(layer.projection, map.getProjectionObject());
380
          if(dataBounds !== null){
381
            dataBounds.extend(newBounds);
382
          } else if(newBounds !== undefined){
383
            dataBounds = newBounds;
384
          }
385
          map.zoomToExtent(dataBounds, false);
386

    
387
          if(map.getZoom() > options.maxZoom){
388
            map.zoomTo(options.maxZoom);
389
          } else if(map.getZoom() < options.minZoom){
390
            map.zoomTo(options.minZoom);
391
          }
392
        }
393

    
394

    
395
        if(options.legendPosition !== undefined && mapResponseObj.legend !== undefined){
396
          var legendSrcUrl = mapResponseObj.geoserver + legendImgSrc + mapResponseObj.legend;
397
          addLegendAsElement(legendSrcUrl);
398
          //addLegendAsLayer(legendSrcUrl, map);
399
        }
400
      }
401

    
402
    };
403

    
404
    /**
405
     *
406
     */
407
    var addLegendAsElement= function(legendSrcUrl){
408

    
409
      mapElement.after('<div class="openlayers_legend"><img src="' + legendSrcUrl + '"></div>');
410
      mapElement.next('.openlayers_legend').css('opacity', options.legendOpacity).find('img').load(function () {
411
        jQuery(this).parent()
412
          .css('position', 'relative')
413
          .css('z-index', '1002')
414
          .css('top', -mapElement.height())
415
          .css('left', mapElement.width()- jQuery(this).width())
416
          .width(jQuery(this).width());
417
      });
418
    };
419

    
420

    
421
    var addLegendAsLayer= function(legendSrcUrl, map){
422
      var w, h;
423

    
424
      // 1. download imge to find height and width
425
      mapElement.after('<div class="openlayers_legend"><img src="' + legendSrcUrl + '"></div>');
426
      mapElement.next('.openlayers_legend').css('display', 'none').css('opacity', options.legendOpacity).find('img').load(function () {
427

    
428
        w = mapElement.next('.openlayers_legend').find('img').width();
429
        h = mapElement.next('.openlayers_legend').find('img').height();
430
        mapElement.next('.openlayers_legend').remove();
431

    
432
//        createLegendLayer();
433
//        // 2. create the Legend Layer
434
        //TODO createLegendLayer as inner fiinction seems like an error
435
//        var createLegendLayer = function(){
436
  //
437
  //
438
//          var legendLayerOptions={
439
//              maxResolution: '.$maxRes.',
440
//              maxExtent: new OpenLayers.Bounds(0, 0, w, h)
441
//          };
442
  //
443
//          var legendLayer = new OpenLayers.Layer.Image(
444
//              'Legend',
445
//              legendSrcUrl,
446
//              new OpenLayers.Bounds(0, 0, w, h),
447
//              new OpenLayers.Size(w, h),
448
//              imageLayerOptions);
449
//        };
450
      });
451

    
452

    
453
    };
454

    
455
    /**
456
     * merge 2 Url query strings
457
     */
458
     var mergeQueryStrings = function(queryStr1, queryStr2){
459
      if(queryStr1.charAt(queryStr1.length - 1) != '&'){
460
        queryStr1 += '&';
461
      }
462
      if(queryStr2.charAt(0) == '&'){
463
        return queryStr1 + queryStr2.substr(1);
464
      } else {
465
        return queryStr1 + queryStr2;
466
      }
467

    
468
     };
469

    
470
     /**
471
      *
472
      */
473
     var createLayers = function( baseLayerNames, defaultBaseLayerName, customWMSBaseLayerData){
474
       var i = 0;
475
       for(; i <  baseLayerNames.length; i++) {
476
         baseLayers[i] = window.CdmOpenLayers.getLayerByName(baseLayerNames[i]);
477
         if(baseLayerNames[i] == defaultBaseLayerName){
478
           defaultBaseLayer = baseLayers[i];
479
         }
480
       }
481
       if(false && customWMSBaseLayerData){
482
            var wmsLayer = createWMSBaseLayer(
483
                   customWMSBaseLayerData.name,
484
                   customWMSBaseLayerData.url,
485
                   customWMSBaseLayerData.params,
486
                   customWMSBaseLayerData.projection,
487
                   customWMSBaseLayerData.unit,
488
                   OpenLayers.Bounds.fromString(customWMSBaseLayerData.maxExtent)
489
                );
490
           // FIXME remove HACK (customWMSBaseLayerData as default)
491
           baseLayers[i++] = wmsLayer;
492
           defaultBaseLayer = wmsLayer;
493
       }
494
     };
495

    
496
     /**
497
      * returns the intersction of the bounds b1 and b2.
498
      * The b1 and b2 do not intersect b1 will be returned.
499
      *
500
      * @param OpenLayers.Bounds b1
501
      * @param OpenLayers.Bounds b2
502
      *
503
      * @return the bounds of the intersection between both rectangles
504
      */
505
     var intersectionOfBounds = function (b1, b2){
506

    
507
         if(b1.intersectsBounds(b2)){
508

    
509
             var left = Math.max(b1.left, b2.left);
510
             var bottom = Math.max(b1.bottom, b2.bottom);
511
             var right = Math.min(b1.right, b2.right);
512
             var top = Math.min(b1.top, b2.top);
513

    
514
             return new OpenLayers.Bounds(left, bottom, right, top);
515

    
516
         } else {
517
             return b1;
518
         }
519
     };
520

    
521
     /**
522
      *
523
      * @param OpenLayers.Bounds b
524
      * @param float aspectRatio width/height
525
      *
526
      * @return the bounds croped to the given aspectRatio
527
      */
528
     var cropBoundsToAspectRatio = function (b, aspectRatio){
529

    
530
         var cropedB = b.clone();
531

    
532
         if(aspectRatio == 1){
533
             return cropedB;
534
         }
535

    
536
         /*
537
          * LonLat:
538
          *   lon {Float} The x-axis coodinate in map units
539
          *   lat {Float} The y-axis coordinate in map units
540
          */
541
         var center = cropedB.getCenterLonLat();
542
         if(aspectRatio < 1){
543
             var dist = (b.getHeight() / 2) * aspectRatio;
544
             cropedB.top = center.lat + dist;
545
             cropedB.cropedBottom = center.lat - dist;
546
         } else if(aspectRatio > 1){
547
             var dist = (b.getWidth() / 2) / aspectRatio;
548
             cropedB.left = center.lon - dist;
549
             cropedB.right = center.lon + dist;
550
         }
551
         return cropedB;
552
     };
553

    
554
     /**
555
      * returns the zoom to bounds.
556
      *
557
      * @param bboxString
558
      *     a string representation of the bounds in degree
559
      * @param layer
560
      *     the Openlayers.Layer
561
      *
562
      * @return the bboxstring projected onto the layer and intersected with the maximum extent of the layer
563
      */
564
     var zoomToBoundsFor = function(bboxString, layer){
565
         var zoomToBounds;
566
         if(typeof bboxString == 'string' && bboxString.length > 6) {
567
             zoomToBounds = OpenLayers.Bounds.fromString(bboxString);
568
             // transform bounding box given in degree values to the projection of the base layer
569
             zoomToBounds.transform(CdmOpenLayers.projections.epsg_4326, layer.projection);
570
         } else if(layer.maxExtent) {
571
             zoomToBounds = layer.maxExtent;
572
             // no need to transform since the bounds are obtained from the layer
573
         } else {
574
             zoomToBounds = new OpenLayers.Bounds(-180, -90, 180, 90);
575
             // transform bounding box given in degree values to the projection of the base layer
576
             zoomToBounds.transform(CdmOpenLayers.projections.epsg_4326, layer.projection);
577
         }
578

    
579
         zoomToBounds = intersectionOfBounds(layer.maxExtent, zoomToBounds);
580

    
581
         return zoomToBounds;
582
     };
583

    
584

    
585

    
586
     /**
587
      * returns the version number contained in the version string:
588
      *   v1.1 --> 1.1
589
      *   v1.2_dev --> 1.2
590
      */
591
     var mapServerVersionNumber = function() {
592
       var pattern = /v([\d\.]+).*$/;
593
       var result;
594
       if (result = mapserverVersion.match(pattern) !== null) {
595
         return result[0];
596
       } else {
597
         return null;
598
       }
599
     };
600

    
601
     /**
602
      * Creates a WMS Base layer
603
      * @param String name
604
      *     A name for the layer
605
      * @param String url
606
      *     Base url for the WMS (e.g.  http://wms.jpl.nasa.gov/wms.cgi)
607
      * @param Object params
608
      *     An object with key/value pairs representing the GetMap query string parameters and parameter values.
609
      * @param Object projection
610
      *    A OpenLayers.Projection object
611
      */
612
     var createWMSBaseLayer= function(name, url, params, projection, unit, maxExtent){
613

    
614
         if(maxExtent == null){
615
             maxExtent = CdmOpenLayers.mapExtends.epsg_4326.clone();
616
             maxExtent.transform(CdmOpenLayers.projections.epsg_4326, projection);
617
         }
618

    
619
         return  new OpenLayers.Layer.WMS(
620
                 name,
621
                 url,
622
                 params,
623
                 {
624
                   maxExtent: maxExtent,
625
                   projection: projection,
626
                   unit: unit,
627
                   isBaseLayer: true,
628
                   displayInLayerSwitcher: true
629
                 }
630
               );
631
     };
632

    
633
  }; // end of CdmOpenLayers.Map
634
})();
635

    
636

    
637

    
638

    
639

    
640

    
(2-2/2)