[mapguide-commits] r4335 - in trunk/Tools/Maestro: MaestroAPI MgCooker

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Nov 9 13:26:32 EST 2009


Author: ksgeograf
Date: 2009-11-09 13:26:32 -0500 (Mon, 09 Nov 2009)
New Revision: 4335

Modified:
   trunk/Tools/Maestro/MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
   trunk/Tools/Maestro/MgCooker/BatchSettings.cs
   trunk/Tools/Maestro/MgCooker/MgCooker.sln
   trunk/Tools/Maestro/MgCooker/Program.cs
   trunk/Tools/Maestro/MgCooker/Progress.cs
   trunk/Tools/Maestro/MgCooker/RenderThread.cs
   trunk/Tools/Maestro/MgCooker/SetupRun.Designer.cs
   trunk/Tools/Maestro/MgCooker/SetupRun.cs
   trunk/Tools/Maestro/MgCooker/SetupRun.resx
Log:
Maestro, MgCooker fixes:
Fixed issue #1086, actually rowcount and columncount were swapped
Fixed issue #1087, Alternate Bounds
Fixed issue #1103, Chrash on large bounds


Modified: trunk/Tools/Maestro/MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
===================================================================
--- trunk/Tools/Maestro/MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2009-11-06 21:25:06 UTC (rev 4334)
+++ trunk/Tools/Maestro/MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj	2009-11-09 18:26:32 UTC (rev 4335)
@@ -1,7 +1,7 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
   <PropertyGroup>
     <ProjectType>Local</ProjectType>
-    <ProductVersion>8.0.50727</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{290B027E-3649-4A60-A9BF-0544831435E2}</ProjectGuid>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -27,6 +27,7 @@
     <OldToolsVersion>2.0</OldToolsVersion>
     <UpgradeBackupLocation>
     </UpgradeBackupLocation>
+    <IsWebBootstrapper>true</IsWebBootstrapper>
     <PublishUrl>http://localhost/OSGeo.MapGuide.MaestroAPI/</PublishUrl>
     <Install>true</Install>
     <InstallFrom>Web</InstallFrom>
@@ -39,7 +40,6 @@
     <MapFileExtensions>true</MapFileExtensions>
     <ApplicationRevision>0</ApplicationRevision>
     <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>true</IsWebBootstrapper>
     <UseApplicationTrust>false</UseApplicationTrust>
     <BootstrapperEnabled>true</BootstrapperEnabled>
   </PropertyGroup>

Modified: trunk/Tools/Maestro/MgCooker/BatchSettings.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/BatchSettings.cs	2009-11-06 21:25:06 UTC (rev 4334)
+++ trunk/Tools/Maestro/MgCooker/BatchSettings.cs	2009-11-09 18:26:32 UTC (rev 4335)
@@ -378,6 +378,26 @@
         public string[] Groups { get { return m_groups; } }
 
         /// <summary>
+        /// The number of tiles to offset the row counter with
+        /// </summary>
+        private int m_rowTileOffset = 0;
+
+        /// <summary>
+        /// The number of tiles to offset the col counter with
+        /// </summary>
+        private int m_colTileOffset = 0;
+
+        /// <summary>
+        /// The tile offset for row indexes for tiles
+        /// </summary>
+        public int RowTileOffset { get { return m_rowTileOffset; } }
+
+        /// <summary>
+        /// The tile offset for col indexes for tiles
+        /// </summary>
+        public int ColTileOffset { get { return m_colTileOffset; } }
+
+        /// <summary>
         /// Constructs a new map to be processed
         /// </summary>
         /// <param name="parent">The parent entry</param>
@@ -416,7 +436,7 @@
                 return;
             }
 
-            MaestroAPI.Box2DType extents = m_maxExtent == null ? m_mapdefinition.Extents : m_maxExtent;
+            MaestroAPI.Box2DType extents = this.MaxExtent ?? m_mapdefinition.Extents;
             double maxscale = m_maxscale;
 
             m_dimensions = new long[this.Resolutions][];
@@ -436,9 +456,22 @@
                     //This is the algorithm proposed by the MapGuide team:
                     //http://www.nabble.com/Pre-Genererate--tiles-for-the-entire-map-at-all-pre-defined-zoom-scales-to6074037.html#a6078663
                     
+                    //The tile extent in meters
+                    double tileWidth  =((INCH_TO_METER / m_parent.Config.DPI * m_parent.Config.TileWidth) * (scale));
+                    double tileHeight = ((INCH_TO_METER / m_parent.Config.DPI * m_parent.Config.TileHeight) * (scale));
+
                     //Using this algorithm, yields a negative number of columns/rows, if the max scale is larger than the max extent of the map.
-                    rows = Math.Max(1, (int)Math.Ceiling((width_in_meters / ((INCH_TO_METER / m_parent.Config.DPI * m_parent.Config.TileWidth) * (scale)))));
-                    cols = Math.Max(1, (int)Math.Ceiling((height_in_meters / ((INCH_TO_METER / m_parent.Config.DPI * m_parent.Config.TileHeight) * (scale)))));
+                    rows = Math.Max(1, (int)Math.Ceiling((height_in_meters / tileHeight)));
+                    cols = Math.Max(1, (int)Math.Ceiling((width_in_meters / tileWidth)));
+
+                    if (m_maxExtent != null)
+                    {
+                        //The extent is overridden, so we need to adjust the start offsets
+                        double offsetX = MaxExtent.MinX - m_mapdefinition.Extents.MinX;
+                        double offsetY = MaxExtent.MinY - m_mapdefinition.Extents.MinY;
+                        m_rowTileOffset = (int)Math.Ceiling(offsetY / tileHeight);
+                        m_colTileOffset = (int)Math.Ceiling(offsetX / tileWidth);
+                    }
                 }
                 else
                 {
@@ -447,18 +480,21 @@
                     //scale ranges. Eg. if max scale range is 1:200, then scale range 1:100 is twice the size,
                     //meaning the full map at 1:100 fills 3840x2560 pixels.
                     //The width/height is then used to calculate the number of rows and columns of 300x300 pixel tiles.
+                    
+                    //The purpose of this method is to enabled tile generation without access to
+                    //coordinate system properties
 
                     long pw = (long)(m_parent.Config.DisplayResolutionWidth * (1 / (scale / maxscale)));
                     long ph = (long)(m_parent.Config.DisplayResolutionHeight * (1 / (scale / maxscale)));
 
-                    rows = (pw + (m_parent.Config.TileWidth - 1)) / m_parent.Config.TileWidth;
-                    cols = (ph + (m_parent.Config.TileHeight - 1)) / m_parent.Config.TileHeight;
+                    rows = (ph + (m_parent.Config.TileHeight - 1)) / m_parent.Config.TileHeight;
+                    cols = (pw + (m_parent.Config.TileWidth - 1)) / m_parent.Config.TileWidth;
                     rows += rows % 2;
                     cols += cols % 2;
                 }
 
+
                 m_dimensions[i] = new long[] {rows, cols};
-
             }
         }
 
@@ -549,33 +585,14 @@
                 int rows = (int)m_dimensions[scaleindex][0];
                 int cols = (int)m_dimensions[scaleindex][1];
 
-                RenderThreads settings = new RenderThreads(this, m_parent, m_scaleindexmap[scaleindex], group, m_mapdefinition.ResourceId);
+                //If the MaxExtents are different from the actual bounds, we need a start offset offset
 
