[mapguide-commits] r7424 - trunk/MgDev/Desktop/MapViewer

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu Mar 28 07:42:03 PDT 2013


Author: jng
Date: 2013-03-28 07:42:03 -0700 (Thu, 28 Mar 2013)
New Revision: 7424

Modified:
   trunk/MgDev/Desktop/MapViewer/MgLegendControlPresenter.cs
Log:
Fix two problems with the mg-desktop legend:
 - #2284: Fix infinite loop due to nested groups being handled improperly
 - Fix layer/group presentation order at any particular level. This ensures that AJAX/Fusion/Maestro/mg-desktop viewers for the first time present the same view of the layer/group structure as presented in the Map Definition editor.

Also use local variables where possible to avoid repeatedly calling accessor methods that result in managed <-> native transitions.

Modified: trunk/MgDev/Desktop/MapViewer/MgLegendControlPresenter.cs
===================================================================
--- trunk/MgDev/Desktop/MapViewer/MgLegendControlPresenter.cs	2013-03-28 14:24:55 UTC (rev 7423)
+++ trunk/MgDev/Desktop/MapViewer/MgLegendControlPresenter.cs	2013-03-28 14:42:03 UTC (rev 7424)
@@ -352,12 +352,12 @@
 
         public TreeNode[] CreateNodes()
         {
-            List<TreeNode> output = new List<TreeNode>();
-            var nodesById = new Dictionary<string, TreeNode>();
-
+            List<TreeNode> topLevelNodes = new List<TreeNode>();
             var scale = _map.ViewScale;
             if (scale < 10.0)
-                return output.ToArray();
+                return topLevelNodes.ToArray();
+            var nodesById = new Dictionary<string, TreeNode>();
+            var groupsById = new Dictionary<string, TreeNode>();
 
             var groups = _map.GetLayerGroups();
             var layers = _map.GetLayers();
@@ -372,7 +372,7 @@
                 if (!group.GetDisplayInLegend())
                     continue;
 
-                //Add ones without parents first.
+                //Add ones without parents first. Queue up child groups
                 if (group.Group != null)
                 {
                     remainingNodes.Add(group);
@@ -380,13 +380,16 @@
                 else
                 {
                     var node = CreateGroupNode(group);
-                    output.Add(node);
+                    topLevelNodes.Add(node);
                     nodesById.Add(group.GetObjectId(), node);
+                    groupsById.Add(group.GetObjectId(), node);
                 }
 
+                //Process child groups
                 while (remainingNodes.Count > 0)
                 {
                     List<MgLayerGroup> toRemove = new List<MgLayerGroup>();
+                    //Establish parent-child relationship for any child groups here
                     for (int j = 0; j < remainingNodes.Count; j++)
                     {
                         var parentId = remainingNodes[j].Group.GetObjectId();
@@ -394,6 +397,12 @@
                         {
                             var node = CreateGroupNode(remainingNodes[j]);
                             nodesById[parentId].Nodes.Add(node);
+
+                            //Got to add this group node too, otherwise we could infinite
+                            //loop looking for a parent that's not registered
+                            nodesById.Add(group.GetObjectId(), node);
+                            groupsById.Add(group.GetObjectId(), node);
+
                             toRemove.Add(remainingNodes[j]);
                         }
                     }
@@ -414,7 +423,8 @@
             var layerMetaNodesToUpdate = new Dictionary<string, MgLayerBase>();
             //Now process layers. Layers without metadata nodes or without layer definition content
             //are added to the list
-            for (int i = 0; i < layers.GetCount(); i++)
+            int layerCount = layers.GetCount();
+            for (int i = 0; i < layerCount; i++)
             {
                 var lyr = layers.GetItem(i);
                 bool display = lyr.DisplayInLegend;
@@ -425,30 +435,34 @@
                 if (!visible)
                     continue;
 
-                if (_layers.ContainsKey(lyr.GetObjectId()))
+                var lyrObjId = lyr.GetObjectId();
+                if (_layers.ContainsKey(lyrObjId))
                 {
-                    if (string.IsNullOrEmpty(_layers[lyr.GetObjectId()].LayerDefinitionContent))
+                    if (string.IsNullOrEmpty(_layers[lyrObjId].LayerDefinitionContent))
                     {
                         var ldfId = lyr.LayerDefinition;
-                        layerIds.Add(ldfId.ToString());
-                        layerMetaNodesToUpdate[ldfId.ToString()] = lyr;
+                        var ldfIdStr = ldfId.ToString();
+                        layerIds.Add(ldfIdStr);
+                        layerMetaNodesToUpdate[ldfIdStr] = lyr;
                     }
                 }
                 else
                 {
                     var ldfId = lyr.LayerDefinition;
-                    layerIds.Add(ldfId.ToString());
-                    layerMetaNodesToUpdate[ldfId.ToString()] = lyr;
+                    var ldfIdStr = ldfId.ToString();
+                    layerIds.Add(ldfIdStr);
+                    layerMetaNodesToUpdate[ldfIdStr] = lyr;
                 }
             }
 
-            if (layerIds.GetCount() > 0)
+            int layerIdCount = layerIds.GetCount();
+            if (layerIdCount > 0)
             {
                 int added = 0;
                 int updated = 0;
                 //Fetch the contents and create/update the required layer metadata nodes
                 MgStringCollection layerContents = _resSvc.GetResourceContents(layerIds, null);
-                for (int i = 0; i < layerIds.GetCount(); i++)
+                for (int i = 0; i < layerIdCount; i++)
                 {
                     string lid = layerIds.GetItem(i);
                     var lyr = layerMetaNodesToUpdate[lid];
@@ -470,8 +484,13 @@
                 Trace.TraceInformation("CreateNodes: {0} layer contents added, {1} layer contents updated", added, updated); //NOXLATE
             }
 
+            //Now create our layer nodes
             List<MgLayerBase> remainingLayers = new List<MgLayerBase>();
-            for (int i = 0; i < layers.GetCount(); i++)
+            //NOTE: We're taking a page out of the Fusion playbook of reverse iterating the layer
+            //collection and prepending the nodes, as this control suffered the same problem as the
+            //Legend widget in Fusion. Doing it this way eliminates the need for doing an extra pass to fix
+            //the layer/group ordering, which may make an impact on really chunky maps.
+            for (int i = layerCount - 1; i >= 0; i--)
             {
                 var layer = layers.GetItem(i);
                 
@@ -493,7 +512,7 @@
                     var node = CreateLayerNode(layer);
                     if (node != null)
                     {
-                        output.Add(node);
+                        topLevelNodes.Insert(0, node);
                         nodesById.Add(layer.GetObjectId(), node);
                         if (layer.ExpandInLegend)
                             node.Expand();
@@ -503,7 +522,7 @@
                 while (remainingLayers.Count > 0)
                 {
                     List<MgLayerBase> toRemove = new List<MgLayerBase>();
-                    for (int j = 0; j < remainingLayers.Count; j++)
+                    for (int j = remainingLayers.Count - 1; j >= 0; j--)
                     {
                         var parentId = remainingLayers[j].Group.GetObjectId();
                         if (nodesById.ContainsKey(parentId))
@@ -511,7 +530,7 @@
                             var node = CreateLayerNode(remainingLayers[j]);
                             if (node != null)
                             {
-                                nodesById[parentId].Nodes.Add(node);
+                                nodesById[parentId].Nodes.Insert(0, node);
                                 if (remainingLayers[j].ExpandInLegend)
                                     node.Expand();
                             }
@@ -543,7 +562,7 @@
                 }
             }
             Trace.TraceInformation("{0} calls made to GenerateLegendImage", legendCallCount); //NOXLATE
-            return output.ToArray();
+            return topLevelNodes.ToArray();
         }
 
         private static bool IsThemeLayerNode(TreeNode node)



More information about the mapguide-commits mailing list