[mapguide-commits] r5681 - in trunk/Tools/Maestro: Maestro.Base Maestro.Base/Commands Maestro.Base/Editor Maestro.Base/Properties Maestro.Base/UI OSGeo.MapGuide.MaestroAPI OSGeo.MapGuide.MaestroAPI/Mapping OSGeo.MapGuide.MaestroAPI/ObjectModels OSGeo.MapGuide.MaestroAPI/Services

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Apr 5 11:04:31 EDT 2011


Author: jng
Date: 2011-04-05 08:04:31 -0700 (Tue, 05 Apr 2011)
New Revision: 5681

Added:
   trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.Designer.cs
   trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.cs
   trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.resx
Modified:
   trunk/Tools/Maestro/Maestro.Base/Commands/ProfileResourceCommand.cs
   trunk/Tools/Maestro/Maestro.Base/Editor/FeatureSourceEditor.cs
   trunk/Tools/Maestro/Maestro.Base/Editor/LayerDefinitionEditor.cs
   trunk/Tools/Maestro/Maestro.Base/Maestro.Base.addin
   trunk/Tools/Maestro/Maestro.Base/Maestro.Base.csproj
   trunk/Tools/Maestro/Maestro.Base/Properties/Resources.Designer.cs
   trunk/Tools/Maestro/Maestro.Base/Properties/Resources.resx
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMapGroup.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMapLayer.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs
   trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Services/IMappingService.cs
Log:
#1650: Port over the profiling feature from Maestro 2.x. Also fix the Clone() method of MapDefinition to detach any event handlers (we don't want these cloned!)


Modified: trunk/Tools/Maestro/Maestro.Base/Commands/ProfileResourceCommand.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Commands/ProfileResourceCommand.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/Maestro.Base/Commands/ProfileResourceCommand.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -20,10 +20,27 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using ICSharpCode.Core;
+using Maestro.Base.UI;
+using Maestro.Base.Services;
 
 namespace Maestro.Base.Commands
 {
-    internal class ProfileResourceCommand : NotImplementedCommand
+    internal class ProfileResourceCommand : AbstractMenuCommand
     {
+        public override void Run()
+        {
+            var wb = Workbench.Instance;
+            var ed = wb.ActiveEditor;
+            if (ed != null)
+            {
+                var exp = wb.ActiveSiteExplorer;
+                var connMgr = ServiceRegistry.GetService<ServerConnectionManager>();
+                var conn = connMgr.GetConnection(exp.ConnectionName);
+                var res = ed.EditorService.GetEditedResource();
+                var diag = new ProfilingDialog(res, res.ResourceID, conn);
+                diag.ShowDialog(wb);
+            }
+        }
     }
 }

Modified: trunk/Tools/Maestro/Maestro.Base/Editor/FeatureSourceEditor.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Editor/FeatureSourceEditor.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/Maestro.Base/Editor/FeatureSourceEditor.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -96,5 +96,13 @@
             }
             base.OnBeforeSave(sender, e);
         }
+
+        public override bool CanProfile
+        {
+            get
+            {
+                return true;
+            }
+        }
     }
 }

Modified: trunk/Tools/Maestro/Maestro.Base/Editor/LayerDefinitionEditor.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Editor/LayerDefinitionEditor.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/Maestro.Base/Editor/LayerDefinitionEditor.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -127,5 +127,13 @@
 
             base.OnBeforeSave(sender, e);
         }
+
+        public override bool CanProfile
+        {
+            get
+            {
+                return true;
+            }
+        }
     }
 }

Modified: trunk/Tools/Maestro/Maestro.Base/Maestro.Base.addin
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Maestro.Base.addin	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/Maestro.Base/Maestro.Base.addin	2011-04-05 15:04:31 UTC (rev 5681)
@@ -343,7 +343,7 @@
             <ToolbarItem id="Profile"
                          icon="clock"
                          tooltip="${res:Menu_File_ProfileResource}"
-                         class="Maestro.Base.Commands.NotImplementedCommand" />
+                         class="Maestro.Base.Commands.ProfileResourceCommand" />
         </Condition>
         <Condition action="Disable" name="EditorFunction" property="CanValidate">
             <ToolbarItem id="Validate"

Modified: trunk/Tools/Maestro/Maestro.Base/Maestro.Base.csproj
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Maestro.Base.csproj	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/Maestro.Base/Maestro.Base.csproj	2011-04-05 15:04:31 UTC (rev 5681)
@@ -302,6 +302,12 @@
     <Compile Include="UI\Preferences\OptionsDialog.Designer.cs">
       <DependentUpon>OptionsDialog.cs</DependentUpon>
     </Compile>
+    <Compile Include="UI\ProfilingDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="UI\ProfilingDialog.Designer.cs">
+      <DependentUpon>ProfilingDialog.cs</DependentUpon>
+    </Compile>
     <Compile Include="UI\RenameItemDialog.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -490,6 +496,9 @@
     <EmbeddedResource Include="UI\Preferences\OptionsDialog.resx">
       <DependentUpon>OptionsDialog.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="UI\ProfilingDialog.resx">
+      <DependentUpon>ProfilingDialog.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="UI\RenameItemDialog.resx">
       <DependentUpon>RenameItemDialog.cs</DependentUpon>
     </EmbeddedResource>