-                if (m_parent.Config.RandomizeTileSequence)
-                {
-                    List<KeyValuePair<int, int>> tmp = new List<KeyValuePair<int, int>>();
-                    for (int r = 0; r < rows; r++)
-                        for (int c = 0; c < cols; c++)
-                            tmp.Add(new KeyValuePair<int, int>(r, c));
+                RenderThreads settings = new RenderThreads(this, m_parent, m_scaleindexmap[scaleindex], group, m_mapdefinition.ResourceId, rows, cols, m_rowTileOffset, m_colTileOffset, m_parent.Config.RandomizeTileSequence);
+                
+                settings.RunAndWait();
 
-                    Random ra = new Random();
-                    while (tmp.Count > 0)
-                    {
-                        int j = ra.Next(0, tmp.Count);
-                        settings.TileSet.Enqueue(tmp[j]);
-                        tmp.RemoveAt(j);
-                    }
-               }
-                else
-                {
-                    for (int r = 0; r < rows; r++)
-                        for (int c = 0; c < cols; c++)
-                            settings.TileSet.Enqueue(new KeyValuePair<int, int>(r, c));
-                }
-
-                settings.RunAndWait();
                 if (settings.TileSet.Count != 0 && !m_parent.Cancel)
-                    throw new Exception("One or more threads chrashed, and the tile set was only partially created");
+                    throw new Exception("All or more threads chrashed, and the tile set was only partially created");
             }
 
             m_parent.InvokeFinishRendering(this, group, scaleindex);

Modified: trunk/Tools/Maestro/MgCooker/MgCooker.sln
===================================================================
--- trunk/Tools/Maestro/MgCooker/MgCooker.sln	2009-11-06 21:25:06 UTC (rev 4334)
+++ trunk/Tools/Maestro/MgCooker/MgCooker.sln	2009-11-09 18:26:32 UTC (rev 4335)
@@ -1,6 +1,6 @@
 
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MgCooker", "MgCooker.csproj", "{C76FFEBF-F047-4BE8-983C-BF8BF3CFB3D9}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OSGeo.MapGuide.MaestroAPI", "..\MaestroAPI\OSGeo.MapGuide.MaestroAPI.csproj", "{290B027E-3649-4A60-A9BF-0544831435E2}"

Modified: trunk/Tools/Maestro/MgCooker/Program.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/Program.cs	2009-11-06 21:25:06 UTC (rev 4334)
+++ trunk/Tools/Maestro/MgCooker/Program.cs	2009-11-09 18:26:32 UTC (rev 4335)
@@ -58,6 +58,7 @@
             //mapdefinition=
             //scaleindex=0,1,2,3,4,5
             //basegroups="x","y"
+            //extentoverride=minx,miny,maxx,maxy
 
             string mapagent = "http://localhost/mapguide";
             string username = "Anonymous";
@@ -75,7 +76,8 @@
             string DPI = "";
             string metersPerUnit = "";
 
-
+            MaestroAPI.Box2DType overrideExtents = null;
+            
             List<string> largs = new List<string>(args);
             Dictionary<string, string> opts = CommandLineParser.ExtractOptions(largs);
             if (opts.ContainsKey("mapagent"))
@@ -105,7 +107,32 @@
                 DPI = opts["DPI"];
             if (opts.ContainsKey("metersperunit"))
                 metersPerUnit = opts["metersperunit"];
