[fusion-commits] r2709 - in trunk: lib widgets

svn_fusion at osgeo.org svn_fusion at osgeo.org
Sun May 19 22:18:21 PDT 2013


Author: jng
Date: 2013-05-19 22:18:21 -0700 (Sun, 19 May 2013)
New Revision: 2709

Modified:
   trunk/lib/Map.js
   trunk/widgets/Legend.js
Log:
This submission fixes the legend display for multiple MapGuide maps within the same MapGroup. 

Modified: trunk/lib/Map.js
===================================================================
--- trunk/lib/Map.js	2013-05-18 10:45:32 UTC (rev 2708)
+++ trunk/lib/Map.js	2013-05-20 05:18:21 UTC (rev 2709)
@@ -387,7 +387,9 @@
 
           if (Fusion.Layers[mapTag.type]) {
               this.aMaps.push(new Fusion.Layers[mapTag.type](this, mapTag, true));
-              this.layerRoot.addGroup(this.aMaps[this.aMaps.length-1].layerRoot);
+              var oGroup = this.aMaps[this.aMaps.length-1].layerRoot;
+              oGroup.isFusionLayer = true;
+              this.layerRoot.addGroup(oGroup);
           } else {
               this.aMaps.push(new Fusion.Layers.Generic(this, mapTag, true));
               this.layerRoot.addLayer(this.aMaps[this.aMaps.length-1].layerRoot);
@@ -396,6 +398,39 @@
         }
         this.triggerEvent(Fusion.Event.MAP_MAP_GROUP_LOADED);
     },
