[mapguide-commits] r7064 - in branches/2.4/MgDev/Desktop: MapViewer MapViewer/AppLayoutEngine MgAppLayout

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Oct 3 06:00:20 PDT 2012


Author: jng
Date: 2012-10-03 06:00:20 -0700 (Wed, 03 Oct 2012)
New Revision: 7064

Added:
   branches/2.4/MgDev/Desktop/MgAppLayout/SheboyganTiled.AppLayout
Modified:
   branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/AppLayout.cs
   branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs
   branches/2.4/MgDev/Desktop/MapViewer/IMapViewer.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgLegend.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgLegendControlPresenter.cs
   branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs
   branches/2.4/MgDev/Desktop/MapViewer/Strings.Designer.cs
   branches/2.4/MgDev/Desktop/MapViewer/Strings.resx
   branches/2.4/MgDev/Desktop/MgAppLayout/MgAppLayout.csproj
   branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout
Log:
#2073: Add a second semi-workaround for mg-desktop's tiled map limitation. We introduce the following new viewer properties:

 * UseRenderMapIfTiledLayersExist
 * RespectFiniteDisplayScales

If UseRenderMapIfTiledLayersExist is true and the map has tiled layers, we use the RenderMap API instead of RenderDynamicOverlay, which has the benefit of being able to render tiled layers if they are visible. If RespectFiniteDisplayScales is true, the viewer will snap any zoom to the map's finite scale list (like AJAX/Fusion does). The two properties combined, will approximate the AJAX/Fusion viewer behaviour wrt a Tiled Map.

The reason this is another semi-workaround and not the definitive solution is that this approach still does not use (our already implemented) tile service APIs and cannot take advantage of pre-rendered tiles in the tile cache, but is more approachable than the existing workaround (using ConvertTiledGroupsToNonTiled) in that the official MapGuide behaviour for RenderMap is the same. Anywhere where we can have behavioural consistency between MapGuide and mg-desktop is a good thing.

Long story short. We can now view tiled maps with minimal compromise, but nothing is actually tiled and cached (the *actual* reason to use a tiled map). Everything is still dynamic. Ideally we want to have the viewer leverage and render off of the existing tile service APIs, and then be able to tweak this logic to support external tiled maps (eg. Google/Bing/OSM). This is still a pipe-dream, but the primary objective of being able to at least *view* MapGuide Tiled Maps has been achieved.

The AppLayout engine has also been updated to support these new viewer properties and also to support a map: lookup property for Component Definitions. Basically any component property that starts with a map: prefix will use the MapDefinition of the named map, thus avoiding having to hard-code a Map Definition. The <Map> element now includes a mandatory <Name> element the is the name of the map. This name is validated on AppLayout load to ensure no bad characters are included.