+            if (opts.ContainsKey("extentoverride"))
+            {
+                string[] parts = opts["extentoverride"].Split(',');
+                if (parts.Length == 4)
+                {
+                    double minx;
+                    double miny;
+                    double maxx;
+                    double maxy;
+                    if (
+                        double.TryParse(parts[0], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out minx) &&
+                        double.TryParse(parts[1], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out miny) &&
+                        double.TryParse(parts[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out maxx) &&
+                        double.TryParse(parts[3], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out maxy)
+                        )
+                    {
+                        overrideExtents = new OSGeo.MapGuide.MaestroAPI.Box2DType();
+                        overrideExtents.MinX = minx;
+                        overrideExtents.MinY = miny;
+                        overrideExtents.MaxX = maxx;
+                        overrideExtents.MaxY = maxy;
+                    }
+                }
+            }
 
+
             try
             {
                 Console.Clear();
@@ -206,6 +233,10 @@
             if (opts.ContainsKey("threadcount") && int.TryParse(opts["threadcount"], out x) && x > 0)
                 bx.Config.ThreadCount = x;
 
+            if (overrideExtents != null)
+                foreach (BatchMap bm in bx.Maps)
+                    bm.MaxExtent = overrideExtents;
+
             if (largs.IndexOf("/commandline") < 0 && largs.IndexOf("commandline") < 0)
             {
                 Progress pg = new Progress(bx);

Modified: trunk/Tools/Maestro/MgCooker/Progress.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/Progress.cs	2009-11-06 21:25:06 UTC (rev 4334)
+++ trunk/Tools/Maestro/MgCooker/Progress.cs	2009-11-09 18:26:32 UTC (rev 4335)
@@ -30,7 +30,6 @@
     public partial class Progress : Form
     {
         private BatchSettings m_bx;
-        private long m_update;
         private List<TimeSpan> m_tileRuns;
         private long m_tileCount;
         private DateTime m_lastUpdate;

Modified: trunk/Tools/Maestro/MgCooker/RenderThread.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/RenderThread.cs	2009-11-06 21:25:06 UTC (rev 4334)
+++ trunk/Tools/Maestro/MgCooker/RenderThread.cs	2009-11-09 18:26:32 UTC (rev 4335)
@@ -63,7 +63,15 @@
         private string MapDefinition;
         private BatchMap Invoker;
 
-        public RenderThreads(BatchMap invoker, BatchSettings parent, int scale, string group, string mapdef)
+        private bool Randomize;
+        private int Rows;
+        private int Cols;
+        private int RowOffset;
+        private int ColOffset;
+
+        private bool FillerComplete = false;
+
+        public RenderThreads(BatchMap invoker, BatchSettings parent, int scale, string group, string mapdef, int rows, int cols, int rowOffset, int colOffset, bool randomize)
         {
             TileSet = new Queue<KeyValuePair<int, int>>();
             SyncLock = new object();
@@ -75,10 +83,18 @@
             this.Parent = parent;
             this.MapDefinition = mapdef;
             this.Invoker = invoker;
+            Randomize = randomize;
+            Rows = rows;
+            Cols = cols;
+            this.RowOffset = rowOffset;
+            this.ColOffset = colOffset;
         }
 
         public void RunAndWait()
         {
+            System.Threading.ThreadPool.QueueUserWorkItem(
+                new System.Threading.WaitCallback(QueueFiller));
+
             for (int i = 0; i < Parent.Config.ThreadCount; i++)
             {
                 System.Threading.ThreadPool.QueueUserWorkItem(
@@ -146,6 +162,91 @@
             }
         }
 
+        /// <summary>
+        /// Helper that fills the queue from a thread
+        /// </summary>
+        /// <param name="dummy">Unused parameter</param>
+        private void QueueFiller(object dummy)
+        {
+            try
+            {
+                if (Randomize)
+                {
+                    Random ra = new Random();
+                    List<int> rows = new List<int>();
+                    int[] cols_full = new int[Cols];
+                    for (int i = 0; i < Rows; i++)
+                        rows.Add(i);
+
+                    for (int i = 0; i < Cols; i++)
+                        cols_full[i] = i;
+
+                    //TODO: This is not really random, because we select
+                    //a row, and then random columns
+
+                    //Unfortunately, I have yet to find a truly random
+                    //pair generation method that is space efficient :(
+
+                    while (rows.Count > 0)
+                    {
+                        int ri = ra.Next(0, rows.Count);
+                        int r = rows[ri];
+                        rows.RemoveAt(ri);
+
+                        List<int> cols = new List<int>(cols_full);
+
+                        while (cols.Count > 0)
+                        {
+                            int ci = ra.Next(0, cols.Count);
+                            int c = cols[ci];
+                            cols.RemoveAt(ci);
+
+                            AddPairToQueue(r + RowOffset, c + ColOffset);
+                        }
+                    }
+                }
+                else
+                {
+                    //Non-random is straightforward
+                    for (int r = 0; r < Rows; r++)
+                        for (int c = 0; c < Cols; c++)
+                            AddPairToQueue(r + RowOffset, c + ColOffset);
+                }
+            }
+            finally
+            {
+                lock(SyncLock)
+                    FillerComplete = true;
+            }
+
+        }
+
+        /// <summary>
+        /// Helper to add a pair to the queue, but prevents huge queue lists
+        /// </summary>
+        /// <param name="r">The row component of the pair</param>
+        /// <param name="c">The column component of the pair</param>
+        private void AddPairToQueue(int r, int c)
+        {
+            bool added = false;
+            while (!added)
+            {
+                lock (SyncLock)
+                    if (TileSet.Count < 500) //Keep at most 500 items in queue
+                    {
+                        TileSet.Enqueue(new KeyValuePair<int, int>(r, c));
+                        added = true;
+                    }
+
+                if (!added) //Prevent CPU spinning
+                    System.Threading.Thread.Sleep(500);
+            }
+        }
+
+        /// <summary>
+        /// Invokes the render callback method
+        /// </summary>
+        /// <param name="dummy">Unused parameter</param>
         private void ThreadRender(object dummy)
         {
             try
@@ -162,20 +263,24 @@
 
                 while (!Parent.Cancel)
                 {
-                    KeyValuePair<int, int> round;
+                    KeyValuePair<int, int>? round = null;
+
                     lock (SyncLock)
                     {
-                        if (TileSet.Count == 0)
-                            return;
+                        if (TileSet.Count == 0 && FillerComplete)
+                            return; //No more data
 
-                        round = TileSet.Dequeue(); ;
+                        if (TileSet.Count > 0)
+                            round = TileSet.Dequeue();
                     }
 
-
                     if (Parent.Cancel)
                         return;
 
-                    RenderTile(ev, con, round.Key, round.Value, Scale, Group);
+                    if (round == null) //No data, but producer is still running
+                        System.Threading.Thread.Sleep(500);
+                    else
+                        RenderTile(ev, con, round.Value.Key, round.Value.Value, Scale, Group);
                 }
 
 

Modified: trunk/Tools/Maestro/MgCooker/SetupRun.Designer.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/SetupRun.Designer.cs	2009-11-06 21:25:06 UTC (rev 4334)
+++ trunk/Tools/Maestro/MgCooker/SetupRun.Designer.cs	2009-11-09 18:26:32 UTC (rev 4335)
@@ -34,10 +34,21 @@
             this.button3 = new System.Windows.Forms.Button();
             this.button2 = new System.Windows.Forms.Button();
             this.button1 = new System.Windows.Forms.Button();
-            this.treeView1 = new System.Windows.Forms.TreeView();
+            this.MapTree = new System.Windows.Forms.TreeView();
             this.imageList1 = new System.Windows.Forms.ImageList(this.components);
             this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
             this.panel2 = new System.Windows.Forms.Panel();
+            this.BoundsOverride = new System.Windows.Forms.GroupBox();
+            this.ModfiedOverrideWarning = new System.Windows.Forms.Label();
+            this.ResetBounds = new System.Windows.Forms.Button();
+            this.txtUpperY = new System.Windows.Forms.TextBox();
+            this.label4 = new System.Windows.Forms.Label();
+            this.txtUpperX = new System.Windows.Forms.TextBox();
+            this.label5 = new System.Windows.Forms.Label();
+            this.txtLowerY = new System.Windows.Forms.TextBox();
+            this.label10 = new System.Windows.Forms.Label();
+            this.txtLowerX = new System.Windows.Forms.TextBox();
+            this.label11 = new System.Windows.Forms.Label();
             this.groupBox1 = new System.Windows.Forms.GroupBox();
             this.UseNativeAPI = new System.Windows.Forms.CheckBox();
             this.Password = new System.Windows.Forms.TextBox();
@@ -64,6 +75,7 @@
             this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
             this.panel1.SuspendLayout();
             this.panel2.SuspendLayout();
+            this.BoundsOverride.SuspendLayout();
             this.groupBox1.SuspendLayout();
             this.groupBox3.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.ThreadCount)).BeginInit();
@@ -81,7 +93,7 @@
             this.panel1.Controls.Add(this.button2);
             this.panel1.Controls.Add(this.button1);
             this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
-            this.panel1.Location = new System.Drawing.Point(0, 424);
+            this.panel1.Location = new System.Drawing.Point(0, 537);
             this.panel1.Name = "panel1";
             this.panel1.Size = new System.Drawing.Size(565, 41);
             this.panel1.TabIndex = 0;
@@ -120,19 +132,19 @@
             this.button1.UseVisualStyleBackColor = true;
             this.button1.Click += new System.EventHandler(this.button1_Click);
             // 
-            // treeView1
+            // MapTree
             // 
-            this.treeView1.CheckBoxes = true;
-            this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.treeView1.ImageIndex = 0;
-            this.treeView1.ImageList = this.imageList1;
-            this.treeView1.Location = new System.Drawing.Point(0, 0);
-            this.treeView1.Name = "treeView1";
-            this.treeView1.SelectedImageIndex = 0;
-            this.treeView1.Size = new System.Drawing.Size(293, 424);
-            this.treeView1.TabIndex = 1;
-            this.treeView1.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterCheck);
-            this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
+            this.MapTree.CheckBoxes = true;
+            this.MapTree.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.MapTree.ImageIndex = 0;
+            this.MapTree.ImageList = this.imageList1;
+            this.MapTree.Location = new System.Drawing.Point(0, 0);
+            this.MapTree.Name = "MapTree";
+            this.MapTree.SelectedImageIndex = 0;
+            this.MapTree.Size = new System.Drawing.Size(293, 537);
+            this.MapTree.TabIndex = 1;
+            this.MapTree.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterCheck);
+            this.MapTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.MapTree_AfterSelect);
             // 
             // imageList1
             // 
@@ -150,15 +162,126 @@
             // 
             // panel2
             // 
+            this.panel2.Controls.Add(this.BoundsOverride);
             this.panel2.Controls.Add(this.groupBox1);
             this.panel2.Controls.Add(this.groupBox3);
             this.panel2.Controls.Add(this.groupBox2);
             this.panel2.Dock = System.Windows.Forms.DockStyle.Right;
             this.panel2.Location = new System.Drawing.Point(293, 0);
             this.panel2.Name = "panel2";
-            this.panel2.Size = new System.Drawing.Size(272, 424);
+            this.panel2.Size = new System.Drawing.Size(272, 537);
             this.panel2.TabIndex = 2;
             // 
+            // BoundsOverride
+            // 
+            this.BoundsOverride.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.BoundsOverride.Controls.Add(this.ModfiedOverrideWarning);
+            this.BoundsOverride.Controls.Add(this.ResetBounds);
+            this.BoundsOverride.Controls.Add(this.txtUpperY);
+            this.BoundsOverride.Controls.Add(this.label4);
+            this.BoundsOverride.Controls.Add(this.txtUpperX);
+            this.BoundsOverride.Controls.Add(this.label5);
+            this.BoundsOverride.Controls.Add(this.txtLowerY);
+            this.BoundsOverride.Controls.Add(this.label10);
+            this.BoundsOverride.Controls.Add(this.txtLowerX);
+            this.BoundsOverride.Controls.Add(this.label11);
+            this.BoundsOverride.Enabled = false;
+            this.BoundsOverride.Location = new System.Drawing.Point(12, 424);
+            this.BoundsOverride.Name = "BoundsOverride";
+            this.BoundsOverride.Size = new System.Drawing.Size(248, 120);
+            this.BoundsOverride.TabIndex = 12;
+            this.BoundsOverride.TabStop = false;
+            this.BoundsOverride.Text = "Override bounds";
+            // 
+            // ModfiedOverrideWarning
+            // 
+            this.ModfiedOverrideWarning.AutoSize = true;
+            this.ModfiedOverrideWarning.Location = new System.Drawing.Point(8, 96);
+            this.ModfiedOverrideWarning.Name = "ModfiedOverrideWarning";
+            this.ModfiedOverrideWarning.Size = new System.Drawing.Size(105, 13);
+            this.ModfiedOverrideWarning.TabIndex = 19;
+            this.ModfiedOverrideWarning.Text = "Coordinates modified";
+            this.ModfiedOverrideWarning.Visible = false;
+            // 
+            // ResetBounds
+            // 
+            this.ResetBounds.Location = new System.Drawing.Point(136, 88);
+            this.ResetBounds.Name = "ResetBounds";
+            this.ResetBounds.Size = new System.Drawing.Size(88, 24);
+            this.ResetBounds.TabIndex = 18;
+            this.ResetBounds.Text = "Reset";
+            this.ResetBounds.UseVisualStyleBackColor = true;
+            this.ResetBounds.Click += new System.EventHandler(this.ResetBounds_Click);
+            // 
+            // txtUpperY
+            // 
+            this.txtUpperY.Location = new System.Drawing.Point(144, 56);
+            this.txtUpperY.Name = "txtUpperY";
+            this.txtUpperY.Size = new System.Drawing.Size(80, 20);
+            this.txtUpperY.TabIndex = 17;
+            this.txtUpperY.TextChanged += new System.EventHandler(this.CoordinateItem_TextChanged);
+            // 
+            // label4
+            // 
+            this.label4.FlatStyle = System.Windows.Forms.FlatStyle.System;
+            this.label4.Location = new System.Drawing.Point(120, 56);
+            this.label4.Name = "label4";
+            this.label4.Size = new System.Drawing.Size(16, 16);
+            this.label4.TabIndex = 16;
+            this.label4.Text = "Y";
+            // 
+            // txtUpperX
+            // 
+            this.txtUpperX.Location = new System.Drawing.Point(32, 56);
+            this.txtUpperX.Name = "txtUpperX";
+            this.txtUpperX.Size = new System.Drawing.Size(72, 20);
+            this.txtUpperX.TabIndex = 15;
+            this.txtUpperX.TextChanged += new System.EventHandler(this.CoordinateItem_TextChanged);
+            // 
+            // label5
+            // 
+            this.label5.FlatStyle = System.Windows.Forms.FlatStyle.System;
+            this.label5.Location = new System.Drawing.Point(8, 56);
+            this.label5.Name = "label5";
+            this.label5.Size = new System.Drawing.Size(16, 16);
+            this.label5.TabIndex = 14;
+            this.label5.Text = "X";
+            // 
+            // txtLowerY
+            // 
+            this.txtLowerY.Location = new System.Drawing.Point(144, 24);
+            this.txtLowerY.Name = "txtLowerY";
+            this.txtLowerY.Size = new System.Drawing.Size(80, 20);
+            this.txtLowerY.TabIndex = 13;
+            this.txtLowerY.TextChanged += new System.EventHandler(this.CoordinateItem_TextChanged);
+            // 
+            // label10
+            // 
+            this.label10.FlatStyle = System.Windows.Forms.FlatStyle.System;
+            this.label10.Location = new System.Drawing.Point(120, 24);
+            this.label10.Name = "label10";
+            this.label10.Size = new System.Drawing.Size(16, 16);
+            this.label10.TabIndex = 12;
+            this.label10.Text = "Y";
+            // 
+            // txtLowerX
+            // 
+            this.txtLowerX.Location = new System.Drawing.Point(32, 24);
+            this.txtLowerX.Name = "txtLowerX";
+            this.txtLowerX.Size = new System.Drawing.Size(72, 20);
+            this.txtLowerX.TabIndex = 11;
+            this.txtLowerX.TextChanged += new System.EventHandler(this.CoordinateItem_TextChanged);
+            // 
+            // label11
+            // 
+            this.label11.FlatStyle = System.Windows.Forms.FlatStyle.System;
+            this.label11.Location = new System.Drawing.Point(8, 24);
+            this.label11.Name = "label11";
+            this.label11.Size = new System.Drawing.Size(16, 16);
+            this.label11.TabIndex = 10;
+            this.label11.Text = "X";
+            // 
             // groupBox1
             // 
             this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
@@ -436,16 +559,18 @@
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(565, 465);
-            this.Controls.Add(this.treeView1);
+            this.ClientSize = new System.Drawing.Size(565, 578);
+            this.Controls.Add(this.MapTree);
             this.Controls.Add(this.panel2);
             this.Controls.Add(this.panel1);
             this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
-            this.MinimumSize = new System.Drawing.Size(449, 492);
+            this.MinimumSize = new System.Drawing.Size(581, 598);
             this.Name = "SetupRun";
             this.Text = "Setup a tile build";
             this.panel1.ResumeLayout(false);
             this.panel2.ResumeLayout(false);
+            this.BoundsOverride.ResumeLayout(false);
+            this.BoundsOverride.PerformLayout();
             this.groupBox1.ResumeLayout(false);
             this.groupBox1.PerformLayout();
             this.groupBox3.ResumeLayout(false);
@@ -469,7 +594,7 @@
         private System.Windows.Forms.Panel panel1;
         private System.Windows.Forms.Button button2;
         private System.Windows.Forms.Button button1;
-        private System.Windows.Forms.TreeView treeView1;
+        private System.Windows.Forms.TreeView MapTree;
         private System.Windows.Forms.Button button3;
         private System.Windows.Forms.SaveFileDialog saveFileDialog1;
         private System.Windows.Forms.ImageList imageList1;
@@ -498,5 +623,16 @@
         private System.Windows.Forms.Panel TilesetLimitPanel;
         private System.Windows.Forms.ToolTip toolTip1;
         private System.Windows.Forms.CheckBox RandomTileOrder;
+        private System.Windows.Forms.GroupBox BoundsOverride;
+        private System.Windows.Forms.TextBox txtUpperY;
+        private System.Windows.Forms.Label label4;
+        private System.Windows.Forms.TextBox txtUpperX;
+        private System.Windows.Forms.Label label5;
+        private System.Windows.Forms.TextBox txtLowerY;
+        private System.Windows.Forms.Label label10;
+        private System.Windows.Forms.TextBox txtLowerX;
+        private System.Windows.Forms.Label label11;
+        private System.Windows.Forms.Button ResetBounds;
+        private System.Windows.Forms.Label ModfiedOverrideWarning;
     }
 }
