Project

General

Profile

« Previous | Next » 

Revision 779840f4

Added by Andreas Kohlbecker over 4 years ago

fix #8430 fixing bbox transformation from data layer to base layer projection

View differences:

modules/cdm_dataportal/js/map/openlayers_map.js
72 72
     * when true the map is made resizable by adding the jQueryUI widget resizable
73 73
     * to the map container. This feature requires that the jQueryUI is loaded
74 74
     */
75
    resizable: false
75
    resizable: false,
76
    wfsRootUrl: 'http://edit.africamuseum.be/geoserver/topp/ows'
76 77
  };
77 78
})(jQuery);
78 79

  
......
89 90
        // EPSG:3857 from http://spatialreference.org/ref/sr-org/6864/proj4/
90 91
        // OpenStreetMap etc
91 92
        Proj4js.defs["EPSG:3857"] = '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6378137 +b=6378137 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs';
93
        Proj4js.defs["EPSG:7777777"] = '+proj=lcc + 42 + 56 + 35 + 24 + 3000000 + 100000';
92 94

  
93 95
        var projections = {
94 96
                epsg_4326: new OpenLayers.Projection("EPSG:4326"),
95 97
                epsg_900913: new OpenLayers.Projection("EPSG:900913"),
96
                epsg_3857:  new OpenLayers.Projection("EPSG:3857")
98
                epsg_3857:  new OpenLayers.Projection("EPSG:3857"),
99
                epsg_7777777:  new OpenLayers.Projection("EPSG:7777777")
97 100
        };
98 101
        var mapExtends = {
99 102
                epsg_4326: new OpenLayers.Bounds(-180, -90, 180, 90),
......
226 229
              tdwg4: 'topp:tdwg_level_4'
227 230
      };
228 231

  
232
      /**
233
       * Known projections by layer name. This map helps avoid requesting the server for the
234
       * projection. See readProjection()
235
       */
236
      var layerProjections = {
237
        'topp:tdwg_level_1': CdmOpenLayers.projections.epsg_4326,
238
        'topp:tdwg_level_2': CdmOpenLayers.projections.epsg_4326,
239
        'topp:tdwg_level_3': CdmOpenLayers.projections.epsg_4326,
240
        'topp:tdwg_level_4': CdmOpenLayers.projections.epsg_4326,
241
        'topp:phytogeographical_regions_of_greece': CdmOpenLayers.projections.epsg_4326,
242
        'topp:euromed_2013': CdmOpenLayers.projections.epsg_7777777,
243
        'topp:flora_cuba_2016': CdmOpenLayers.projections.epsg_4326
244
      };
245

  
229 246
      if(opts.resizable === true) {
230 247
        // resizable requires jQueryUI to  be loaded!!!
231 248
        mapContainerElement.resizable({
......
254 271

  
255 272
          initMap();
256 273

  
257
          // now it is
274

  
258 275
          if(opts.boundingBox){
259 276
            boundingBox = OpenLayers.Bounds.fromString(opts.boundingBox);
260
            boundingBox.transform(CdmOpenLayers.projections.epsg_4326, map.getProjectionObject());
261 277
          }
262 278

  
263 279
          // -- Distribution Layer --
......
288 304
              success: function(data){
289 305
                  var layers = createDataLayer(data, "AREA");
290 306
                  addLayers(layers);
291
                  layerDataLoaded();
307
                // layerDataLoaded(); will be called after reading the projection from the WFS for the data layer
292 308
              }
293 309
            });
294 310
          }
......
320 336
              success: function(data){
321 337
                  var layers = createDataLayer(data, "POINT");
322 338
                  addLayers(layers);
323
                  layerDataLoaded();
339
                  // layerDataLoaded(); will be called after reading the projection from the WFS for the data layer
324 340
              }
325 341
            });
326 342
          }
......
358 374

  
359 375
        };
