Project

General

Profile

« Previous | Next » 

Revision 753d936d

Added by Andreas Kohlbecker almost 8 years ago

fixing problems in openlayers maps with userdefined bbox and projections

View differences:

modules/cdm_dataportal/includes/maps.inc
67 67
    if ($force_map_type == 1) {
68 68
      _add_jquery_ui();
69 69
    $map_html = get_openlayers_map(
70
        $map_settings['bbox'],
71 70
        $occurrence_query,
72 71
        $distribution_query,
73 72
        $legend_format_query,
......
81 80
      $map_html = get_image_map(
82 81
        $map_settings['image_map']['width'],
83 82
        $map_height,
84
        $map_settings['bbox'],
85 83
        $occurrence_query,
86 84
        $distribution_query,
87 85
        $legend_format_query,
......
215 213
 * @return String
216 214
 *    rendered html
217 215
 */
218
function get_openlayers_map($bounding_box = FALSE, $occurrenceQuery = FALSE, $distributionQuery = FALSE,
216
function get_openlayers_map($occurrenceQuery = FALSE, $distributionQuery = FALSE,
219 217
                            $legendFormatQuery = FALSE, $map_caption = FALSE, array $event_listeners = array(),
220 218
                            $resizable = false) {
221 219

  
......
234 232
  $width = 512;
235 233

  
236 234
  $openlayers_map_query_string = '&img=false&ms=' . $width
237
  . ($bounding_box ? '&bbox=' . $bounding_box : '')
238 235
  . ($labels_on ? '&label=' . $labels_on : '');
239 236

  
240 237
  if ($occurrenceQuery) {
......
362 359
 * @todo Enter description here ...
363 360
 *
364 361
 * @param unknown_type $width
365
 * @param unknown_type $bounding_box
366 362
 * @param unknown_type $occurrenceQuery
367 363
 * @param unknown_type $distributionQuery
368 364
 * @param unknown_type $legendFormatQuery
......
371 367
* @return String
372 368
 *    rendered html
373 369
 */
374
function get_image_map($width, $height= NULL, $bounding_box = FALSE, $occurrenceQuery = FALSE, $distributionQuery = FALSE, $legendFormatQuery = FALSE, $map_caption = FALSE) {
370
function get_image_map($width, $height= NULL, $occurrenceQuery = FALSE, $distributionQuery = FALSE, $legendFormatQuery = FALSE, $map_caption = FALSE) {
375 371

  
376 372
  $map_settings = get_array_variable_merged(CDM_MAP_DISTRIBUTION, CDM_MAP_DISTRIBUTION_DEFAULT);
377 373

  
......
382 378

  
383 379
  $query_string = '&img=true&recalculate=false&ms=' . $width . ($height ? ',' . $height : '')
384 380
  // Additional query parameters as set in the data portal admin section.
385
  . ($bounding_box ? '&bbox=' . $bounding_box : '')
381
  . ($map_settings['bbox'] ? '&bbox=' . $map_settings['bbox'] : '')
386 382
  . ($map_settings['show_labels'] ? '&label=' . $map_settings['show_labels'] : '');
387 383

  
388 384
  if ($map_caption) {
modules/cdm_dataportal/js/map/openlayers_map.js
8 8

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

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

  
13
        return this.each(function(){
14
            this.cdmOpenlayersMap = new CdmOpenLayers.Map($(this), mapserverBaseUrl, mapserverVersion, opts);
15
            this.cdmOpenlayersMap.init();
16
        }); // END each
13
      // sanitize invalid opts.boundingBox
14
      if(opts.boundingBox &&  !( typeof opts.boundingBox  == 'string' && opts.boundingBox .length > 6)) {
15
        opts.boundingBox = null;
16
      }
17

  
18
      return this.each(function(){
19
          this.cdmOpenlayersMap = new CdmOpenLayers.Map($(this), mapserverBaseUrl, mapserverVersion, opts);
20
          this.cdmOpenlayersMap.init();
21
      }); // END each
17 22

  
18 23
    }; // END cdm_openlayers_map
19 24

  
......
24 29
    legendPosition:  null,      // 1,2,3,4,5,6 = display a legend in the corner specified by the number
25 30
    distributionOpacity: 0.75,
26 31
    legendOpacity: 0.75,
27
    boundingBox: "-180,-90,180,90",
32
    // These are bounds in the epsg_4326 projection in degree
33
    boundingBox: null,
28 34
    aspectRatio: 2, // w/h
29 35
    showLayerSwitcher: false,
30 36
    baseLayerNames: ["osgeo_vmap0"],
......
110 116
     */
111 117
    window.CdmOpenLayers.Map = function(mapElement, mapserverBaseUrl, mapserverVersion, opts){
112 118

  
113
        var mapServicePath = '/edit_wp5';
114

  
115
        // firebug console stub (avoids errors if firebug is not active)
116
        if(typeof console === "undefined") {
117
            console = { log: function() { } };
118
        }
119

  
120
        // sanitize given options
121
        try {
122
            opts.customWMSBaseLayerData.max_extent = OpenLayers.Bounds.fromString(opts.customWMSBaseLayerData.max_extent);
123
        } catch(e){
124
            opts.customWMSBaseLayerData.max_extent = null;
125
        }
126

  
127

  
128
        var legendImgSrc = null;
129

  
130
        var map = null;
131

  
132
        var infoElement = null;
133

  
134
        var dataBounds = null;
135

  
136
        var baseLayers = [];
137
        var defaultBaseLayer = null;
138

  
139
        var zoomToBounds = null;
140
        var zoomToClosestLevel = true;
141

  
142
        var LAYER_DATA_CNT = 0;
143

  
144
        /* this is usually the <div id="openlayers"> element */
145
        var mapContainerElement = mapElement.parent();
146

  
147
        var defaultControls = [
148
                               new OpenLayers.Control.PanZoom(),
149
                               new OpenLayers.Control.Navigation({zoomWheelEnabled: false, handleRightClicks:true, zoomBoxKeyMask: OpenLayers.Handler.MOD_CTRL})
150
                               ];
151

  
152

  
153
        var layerByNameMap = {
154
                tdwg1: 'topp:tdwg_level_1',
155
                tdwg2: 'topp:tdwg_level_2',
156
                tdwg3: 'topp:tdwg_level_3',
157
                tdwg4: 'topp:tdwg_level_4'
158
        };
159

  
160
        if(opts.resizable == true) {
161
          // resizable requires jQueryUI to  be loaded!!!
162
          mapContainerElement.resizable({
163
            resize: function( event, ui ) {
164
              map.updateSize();
165
              //   this.printInfo();
166
            }
167
          });
168
        }
119
      var mapServicePath = '/edit_wp5';
120

  
121
      // firebug console stub (avoids errors if firebug is not active)
122
      if(typeof console === "undefined") {
123
          console = { log: function() { } };
124
      }
125

  
126
      // sanitize given options
127
      try {
128
          opts.customWMSBaseLayerData.max_extent = OpenLayers.Bounds.fromString(opts.customWMSBaseLayerData.max_extent);
129
      } catch(e){
130
          opts.customWMSBaseLayerData.max_extent = null;
131
      }
132

  
133

  
134
      var legendImgSrc = null;
135

  
136
      var map = null;
137

  
138
      var infoElement = null;
139

  
140
      var baseLayers = [];
141

  
142
      var defaultBaseLayer = null;
143

  
144
      /**
145
       * Default bounding box for map viewport in the projection of the base layer.
146
       * as defined by the user, can be null.
147
       *
148
       * These are bounds in the epsg_4326 projection, and will be transformed to the baselayer projection.
149
       *
150
       * @type string
151
       */
152
      var defaultBaseLayerBoundingBox = "-180,-90,180,90";
153

  
154
      /**
155
       * bounding box for map viewport as defined by the user, can be null.
156
       *
157
       * These are bounds in the projection of the base layer.
158
       *
159
       * @type string
160
       */
161
      var boundingBox = null;
162

  
163
      /**
164
       * Bounds for the view port calculated from the data layer responses.
165
       * These are either calculated by the minimum bounding box which
166
       * encloses the data in the data layers, or it is equal to the
167
       * boundingBox as defined by the user.
168
       *
169
       * These are bounds in the projection of the base layer.
170
       *
171
       * @see boundingBox
172
       *
173
       * @type OpenLayers.Bounds
174
       */
175
      var dataBounds = null;
176

  
177
      /**
178
       * Final value for the view port, calculated from the other bounds.
179
       *
180
       * These are bounds in the projection of the base layer.
181
       *
182
       * @type OpenLayers.Bounds
183
       */
184
      var zoomToBounds = null;
185

  
186
      var zoomToClosestLevel = true;
187

  
188
      var LAYER_DATA_CNT = 0;
189

  
190
      /* this is usually the <div id="openlayers"> element */
191
      var mapContainerElement = mapElement.parent();
192

  
193
      var defaultControls = [
194
         new OpenLayers.Control.PanZoom(),
195
         new OpenLayers.Control.Navigation(
196
           {
197
             zoomWheelEnabled: false,
198
             handleRightClicks:true,
199
             zoomBoxKeyMask: OpenLayers.Handler.MOD_CTRL
200
           }
201
         )
202
      ];
203

  
204

  
205
      var layerByNameMap = {
206
              tdwg1: 'topp:tdwg_level_1',
207
              tdwg2: 'topp:tdwg_level_2',
208
              tdwg3: 'topp:tdwg_level_3',
209
              tdwg4: 'topp:tdwg_level_4'
210
      };
211

  
212
      if(opts.resizable == true) {
213
        // resizable requires jQueryUI to  be loaded!!!
214
        mapContainerElement.resizable({
215
          resize: function( event, ui ) {
216
            map.updateSize();
217
            //   this.printInfo();
218
          }
219
        });
220
      }
169 221

  
170 222
        /**
171 223
         *
172 224
         */
173 225
        this.init = function(){ // public function
174 226

  
175
            // set the height of the container element
227
          // set the height of the container element
228
          adjustHeight();
229

  
230
          // register for resize events to be able to adjust the map aspect ratio and legend position
231
          jQuery( window ).resize(function() {
176 232
            adjustHeight();
233
            adjustLegendAsElementPosition();
234
          });
177 235

  
178
            // register for resize events to be able to adjust the map aspect ratio and legend position
179
            jQuery( window ).resize(function() {
180
              adjustHeight();
181
              adjustLegendAsElementPosition();
182
            });
236
          createBaseLayers(opts.baseLayerNames, opts.defaultBaseLayerName, opts.customWMSBaseLayerData);
183 237

  
184
            createBaseLayers(opts.baseLayerNames, opts.defaultBaseLayerName, opts.customWMSBaseLayerData);
238
          initMap();
185 239

  
186
            initMap();
240
          // now it is
241
          if(opts.boundingBox){
242
            boundingBox = OpenLayers.Bounds.fromString(opts.boundingBox);
243
            boundingBox.transform(CdmOpenLayers.projections.epsg_4326, map.getProjectionObject());
244
          }
187 245

  
188
            // -- Distribution Layer --
189
            var mapServiceRequest;
190
            var distributionQuery = mapElement.attr('distributionQuery');
246
          // -- Distribution Layer --
247
          var mapServiceRequest;
248
          var distributionQuery = mapElement.attr('distributionQuery');
191 249

  
192
            if(distributionQuery !== undefined){
193
                distributionQuery = mergeQueryStrings(distributionQuery, '&recalculate=false');
194
                if(typeof legendPosition == 'number'){
195
                    distributionQuery = mergeQueryStrings(distributionQuery, 'legend=1&mlp=' + opts.legendPosition);
196
                }
250
          if(distributionQuery !== undefined){
251
            distributionQuery = mergeQueryStrings(distributionQuery, '&recalculate=false');
252
            if(typeof legendPosition == 'number'){
253
              distributionQuery = mergeQueryStrings(distributionQuery, 'legend=1&mlp=' + opts.legendPosition);
254
            }
255
            if(opts.boundingBox){
256
              distributionQuery = mergeQueryStrings(distributionQuery, 'bbox=' + boundingBox);
257
            }
197 258

  
198
                distributionQuery = mergeQueryStrings(distributionQuery, 'callback=?');
199
                var legendFormatQuery = mapElement.attr('legendFormatQuery');
200
                if(legendFormatQuery !== undefined){
201
                    legendImgSrc = mergeQueryStrings('/GetLegendGraphic?SERVICE=WMS&VERSION=1.1.1', legendFormatQuery);
202
                }
259
            distributionQuery = mergeQueryStrings(distributionQuery, 'callback=?');
260
            var legendFormatQuery = mapElement.attr('legendFormatQuery');
261
            if(legendFormatQuery !== undefined){
262
              legendImgSrc = mergeQueryStrings('/GetLegendGraphic?SERVICE=WMS&VERSION=1.1.1', legendFormatQuery);
263
            }
203 264

  
204
                mapServiceRequest = mapserverBaseUrl + mapServicePath + '/' + mapserverVersion + '/rest_gen.php?' + distributionQuery;
265
            mapServiceRequest = mapserverBaseUrl + mapServicePath + '/' + mapserverVersion + '/rest_gen.php?' + distributionQuery;
205 266

  
206
                LAYER_DATA_CNT++;
207
                jQuery.ajax({
208
                    url: mapServiceRequest,
209
                    dataType: "jsonp",
210
                    success: function(data){
211
                        var layers = createDataLayer(data, "AREA");
212
                        addLayers(layers);
213
                        layerDataLoaded();
214
                    }
215
                });
216
            }
267
            LAYER_DATA_CNT++;
268
            jQuery.ajax({
269
              url: mapServiceRequest,
270
              dataType: "jsonp",
271
              success: function(data){
272
                  var layers = createDataLayer(data, "AREA");
273
                  addLayers(layers);
274
                  layerDataLoaded();
275
              }
276
            });
277
          }
217 278

  
218
            // -- Occurrence Layer --
219
            var occurrenceQuery = mapElement.attr('occurrenceQuery');
220
            if(occurrenceQuery !== undefined){
221
                occurrenceQuery = mergeQueryStrings(occurrenceQuery, '&recalculate=false');
279
          // -- Occurrence Layer --
280
          var occurrenceQuery = mapElement.attr('occurrenceQuery');
281
          if(occurrenceQuery !== undefined){
282
            occurrenceQuery = mergeQueryStrings(occurrenceQuery, '&recalculate=false');
222 283
//              if(typeof legendPosition == 'number'){
223 284
//              occurrenceQuery = mergeQueryStrings(distributionQuery, 'legend=1&mlp=' + opts.legendPosition);
224 285
//              }
225 286

  
226 287

  
227
                occurrenceQuery = mergeQueryStrings(occurrenceQuery, 'callback=?');
288
            occurrenceQuery = mergeQueryStrings(occurrenceQuery, 'callback=?');
228 289
//              var legendFormatQuery = mapElement.attr('legendFormatQuery');
229 290
//              if(legendFormatQuery !== undefined){
230 291
//              legendImgSrc = mergeQueryStrings('/GetLegendGraphic?SERVICE=WMS&VERSION=1.1.1', legendFormatQuery);
231 292
//              }
293
            if(opts.boundingBox){
294
              occurrenceQuery = mergeQueryStrings(occurrenceQuery, 'bbox=' + boundingBox);
295
            }
232 296

  
233
                mapServiceRequest = mapserverBaseUrl + mapServicePath + '/' + mapserverVersion + '/rest_gen.php?' + occurrenceQuery;
297
            mapServiceRequest = mapserverBaseUrl + mapServicePath + '/' + mapserverVersion + '/rest_gen.php?' + occurrenceQuery;
234 298

  
235
                LAYER_DATA_CNT++;
236
                jQuery.ajax({
237
                    url: mapServiceRequest,
238
                    dataType: "jsonp",
239
                    success: function(data){
240
                        var layers = createDataLayer(data, "POINT");
241
                        addLayers(layers);
242
                        layerDataLoaded();
243
                    }
244
                });
245
            }
299
            LAYER_DATA_CNT++;
300
            jQuery.ajax({
301
              url: mapServiceRequest,
302
              dataType: "jsonp",
303
              success: function(data){
304
                  var layers = createDataLayer(data, "POINT");
305
                  addLayers(layers);
306
                  layerDataLoaded();
307
              }
308
            });
309
          }
246 310

  
247 311
            if(LAYER_DATA_CNT == 0) {
248 312
              // a map only with base layer
......
426 490
            map.setBaseLayer(defaultBaseLayer);
427 491

  
428 492
            // calculate the bounds to zoom to
429
            zoomToBounds = zoomToBoundsFor(opts.boundingBox, defaultBaseLayer);
493
            zoomToBounds = zoomToBoundsFor(opts.boundingBox ? opts.boundingBox : defaultBaseLayerBoundingBox, defaultBaseLayer);
430 494
            zoomToBounds = cropBoundsToAspectRatio(zoomToBounds, map.getSize().w / map.getSize().h);
431 495
            console.log("baselayer zoomToBounds: " + zoomToBounds);
432 496

  
......
521 585
                }
522 586

  
523 587
                if(layers.length > 0) {
524
                  // calculate zoomBounds for the using the first layer
588
                  // calculate zoomBounds using the first layer
525 589
                  if(mapResponseObj.bbox !== undefined){
590
                    // mapResponseObj.bbox are bounds for the projection of the specific layer
526 591
                    var newBounds =  OpenLayers.Bounds.fromString( mapResponseObj.bbox );
527 592
                    newBounds.transform(layers[0].projection, map.getProjectionObject());
528 593
                    if(dataBounds !== null){
......
716 781
            return cropedB;
717 782
        };
718 783

  
719
        /**
720
         * returns the zoom to bounds.
721
         *
722
         * @param bboxString
723
         *     a string representation of the bounds in degree
724
         * @param layer
725
         *     the Openlayers.Layer
726
         *
727
         * @return the bboxstring projected onto the layer and intersected with the maximum extent of the layer
728
         */
729
        var zoomToBoundsFor = function(bboxString, layer){
730
            var zoomToBounds;
731
            if(typeof bboxString == 'string' && bboxString.length > 6) {
732
                zoomToBounds = OpenLayers.Bounds.fromString(bboxString);
733
                // transform bounding box given in degree values to the projection of the base layer
734
                zoomToBounds.transform(CdmOpenLayers.projections.epsg_4326, layer.projection);
735
            } else if(layer.maxExtent) {
736
                zoomToBounds = layer.maxExtent;
737
                // no need to transform since the bounds are obtained from the layer
738
            } else {
739
                zoomToBounds = new OpenLayers.Bounds(-180, -90, 180, 90);
740
                // transform bounding box given in degree values to the projection of the base layer
741
                zoomToBounds.transform(CdmOpenLayers.projections.epsg_4326, layer.projection);
742
            }
743

  
744
            zoomToBounds = intersectionOfBounds(layer.maxExtent, zoomToBounds);
745

  
746
            return zoomToBounds;
747
        };
748

  
749

  
750

  
751 784
        /**
752 785
         * returns the version number contained in the version string:
753 786
         *   v1.1 --> 1.1
......
763 796
            }
764 797
        };
765 798

  
799

  
800

  
801
      /**
802
       * returns the zoom to bounds.
803
       *
804
       * NOTE: only used for the base layer
805
       *
806
       * @param bboxString
807
       *     a string representation of the bounds in degree for epsg_4326
808
       * @param layer
809
       *     the Openlayers.Layer
810
       *
811
       * @return the bboxstring projected onto the layer and intersected with the maximum extent of the layer
812
       */
813
      var zoomToBoundsFor = function(bboxString, layer){
814
        var zoomToBounds;
815
        if(bboxString) {
816
          zoomToBounds = OpenLayers.Bounds.fromString(bboxString);
817
          // transform bounding box given in degree values to the projection of the base layer
818
          zoomToBounds.transform(CdmOpenLayers.projections.epsg_4326, layer.projection);
819
        } else if(layer.maxExtent) {
820
          zoomToBounds = layer.maxExtent;
821
          // no need to transform since the bounds are obtained from the layer
822
        } else {
823
          zoomToBounds = new OpenLayers.Bounds(-180, -90, 180, 90);
824
          // transform bounding box given in degree values to the projection of the base layer
825
          zoomToBounds.transform(CdmOpenLayers.projections.epsg_4326, layer.projection);
826
        }
827

  
828
        zoomToBounds = intersectionOfBounds(layer.maxExtent, zoomToBounds);
829

  
830
        return zoomToBounds;
831
      };
832

  
766 833
        var log = function(message, addTimeStamp){
767 834
          var timestamp = '';
768 835
          if(addTimeStamp == true){

Also available in: Unified diff