\ No newline at end of file

Modified: trunk/Tools/Maestro/MgCooker/SetupRun.cs
===================================================================
--- trunk/Tools/Maestro/MgCooker/SetupRun.cs	2009-11-06 21:25:06 UTC (rev 4334)
+++ trunk/Tools/Maestro/MgCooker/SetupRun.cs	2009-11-09 18:26:32 UTC (rev 4335)
@@ -31,6 +31,8 @@
     {
         private MaestroAPI.ServerConnectionI m_connection;
         private Dictionary<string, string> m_commandlineargs;
+        private Dictionary<string, MaestroAPI.Box2DType> m_coordinateOverrides;
+        private bool m_isUpdating = false;
 
         private SetupRun()
         {
@@ -43,6 +45,7 @@
         {
             m_connection = connection;
             m_commandlineargs = args;
+            m_coordinateOverrides = new Dictionary<string, OSGeo.MapGuide.MaestroAPI.Box2DType>();
 
             if (m_commandlineargs.ContainsKey("mapdefinitions"))
                 m_commandlineargs.Remove("mapdefinitions");
@@ -103,15 +106,16 @@
                 maps = tmp.ToArray();
             }
 
-            treeView1.Nodes.Clear();
+            MapTree.Nodes.Clear();
             foreach (string m in maps)
             {
                 MaestroAPI.MapDefinition mdef = m_connection.GetMapDefinition(m);
-                if (mdef.BaseMapDefinition != null && mdef.BaseMapDefinition.FiniteDisplayScale != null && mdef.BaseMapDefinition.BaseMapLayerGroup != null)
+                if (mdef.BaseMapDefinition != null && mdef.BaseMapDefinition.FiniteDisplayScale != null && mdef.BaseMapDefinition.BaseMapLayerGroup != null && mdef.BaseMapDefinition.BaseMapLayerGroup.Count > 0)
                 {
-                    TreeNode mn = treeView1.Nodes.Add(m);
+                    TreeNode mn = MapTree.Nodes.Add(m);
                     //mn.Checked = true;
-                    mn.ImageIndex  = mn.SelectedImageIndex = 0;
+                    mn.ImageIndex = mn.SelectedImageIndex = 0;
+                    mn.Tag = mdef;
                     foreach (MaestroAPI.BaseMapLayerGroupCommonType g in mdef.BaseMapDefinition.BaseMapLayerGroup)
                     {
                         TreeNode gn = mn.Nodes.Add(g.Name);
@@ -129,7 +133,6 @@
 
                     mn.Expand();
                 }
-                
             }
         }
 
@@ -205,6 +208,8 @@
                     BatchMap bm = new BatchMap(bx, c.MapDefinition);
                     bm.SetGroups(new string[] { c.Group });
                     bm.SetScales(c.ScaleIndexes);
+                    if (c.ExtentOverride != null)
+                        bm.MaxExtent = c.ExtentOverride;
                     bx.Maps.Add(bm);
                 }
 
@@ -221,7 +226,7 @@
         private List<Config> ReadTree()
         {
             List<Config> lst = new List<Config>();
-            foreach(TreeNode mn in treeView1.Nodes)
+            foreach(TreeNode mn in MapTree.Nodes)
                 if (mn.Checked)
                 {
                     foreach(TreeNode gn in mn.Nodes)
@@ -233,7 +238,7 @@
                                     ix.Add(sn.Index);
 
                             if (ix.Count > 0)
-                                lst.Add(new Config(mn.Text, gn.Text, ix.ToArray()));
+                                lst.Add(new Config(mn.Text, gn.Text, ix.ToArray(), (m_coordinateOverrides.ContainsKey(mn.Text) ? m_coordinateOverrides[mn.Text] : null)));
                         }
                 }
 
@@ -245,12 +250,14 @@
             public string MapDefinition;
             public string Group;
             public int[] ScaleIndexes;
+            public MaestroAPI.Box2DType ExtentOverride = null;
 
-            public Config(string MapDefinition, string Group, int[] ScaleIndexes)
+            public Config(string MapDefinition, string Group, int[] ScaleIndexes, MaestroAPI.Box2DType ExtentOverride)
             {
                 this.MapDefinition = MapDefinition;
                 this.Group = Group;
                 this.ScaleIndexes = ScaleIndexes;
+                this.ExtentOverride = ExtentOverride;
             }
         }
 