Modified: branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/AppLayout.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/AppLayout.cs	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/AppLayout.cs	2012-10-03 13:00:20 UTC (rev 7064)
@@ -47,6 +47,7 @@
             layout.Settings = new AppLayoutSettings()
             {
                 ConvertTiledGroupsToNonTiled = true,
+                UseRenderMap = true,
                 SelectionColor = Util.ToHtmlColorWithAlpha(System.Drawing.Color.Blue),
                 ShowVertexCoordinatesWhenDigitizing = false,
                 ZoomInFactor = 0.5,
@@ -269,6 +270,12 @@
         public bool ConvertTiledGroupsToNonTiled { get; set; }
 
         [XmlElement]
+        public bool UseRenderMap { get; set; }
+
+        [XmlElement]
+        public bool RespectFiniteScales { get; set; }
+
+        [XmlElement]
         public bool ShowVertexCoordinatesWhenDigitizing { get; set; }
 
         [XmlElement]
@@ -317,6 +324,9 @@
     public class MapReference
     {
         [XmlElement]
+        public string Name { get; set; }
+
+        [XmlElement]
         public string MapDefinition { get; set; }
     }
 
@@ -432,6 +442,7 @@
     /// </summary>
     public class StringPrefixes
     {
+        public const string MAPDEFINITION = "map:";
         public const string COMPONENTID = "component:";
         public const string COLOR = "color:";
         public const string ENUM = "enum:";

Modified: branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MapViewer/AppLayoutEngine/Shell.cs	2012-10-03 13:00:20 UTC (rev 7064)
@@ -55,6 +55,8 @@
             _menuInvoker = new MgMenuItemComponentInvoker();
             _toolInvoker = new MgToolButtonComponentInvoker();
 
+            ValidateMapNames(layout);
+
             InitializeComponentSet(layout);
             InitializeMenu(layout.Menu);
             InitializeToolbar(layout.Toolbar);
@@ -91,6 +93,21 @@
             mapViewer.PropertyChanged += new PropertyChangedEventHandler(OnMapViewerPropertyChanged);
         }
 
+        const string RESERVED_CHARS = "\\:*?\"<>|&'%=/";
+
+        private static void ValidateMapNames(AppLayout layout)
+        {
+            string mapName = layout.Map.Name;
+            if (mapName.Contains(" "))
+                throw new InvalidOperationException(string.Format(Strings.ErrorInvalidMapName, mapName));
+
+            foreach (char c in mapName)
+            {
+                if (RESERVED_CHARS.IndexOf(c) >= 0)
+                    throw new InvalidOperationException(string.Format(Strings.ErrorInvalidMapName, mapName));
+            }
+        }
+
         private void SetLanguage(CultureInfo lang)
         {
             //The reason we have to do this is because we're setting the language after this object
@@ -382,8 +399,17 @@
 
                 foreach (var prop in compDef.Properties)
                 {
-                    if (prop.Value.StartsWith(StringPrefixes.COLOR))
+                    if (prop.Value.StartsWith(StringPrefixes.MAPDEFINITION))
                     {
+                        var mapName = prop.Value.Substring(StringPrefixes.MAPDEFINITION.Length);
+                        //TODO: Update for multi-maps if/when we support it
+                        if (layout.Map.Name == mapName)
+                            comp.SetPropertyValue(prop.Name, mapName);
+                        else
+                            throw new InvalidOperationException(string.Format(Strings.ErrorMapNotFound, mapName));
+                    }
+                    else if (prop.Value.StartsWith(StringPrefixes.COLOR))
+                    {
                         var colorStr = prop.Value.Substring(StringPrefixes.COLOR.Length);
                         var color = Util.FromHtmlColor(colorStr);
                         comp.SetPropertyValue(prop.Name, color);
@@ -421,6 +447,8 @@
             //Apply viewer properties. We do this here because we want to respect the viewer options component
             //So we apply before the viewer options component gets its chance to
             mapViewer.ConvertTiledGroupsToNonTiled = layout.Settings.ConvertTiledGroupsToNonTiled;
+            mapViewer.UseRenderMapIfTiledLayersExist = layout.Settings.UseRenderMap;
+            mapViewer.RespectFiniteDisplayScales = layout.Settings.RespectFiniteScales;
             mapViewer.SelectionColor = Util.FromHtmlColor(layout.Settings.SelectionColor);
             mapViewer.ShowVertexCoordinatesWhenDigitizing = layout.Settings.ShowVertexCoordinatesWhenDigitizing;
             mapViewer.ZoomInFactor = layout.Settings.ZoomInFactor;

Modified: branches/2.4/MgDev/Desktop/MapViewer/IMapViewer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/IMapViewer.cs	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MapViewer/IMapViewer.cs	2012-10-03 13:00:20 UTC (rev 7064)
@@ -371,11 +371,28 @@
         /// <summary>
         /// Gets or sets whether to convert tiled layers to non-tiled layers. This is a workaround
         /// setting for tiled maps to be displayed as viewer support for tiled layers is still not
-        /// implemented
+        /// implemented.
+        /// 
+        /// If <see cref="P:OSGeo.MapGuide.Viewer.IMapViewer.UseRenderMapIfTiledLayersExist"/> is set
+        /// to true, this property has no effect.
         /// </summary>
         bool ConvertTiledGroupsToNonTiled { get; set; }
 
         /// <summary>
+        /// Gets whether to use the RenderMap API instead of RenderDynamicOverlay if the map has tiled
+        /// layers. RenderMap includes tiled layers as part of the output image, but will not take advantage
+        /// of any tile caching mechanisms. Setting this property to true nullifies any effect of the 
+        /// <see cref="P:OSGeo.MapGuide.Viewer.IMapViewer.ConvertTiledGroupsToNonTiled"/> property
+        /// </summary>
+        bool UseRenderMapIfTiledLayersExist { get; set; }
+
+        /// <summary>
+        /// Gets whether to respect the list of finite display scales in a map being viewed if there are any defined.
+        /// If true, all zooms will "snap" to the nearest finite display scale
+        /// </summary>
+        bool RespectFiniteDisplayScales { get; set; }
+
+        /// <summary>
         /// Gets whether this viewer has a map loaded into it
         /// </summary>
         bool HasLoadedMap { get; }

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgLegend.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgLegend.cs	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgLegend.cs	2012-10-03 13:00:20 UTC (rev 7064)
@@ -196,14 +196,15 @@
             RefreshLegend();
         }
 
-        
-
         private void trvLegend_AfterCheck(object sender, TreeViewEventArgs e)
         {
             if (e.Node.Tag == null)
                 return;
 
             var meta = ((LegendNodeMetadata)e.Node.Tag);
+            if (!meta.Checkable)
+                return;
+
             if (meta.IsGroup) //Group
             {
                 _presenter.SetGroupVisible(meta.ObjectId, e.Node.Checked);
@@ -220,6 +221,9 @@
                 return;
 
             var meta = ((LegendNodeMetadata)e.Node.Tag);
+            if (!meta.Checkable) //Shouldn't happen, but just in case
+                return;
+
             if (meta.IsGroup) //Group
             {
                 _presenter.SetGroupExpandInLegend(meta.ObjectId, true);

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgLegendControlPresenter.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgLegendControlPresenter.cs	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgLegendControlPresenter.cs	2012-10-03 13:00:20 UTC (rev 7064)
@@ -622,7 +622,7 @@
                 var checkBoxOffset = xoffset;
                 var selectabilityOffset = xoffset + 16;
                 var iconOffsetNoSelect = xoffset + 16;
-                if (themeMeta != null) //No checkbox for theme rule nodes
+                if (layerMeta != null && !layerMeta.Checkable) //No checkbox for theme rule nodes
                 {
                     selectabilityOffset = xoffset;
                     iconOffsetNoSelect = xoffset;
@@ -634,7 +634,7 @@
                 //Uncomment if you need to "see" the bounds of the node
                 //e.Graphics.DrawRectangle(Pens.Black, e.Node.Bounds);
 
-                if (layerMeta != null) //No checkbox for theme rule nodes
+                if (layerMeta != null && layerMeta.Checkable) //No checkbox for theme rule nodes
                 {
                     if (Application.RenderWithVisualStyles)
                     {
@@ -774,6 +774,8 @@
         {
             public bool IsGroup { get; protected set; }
 
+            public bool Checkable { get; protected set; }
+
             public abstract string ObjectId { get; }
         }
 
@@ -786,6 +788,7 @@
             {
                 base.IsGroup = true;
                 this.Group = group;
+                this.Checkable = true;
             }
 
             public override string ObjectId
@@ -802,6 +805,7 @@
                 this.IsPlaceholder = bPlaceholder;
                 this.ThemeIcon = themeIcon;
                 this.Label = labelText;
+                this.Checkable = false;
             }
 
             public bool IsPlaceholder { get; private set; }
@@ -858,6 +862,7 @@
             {
                 base.IsGroup = false;
                 this.Layer = layer;
+                this.Checkable = (layer.Group != null && layer.Group.LayerGroupType == MgLayerGroupType.Normal);
                 this.IsSelectable = (layer != null) ? layer.Selectable : false;
                 this.DrawSelectabilityIcon = (layer != null && bInitiallySelectable);
                 this.WasInitiallySelectable = bInitiallySelectable;

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs	2012-10-03 13:00:20 UTC (rev 7064)
@@ -1213,6 +1213,7 @@
 
         private void OnMapSetOnProvider(object sender, EventArgs e)
         {
+            _hasTiledLayers = null;
             _map = _provider.GetMap();
             _mapCs = _provider.GetMapCoordinateSystem();
             _mapMeasure = _mapCs.GetMeasure();
@@ -1301,7 +1302,28 @@
             set;
         }
 
+        [Category("MapGuide Viewer")] //NOXLATE
+        [Description("If true, the viewer will use the RenderMap API instead of RenderDynamicOverlay allowing tiled layers to be rendered to the final image. Setting this property to true nullifies the ConvertTiledGroupsToNonTiled property")] //NOXLATE
+        [DefaultValue(true)]
         /// <summary>
+        /// Gets whether to use the RenderMap API instead of RenderDynamicOverlay if the map has tiled
+        /// layers. RenderMap includes tiled layers as part of the output image, but will not take advantage
+        /// of any tile caching mechanisms. Setting this property to true nullifies any effect of the 
+        /// <see cref="P:OSGeo.MapGuide.Viewer.IMapViewer.ConvertTiledGroupsToNonTiled"/> property
+        /// </summary>
+        public bool UseRenderMapIfTiledLayersExist { get; set; }
+
+        [Category("MapGuide Viewer")] //NOXLATE
+        [Description("If true, all zooms will snap to the nearest finite display scale defined in the map being viewed")] //NOXLATE
+        [DefaultValue(true)]
+        /// <summary>
+        /// Gets whether to respect the list of finite display scales in a map being viewed if there are any defined.
+        /// If true, all zooms will "snap" to the nearest finite display scale. Otherwise, the viewer will disregard
+        /// this list when zooming in or out.
+        /// </summary>
+        public bool RespectFiniteDisplayScales { get; set; }
+
+        /// <summary>
         /// Raised when the viewer has been initialized
         /// </summary>
         [Category("MapGuide Viewer")] //NOXLATE
@@ -1452,6 +1474,10 @@
 
         class RenderWorkArgs
         {
+            public RenderWorkArgs() { this.UseRenderMap = false; }
+
+            public bool UseRenderMap { get; set; }
+
             public MgViewerRenderingOptions SelectionRenderingOptions { get; set; }
 
             public MgViewerRenderingOptions MapRenderingOptions { get; set; }
@@ -1566,6 +1592,7 @@
             {
                 var args = new RenderWorkArgs()
                 {
+                    UseRenderMap = this.UseRenderMapIfTiledLayersExist && this.HasTiledLayers,
                     MapRenderingOptions = _overlayRenderOpts,
                     RaiseEvents = raiseEvents
                 };
@@ -1592,6 +1619,37 @@
             }
         }
 
+        private bool? _hasTiledLayers;
+
+        internal bool HasTiledLayers
+        {
+            get
+            {
+                if (!_hasTiledLayers.HasValue)
+                {
+                    if (_map != null)
+                    {
+                        var groups = _map.GetLayerGroups();
+                        for (int i = 0; i < groups.Count; i++)
+                        {
+                            if (groups[i].LayerGroupType == MgLayerGroupType.BaseMap)
+                            {
+                                _hasTiledLayers = true;
+                                break;
+                            }
+                        }
+                        if (!_hasTiledLayers.HasValue)
+                            _hasTiledLayers = false;
+                    }
+                    else
+                    {
+                        _hasTiledLayers = false;
+                    }
+                }
+                return _hasTiledLayers.Value;
+            }
+        }
+
         /// <summary>
         /// Raised when the map has been refreshed
         /// </summary>
@@ -1810,13 +1868,16 @@
 
         internal void ZoomToView(double x, double y, double scale, bool refresh, bool raiseEvents, bool addToHistoryStack)
         {
+            var newScale = NormalizeScale(scale);
+            if (_map.FiniteDisplayScaleCount > 0 && this.RespectFiniteDisplayScales)
+                newScale = GetNearestFiniteScale(scale);
             if (addToHistoryStack)
             {
                 //If not current view, then any entries from the current view index are no longer needed
                 if (ViewHistoryIndex < _viewHistory.Count - 1)
                     PruneHistoryEntriesFromCurrentView();
 
-                _viewHistory.Add(new MgMapViewHistoryEntry(x, y, scale));
+                _viewHistory.Add(new MgMapViewHistoryEntry(x, y, newScale));
                 OnPropertyChanged("ViewHistory"); //NOXLATE
                 _viewHistoryIndex = _viewHistory.Count - 1;
                 OnPropertyChanged("ViewHistoryIndex"); //NOXLATE
@@ -1833,7 +1894,7 @@
             Trace.TraceInformation("Center is (" + x + ", " + y + ")");
 #endif
             var oldScale = _map.ViewScale;
-            _provider.SetViewScale(NormalizeScale(scale));
+            _provider.SetViewScale(newScale);
 
             if (oldScale != _map.ViewScale)
             {
@@ -1853,6 +1914,36 @@
                 RefreshMap(raiseEvents);
         }
 
+        private double GetNearestFiniteScale(double scale)
+        {
+            return _map.GetFiniteDisplayScaleAt(GetFiniteScaleIndex(scale));
+        }
+
+        private int GetFiniteScaleIndex(double reqScale)
+        {
+            var index = 0;
+            var scaleCount = _map.GetFiniteDisplayScaleCount();
+            if (scaleCount > 0)
+            {
+                var bestDiff = Math.Abs(_map.GetFiniteDisplayScaleAt(0) - reqScale);
+                for (var i = 1; i < scaleCount; i++)
+                {
+                    var scaleDiff = Math.Abs(_map.GetFiniteDisplayScaleAt(i) - reqScale);
+                    if (scaleDiff < bestDiff)
+                    {
+                        index = i;
+                        bestDiff = scaleDiff;
+                        if (bestDiff == 0)
+                        {
+                            //perfect match
+                            break;
+                        }
+                    }
+                }
+            }
+            return index;
+        }
+
         /// <summary>
         /// Raised when the scale of the current runtime map has changed
         /// </summary>
@@ -1874,7 +1965,11 @@
             var res = new RenderResult() { RaiseEvents = args.RaiseEvents, InvalidateRegardless = args.InvalidateRegardless };
             if (args.MapRenderingOptions != null)
             {
-                var br = _provider.RenderDynamicOverlay(null, args.MapRenderingOptions);
+                MgByteReader br = null;
+                if (args.UseRenderMap)
+                    br = _provider.RenderMap(null, args.MapRenderingOptions.Format);
+                else
+                    br = _provider.RenderDynamicOverlay(null, args.MapRenderingOptions);
                 byte[] b = new byte[br.GetLength()];
                 br.Read(b, b.Length);
                 using (var ms = new MemoryStream(b))

Modified: branches/2.4/MgDev/Desktop/MapViewer/Strings.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/Strings.Designer.cs	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MapViewer/Strings.Designer.cs	2012-10-03 13:00:20 UTC (rev 7064)
@@ -169,6 +169,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to Invalid map name "{0}". A map name cannot have spaces or any of the following characters: \:*?"<>|&'%=/.
+        /// </summary>
+        internal static string ErrorInvalidMapName {
+            get {
+                return ResourceManager.GetString("ErrorInvalidMapName", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to Layer metadata not fully initialized.
         /// </summary>
         internal static string ErrorLayerMetadataNotFullyInitialized {
@@ -187,6 +196,15 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to A map named ({0}) was not found in the AppLayout.
+        /// </summary>
+        internal static string ErrorMapNotFound {
+            get {
+                return ResourceManager.GetString("ErrorMapNotFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to This feature is not yet implemented.
         /// </summary>
         internal static string ErrorNotImplemented {

Modified: branches/2.4/MgDev/Desktop/MapViewer/Strings.resx
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/Strings.resx	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MapViewer/Strings.resx	2012-10-03 13:00:20 UTC (rev 7064)
@@ -381,4 +381,10 @@
   <data name="TextLayersRefreshing" xml:space="preserve">
     <value>Layers (Refreshing...)</value>
   </data>
+  <data name="ErrorInvalidMapName" xml:space="preserve">
+    <value>Invalid map name "{0}". A map name cannot have spaces or any of the following characters: \:*?"<>|&'%=/</value>
+  </data>
+  <data name="ErrorMapNotFound" xml:space="preserve">
+    <value>A map named ({0}) was not found in the AppLayout</value>
+  </data>
 </root>
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MgAppLayout/MgAppLayout.csproj
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/MgAppLayout.csproj	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/MgAppLayout.csproj	2012-10-03 13:00:20 UTC (rev 7064)
@@ -85,6 +85,9 @@
       <AutoGen>True</AutoGen>
       <DependentUpon>Resources.resx</DependentUpon>
     </Compile>
+    <None Include="SheboyganTiled.AppLayout">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>

Modified: branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout	2012-10-01 18:04:50 UTC (rev 7063)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/Sheboygan.AppLayout	2012-10-03 13:00:20 UTC (rev 7064)
@@ -3,9 +3,10 @@
   <Title>MapGuide Desktop App Layout Example</Title>
   <Icon>app.ico</Icon>
   <Settings>
-    <InvokeOnStartup>Startup</InvokeOnStartup>
     <SelectionColor>0000FF</SelectionColor>
-    <ConvertTiledGroupsToNonTiled>true</ConvertTiledGroupsToNonTiled>
+    <ConvertTiledGroupsToNonTiled>false</ConvertTiledGroupsToNonTiled>
+    <UseRenderMap>false</UseRenderMap>
+    <RespectFiniteScales>false</RespectFiniteScales>
     <ShowVertexCoordinatesWhenDigitizing>false</ShowVertexCoordinatesWhenDigitizing>
     <ZoomInFactor>0.5</ZoomInFactor>
     <ZoomOutFactor>2</ZoomOutFactor>
@@ -23,6 +24,7 @@
     </PropertyPane>
   </InfoPane>
   <Map>
+    <Name>Sheboygan</Name>
     <MapDefinition>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</MapDefinition>
   </Map>
   <Menu>
@@ -164,20 +166,6 @@
           </ItemBase>
         </Items>
       </ItemBase>
-      <ItemBase xsi:type="SeparatorItem" />
-      <ItemBase xsi:type="SubMenu">
-        <Label>Custom</Label>
-        <Items>
-          <ItemBase xsi:type="CommandItem">
-            <ComponentID>PlotToDwf</ComponentID>
-            <ShowLabel>false</ShowLabel>
-          </ItemBase>
-          <ItemBase xsi:type="CommandItem">
-            <ComponentID>Profile</ComponentID>
-            <ShowLabel>false</ShowLabel>
-          </ItemBase>
-        </Items>
-      </ItemBase>
     </Items>
   </Toolbar>
   <ContextMenu>
@@ -247,7 +235,6 @@
   </ContextMenu>
   <TaskPane>
     <Width>250</Width>
-    <InitialComponentID>SamplesTaskPane</InitialComponentID>
     <TaskMenu>
       <Items>
         <ItemBase xsi:type="CommandItem">
@@ -318,7 +305,7 @@
         </NameValue>
         <NameValue>
           <Name>MapDefinition</Name>
-          <Value>Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition</Value>
+          <Value>map:Sheboygan</Value>
         </NameValue>
       </Properties>
     </ComponentDefinition>
@@ -434,70 +421,5 @@
       <ComponentID>ZoomToSelection</ComponentID>
       <ClassName>OSGeo.MapGuide.Viewer.MgZoomToSelectionComponent</ClassName>
     </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>PlotToDwf</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgPlotToDwfComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>Profile</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgProfileComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>Startup</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgStartupComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>SamplesTaskPane</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgSampleTaskPaneComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>HelloMap</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgHelloMapComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>HelloViewer</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgHelloViewerComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>InteractingWithLayers</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgInteractingWithLayersComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>WorkingWithFeatureData</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgWorkingWithFeatureDataComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>ModifyingMapsAndLayers</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgModifyingMapsAndLayersComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>AnalyzingFeatures</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgAnalyzingFeaturesComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>DigitizingAndRedlining</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgDigitizingAndRedliningComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>CustomOutput</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgCustomOutputComponent</ClassName>
-    </ComponentDefinition>
-    <ComponentDefinition>
-      <ComponentID>PrePostRender</ComponentID>
-      <Assembly>SampleExtension.dll</Assembly>
-      <ClassName>SampleExtension.MgPrePostRenderingComponent</ClassName>
-    </ComponentDefinition>
   </Components>
 </AppLayout>
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/MgAppLayout/SheboyganTiled.AppLayout
===================================================================
--- branches/2.4/MgDev/Desktop/MgAppLayout/SheboyganTiled.AppLayout	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgAppLayout/SheboyganTiled.AppLayout	2012-10-03 13:00:20 UTC (rev 7064)
@@ -0,0 +1,425 @@
+<?xml version="1.0"?>
+<AppLayout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <Title>MapGuide Desktop App Layout Example</Title>
+  <Icon>app.ico</Icon>
+  <Settings>
+    <SelectionColor>0000FF</SelectionColor>
+    <ConvertTiledGroupsToNonTiled>false</ConvertTiledGroupsToNonTiled>
+    <UseRenderMap>true</UseRenderMap>
+    <RespectFiniteScales>true</RespectFiniteScales>
+    <ShowVertexCoordinatesWhenDigitizing>false</ShowVertexCoordinatesWhenDigitizing>
+    <ZoomInFactor>0.5</ZoomInFactor>
+    <ZoomOutFactor>2</ZoomOutFactor>
+    <PointPixelBuffer>3</PointPixelBuffer>
+  </Settings>
+  <InfoPane>
+    <Width>200</Width>
+    <Legend>
+      <Visible>true</Visible>
+      <ShowTooltips>true</ShowTooltips>
+      <ThemeCompressionLimit>25</ThemeCompressionLimit>
+    </Legend>
+    <PropertyPane>
+      <Visible>true</Visible>
+    </PropertyPane>
+  </InfoPane>
+  <Map>
+    <Name>SheboyganTiled</Name>
+    <MapDefinition>Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition</MapDefinition>
+  </Map>
+  <Menu>
+    <Items>
+      <ItemBase xsi:type="SubMenu">
+        <Label>File</Label>
+        <Items>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>LoadMap</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>LoadPackage</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="SeparatorItem" />
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Quit</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+        </Items>
+      </ItemBase>
+      <ItemBase xsi:type="SubMenu">
+        <Label>Tools</Label>
+        <Items>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Buffer</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Measure</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Query</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Theme</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="SeparatorItem" />
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>ViewerOptions</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+        </Items>
+      </ItemBase>
+    </Items>
+  </Menu>
+  <Toolbar>
+    <Items>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>PrintMap</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>CopyMap</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomIn</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomOut</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>InitialView</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomPrev</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomNext</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>Select</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>SelectRadius</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>SelectPolygon</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>Pan</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ClearSelection</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>RefreshMap</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>TooltipToggle</ComponentID>
+        <ShowLabel>true</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="SubMenu">
+        <Label>Tools</Label>
+        <Items>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Buffer</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Measure</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Query</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Theme</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="SeparatorItem" />
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>ViewerOptions</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+        </Items>
+      </ItemBase>
+    </Items>
+  </Toolbar>
+  <ContextMenu>
+    <Items>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>RefreshMap</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomIn</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomOut</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ZoomToSelection</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>InitialView</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>Pan</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>Select</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ClearSelection</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="SubMenu">
+        <Label>Tools</Label>
+        <Items>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Buffer</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Measure</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Query</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+          <ItemBase xsi:type="CommandItem">
+            <ComponentID>Theme</ComponentID>
+            <ShowLabel>false</ShowLabel>
+          </ItemBase>
+        </Items>
+      </ItemBase>
+      <ItemBase xsi:type="SeparatorItem" />
+      <ItemBase xsi:type="CommandItem">
+        <ComponentID>ViewerOptions</ComponentID>
+        <ShowLabel>false</ShowLabel>
+      </ItemBase>
+    </Items>
+  </ContextMenu>
+  <TaskPane>
+    <Width>250</Width>
+    <TaskMenu>
+      <Items>
+        <ItemBase xsi:type="CommandItem">
+          <ComponentID>Buffer</ComponentID>
+          <ShowLabel>false</ShowLabel>
+        </ItemBase>
+        <ItemBase xsi:type="CommandItem">
+          <ComponentID>Measure</ComponentID>
+          <ShowLabel>false</ShowLabel>
+        </ItemBase>
+        <ItemBase xsi:type="CommandItem">
+          <ComponentID>Query</ComponentID>
+          <ShowLabel>false</ShowLabel>
+        </ItemBase>
+        <ItemBase xsi:type="CommandItem">
+          <ComponentID>Theme</ComponentID>
+          <ShowLabel>false</ShowLabel>
+        </ItemBase>
+      </Items>
+    </TaskMenu>
+  </TaskPane>
+  <Components>
+    <ComponentDefinition>
+      <ComponentID>Buffer</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgBufferComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>DefaultLayerName</Name>
+          <Value>BufferLayer</Value>
+        </NameValue>
+        <NameValue>
+          <Name>DefaultBufferUnits</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MeasurementUnit:Meters</Value>
+        </NameValue>
+        <NameValue>
+          <Name>Target</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MgViewerTarget:TaskPane</Value>
+        </NameValue>
+        <NameValue>
+          <Name>TaskPane</Name>
+          <Value>taskpane:</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>SelectRadius</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgCircleSelectComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ClearSelection</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgClearSelectionComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>CopyMap</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgCopyMapComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>InitialView</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgInitialViewComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>LoadMap</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgLoadMapComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>Label</Name>
+          <Value>Load Sheboygan Map</Value>
+        </NameValue>
+        <NameValue>
+          <Name>MapDefinition</Name>
+          <Value>map:SheboyganTiled</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>LoadPackage</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgLoadPackageComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>InvokeOnPackageLoad</Name>
+          <Value>component:LoadMap</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Measure</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgMeasureComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>MeasureMode</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MeasureMode:Line</Value>
+        </NameValue>
+        <NameValue>
+          <Name>PreferredUnits</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MeasurementUnit:Meters</Value>
+        </NameValue>
+        <NameValue>
+          <Name>Target</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MgViewerTarget:TaskPane</Value>
+        </NameValue>
+        <NameValue>
+          <Name>TaskPane</Name>
+          <Value>taskpane:</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Pan</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgPanComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>SelectPolygon</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgPolygonSelectComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>PrintMap</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgPrintComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Query</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgQueryComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>Target</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MgViewerTarget:TaskPane</Value>
+        </NameValue>
+        <NameValue>
+          <Name>TaskPane</Name>
+          <Value>taskpane:</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Quit</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.AppLayoutEngine.MgQuitComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>RefreshMap</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgRefreshMapComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Select</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgSelectComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>Theme</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgThemeComponent</ClassName>
+      <Properties>
+        <NameValue>
+          <Name>Target</Name>
+          <Value>enum:OSGeo.MapGuide.Viewer.MgViewerTarget:TaskPane</Value>
+        </NameValue>
+        <NameValue>
+          <Name>TaskPane</Name>
+          <Value>taskpane:</Value>
+        </NameValue>
+      </Properties>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>TooltipToggle</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgTooltipToggleComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ViewerOptions</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgViewerOptionsComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ZoomIn</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgZoomInComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ZoomNext</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgZoomNextComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ZoomOut</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgZoomOutComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ZoomPrev</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgZoomPreviousComponent</ClassName>
+    </ComponentDefinition>
+    <ComponentDefinition>
+      <ComponentID>ZoomToSelection</ComponentID>
+      <ClassName>OSGeo.MapGuide.Viewer.MgZoomToSelectionComponent</ClassName>
+    </ComponentDefinition>
+  </Components>
+</AppLayout>
\ No newline at end of file



More information about the mapguide-commits mailing list