Modified: trunk/Tools/Maestro/Maestro.Base/Properties/Resources.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Properties/Resources.Designer.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/Maestro.Base/Properties/Resources.Designer.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -326,6 +326,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Close.
+        /// </summary>
+        internal static string CloseButtonText {
+            get {
+                return ResourceManager.GetString("CloseButtonText", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to This resource {0} has unsaved changes. Close and discard these changes?.
         /// </summary>
         internal static string CloseUnsavedResource {
@@ -1256,6 +1265,153 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Failed while profiling LayerDefinition: {0},
+        ///Error message: {1}.
+        /// </summary>
+        internal static string Prof_LayerDefinitionProfilingError {
+            get {
+                return ResourceManager.GetString("Prof_LayerDefinitionProfilingError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to *** Done ***.
+        /// </summary>
+        internal static string Prof_LogMessageDone {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageDone", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Profiling FeatureSource: {0}.
+        /// </summary>
+        internal static string Prof_LogMessageFeatureSource {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageFeatureSource", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Identity fetching (ms): .
+        /// </summary>
+        internal static string Prof_LogMessageIdentifyFetching {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageIdentifyFetching", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Profiling LayerDefinition: {0}.
+        /// </summary>
+        internal static string Prof_LogMessageLayerDefinition {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageLayerDefinition", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Profiling MapDefinition: {0}.
+        /// </summary>
+        internal static string Prof_LogMessageMapDefinition {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageMapDefinition", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Full map rendering (ms): .
+        /// </summary>
+        internal static string Prof_LogMessageRenderingMap {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageRenderingMap", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Rendering scales (ms): .
+        /// </summary>
+        internal static string Prof_LogMessageRenderingScales {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageRenderingScales", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Runtime layer creation (ms): .
+        /// </summary>
+        internal static string Prof_LogMessageRuntimeLayer {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageRuntimeLayer", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Total for runtime Map Generation (ms): .
+        /// </summary>
+        internal static string Prof_LogMessageRuntimeMap {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageRuntimeMap", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Runtime map generation in one go (ms):.
+        /// </summary>
+        internal static string Prof_LogMessageRuntimeMapTotal {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageRuntimeMapTotal", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Time to render scale range [{0} : {1}] (ms):  .
+        /// </summary>
+        internal static string Prof_LogMessageScaleRange {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageScaleRange", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The resource type is not supported for profiling.
+        /// </summary>
+        internal static string Prof_LogMessageUnsupportedResourceType {
+            get {
+                return ResourceManager.GetString("Prof_LogMessageUnsupportedResourceType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed while profiling MapDefinition rendering: {0},
+        ///Error message: {1}.
+        /// </summary>
+        internal static string Prof_MapRenderingError {
+            get {
+                return ResourceManager.GetString("Prof_MapRenderingError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Rendered image size is: {0}.
+        /// </summary>
+        internal static string Prof_MapRenderingImageSize {
+            get {
+                return ResourceManager.GetString("Prof_MapRenderingImageSize", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Failed while profiling MapDefinition runtime: {0},
+        ///Error message: {1}.
+        /// </summary>
+        internal static string Prof_RuntimeMapProfilingError {
+            get {
+                return ResourceManager.GetString("Prof_RuntimeMapProfilingError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Updating References.
         /// </summary>
         internal static string ProgressUpdatingReferences {

Modified: trunk/Tools/Maestro/Maestro.Base/Properties/Resources.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/Properties/Resources.resx	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/Maestro.Base/Properties/Resources.resx	2011-04-05 15:04:31 UTC (rev 5681)
@@ -907,4 +907,74 @@
   <data name="SiteExplorer_DuplicateResources" xml:space="preserve">
     <value>Duplicate Resources</value>
   </data>
+  <data name="CloseButtonText" xml:space="preserve">
+    <value>Close</value>
+    <comment>The text on the close button</comment>
+  </data>
+  <data name="Prof_LayerDefinitionProfilingError" xml:space="preserve">
+    <value>Failed while profiling LayerDefinition: {0},
+Error message: {1}</value>
+    <comment>An error message that is displayed when the layer definition profiling fails</comment>
+  </data>
+  <data name="Prof_LogMessageDone" xml:space="preserve">
+    <value>*** Done ***</value>
+    <comment>A message written in the log to indicate that the operation is complete</comment>
+  </data>
+  <data name="Prof_LogMessageFeatureSource" xml:space="preserve">
+    <value>Profiling FeatureSource: {0}</value>
+    <comment>A message written in the log when profiling a featuresource</comment>
+  </data>
+  <data name="Prof_LogMessageIdentifyFetching" xml:space="preserve">
+    <value>Identity fetching (ms): </value>
+    <comment>A message written in the log when profiling identity fetching</comment>
+  </data>
+  <data name="Prof_LogMessageLayerDefinition" xml:space="preserve">
+    <value>Profiling LayerDefinition: {0}</value>
+    <comment>A message written in the log when profiling a layerdefinition</comment>
+  </data>
+  <data name="Prof_LogMessageMapDefinition" xml:space="preserve">
+    <value>Profiling MapDefinition: {0}</value>
+    <comment>A message written in the log when profiling a mapdefinition</comment>
+  </data>
+  <data name="Prof_LogMessageRenderingMap" xml:space="preserve">
+    <value>Full map rendering (ms): </value>
+    <comment>A message written in the log when profiling runtime map rendering</comment>
+  </data>
+  <data name="Prof_LogMessageRenderingScales" xml:space="preserve">
+    <value>Rendering scales (ms): </value>
+    <comment>A message written in the log when profiling a scale rendering</comment>
+  </data>
+  <data name="Prof_LogMessageRuntimeLayer" xml:space="preserve">
+    <value>Runtime layer creation (ms): </value>
+    <comment>A message written in the log when profiling a runtime layer creation</comment>
+  </data>
+  <data name="Prof_LogMessageRuntimeMap" xml:space="preserve">
+    <value>Total for runtime Map Generation (ms): </value>
+    <comment>A message written in the log when profiling runtime map generation</comment>
+  </data>
+  <data name="Prof_LogMessageRuntimeMapTotal" xml:space="preserve">
+    <value>Runtime map generation in one go (ms):</value>
+    <comment>A message written in the log when profiling runtime map generation</comment>
+  </data>
+  <data name="Prof_LogMessageScaleRange" xml:space="preserve">
+    <value>Time to render scale range [{0} : {1}] (ms):  </value>
+    <comment>A message written in the log when profiling a certain scalerange</comment>
+  </data>
+  <data name="Prof_LogMessageUnsupportedResourceType" xml:space="preserve">
+    <value>The resource type is not supported for profiling</value>
+    <comment>A message written in the log if a certain resource is not supported</comment>
+  </data>
+  <data name="Prof_MapRenderingError" xml:space="preserve">
+    <value>Failed while profiling MapDefinition rendering: {0},
+Error message: {1}</value>
+    <comment>An error message displayed when profiling mapdefinition rendering fails</comment>
+  </data>
+  <data name="Prof_RuntimeMapProfilingError" xml:space="preserve">
+    <value>Failed while profiling MapDefinition runtime: {0},
+Error message: {1}</value>
+    <comment>An error message displayed when profiling a mapdefinition fails</comment>
+  </data>
+  <data name="Prof_MapRenderingImageSize" xml:space="preserve">
+    <value>Rendered image size is: {0}</value>
+  </data>
 </root>
\ No newline at end of file

Added: trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.Designer.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.Designer.cs	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.Designer.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -0,0 +1,98 @@
+namespace Maestro.Base.UI
+{
+    partial class ProfilingDialog
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProfilingDialog));
+            this.Results = new System.Windows.Forms.TextBox();
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.CancelBtn = new System.Windows.Forms.Button();
+            this.backgroundWorker = new System.ComponentModel.BackgroundWorker();
+            this.btnSave = new System.Windows.Forms.Button();
+            this.panel1.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // Results
+            // 
+            resources.ApplyResources(this.Results, "Results");
+            this.Results.Name = "Results";
+            this.Results.ReadOnly = true;
+            // 
+            // panel1
+            // 
+            this.panel1.Controls.Add(this.btnSave);
+            this.panel1.Controls.Add(this.CancelBtn);
+            resources.ApplyResources(this.panel1, "panel1");
+            this.panel1.Name = "panel1";
+            // 
+            // CancelBtn
+            // 
+            resources.ApplyResources(this.CancelBtn, "CancelBtn");
+            this.CancelBtn.Name = "CancelBtn";
+            this.CancelBtn.UseVisualStyleBackColor = true;
+            this.CancelBtn.Click += new System.EventHandler(this.CancelBtn_Click);
+            // 
+            // backgroundWorker
+            // 
+            this.backgroundWorker.WorkerReportsProgress = true;
+            this.backgroundWorker.WorkerSupportsCancellation = true;
+            this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_DoWork);
+            this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_RunWorkerCompleted);
+            this.backgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker_ProgressChanged);
+            // 
+            // btnSave
+            // 
+            resources.ApplyResources(this.btnSave, "btnSave");
+            this.btnSave.Name = "btnSave";
+            this.btnSave.UseVisualStyleBackColor = true;
+            this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
+            // 
+            // ProfilingDialog
+            // 
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
+            resources.ApplyResources(this, "$this");
+            this.ControlBox = false;
+            this.Controls.Add(this.Results);
+            this.Controls.Add(this.panel1);
+            this.Name = "ProfilingDialog";
+            this.Load += new System.EventHandler(this.Profiling_Load);
+            this.panel1.ResumeLayout(false);
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.TextBox Results;
+        private System.Windows.Forms.Panel panel1;
+        private System.Windows.Forms.Button CancelBtn;
+        private System.ComponentModel.BackgroundWorker backgroundWorker;
+        private System.Windows.Forms.Button btnSave;
+    }
+}
\ No newline at end of file

Added: trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.cs
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.cs	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -0,0 +1,472 @@
+#region Disclaimer / License
+// Copyright (C) 2011, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+// 
+#endregion
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using OSGeo.MapGuide.MaestroAPI.Mapping;
+using OSGeo.MapGuide.MaestroAPI;
+using OSGeo.MapGuide.ObjectModels.MapDefinition;
+using OSGeo.MapGuide.ObjectModels;
+using OSGeo.MapGuide.MaestroAPI.Services;
+using OSGeo.MapGuide.MaestroAPI.Resource;
+using OSGeo.MapGuide.ObjectModels.LayerDefinition;
+using OSGeo.MapGuide.MaestroAPI.Exceptions;
+using OSGeo.MapGuide.ObjectModels.FeatureSource;
+using Maestro.Shared.UI;
+using ICSharpCode.Core;
+
+namespace Maestro.Base.UI
+{
+    public partial class ProfilingDialog : Form
+    {
+        private IServerConnection m_connection;
+        private IResource m_item;
+        private string m_resourceId;
+
+        private RuntimeMap m_tempmap;
+
+        public ProfilingDialog(IResource item, string resourceId, IServerConnection connection)
+            : this()
+        {
+            m_connection = connection;
+            m_item = item;
+            m_resourceId = resourceId;
+        }
+
+        private ProfilingDialog()
+        {
+            InitializeComponent();
+            m_tempmap = null;
+        }
+
+        private void CancelBtn_Click(object sender, EventArgs e)
+        {
+            if (!backgroundWorker.IsBusy)
+                this.Close();
+            else if (!backgroundWorker.CancellationPending)
+                backgroundWorker.CancelAsync();
+        }
+
+        private void ProfileFeatureSource(IFeatureSource fs)
+        {
+            //TODO: Determine what profiling benchmarks to use
+            string resourceId = fs == m_item ? m_resourceId : fs.ResourceID;
+            backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_LogMessageFeatureSource, resourceId)));
+        }
+
+        private static void SetTempLayer(IMapDefinition mdf, string resourceId)
+        {
+            var layers = new List<IMapLayer>(mdf.MapLayer);
+            for (int i = 0; i < layers.Count; i++)
+            {
+                mdf.RemoveLayer(layers[i]);
+            }
+
+            var layer = mdf.AddLayer(null, "x", resourceId);
+            layer.Visible = true;
+            layer.Selectable = true;
+            layer.Name = "x";
+            layer.LegendLabel = "";
+        }
+
+        private void MakeTempMap()
+        {
+            if (m_tempmap == null)
+            {
+                IMapDefinition m = ObjectFactory.CreateMapDefinition(m_connection, "");
+                m.CoordinateSystem = @"LOCAL_CS[""*XY-M*"", LOCAL_DATUM[""*X-Y*"", 10000], UNIT[""Meter"", 1], AXIS[""X"", EAST], AXIS[""Y"", NORTH]]";
+                m.SetExtents(-1, -1, 1, 1);
+
+                m.ResourceID = "Library://non-existing.MapDefinition";
+                var mpsvc = (IMappingService)m_connection.GetService((int)ServiceType.Mapping);
+                var rid = new ResourceIdentifier(Guid.NewGuid().ToString(), ResourceTypes.RuntimeMap, m_connection.SessionID);
+
+                m_tempmap = mpsvc.CreateMap(m);
+            }
+        }
+
+
+        private void ProfileLayerDefinition(ILayerDefinition ldef)
+        {
+            //TODO: This was a line-by-line port from 2.x to match the 3.x APIs
+            //we should find time to clean this up and ensure the profiling numbers are
+            //truly reflective of actual performance metrics
+            if (backgroundWorker.CancellationPending)
+                return;
+
+            string resourceId = ldef == m_item ? m_resourceId : ldef.ResourceID;
+
+            MakeTempMap();
+
+            backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_LogMessageLayerDefinition, resourceId)));
+            using (new Timer(Properties.Resources.Prof_LogMessageRuntimeLayer, backgroundWorker))
+            {
+                try
+                {
+                    IMapDefinition mdef = ObjectFactory.CreateMapDefinition(m_connection, "");
+                    mdef.ResourceID = "Library://ProfileTest.MapDefinition"; //Flub it
+                    IMapLayer layer = mdef.AddLayer(null, "Test Layer", ldef.ResourceID);
+                    layer.Visible = false;
+                    layer.Selectable = false;
+
+                    if (backgroundWorker.CancellationPending)
+                        return;
+
+                    var mpsvc = (IMappingService)m_connection.GetService((int)ServiceType.Mapping);
+                    
+                    var map = mpsvc.CreateMap(mdef);
+                    using (new Timer(Properties.Resources.Prof_LogMessageIdentifyFetching, backgroundWorker))
+                    {
+                        var rtl = map.GetLayerByName("Test Layer");
+                        rtl.Visible = true;
+                        rtl.Selectable = true;
+                    }
+
+                    map.Save();
+                }
+                catch (Exception ex)
+                {
+                    string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                    backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_LayerDefinitionProfilingError, resourceId, msg)));
+                }
+            }
+
+            if (backgroundWorker.CancellationPending)
+                return;
+
+            ILayerDefinition lx = (ILayerDefinition)ldef.Clone();
+            if (lx.SubLayer.LayerType == LayerType.Vector || lx.SubLayer.LayerType == LayerType.Raster)
+            {
+                using (new Timer(Properties.Resources.Prof_LogMessageRenderingScales, backgroundWorker))
+                {
+                    if (lx.SubLayer.LayerType == LayerType.Vector)
+                    {
+                        IVectorLayerDefinition vlx = lx.SubLayer as IVectorLayerDefinition;
+                        //VectorScaleRangeTypeCollection ranges = vlx.VectorScaleRange;
+                        List<IVectorScaleRange> ranges = new List<IVectorScaleRange>(vlx.VectorScaleRange);
+                        foreach (var vsr in ranges)
+                        {
+                            if (backgroundWorker.CancellationPending)
+                                return;
+
+                            string tmp1 = new ResourceIdentifier(Guid.NewGuid().ToString(), ResourceTypes.LayerDefinition, m_connection.SessionID);
+
+                            try
+                            {
+                                double minscale = vsr.MinScale.HasValue ? vsr.MinScale.Value : 0;
+                                double maxscale = vsr.MaxScale.HasValue ? vsr.MaxScale.Value : 10000000;
+
+                                vlx.RemoveAllScaleRanges();
+                                vsr.MinScale = null;
+                                vsr.MaxScale = null;
+                                vlx.AddVectorScaleRange(vsr);
+
+                                m_connection.ResourceService.SaveResourceAs(lx, tmp1);
+
+                                if (backgroundWorker.CancellationPending)
+                                    return;
+
+                                var lst = m_connection.FeatureService.GetSpatialContextInfo(vlx.ResourceId, false);
+
+                                //Create a runtime map just containing this particular layer at this particular scale range
+                                //We are profiling the stylization settings for this layer
+                                var mdf = ObjectFactory.CreateMapDefinition(m_connection, "");
+                                if (lst.SpatialContext != null && lst.SpatialContext.Count >= 1)
+                                {
+                                    mdf.CoordinateSystem = lst.SpatialContext[0].CoordinateSystemWkt;
+                                    if (string.IsNullOrEmpty(m_tempmap.CoordinateSystem))
+                                        mdf.CoordinateSystem = @"LOCAL_CS[""*XY-M*"", LOCAL_DATUM[""*X-Y*"", 10000], UNIT[""Meter"", 1], AXIS[""X"", EAST], AXIS[""Y"", NORTH]]";
+                                    
+                                    double llx = double.Parse(lst.SpatialContext[0].Extent.LowerLeftCoordinate.X, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture);
+                                    double lly = double.Parse(lst.SpatialContext[0].Extent.LowerLeftCoordinate.Y, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture); ;
+                                    double urx = double.Parse(lst.SpatialContext[0].Extent.UpperRightCoordinate.X, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture); ;
+                                    double ury = double.Parse(lst.SpatialContext[0].Extent.UpperRightCoordinate.Y, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture); ;
+
+                                    m_tempmap.DataExtent = ObjectFactory.CreateEnvelope(llx, lly, urx, ury);
+                                }
+
+                                SetTempLayer(mdf, tmp1);
+                                
+                                var mpsvc = (IMappingService)m_connection.GetService((int)ServiceType.Mapping);
+
+                                mdf.ResourceID = "Library://ProfileTest.MapDefinition"; //Flub it
+                                var rtmap = mpsvc.CreateMap(mdf);
+
+                                if (m_connection.ResourceService.ResourceExists(rtmap.ResourceID))
+                                    m_connection.ResourceService.DeleteResource(rtmap.ResourceID);
+
+                                rtmap.Save();
+
+                                if (backgroundWorker.CancellationPending)
+                                    return;
+
+                                using (new Timer(string.Format(Properties.Resources.Prof_LogMessageScaleRange, minscale, maxscale), backgroundWorker))
+                                {
+                                    //TODO: Use extents rather than scale
+                                    //using (System.IO.Stream s = m_connection.RenderRuntimeMap(tmp2, m.Extents, 1024, 800, 96))
+                                    using (System.IO.Stream s = mpsvc.RenderRuntimeMap(rtmap.ResourceID, ((rtmap.DataExtent.MaxX - rtmap.DataExtent.MinX) / 2) + rtmap.DataExtent.MinX, ((rtmap.DataExtent.MaxY - rtmap.DataExtent.MinY) / 2) + rtmap.DataExtent.MinY, 50000, 1024, 800, 96))
+                                    {
+                                        backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_MapRenderingImageSize, s.Length)));
+                                    }
+                                }
+                            }
+                            finally
+                            {
+                                try { m_connection.ResourceService.DeleteResource(tmp1); }
+                                catch { }
+                            }
+                        }
+
+                    }
+                }
+            }
+
+            if (backgroundWorker.CancellationPending)
+                return;
+
+            backgroundWorker.ReportProgress(0, ("\r\n"));
+        }
+
+        private void ProfileMapDefinition(IMapDefinition mapDef)
+        {
+            //TODO: This was a line-by-line port from 2.x to match the 3.x APIs
+            //we should find time to clean this up and ensure the profiling numbers are
+            //truly reflective of actual performance metrics
+            var mdef = (IMapDefinition)mapDef.Clone();
+            if (backgroundWorker.CancellationPending)
+                return;
+
+            string resourceId = mdef == m_item ? m_resourceId : mdef.ResourceID;
+
+            backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_LogMessageMapDefinition, resourceId)));
+
+            using (new Timer(Properties.Resources.Prof_LogMessageRuntimeMap, backgroundWorker))
+            {
+                foreach (var ml in mdef.MapLayer)
+                {
+                    try
+                    {
+                        if (backgroundWorker.CancellationPending)
+                            return;
+
+                        ILayerDefinition ldef = (ILayerDefinition)mdef.CurrentConnection.ResourceService.GetResource(ml.ResourceId);
+                        ProfileLayerDefinition(ldef);
+                    }
+                    catch (Exception ex)
+                    {
+                        string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                        backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_LayerDefinitionProfilingError, ml.ResourceId, msg)));
+                    }
+                }
+
+                if (mdef.BaseMap != null)
+                {
+                    foreach (var g in mdef.BaseMap.BaseMapLayerGroup)
+                    {
+                        if (g.BaseMapLayer != null)
+                        {
+                            foreach (var ml in g.BaseMapLayer)
+                            {
+                                try
+                                {
+                                    if (backgroundWorker.CancellationPending)
+                                        return;
+
+                                    ILayerDefinition ldef = (ILayerDefinition)mdef.CurrentConnection.ResourceService.GetResource(ml.ResourceId);
+                                    ProfileLayerDefinition(ldef);
+                                }
+                                catch (Exception ex)
+                                {
+                                    string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                                    backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_LayerDefinitionProfilingError, ml.ResourceId, msg)));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (backgroundWorker.CancellationPending)
+                return;
+
+            var mpsvc = (IMappingService)m_connection.GetService((int)ServiceType.Mapping);
+
+            try
+            {
+                if (backgroundWorker.CancellationPending)
+                    return;
+
+                //m_connection.ResetFeatureSourceSchemaCache();
+                using (new Timer(Properties.Resources.Prof_LogMessageRuntimeMapTotal, backgroundWorker))
+                    mpsvc.CreateMap(mdef);
+            }
+            catch (Exception ex)
+            {
+                string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_RuntimeMapProfilingError, resourceId, msg)));
+            }
+
+            try
+            {
+                if (backgroundWorker.CancellationPending)
+                    return;
+
+                //Flub for runtime map creation
+                mdef.ResourceID = "Library://ProfilingTest.MapDefinition";
+
+                var rtmap = mpsvc.CreateMap(mdef);
+
+                if (m_connection.ResourceService.ResourceExists(rtmap.ResourceID))
+                    m_connection.ResourceService.DeleteResource(rtmap.ResourceID);
+
+                rtmap.Save();
+
+                using (new Timer(Properties.Resources.Prof_LogMessageRenderingMap, backgroundWorker))
+                {
+                    //TODO: Use extents rather than scale
+                    //using (System.IO.Stream s = m_connection.RenderRuntimeMap(tmp2, mdef.Extents, 1024, 800, 96))
+                    using (System.IO.Stream s = mpsvc.RenderRuntimeMap(rtmap.ResourceID, ((mdef.Extents.MaxX - mdef.Extents.MinX) / 2) + mdef.Extents.MinX, ((mdef.Extents.MaxY - mdef.Extents.MinY) / 2) + mdef.Extents.MinY, 50000, 1024, 800, 96))
+                    {
+                        //Just dispose it after being read
+                        backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_MapRenderingImageSize, s.Length)));
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                string msg = NestedExceptionMessageProcessor.GetFullMessage(ex);
+                backgroundWorker.ReportProgress(0, (string.Format(Properties.Resources.Prof_MapRenderingError, resourceId, msg)));
+            }
+        }
+
+        private class Timer : IDisposable 
+        {
+            private string m_text;
+            private bool m_isDisposed;
+            private DateTime m_begin;
+            private BackgroundWorker m_worker;
+
+            public Timer(string text, BackgroundWorker worker)
+            {
+                m_begin = DateTime.Now;
+                m_isDisposed = false;
+                m_text = text;
+                m_worker = worker;
+            }
+
+            #region IDisposable Members
+
+            public void Dispose()
+            {
+                if (!m_isDisposed)
+                {
+                    TimeSpan ts = DateTime.Now - m_begin;
+                    m_isDisposed = true;
+                    m_worker.ReportProgress(0, (m_text + ts.TotalMilliseconds)); //ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00") + "." + ts.Milliseconds.ToString("000")));
+                    m_worker = null;
+                    m_text = null;
+                }
+            }
+
+            #endregion
+        }
+
+        private void Profiling_Load(object sender, EventArgs e)
+        {
+            backgroundWorker.RunWorkerAsync();
+        }
+
+        private void Profiling_FormClosing(object sender, FormClosingEventArgs e)
+        {
+            if (backgroundWorker.IsBusy)
+            {
+                e.Cancel = true;
+
+                if (!backgroundWorker.CancellationPending)
+                    backgroundWorker.CancelAsync();
+            }
+        }
+
+        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
+        {
+            if (m_item.ResourceType == ResourceTypes.FeatureSource)
+            {
+                ProfileFeatureSource(m_item as IFeatureSource);
+            }
+            else if (m_item.ResourceType == ResourceTypes.LayerDefinition)
+            {
+                ProfileLayerDefinition(m_item as ILayerDefinition);
+            }
+            else if (m_item.ResourceType == ResourceTypes.MapDefinition)
+            {
+                ProfileMapDefinition(m_item as IMapDefinition);
+            }
+            else
+            {
+                backgroundWorker.ReportProgress(0, Properties.Resources.Prof_LogMessageUnsupportedResourceType);
+            }
+        }
+
+        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
+        {
+            CancelBtn.Text = Properties.Resources.CloseButtonText;
+            btnSave.Enabled = true;
+            WriteString(Properties.Resources.Prof_LogMessageDone);
+        }
+
+        private void WriteString(string message)
+        {
+            if (string.IsNullOrEmpty(message))
+                return;
+
+            bool scroll = Math.Abs((Results.SelectionStart + Results.SelectionLength) - Results.Text.Length) < 20;
+
+            Results.Text += message + "\r\n";
+            if (scroll)
+            {
+                Results.SelectionLength = 0;
+                Results.SelectionStart = Results.Text.Length;
+                Results.ScrollToCaret();
+            }
+        }
+
+        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
+        {
+            WriteString(e.UserState as string);
+        }
+
+        private void btnSave_Click(object sender, EventArgs e)
+        {
+            using (var diag = DialogFactory.SaveFile())
+            {
+                if (diag.ShowDialog() == DialogResult.OK)
+                {
+                    System.IO.File.WriteAllText(diag.FileName, Results.Text);
+                    MessageService.ShowMessage(string.Format(Properties.Resources.Log_Saved, diag.FileName));
+                }
+            }
+        }
+
+    }
+}

Added: trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.resx
===================================================================
--- trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.resx	                        (rev 0)
+++ trunk/Tools/Maestro/Maestro.Base/UI/ProfilingDialog.resx	2011-04-05 15:04:31 UTC (rev 5681)
@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="Results.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
+    <value>Fill</value>
+  </data>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="Results.Font" type="System.Drawing.Font, System.Drawing">
+    <value>Courier New, 9.75pt</value>
+  </data>
+  <data name="Results.Location" type="System.Drawing.Point, System.Drawing">
+    <value>0, 0</value>
+  </data>
+  <assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="Results.Multiline" type="System.Boolean, mscorlib">
+    <value>True</value>
+  </data>
+  <data name="Results.ScrollBars" type="System.Windows.Forms.ScrollBars, System.Windows.Forms">
+    <value>Both</value>
+  </data>
+  <data name="Results.Size" type="System.Drawing.Size, System.Drawing">
+    <value>444, 245</value>
+  </data>
+  <data name="Results.TabIndex" type="System.Int32, mscorlib">
+    <value>14</value>
+  </data>
+  <data name="&gt;&gt;Results.Name" xml:space="preserve">
+    <value>Results</value>
+  </data>
+  <data name="&gt;&gt;Results.Type" xml:space="preserve">
+    <value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;Results.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;Results.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="btnSave.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Bottom, Left</value>
+  </data>
+  <data name="btnSave.Enabled" type="System.Boolean, mscorlib">
+    <value>False</value>
+  </data>
+  <data name="btnSave.Location" type="System.Drawing.Point, System.Drawing">
+    <value>12, 6</value>
+  </data>
+  <data name="btnSave.Size" type="System.Drawing.Size, System.Drawing">
+    <value>75, 23</value>
+  </data>
+  <data name="btnSave.TabIndex" type="System.Int32, mscorlib">
+    <value>2</value>
+  </data>
+  <data name="btnSave.Text" xml:space="preserve">
+    <value>Save</value>
+  </data>
+  <data name="&gt;&gt;btnSave.Name" xml:space="preserve">
+    <value>btnSave</value>
+  </data>
+  <data name="&gt;&gt;btnSave.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;btnSave.Parent" xml:space="preserve">
+    <value>panel1</value>
+  </data>
+  <data name="&gt;&gt;btnSave.ZOrder" xml:space="preserve">
+    <value>0</value>
+  </data>
+  <data name="CancelBtn.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
+    <value>Bottom, Right</value>
+  </data>
+  <data name="CancelBtn.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
+    <value>NoControl</value>
+  </data>
+  <data name="CancelBtn.Location" type="System.Drawing.Point, System.Drawing">
+    <value>357, 6</value>
+  </data>
+  <data name="CancelBtn.Size" type="System.Drawing.Size, System.Drawing">
+    <value>75, 23</value>
+  </data>
+  <data name="CancelBtn.TabIndex" type="System.Int32, mscorlib">
+    <value>1</value>
+  </data>
+  <data name="CancelBtn.Text" xml:space="preserve">
+    <value>Stop</value>
+  </data>
+  <data name="&gt;&gt;CancelBtn.Name" xml:space="preserve">
+    <value>CancelBtn</value>
+  </data>
+  <data name="&gt;&gt;CancelBtn.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;CancelBtn.Parent" xml:space="preserve">
+    <value>panel1</value>
+  </data>
+  <data name="&gt;&gt;CancelBtn.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
+    <value>Bottom</value>
+  </data>
+  <data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
+    <value>0, 245</value>
+  </data>
+  <data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
+    <value>444, 40</value>
+  </data>
+  <data name="panel1.TabIndex" type="System.Int32, mscorlib">
+    <value>13</value>
+  </data>
+  <data name="&gt;&gt;panel1.Name" xml:space="preserve">
+    <value>panel1</value>
+  </data>
+  <data name="&gt;&gt;panel1.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;panel1.Parent" xml:space="preserve">
+    <value>$this</value>
+  </data>
+  <data name="&gt;&gt;panel1.ZOrder" xml:space="preserve">
+    <value>1</value>
+  </data>
+  <metadata name="backgroundWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
+    <value>444, 285</value>
+  </data>
+  <data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
+    <value>CenterParent</value>
+  </data>
+  <data name="$this.Text" xml:space="preserve">
+    <value>Profiling Resource</value>
+  </data>
+  <data name="&gt;&gt;backgroundWorker.Name" xml:space="preserve">
+    <value>backgroundWorker</value>
+  </data>
+  <data name="&gt;&gt;backgroundWorker.Type" xml:space="preserve">
+    <value>System.ComponentModel.BackgroundWorker, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+  <data name="&gt;&gt;$this.Name" xml:space="preserve">
+    <value>ProfilingDialog</value>
+  </data>
+  <data name="&gt;&gt;$this.Type" xml:space="preserve">
+    <value>System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </data>
+</root>
\ No newline at end of file

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMapGroup.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMapGroup.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMapGroup.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -37,7 +37,7 @@
         internal RuntimeMapGroup() 
         {
             _disableChangeTracking = true;
-
+            this.Group = "";
             this.Type = kNormal;
             this.ObjectId = Guid.NewGuid().ToString();
         }

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMapLayer.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMapLayer.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Mapping/RuntimeMapLayer.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -75,6 +75,7 @@
             this.IdentityProperties = new PropertyInfo[0];
             this.ObjectId = Guid.NewGuid().ToString();
             this.Parent = parent;
+            this.Group = string.Empty;
         }
 
         internal RuntimeMapLayer(RuntimeMap parent, ILayerDefinition ldf)
@@ -84,7 +85,6 @@
 
             this.LayerDefinitionID = ldf.ResourceID;
             this.ExpandInLegend = false;
-            this.Group = null;
             this.Name = ResourceIdentifier.GetName(ldf.ResourceID);
             this.Selectable = true;
             this.ShowInLegend = true;

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/MapDefinition.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -27,6 +27,7 @@
 using OSGeo.MapGuide.ObjectModels.LayerDefinition;
 using OSGeo.MapGuide.ObjectModels.Common;
 using OSGeo.MapGuide.ObjectModels.MapDefinition;
+using System.ComponentModel;
 
 #pragma warning disable 1591, 0114, 0108
 
@@ -49,11 +50,21 @@
                 OnPropertyChanged("BackgroundColor");
             }
         }
+
+        protected void DetachChangeListeners()
+        {
+            var handler = this.PropertyChanged;
+            foreach (var h in handler.GetInvocationList())
+            {
+                this.PropertyChanged -= (PropertyChangedEventHandler)h;
+            }
+            handler = null;
+        }
     }
 
     partial class MapDefinition : IMapDefinition
     {
-        internal MapDefinition() { } 
+        internal MapDefinition() { }
 
         private static readonly Version RES_VERSION = new Version(1, 0, 0);
 
@@ -109,7 +120,9 @@
 
         object ICloneable.Clone()
         {
-            return this.Clone();
+            var mdf = this.Clone();
+            mdf.DetachChangeListeners();
+            return mdf;
         }
 
         [XmlAttribute("noNamespaceSchemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/ObjectModels/ObjectFactory.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -206,6 +206,30 @@
         }
 
         /// <summary>
+        /// Creates the web layout. The schema version used is the highest supported one by the connection 
+        /// </summary>
+        /// <param name="owner"></param>
+        /// <param name="mapDefinitionId"></param>
+        /// <returns></returns>
+        public static IWebLayout CreateWebLayout(IServerConnection owner, string mapDefinitionId)
+        {
+            var ver = owner.Capabilities.GetMaxSupportedResourceVersion(ResourceTypes.WebLayout);
+            return CreateWebLayout(owner, ver, mapDefinitionId);
+        }
+
+        /// <summary>
+        /// Creates the default layer. The schema version used is the highest supported one by the connection
+        /// </summary>
+        /// <param name="owner"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public static ILayerDefinition CreateDefaultLayer(IServerConnection owner, LayerType type)
+        {
+            var ver = owner.Capabilities.GetMaxSupportedResourceVersion(ResourceTypes.LayerDefinition);
+            return CreateDefaultLayer(owner, type, ver);
+        }
+
+        /// <summary>
         /// Creates the default layer.
         /// </summary>
         /// <param name="owner">The owner.</param>
@@ -348,6 +372,19 @@
         }
 
         /// <summary>
+        /// Creates the simple symbol. The schema version used is the highest supported one by the connection 
+        /// </summary>
+        /// <param name="owner"></param>
+        /// <param name="name"></param>
+        /// <param name="description"></param>
+        /// <returns></returns>
+        public static ISimpleSymbolDefinition CreateSimpleSymbol(IServerConnection owner, string name, string description)
+        {
+            var ver = owner.Capabilities.GetMaxSupportedResourceVersion(ResourceTypes.SymbolDefinition);
+            return CreateSimpleSymbol(owner, ver, name, description);
+        }
+
+        /// <summary>
         /// Creates the compound symbol.
         /// </summary>
         /// <param name="owner">The owner.</param>
@@ -366,6 +403,19 @@
             return comp;
         }
 
+        /// <summary>
+        /// Creates the compound symbol. The schema version used is the highest supported one by the connection 
+        /// </summary>
+        /// <param name="owner"></param>
+        /// <param name="name"></param>
+        /// <param name="description"></param>
+        /// <returns></returns>
+        public static ICompoundSymbolDefinition CreateCompoundSymbol(IServerConnection owner, string name, string description)
+        {
+            var ver = owner.Capabilities.GetMaxSupportedResourceVersion(ResourceTypes.SymbolDefinition);
+            return CreateCompoundSymbol(owner, ver, name, description);
+        }
+
         static readonly string[] parameterizedWidgets = 
         {
             KnownWidgetNames.CTRLClick,

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/PlatformConnectionBase.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -1703,8 +1703,12 @@
         /// <returns></returns>
         protected virtual double InferMPU(string csWkt, double units)
         {
-            var cs = CoordinateSystemBase.Create(csWkt);
-            return cs.MetersPerUnitX * units;
+            try
+            {
+                var cs = CoordinateSystemBase.Create(csWkt);
+                return cs.MetersPerUnitX * units;
+            }
+            catch { return 1.0; }
         }
 
         /// <summary>
@@ -1742,6 +1746,30 @@
         }
 
         /// <summary>
+        /// Creates a new runtime map instance from an existing map definition.  The runtime map resource id is calculated from the 
+        /// current session id and the name component of the Map Definition resource id
+        /// </summary>
+        /// <param name="mdf"></param>
+        /// <returns></returns>
+        public RuntimeMap CreateMap(IMapDefinition mdf)
+        {
+            var rid = new ResourceIdentifier(ResourceIdentifier.GetName(mdf.ResourceID), ResourceTypes.RuntimeMap, this.SessionID);
+            return CreateMap(rid.ToString(), mdf);
+        }
+
+        /// <summary>
+        /// Creates a new runtime map instance from an existing map definition. The runtime map resource id is calculated from the 
+        /// current session id and the name component of the Map Definition resource id
+        /// </summary>
+        /// <param name="mdf"></param>
+        /// <returns></returns>
+        public RuntimeMap CreateMap(IMapDefinition mdf, double metersPerUnit)
+        {
+            var rid = new ResourceIdentifier(ResourceIdentifier.GetName(mdf.ResourceID), ResourceTypes.RuntimeMap, this.SessionID);
+            return CreateMap(rid.ToString(), mdf, metersPerUnit);
+        }
+
+        /// <summary>
         /// Creates a new runtime map instance from an existing map definition. Meters per unit
         /// is calculated from the Coordinate System WKT of the map definition.
         /// </summary>

Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Services/IMappingService.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Services/IMappingService.cs	2011-04-05 12:23:45 UTC (rev 5680)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Services/IMappingService.cs	2011-04-05 15:04:31 UTC (rev 5681)
@@ -31,9 +31,25 @@
     public interface IMappingService : IService
     {
         /// <summary>
+        /// Creates a new runtime map instance from an existing map definition.
+        /// </summary>
+        /// <param name="mapDef"></param>
+        /// <returns></returns>
+        RuntimeMap CreateMap(IMapDefinition mapDef);
+
+        /// <summary>
         /// Creates a new runtime map instance from an existing map definition. Meters per unit
         /// is calculated from the Coordinate System WKT of the map definition.
         /// </summary>
+        /// <param name="mapDef"></param>
+        /// <param name="metersPerUnit"></param>
+        /// <returns></returns>
+        RuntimeMap CreateMap(IMapDefinition mapDef, double metersPerUnit);
+
+        /// <summary>
+        /// Creates a new runtime map instance from an existing map definition. Meters per unit
+        /// is calculated from the Coordinate System WKT of the map definition.
+        /// </summary>
         /// <remarks>
         /// Calculation of meters-per-unit may differ between implementations. This may have an adverse
         /// effect on things such as rendering and measuring depending on the underlying implementation



More information about the mapguide-commits mailing list