@@ -323,6 +330,18 @@
                             sw.Write(c.ScaleIndexes[i].ToString());
                         }
 
+                        if (c.ExtentOverride != null)
+                        {
+                            sw.Write(" --extentoverride=");
+                            sw.Write(c.ExtentOverride.MinX.ToString(System.Globalization.CultureInfo.InvariantCulture));
+                            sw.Write(",");
+                            sw.Write(c.ExtentOverride.MinY.ToString(System.Globalization.CultureInfo.InvariantCulture));
+                            sw.Write(",");
+                            sw.Write(c.ExtentOverride.MaxX.ToString(System.Globalization.CultureInfo.InvariantCulture));
+                            sw.Write(",");
+                            sw.Write(c.ExtentOverride.MaxY.ToString(System.Globalization.CultureInfo.InvariantCulture));
+                        }
+
                         sw.Write(args.ToString());
                         sw.WriteLine();
                     }
@@ -383,11 +402,93 @@
         private void UseOfficialMethod_CheckedChanged(object sender, EventArgs e)
         {
             OfficialMethodPanel.Enabled = UseOfficialMethod.Checked;
+            MapTree_AfterSelect(null, null);
         }
 
-        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
+        private void MapTree_AfterSelect(object sender, TreeViewEventArgs e)
         {
+            if (m_isUpdating)
+                return;
 
+            if (MapTree.SelectedNode == null || !UseOfficialMethod.Checked)
+            {
+                BoundsOverride.Enabled = false;
+                BoundsOverride.Tag = null;
+            }
+            else
+            {
+                BoundsOverride.Enabled = true;
+                TreeNode root = MapTree.SelectedNode;
+                while (root.Parent != null)
+                    root = root.Parent;
+
+                MaestroAPI.Box2DType box;
+                if (m_coordinateOverrides.ContainsKey(root.Text))
+                    box = m_coordinateOverrides[root.Text];
+                else
+                    box = ((MaestroAPI.MapDefinition)root.Tag).Extents;
+
+                BoundsOverride.Tag = root;
+
+                try
+                {
+                    m_isUpdating = true;
+                    txtLowerX.Text = box.MinX.ToString(System.Globalization.CultureInfo.CurrentUICulture);
+                    txtLowerY.Text = box.MinY.ToString(System.Globalization.CultureInfo.CurrentUICulture);
+                    txtUpperX.Text = box.MaxX.ToString(System.Globalization.CultureInfo.CurrentUICulture);
+                    txtUpperY.Text = box.MaxY.ToString(System.Globalization.CultureInfo.CurrentUICulture);
+                }
+                finally
+                {
+                    m_isUpdating = false;
+                }
+
+                ModfiedOverrideWarning.Visible = m_coordinateOverrides.ContainsKey(root.Text);
+            }
         }