+    
+    _fixBaseLayerGroupVisibility: function() {
+        //Fix Defect: the Base Layer Group should be invisiable when the "initially visiable in map" is set to false
+        var i = 0;
+        var j = 0;
+        for (i = 0;i < this.layerRoot.groups.length; i++) {
+            if (this.layerRoot.groups[i].uniqueId == "layerRoot") {
+                for (var k = 0; k < this.layerRoot.groups[i].groups.length; k++) {
+                    if (!this.layerRoot.groups[i].groups[k].initiallyVisible) {
+                        for (j = 0; j < this.aMaps.length; j++) {
+                            if (this.aMaps[j].arch != 'MapGuide') {
+                                continue;
+                            }
+                            if (this.aMaps[j].oLayerOL.params.basemaplayergroupname === this.layerRoot.groups[i].groups[k].name) {
+                                this.aMaps[j].oLayerOL.setVisibility(false);
+                            } 
+                        }
+                    }   
+                }
+            } else {
+                if (!this.layerRoot.groups[i].initiallyVisible){
+                    for (j = 0; j < this.aMaps.length; j++) {
+                        if (this.aMaps[j].arch != 'MapGuide') {
+                            continue;
+                        }
+                        if (this.aMaps[j].oLayerOL.params.basemaplayergroupname === this.layerRoot.groups[i].name) {
+                            this.aMaps[j].oLayerOL.setVisibility(false);
+                        } 
+                    }
+                }   
+            }
+        }
+    },
 
     /**
      * Function: layerLoaded
@@ -409,101 +444,142 @@
      * Return: none
      */
     layerLoaded: function(mapTag) {
-      for (var i=0; i<this.aMaps.length; ++i) {
-        if (!this.aMaps[i].isMapLoaded()) {
-          return;
+        for (var i=0; i<this.aMaps.length; ++i) {
+            if (!this.aMaps[i].isMapLoaded()) {
+                return;
+            }
         }
-      }
-      this.mapsLoaded = true;
-      if (this.aMaps.length == 1) {
-        this.oMapOL.setBaseLayer(this.aMaps[0].oLayerOL);
-      }
+        this.mapsLoaded = true;
+        if (this.aMaps.length == 1) {
+            this.oMapOL.setBaseLayer(this.aMaps[0].oLayerOL);
+            this._fixBaseLayerGroupVisibility();
+        } else {
+            //Due to initialization being done asynchronously, re-order the maps to ensure the OpenLayers draw order matches the order of this.aMaps
+            //Fortunately this.aMaps[i] already carries the related OpenLayers layer object.
 
-      // Take advantage of new client-zoom capabilities introduced in OpenLayers 2.12
-      //
-      // What we do here is for every grid-based commerical layer, we tack on extra resolutions
-      // of the MapGuide OL Layer that is below the minimum supported resolution of the commercial
-      // layers. The existing resolutions array is shifted to the layer's serverResolutions array.
-      //
-      // When we go below the minimum supported resolution of these commercial layers, 
-      // client-zoom kicks in and stretches the commerical layers appropriately.
-      //
-      // A small side-effect is that if fractionalZoom = true, and the layer setup is such that
-      // this won't be set to false during initialization (eg. fractionalZoom = true + 
-      // A MapGuide dynamic map + OSM layers), then the OSM layers will almost always be slightly 
-      // stretched, as any zoom scale is allowed and OL will be stretching the OSM layers to match.
-      //
-      // This technique does not work with Google layers (as they aren't grid-based). The mere presence
-      // of Google layers (or any non-Grid layers) will disable client-zoom if a non-Grid layer is the active
-      // one, and your map will be snapping to whatever discrete scale list that is imposed by the commercial layer
-      //
-      // With these changes the behaviour is like so (OSM is interchangeable with any other grid-based layer, MapGuide
-      // is assumed to be fully dynamic and have no tiled layers):
-      //
-      // - MapGuide + OSM (fractionalZoom = true): Fully dynamic map and OSM tiles are stretched accordingly. OSM 
-      //                                           tiles will most likely never be un-stretched due to the fully dynamic
-      //                                           nature of the map.
-      // - MapGuide + OSM (fractionalZoom = false): Scales "snap" to OSM scales and are stretched accordingly 
-      //                                            when going below the minimum supported OSM scale
-      // - MapGuide + OSM + Explicit Scale List: Scales "snap" to OSM scales (any MG scales within the OSM scale 
-      //                                         list are disregarded). OSM tiles are stretched accordingly when 
-      //                                         going below the minimum supported OSM scale
-      //                                         
-      // MapGuide Map Definitions with tiled layers cannot take advantage of client-zoom (at least to my knowledge and for
-      // this initial implementation). 
-      //
-      // So the same rules apply for MG tiled map integration: It must use the same scale list as Google + Bing + OSM.
-      var newResolutions = null;
-      var mgResolutions = null;
-      var bCanUseClientZoom = true;
-      for (var i = 0; i < this.aMaps.length; i++) {
-          if (this.aMaps[i].arch == 'MapGuide') {
-              mgResolutions = this.aMaps[i].oLayerOL.resolutions;
-              if (this.aMaps[i].bSingleTile) {
-                bCanUseClientZoom = true;
-              } else {
-                //TODO: How smart can we be to make this be true?
-                bCanUseClientZoom = false;
-              }
-              break;
-          }
-      }
+            var mgLayerCount = 0;
 
-      //console.log("Can use client-zoom: " + bCanUseClientZoom);
-      if (bCanUseClientZoom) {
+            //First remove the ones in question
+            for (var i = 0; i < this.aMaps.length; i++) {
+                if (this.aMaps[i].arch == 'MapGuide') {
+                    mgLayerCount++;
+                }
+                
+                //if (this.aMaps[i].oLayerOL != this.oMapOL.layers[i])
+                //    console.log("Found OL layer not in correct position");
+                    
+                this.oMapOL.removeLayer(this.aMaps[i].oLayerOL);
+            }
+
+            //Now re-add them in the correct order
+            for (var i = 0; i < this.aMaps.length; i++) {
+                this.oMapOL.addLayer(this.aMaps[i].oLayerOL);
+            }
+
+            this._fixBaseLayerGroupVisibility();
+            
+            //HACK: Force alwaysInRange = true if more than one Map Definition was found in the MapGroup
+            //
+            //I suspect the underlying problem is the variations in coordinate system name and/or WKT of the
+            //Map Definitions in question that screw up the map resolution calculations that determine
+            //whether the OpenLayers.Layer object actually renders or not. Setting alwaysInRange = true will
+            //skip this (incorrect) calculation
+            if (mgLayerCount > 1) {
+                for (var i = 0; i < this.aMaps.length; i++) {
+                    if (this.aMaps[i].arch == 'MapGuide') {
+                        this.aMaps[i].oLayerOL.isBaseLayer = false; //Required for multiple MG tiled maps a in a MapGroup to be in sync
+                        this.aMaps[i].oLayerOL.alwaysInRange = true;
+                        this.aMaps[i].oLayerOL.setVisibility(true);
+                    }
+                }
+            }
+        }
+
+        // Take advantage of new client-zoom capabilities introduced in OpenLayers 2.12
+        //
+        // What we do here is for every grid-based commerical layer, we tack on extra resolutions
+        // of the MapGuide OL Layer that is below the minimum supported resolution of the commercial
+        // layers. The existing resolutions array is shifted to the layer's serverResolutions array.
+        //
+        // When we go below the minimum supported resolution of these commercial layers, 
+        // client-zoom kicks in and stretches the commerical layers appropriately.
+        //
+        // A small side-effect is that if fractionalZoom = true, and the layer setup is such that
+        // this won't be set to false during initialization (eg. fractionalZoom = true + 
+        // A MapGuide dynamic map + OSM layers), then the OSM layers will almost always be slightly 
+        // stretched, as any zoom scale is allowed and OL will be stretching the OSM layers to match.
+        //
+        // This technique does not work with Google layers (as they aren't grid-based). The mere presence
+        // of Google layers (or any non-Grid layers) will disable client-zoom if a non-Grid layer is the active
+        // one, and your map will be snapping to whatever discrete scale list that is imposed by the commercial layer
+        //
+        // With these changes the behaviour is like so (OSM is interchangeable with any other grid-based layer, MapGuide
+        // is assumed to be fully dynamic and have no tiled layers):
+        //
+        // - MapGuide + OSM (fractionalZoom = true): Fully dynamic map and OSM tiles are stretched accordingly. OSM 
+        //                                           tiles will most likely never be un-stretched due to the fully dynamic
+        //                                           nature of the map.
+        // - MapGuide + OSM (fractionalZoom = false): Scales "snap" to OSM scales and are stretched accordingly 
+        //                                            when going below the minimum supported OSM scale
+        // - MapGuide + OSM + Explicit Scale List: Scales "snap" to OSM scales (any MG scales within the OSM scale 
+        //                                         list are disregarded). OSM tiles are stretched accordingly when 
+        //                                         going below the minimum supported OSM scale
+        //                                         
+        // MapGuide Map Definitions with tiled layers cannot take advantage of client-zoom (at least to my knowledge and for
+        // this initial implementation). 
+        //
+        // So the same rules apply for MG tiled map integration: It must use the same scale list as Google + Bing + OSM.
+        var newResolutions = null;
+        var mgResolutions = null;
+        var bCanUseClientZoom = true;
         for (var i = 0; i < this.aMaps.length; i++) {
-            if (this.aMaps[i].arch == 'Generic') {
-                var oLayer = this.aMaps[i].oLayerOL;
-                oLayer.serverResolutions = oLayer.resolutions;
-                if (newResolutions == null) {
-                    newResolutions = [];
-                    for (var j = 0; j < oLayer.serverResolutions.length; j++) {
-                        newResolutions.push(oLayer.serverResolutions[j]);
-                    }
-                    for (var j = 0; j < mgResolutions.length; j++) {
-                        if (mgResolutions[j] < oLayer.minResolution) {
-                            newResolutions.push(mgResolutions[j]);
+            if (this.aMaps[i].arch == 'MapGuide') {
+                mgResolutions = this.aMaps[i].oLayerOL.resolutions;
+                if (this.aMaps[i].bSingleTile) {
+                    bCanUseClientZoom = true;
+                } else {
+                    //TODO: How smart can we be to make this be true?
+                    bCanUseClientZoom = false;
+                }
+                break;
+            }
+        }
+
+        //console.log("Can use client-zoom: " + bCanUseClientZoom);
+        if (bCanUseClientZoom) {
+            for (var i = 0; i < this.aMaps.length; i++) {
+                if (this.aMaps[i].arch == 'Generic') {
+                    var oLayer = this.aMaps[i].oLayerOL;
+                    oLayer.serverResolutions = oLayer.resolutions;
+                    if (newResolutions == null) {
+                        newResolutions = [];
+                        for (var j = 0; j < oLayer.serverResolutions.length; j++) {
+                            newResolutions.push(oLayer.serverResolutions[j]);
                         }
+                        for (var j = 0; j < mgResolutions.length; j++) {
+                            if (mgResolutions[j] < oLayer.minResolution) {
+                                newResolutions.push(mgResolutions[j]);
+                            }
+                        }
                     }
+                    oLayer.resolutions = newResolutions;
+                    var newScales = [];
+                    for (var j = 0; j < newResolutions.length; j++) {
+                        newScales.push(OpenLayers.Util.getScaleFromResolution(newResolutions[j], oLayer.units));
+                    }
+                    oLayer.scales = newScales;
+                    oLayer.minResolution = newResolutions[newResolutions.length - 1];
+                    oLayer.maxScale = newScales[newScales.length - 1];
+                    oLayer.numZoomLevels = newScales.length;
                 }
-                oLayer.resolutions = newResolutions;
-                var newScales = [];
-                for (var j = 0; j < newResolutions.length; j++) {
-                    newScales.push(OpenLayers.Util.getScaleFromResolution(newResolutions[j], oLayer.units));
-                }
-                oLayer.scales = newScales;
-                oLayer.minResolution = newResolutions[newResolutions.length - 1];
-                oLayer.maxScale = newScales[newScales.length - 1];
-                oLayer.numZoomLevels = newScales.length;
+                //TODO: Do the same for tiled MapGuide oLayerOL objects, allowing for such layers to be scaled client-side as well
             }
-            //TODO: Do the same for tiled MapGuide oLayerOL objects, allowing for such layers to be scaled client-side as well
         }
-      }
-      
-      var initialExtent = this.setInitialExtents();
-      this.setExtents(initialExtent);
 
-      this.triggerEvent(Fusion.Event.MAP_LOADED, mapTag);
+        var initialExtent = this.setInitialExtents();
+        this.setExtents(initialExtent);
+
+        this.triggerEvent(Fusion.Event.MAP_LOADED, mapTag);
     },
 
     /**

Modified: trunk/widgets/Legend.js
===================================================================
--- trunk/widgets/Legend.js	2013-05-18 10:45:32 UTC (rev 2708)
+++ trunk/widgets/Legend.js	2013-05-20 05:18:21 UTC (rev 2709)
@@ -260,7 +260,7 @@
         this.imgDisabledLayerIcon = json.DisabledLayerIcon ? json.DisabledLayerIcon[0] : this.oLegend.defaultDisabledLayerIcon;
         this.imgLayerInfoIcon = json.LayerInfoIcon ? json.LayerInfoIcon[0] : this.oLegend.defaultLayerInfoIcon;
         this.imgGroupInfoIcon = json.GroupInfoIcon ? json.GroupInfoIcon[0] : this.oLegend.defaultGroupInfoIcon;
-       
+
         //not used?
         //this.layerInfoURL = json.LayerInfoURL ? json.LayerInfoURL[0] : '';
         this.selectedLayer = null;
@@ -417,25 +417,52 @@
     renderLegend: function(r) {
         this.bIsDrawn = false;
         this.clear();
-
         if (this.showRootFolder) {
-            this.oRoot.setLabel(this.oLegend.getMapLayer().getMapTitle());
+            this.oRoot.setLabel(this.getMap().mapGroup.mapId);
         }
+        
         var startGroup = this.layerRoot;
-        if (!this.showMapFolder) {
-          startGroup = this.layerRoot.groups[0];
-        }
+        if (!this.showMapFolder)
+            startGroup = this.layerRoot.groups[0];
+        
         if (!startGroup.legend) {
             startGroup.legend = {};
             startGroup.legend.treeItem = this.oRoot;
         }
-        for (var i=0; i<startGroup.groups.length; i++) {
-            //startGroup.groups[i].visible = true;
-            this.processMapGroup(startGroup.groups[i], this.oRoot);
+        
+        if (this.layerRoot.groups.length > 1) { //Multi-map
+            if (this.showMapFolder) {
+                for (var i = 0; i < this.layerRoot.groups.length; i++) {
+                    this.processMapGroup(this.layerRoot.groups[i], this.oRoot);
+                }
+            } else {
+                for (var i = 0; i < this.layerRoot.groups.length; i++) {
+                    var mapRoot = this.layerRoot.groups[i];
+                    if (!mapRoot.legend) {
+                        mapRoot.legend = {};
+                        mapRoot.legend.treeItem = this.oRoot;
+                    }
+                    for (var j = 0; j < mapRoot.groups.length; j++) {
+                        this.processMapGroup(mapRoot.groups[j], this.oRoot);
+                    }
+                    for (var j = 0; j < mapRoot.layers.length; j++) {
+                        this.processMapLayer(mapRoot.layers[j], this.oRoot);
+                    }
+                }
+            }
+        } else { //Single-map
+            if (!startGroup.legend) {
+                startGroup.legend = {};
+                startGroup.legend.treeItem = this.oRoot;
+            }
+            for (var i = 0; i < startGroup.groups.length; i++) {
+                this.processMapGroup(startGroup.groups[i], this.oRoot);
+            }
+            for (var i = 0; i < startGroup.layers.length; i++) {
+                this.processMapLayer(startGroup.layers[i], this.oRoot);
+            }
         }
-        for (var i=0; i<startGroup.layers.length; i++) {
-            this.processMapLayer(startGroup.layers[i], this.oRoot);
-        }
+        
         this.bIsDrawn = true;
         this.update();
     },
@@ -465,7 +492,6 @@
             // );
 
             folder.add(treeItem);
-
             var groupInfo = group.oMap.getGroupInfoUrl(group.groupName);
             if (groupInfo) {
                 treeItem.setGroupInfo(groupInfo, this.imgGroupInfoIcon);
@@ -1034,7 +1060,6 @@
             this.layerInfoIcon.set('src', icon);
         }
     },
-    
     setGroupInfo: function(url, icon) {
         //change class to make fusionGroupInfo display block
         this.domObj.addClass('fusionShowGroupInfo');



More information about the fusion-commits mailing list