360 376

  
377
      /**
378
       * Provides the layer name which can be used in WMS/WFS requests.
379
       * The layerData.tdwg field contains invalid layer names in case of
380
       * the tdwg layers. This function handles with this bug.
381
       *
382
       * @param layerData
383
       * @returns String
384
       *    the correct layer name
385
       */
386
        var fixLayerName = function(layerData){
387
         var wmsLayerName = layerByNameMap[layerData.tdwg];
388
         if(!wmsLayerName){
389
           wmsLayerName = "topp:" + layerData.tdwg;
390
         }
391
         return wmsLayerName;
392
        };
393

  
361 394
        var layerDataLoaded = function() {
362 395
          LAYER_DATA_CNT--;
363 396
          if(LAYER_DATA_CNT === 0){
......
366 399
        };
367 400

  
368 401
        var initPostDataLoaded = function () {
369
          // all layers prepared, make the visible
402
          // all layers prepared, make them visible
370 403
          map.layers.forEach(function(layer){
371 404
            layer.setVisibility(true);
372 405
          });
......
631 664
              for ( var i in mapResponseObj.layers) {
632 665
                var layerData = mapResponseObj.layers[i];
633 666

  
634
                console.log(" " + i +" -> " + layerData.tdwg);
667
                var layerName = fixLayerName(layerData);
668
                console.log(" " + i +" -> " +layerName);
635 669
                var layer = new OpenLayers.Layer.WMS(
636
                  layerData.tdwg,
670
                  layerName,
637 671
                  mapResponseObj.geoserver + "/wms",
638 672
                  {
639
                      layers: layerByNameMap[layerData.tdwg],
673
                      layers: fixLayerName(layerData),
640 674
                      transparent:"true",
641 675
                      format:"image/png"
642 676
                  },
......
652 686
            if(layers.length > 0) {
653 687
              // calculate zoomBounds using the first layer
654 688
              if(mapResponseObj.bbox !== undefined){
655
                // mapResponseObj.bbox are bounds  are always returned in EPSG:4326 since the point service does not know about the projection
656 689
                var newBounds =  OpenLayers.Bounds.fromString( mapResponseObj.bbox );
690
                var projection;
657 691
                if(dataType === "POINT"){
658
                  console.log("createDataLayer() : transforming newBounds: " + newBounds + " to referenceProjection()=" + referenceProjection() + "(map.getProjectionObject()=" + map.getProjectionObject() +")" );
659
                  // newBounds.transform(layers[0].projection, map.getProjectionObject());
660
                  newBounds.transform(CdmOpenLayers.projections.epsg_4326, referenceProjection());
692
                  projection = CdmOpenLayers.projections.epsg_4326;
693
                  // mapResponseObj.bbox are bounds  are always returned in EPSG:4326 since the point service does not know about the projection
694
                  // console.log("createDataLayer() POINT: referenceProjection()=" + referenceProjection() + ", map.getProjectionObject()=" + map.getProjectionObject() );
695
                  processDataBounds(projection, newBounds, dataType, layerDataLoaded);
661 696
                } else {
662 697
                  // Type == AREA
663
                  console.log("createDataLayer() : no need to transform the newBounds: " + newBounds + " to referenceProjection()=" + referenceProjection());
664
                  // expecting that the bounds are already in the correct projection.
698
                  // the bounds are in the projection of the data layer
699
                  // here we expect that all data layers are in the same projection and will use the first data layer as reference
700
                  // the edit map service is most probably working the same and is not expected to be able to handle multiple data layers
701
                  // with different projections
702
                  readProjection(layers[0], function(projection) {
703
                    processDataBounds(projection, newBounds, dataType, layerDataLoaded);
704
                  })
665 705
                }
666 706

  
707
                console.log("createDataLayer() " + dataType + ": transforming newBounds " + newBounds + " from projection=" +  projection + " to referenceProjection()=" + referenceProjection());
708
                newBounds.transform(projection, referenceProjection());
667 709
                if(dataBounds !== null){
668 710
                  dataBounds.extend(newBounds);
669 711
                } else if(newBounds !== undefined){
......
671 713
                }
672 714

  
673 715
                zoomToBounds = dataBounds;
674
                console.log("createDataLayer() : data layer zoomToBounds: " + zoomToBounds);
716
                console.log("createDataLayer() : viewport zoomToBounds are now: " + zoomToBounds);
675 717
                zoomToClosestLevel = false;
676 718
              }
677 719
            }
678 720

  
679

  
680

  
681 721
            if(legendImgSrc != null && opts.legendPosition !== undefined && mapResponseObj.legend !== undefined){
682 722
                var legendSrcUrl = mapResponseObj.geoserver + legendImgSrc + mapResponseObj.legend;
683 723
                addLegendAsElement(legendSrcUrl);
......
689 729

  
690 730
        };
691 731

  
732
      /**
733
       * transforms the newBounds from the projection to the referenceProjection() and finally calculates the
734
       * zoomBounds for the viewport.
735
       *
736
       * @param projection
737
       * @param newBounds
738
       * @param layerDataTypeString
739
       *    Only used for logging, (either "AREA" or "POINT")
740
       * @param callback
741
       */
742
        var processDataBounds = function(projection, newBounds, layerDataTypeString, callback){
743

  
744
          console.log("createDataLayer() " + layerDataTypeString + ": transforming newBounds " + newBounds + " from projection=" +  projection + " to referenceProjection()=" + referenceProjection());
745
          newBounds.transform(projection, referenceProjection());
746
          if(dataBounds !== null){
747
            dataBounds.extend(newBounds);
748
          } else if(newBounds !== undefined){
749
            dataBounds = newBounds;
750
          }
751

  
752
          zoomToBounds = dataBounds;
753
          console.log("createDataLayer() : viewport zoomToBounds are now: " + zoomToBounds);
754
          zoomToClosestLevel = false;
755
          callback();
756
        };
757

  
758
      /**
759
       * Get the crs data from the WFS and read the projection name from it. Finally the supplied callback will
760
       * be called with the matching projection object as parameter.
761
       * @param layer
762
       * @param callback
763
       *   Function(Projection projection)
764
       */
765
        var readProjection = function(layer, callback){
766

  
767
          var projection = layer.projection;
768

  
769
          if(!projection) {
770
            projection = layerProjections[layer.name];
771
          }
772

  
773

  
774
          if(projection) {
775
            callback(projection);
776
          } else {
777
            // asking the edit map server would be the best:
778
            //    > http://edit.africamuseum.be/geoserver/topp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=topp:euromed_2013&maxFeatures=1&outputFormat=application/json
779
            // or
780
            //    > http://edit.africamuseum.be/geoserver/topp/ows?service=WFS&request=getCapabilities'
781
            // but the latter returns only XML
782
            var parameters = {
783
              service: 'WFS',
784
              version: '1.0.0',
785
              request: 'GetFeature',
786
              typeName: layer.name,
787
              maxFeatures: 1, // only one feature
788
              outputFormat: 'text/javascript',
789
              format_options: 'callback:getJson'
790
            };
791

  
792
            jQuery.ajax({
793
              url: opts.wfsRootUrl + "?" + jQuery.param(parameters),
794
              dataType: 'jsonp',
795
              jsonpCallback: 'getJson',
796
              success: function(data, textStatus, jqXHR){
797
                if(data.crs && data.crs.type && data.crs.properties.code){
798
                  var projectionName = data.crs.type + "_" + data.crs.properties.code;
799
                  log("projection name found in WFS response:" + projectionName);
800
                  projection = CdmOpenLayers.projections[projectionName.toLowerCase()];
801
                  callback(projection);
802
                }
803
              },
804
              error : function(jqXHR, textStatus, errorThrown) {
805
                log("projection name not found in WFS response, due to error: " + textStatus);
806
                projection = CdmOpenLayers.projections.epsg_4326;
807
                callback(projection);
808
              }
809

  
810
            });
811
          }
812
        };
813

  
692 814
        /**
693 815
         *
694 816
         */

Also available in: Unified diff