+
+        private void ResetBounds_Click(object sender, EventArgs e)
+        {
+            if (BoundsOverride.Tag as TreeNode == null)
+                return;
+
+            TreeNode root = BoundsOverride.Tag as TreeNode;
+
+            if (m_coordinateOverrides.ContainsKey(root.Text))
+                m_coordinateOverrides.Remove(root.Text);
+
+            MapTree_AfterSelect(null, null);
+        }
+
+        private void CoordinateItem_TextChanged(object sender, EventArgs e)
+        {
+            if (BoundsOverride.Tag as TreeNode == null || m_isUpdating)
+                return;
+
+            TreeNode root = BoundsOverride.Tag as TreeNode;
+
+            if (!m_coordinateOverrides.ContainsKey(root.Text))
+            {
+                MaestroAPI.Box2DType newbox = new OSGeo.MapGuide.MaestroAPI.Box2DType();
+                MaestroAPI.Box2DType origbox = ((MaestroAPI.MapDefinition)root.Tag).Extents;
+
+                newbox.MinX = origbox.MinX;
+                newbox.MinY = origbox.MinY;
+                newbox.MaxX = origbox.MaxX;
+                newbox.MaxY = origbox.MaxY;
+
+                m_coordinateOverrides.Add(root.Text, newbox);
+            }
+
+            double d;
+            if (double.TryParse(txtLowerX.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentUICulture, out d))
+                m_coordinateOverrides[root.Text].MinX = d;
+            if (double.TryParse(txtLowerY.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentUICulture, out d))
+                m_coordinateOverrides[root.Text].MinY = d;
+            if (double.TryParse(txtUpperX.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentUICulture, out d))
+                m_coordinateOverrides[root.Text].MaxX = d;
+            if (double.TryParse(txtUpperY.Text, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.CurrentUICulture, out d))
+                m_coordinateOverrides[root.Text].MaxY = d;
+        }
     }
 }
\ No newline at end of file

Modified: trunk/Tools/Maestro/MgCooker/SetupRun.resx
===================================================================
--- trunk/Tools/Maestro/MgCooker/SetupRun.resx	2009-11-06 21:25:06 UTC (rev 4334)
+++ trunk/Tools/Maestro/MgCooker/SetupRun.resx	2009-11-09 18:26:32 UTC (rev 4335)
@@ -124,64 +124,61 @@
     <value>
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
-        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABO
-        DQAAAk1TRnQBSQFMAgEBBAEAAQkBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
-        AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AKgABHgIBASgBJgIB
-        ATYBJgIBATYBJgIBATYBJgIBATYBJgIBATYBJgIBATYBJgIBATYBJgIBATYBJgIBATYBJgIBATYBJgIB
-        ATYBHAIBASYcAAEXAgEBHgFiAhIBxgEfAgEBKgEDAgEBA6AAA/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/
-        A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/ARwCAQEmHAABnwJ/AfcB9AHmAeEB/wHlAdABzAH9AakBjgGN
-        AfkBTQICAZEBEgIBAReYAAP9Af8B9QHoAeQB/wH0AeUB4AH/AfIB4gHdAf8B8QHgAdkB/wHwAd0B1gH/
-        Ae8B2wHTAf8B7gHZAdEB/wHuAdgB0AH/Ae4B2AHQAf8B7gHYAdAB/wP9Af8BHAIBASYYAAEtAgEBQwH1
-        AegB4wH/AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AfIB4QHbAf8B0AGwAawB+gGFAlgB8AE3AgEBWAEN
-        AgEBDwwAAR8CAQEqAR8CAQEqIAABBwIBAQcBHwIBASoBHwIBASpMAAP9Af8B9wHtAekB/wH2AeoB5gH/
-        AfQB5wHjAf8B3QG1AbAB/wG9AXQBbwH/Ab4BeAFzAf8B4wHCAbwB/wHvAdoB0gH/Ae4B2AHQAf8B7gHY
-        AdAB/wP9Af8BHAIBASYYAAGqAY8BjgH4AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHdAf8B8gHh
-        AdsB/wHxAd8B2QH/AfAB3QHXAf8B7wHcAdUB/wG2AaABnAH6AV0CDgHCCAADBAH/KAABMQIBAUwDBAH/
-        TAAD/QH/AfgB8AHtAf8B7QHXAdIB/wG5AYkBcgH/AWIBkwEyAf8B6gGxAToB/wHoAa4BMQH/AesBwQFl
-        Af8BsQFcAVcB/wHuAdkB0gH/Ae4B2QHSAf8D/QH/ARwCAQEmFAABQQIBAXAB9QHpAeUB/wH1AegB4wH/
-        AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AfIB4QHbAf8B8QHfAdkB/wHwAd0B1wH/Ae8B3AHVAf8B7wHa
-        AdMB/wE5AgEBXAgAAwQB/wgAAUcCAQF/AQIDAQEDAgEBAgFGAgEBfQQAASkCAQE8ASYCAQE3BAABMAIB
-        AUoDBAH/DAABEgIBARcBTQIDAdEDBAH/ASkCAQE8EAABOQIBAVwDBAH/GAAD/QH/AfYB6gHmAf8B6AG/
-        AZwB/wH7AcsBZQH/AT8BrQFMAf8BVwGdAS0B/wH+AcQBRQH/Af4BvgEwAf8B9gG2ASYB/wGXAXUBUgH/
-        AfAB3QHWAf8D/QH/ARwCAQEmFAABugGcAZsB+AH1AekB5QH/AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/
-        AfIB4wHdAf8B8gHhAdsB/wHxAd8B2QH/AfAB3QHXAf8B7wHcAdUB/wGWAncB9gEGAgEBBggAAwQB/wgA
-        AwQB/wFGAgEBfQFJAgIBhQMEAf8EAAMEAf8DBAH/BAABMAIBAUoDBAH/EAABQwIBAXQDBAH/FAABDgIB
-        AREBSgIDAdUYAAP9Af8BuQFiAU0B/wH6Ac4BcQH/AaQBtgFZAf8BPwGtAU0B/wE+Aa0BTAH/AckBvwFb
-        Af8B/gHEAUQB/wH+AcABNQH/AT0BpQFEAf8BvAF0AXEB/wP9Af8BHAIBASYQAAFTAgUBngH2AesB5wH/
-        AfUB6QHlAf8B9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8B8AHd
-        AdcB/wHaAcgBwwH8ASkCAQE8DAADBAH/KAABMAIBAUoDBAH/EAABQwIBAXQDBAH/NAAD/QH/AeoBwwGh
-        Af8B/QHWAYQB/wGbAbYBXwH/AT0BnwEyAf8B8QHYAZEB/wH9AdEBdQH/AZwBsAFGAf8BPwGtAU0B/wE/
-        Aa0BTQH/AZgBcAFPAf8D/QH/ARwCAQEmEAABxAGkAaEB9wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0
-        AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8B8AHdAdcB/wGBAU0BSwHrAQMCAQEC
-        DAADBAH/KAABMAIBAUoDBAH/EAABQwIBAXQDBAH/FAABAwIBAQMBUQICAaEYAAP9Af8B+gHiAbkB/wFA
-        AZoBKQH/AtQBmwH/Af0B4wG1Af8B/QHdAZ0B/wH9AdQBfgH/AeQByAFjAf8BPgGsAUsB/wFVAZwBKgH/
-        AZ4BigFgAf8D/QH/ARwCAQEmDAABZgIXAckB9wHtAekB/wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0
-        AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8B1QG1Aa4B+gEcAgEBJhAAAwQB/ygA
-        ATACAQFKAwQB/xAAAUMCAQF0AwQB/xQAAT8CAQFrAwQB/xgAA/0B/wFyAZABOgH/AT8BrQFNAf8BPwGt
-        AU0B/wGvAcEBeQH/Af0B2wGVAf8B/QHTAXkB/wH+AcoBVwH/AUcBmgEpAf8BPQGXASQB/wGcAXIBUAH/
-        A/0B/wEcAgEBJggAAQUCAQEFAdkBwgG/AfoB9wHtAekB/wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0
-        AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8BZgIcAdIUAAMEAf8oAAEwAgEBSgME
-        Af8QAAFDAgEBdgMEAf80AAP9Af8BvgF0AVQB/wE/Aa0BTQH/AT4BowE7Af8BPgGtAUwB/wHAAcIBbAH/
-        Af4BzgFnAf8B/gHGAUkB/wFeAZQBGwH/AcIBugFLAf8BxQGBAX0B/wP9Af8BHAIBASYIAAF/AkYB5wH4
-        Ae4B6wH/AfcB7QHpAf8B9gHrAecB/wH1AekB5QH/AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHd
-        Af8B8gHhAdsB/wHCAaIBnwH4ARQCAQEaFAADBAH/KAABMAIBAUoDBAH/DAABCgIBAQsBRAIEAd4DBAH/
-        NAAD/QH/AfcB7QHpAf8BegGQAT4B/wGnAbUBUwH/AT8BkwEdAf8BqgG3AVUB/wFSAZ4BLgH/AfIBwgFG
-        Af8B/gG9ASsB/wHFAX0BaQH/AfkB8QHuAf8D/QH/ARwCAQEmBAABFAIBARkB2wHGAcUB+gH4Ae4B6wH/
+        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACM
+        DAAAAk1TRnQBSQFMAgEBBAEAATQBAAE0AQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+        AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AKgADHAEoAyQBNgMk
+        ATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDGwEmHAADFgEeAVsCVQHGAx0BKgMC
+        AQOgAAP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wMbASYcAAGL
+        Am4B9wH0AeYB4QH/AdMBvgG9Af0BkgGIAYcB+QFNAkwBkQMRAReYAAP9Af8B9QHoAeQB/wH0AeUB4AH/
+        AfIB4gHdAf8B8QHgAdkB/wHwAd0B1gH/Ae8B2wHTAf8B7gHZAdEB/wHuAdgB0AH/Ae4B2AHQAf8B7gHY
+        AdAB/wP9Af8DGwEmGAABLAIrAUMB9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/
+        AbMBoQGeAfoBbgJaAfABNgI1AVgDCwEPDAADHQEqAx0BKiAAAwUBBwMdASoDHQEqTAAD/QH/AfcB7QHp
+        Af8B9gHqAeYB/wH0AecB4wH/Ad0BtQGwAf8BvQFuAWkB/wG+AXIBbQH/AeMBwgG8Af8B7wHaAdIB/wHu
+        AdgB0AH/Ae4B2AHQAf8D/QH/AxsBJhgAAZcCfgH4AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHd
+        Af8B8gHhAdsB/wHxAd8B2QH/AfAB3QHXAf8B7wHcAdUB/wGkAZIBjAH6AVkCVgHCCwAB/ygAAzABTAMA
+        Af9MAAP9Af8B+AHwAe0B/wHtAdcB0gH/AbkBiQFsAf8BXAGTASwB/wHqAbEBNAH/AegBrgErAf8B6wHB
+        AV8B/wGxAVYBUQH/Ae4B2QHSAf8B7gHZAdIB/wP9Af8DGwEmFAADQAFwAfUB6QHlAf8B9QHoAeMB/wH0
+        AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8B8AHdAdcB/wHvAdwB1QH/Ae8B2gHT
+        Af8DOAFcCwAB/wgAAUYCRQF/AwAEAQECA0UBfQQAAygBPAMlATcEAAMvAUoDAAH/DAADEQEXAVgCVAHR
+        AwAB/wMoATwQAAM4AVwDAAH/GAAD/QH/AfYB6gHmAf8B6AG/AZwB/wH7AcsBXwH/ATkBrQFGAf8BUQGd
+        AScB/wH+AcQBPwH/Af4BvgEqAf8B9gG2ASAB/wGXAW8BTAH/AfAB3QHWAf8D/QH/AxsBJhQAAZ8BkAGO
+        AfgB9QHpAeUB/wH1AegB4wH/AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AfIB4QHbAf8B8QHfAdkB/wHw
+        Ad0B1wH/Ae8B3AHVAf8BgQJoAfYDBAEGCwAB/wsAAf8DRQF9A0gBhQMAAf8HAAH/AwAB/wQAAy8BSgMA
+        Af8QAANCAXQDAAH/FAADDQERAVoCVAHVGAAD/QH/AbkBXAFHAf8B+gHOAWsB/wGkAbYBUwH/ATkBrQFH
+        Af8BOAGtAUYB/wHJAb8BVQH/Af4BxAE+Af8B/gHAAS8B/wE3AaUBPgH/AbwBbgFrAf8D/QH/AxsBJhAA
+        A1ABngH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/
+        AfEB3wHZAf8B8AHdAdcB/wHFAbkBtQH8AygBPA8AAf8oAAMvAUoDAAH/EAADQgF0AwAB/zQAA/0B/wHq
+        AcMBoQH/Af0B1gGEAf8BmwG2AVkB/wE3AZ8BLAH/AfEB2AGRAf8B/QHRAW8B/wGcAbABQAH/ATkBrQFH
+        Af8BOQGtAUcB/wGYAWoBSQH/A/0B/wMbASYQAAGlAY4BjAH3AfYB6wHnAf8B9QHpAeUB/wH1AegB4wH/
+        AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AfIB4QHbAf8B8QHfAdkB/wHwAd0B1wH/AW4BWAFXAesDAQEC
+        DwAB/ygAAy8BSgMAAf8QAANCAXQDAAH/FAADAgEDA1EBoRgAA/0B/wH6AeIBuQH/AToBmgEjAf8C1AGb
+        Af8B/QHjAbUB/wH9Ad0BnQH/Af0B1AF4Af8B5AHIAV0B/wE4AawBRQH/AU8BnAEkAf8BngGKAVoB/wP9
+        Af8DGwEmDAABXAJWAckB9wHtAekB/wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0AeYB4QH/AfMB5AHf
+        Af8B8gHjAd0B/wHyAeEB2wH/AfEB3wHZAf8BuAGjAaAB+gMbASYTAAH/KAADLwFKAwAB/xAAA0IBdAMA
+        Af8UAAM+AWsDAAH/GAAD/QH/AWwBkAE0Af8BOQGtAUcB/wE5Aa0BRwH/Aa8BwQFzAf8B/QHbAZUB/wH9
+        AdMBcwH/Af4BygFRAf8BQQGaASMB/wE3AZcBHgH/AZwBbAFKAf8D/QH/AxsBJggAAwQBBQG9AakBpwH6
         AfcB7QHpAf8B9gHrAecB/wH1AekB5QH/AfUB6AHjAf8B9AHmAeEB/wHzAeQB3wH/AfIB4wHdAf8B8gHh
-        AdsB/wFXAgYBrxgAAUICBAHfAUkCAgGHIAABDQIBAQ8BUwICAbcBQgIEAd9MAAP9Af8B+QHxAe4B/wHy
-        AeEB2wH/Aa0BhgFaAf8B7gHYAYsB/wFTAZ4BLgH/AT4BrQFMAf8BRAGUASAB/wG7AWcBUwH/AfgB8AHt
-        Af8B+QHxAe4B/wP9Af8BHAIBASYIAAEDAgEBAgFXAgcBpwG2AZ4BnAH5AfYB6wHnAf8B9QHpAeUB/wH1
-        AegB4wH/AfQB5gHhAf8B8wHkAd8B/wHyAeMB3QH/AboBmgGWAfgBEAIBAROYAAP9Af8B+QHxAe4B/wH5
-        AfEB7gH/AfkB8QHuAf8B7AHSAckB/wHSAZUBggH/AdQBmgGJAf8B8gHhAdwB/wH5AfEB7gH/AfkB8QHu
-        Af8B+QHxAe4B/wP9Af8BHAIBASYUAAEeAgEBKQF6AT8BPgHkAcYBrQGqAfkB9AHmAeEB/wHzAeQB3wH/
-        AfIB4wHdAf8BSgICAYicAAP9Af8B+gH2AfQB/wH6AfYB9AH/AfoB9gH0Af8B+gH2AfQB/wH6AfYB9AH/
-        AfoB9gH0Af8B+gH2AfQB/wH6AfYB9AH/AfoB9gH0Af8B+gH2AfQB/wP9Af8BHAIBASYgAAE/AgEBawGn
-        AZABjgH6AagBjQGMAfgBCQIBAQqcAAGlAqAB/wGkAaABnwH/AaQCnwH/AaMCngH/AaICnQH/AaECnAH/
-        AaACmwH/AZ8CmgH/AZ0CmQH/AZwBmAGXAf8BmwKWAf8BmQKVAf/IAAFCAU0BPgcAAT4DAAEoAwABQAMA
-        ASADAAEBAQABAQYAAQEWAAP/gQABwAEBAfwBPwT/AcABAQH8AQ8E/wHAAQEB+AEBAc8B8QL/AcABAQH4
-        AQAB3wH5Av8BwAEBAfABAAHYAUkBwwHPAcABAQHwAQAB2AFJAecBzwHAAQEB4AEBAd8B+QHnAf8BwAEB
-        AeABAQHfAfkB5wHPAcABAQHAAQMB3wH5AecBzwHAAQEBgAEHAd8B+QHnAf8BwAEBAYABBwHfAfkBxwH/
-        AcABAQEAAQ8BzwHxAv8BwAEBAYABDwT/AcABAQHwAR8E/wHAAQEB/gEfBP8BwAEDBv8L
+        AdsB/wHxAd8B2QH/AV0CVgHSFwAB/ygAAy8BSgMAAf8QAANCAXYDAAH/NAAD/QH/Ab4BbgFOAf8BOQGt
+        AUcB/wE4AaMBNQH/ATgBrQFGAf8BwAHCAWYB/wH+Ac4BYQH/Af4BxgFDAf8BWAGUARUB/wHCAboBRQH/
+        AcUBgQF3Af8D/QH/AxsBJggAAWoCVQHnAfgB7gHrAf8B9wHtAekB/wH2AesB5wH/AfUB6QHlAf8B9QHo
+        AeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wHyAeEB2wH/AaYBlAGSAfgDEwEaFwAB/ygAAy8BSgMA
+        Af8MAAMIAQsBVgJOAd4DAAH/NAAD/QH/AfcB7QHpAf8BdAGQATgB/wGnAbUBTQH/ATkBkwEXAf8BqgG3
+        AU8B/wFMAZ4BKAH/AfIBwgFAAf8B/gG9ASUB/wHFAXcBYwH/AfkB8QHuAf8D/QH/AxsBJgQAAxIBGQG/
+        AawBqwH6AfgB7gHrAf8B9wHtAekB/wH2AesB5wH/AfUB6QHlAf8B9QHoAeMB/wH0AeYB4QH/AfMB5AHf
+        Af8B8gHjAd0B/wHyAeEB2wH/AVQCUwGvGAABVwJKAd8BSQJIAYcgAAMLAQ8DVQG3AVcCSgHfTAAD/QH/
+        AfkB8QHuAf8B8gHhAdsB/wGtAYYBVAH/Ae4B2AGLAf8BTQGeASgB/wE4Aa0BRgH/AT4BlAEaAf8BuwFh
+        AU0B/wH4AfAB7QH/AfkB8QHuAf8D/QH/AxsBJggAAwEBAgFSAlEBpwGhAo0B+QH2AesB5wH/AfUB6QHl
+        Af8B9QHoAeMB/wH0AeYB4QH/AfMB5AHfAf8B8gHjAd0B/wGfAY0BhwH4Aw4BE5gAA/0B/wH5AfEB7gH/
+        AfkB8QHuAf8B+QHxAe4B/wHsAdIByQH/AdIBlQGCAf8B1AGaAYkB/wHyAeEB3AH/AfkB8QHuAf8B+QHx
+        Ae4B/wH5AfEB7gH/A/0B/wMbASYUAAMdASkBZAJUAeQBrQGWAZIB+QH0AeYB4QH/AfMB5AHfAf8B8gHj
+        Ad0B/wFJAkgBiJwAA/0B/wH6AfYB9AH/AfoB9gH0Af8B+gH2AfQB/wH6AfYB9AH/AfoB9gH0Af8B+gH2
+        AfQB/wH6AfYB9AH/AfoB9gH0Af8B+gH2AfQB/wH6AfYB9AH/A/0B/wMbASYgAAM+AWsBmwJ+AfoBlwJ9
+        AfgDBwEKnAABpQKgAf8BpAGgAZ8B/wGkAp8B/wGjAp4B/wGiAp0B/wGhApwB/wGgApsB/wGfApoB/wGd
+        ApkB/wGcAZgBlwH/AZsClgH/AZkClQH/yAABQgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEB
+        FgAD/4EAAcABAQH8AT8E/wHAAQEB/AEPBP8BwAEBAfgBAQHPAfEC/wHAAQEB+AEAAd8B+QL/AcABAQHw
+        AQAB2AFJAcMBzwHAAQEB8AEAAdgBSQHnAc8BwAEBAeABAQHfAfkB5wH/AcABAQHgAQEB3wH5AecBzwHA
+        AQEBwAEDAd8B+QHnAc8BwAEBAYABBwHfAfkB5wH/AcABAQGAAQcB3wH5AccB/wHAAQEBAAEPAc8B8QL/
+        AcABAQGAAQ8E/wHAAQEB8AEfBP8BwAEBAf4BHwT/AcABAwb/Cw==
 </value>
   </data>
   <metadata name="saveFileDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">



More information about the mapguide-commits mailing list