[mapguide-commits] r6885 - in branches/2.4/MgDev/Desktop: MapViewer MapViewer.Desktop SampleExtension SampleExtension/Resources

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Jul 10 05:25:44 PDT 2012


Author: jng
Date: 2012-07-10 05:25:43 -0700 (Tue, 10 Jul 2012)
New Revision: 6885

Added:
   branches/2.4/MgDev/Desktop/MapViewer.Desktop/MgdTransientMapState.cs
   branches/2.4/MgDev/Desktop/SampleExtension/Resources/Redline.txt
Modified:
   branches/2.4/MgDev/Desktop/MapViewer.Desktop/MapViewer.Desktop.csproj
   branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.cs
   branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.cs
   branches/2.4/MgDev/Desktop/SampleExtension/Layers.Designer.cs
   branches/2.4/MgDev/Desktop/SampleExtension/Layers.resx
   branches/2.4/MgDev/Desktop/SampleExtension/MgStartupComponent.cs
   branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj
Log:
mg-desktop updates:
 - #2062: Complete the Sample AppLayout extension with Custom Output and Digitizing/Redlining samples. Also clean up the startup message text.
 - Fix incorrect cutoff number for Ctrl-Z during linestring/polygon digitization
 - Add a new MgdTransientMapState class allowing for temporary display parameters (x,y,scale,width,height,dpi) to be applied to the current map on the viewer, allowing for custom views and sizes to be rendered off of this map without permanently changing state. The Custom Output sample demonstrates use of this class.

Modified: branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/MapViewer/MgMapViewer.cs	2012-07-10 12:25:43 UTC (rev 6885)
@@ -251,7 +251,7 @@
                 if (this.DigitizingType == MapDigitizationType.LineString ||
                     this.DigitizingType == MapDigitizationType.Polygon)
                 {
-                    if (dPath.Count > 1) //Slice off the last recorded point
+                    if (dPath.Count > 2) //Slice off the last recorded point
                     {
                         dPath.RemoveAt(dPath.Count - 1);
                         Invalidate();

Modified: branches/2.4/MgDev/Desktop/MapViewer.Desktop/MapViewer.Desktop.csproj
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer.Desktop/MapViewer.Desktop.csproj	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/MapViewer.Desktop/MapViewer.Desktop.csproj	2012-07-10 12:25:43 UTC (rev 6885)
@@ -57,6 +57,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="MgDesktopMapViewerProvider.cs" />
+    <Compile Include="MgdTransientMapState.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>

Added: branches/2.4/MgDev/Desktop/MapViewer.Desktop/MgdTransientMapState.cs
===================================================================
--- branches/2.4/MgDev/Desktop/MapViewer.Desktop/MgdTransientMapState.cs	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MapViewer.Desktop/MgdTransientMapState.cs	2012-07-10 12:25:43 UTC (rev 6885)
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OSGeo.MapGuide.Viewer.Desktop
+{
+    /// <summary>
+    /// Represents a stack of transient map states. This is used to manipulate the display parameters
+    /// of a <see cref="T:OSGeo.MapGuide.MgdMap"/> in a manner that can be undone upon disposal
+    /// of this stack, allowing your map to be used for <see cref="T:OSGeo.MapGuide.MgdRenderingService.RenderMap()"/>
+    /// calls without permanently altering state.
+    /// </summary>
+    public class MgdTransientMapState : IDisposable
+    {
+        private MgdMap _map;
+
+        private Stack<MgdMapStateTransition> _states;
+
+        private MgdMapDisplayParameters _origState;
+
+        public MgdTransientMapState(MgdMap map)
+        {
+            _map = map;
+            _origState = GetCurrentState();
+            _states = new Stack<MgdMapStateTransition>();
+        }
+
+        private MgdMapDisplayParameters GetCurrentState()
+        {
+            var pt = _map.ViewCenter;
+            var coord = pt.Coordinate;
+            return new MgdMapDisplayParameters(coord.X, coord.Y, _map.ViewScale, _map.DisplayWidth, _map.DisplayHeight, _map.DisplayDpi);
+        }
+
+        private void ApplyState(MgdMapDisplayParameters state)
+        {
+            _map.SetViewCenterXY(state.X, state.Y);
+            _map.SetViewScale(state.Scale);
+            _map.SetDisplaySize(state.Width, state.Height);
+            if (state.DPI.HasValue)
+                _map.DisplayDpi = state.DPI.Value;
+        }
+
+        public int Depth { get { return _states.Count; } }
+
+        /// <summary>
+        /// Pushes the given state onto the map state stack. The map takes on the display parameters specified
+        /// in this given state.
+        /// </summary>
+        /// <param name="state"></param>
+        public void PushState(MgdMapDisplayParameters state)
+        {
+            if (state == null)
+                throw new ArgumentNullException("state");
+
+            var oldState = GetCurrentState();
+            ApplyState(state);
+
+            _states.Push(new MgdMapStateTransition() { OldState = oldState, NewState = state });
+        }
+
+        /// <summary>
+        /// Pops the latest state from the map state stack. The map state is restored to
+        /// the previously applied state.
+        /// </summary>
+        /// <returns>The state that was previously applied</returns>
+        public MgdMapDisplayParameters PopState()
+        {
+            if (_states.Count == 0)
+                return null;
+
+            var trans = _states.Pop();
+            ApplyState(trans.OldState);
+            return trans.NewState;
+        }
+
+        public void Dispose()
+        {
+            while (_states.Count > 0)
+            {
+                this.PopState();
+            }
+            ApplyState(_origState);
+        }
+    }
+
+    internal class MgdMapStateTransition
+    {
+        public MgdMapDisplayParameters NewState { get; set; }
+
+        public MgdMapDisplayParameters OldState { get; set; }
+    }
+
+    /// <summary>
+    /// Represents display parameters for a map
+    /// </summary>
+    public class MgdMapDisplayParameters
+    {
+        public double X { get; private set; }
+        public double Y { get; private set; }
+        public double Scale { get; private set; }
+        public int Width { get; private set; }
+        public int Height { get; private set; }
+        public int? DPI { get; private set; }
+
+        public MgdMapDisplayParameters(double x, double y, double scale, int width, int height)
+        {
+            this.X = x;
+            this.Y = y;
+            this.Scale = scale;
+            this.Width = width;
+            this.Height = height;
+        }
+
+        public MgdMapDisplayParameters(double x, double y, double scale, int width, int height, int dpi)
+            : this(x, y, scale, width, height)
+        {
+            this.DPI = dpi;
+        }
+    }
+}

Modified: branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.Designer.cs	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.Designer.cs	2012-07-10 12:25:43 UTC (rev 6885)
@@ -29,25 +29,126 @@
         private void InitializeComponent()
         {
             this.label1 = new System.Windows.Forms.Label();
+            this.groupBox1 = new System.Windows.Forms.GroupBox();
+            this.btnRenderMap4 = new System.Windows.Forms.Button();
+            this.btnRenderMap3 = new System.Windows.Forms.Button();
+            this.btnRenderMap2 = new System.Windows.Forms.Button();
+            this.btnRenderMap1 = new System.Windows.Forms.Button();
+            this.groupBox2 = new System.Windows.Forms.GroupBox();
+            this.btnSinglePlot = new System.Windows.Forms.Button();
+            this.btnMultiPlot = new System.Windows.Forms.Button();
+            this.groupBox1.SuspendLayout();
+            this.groupBox2.SuspendLayout();
             this.SuspendLayout();
             // 
             // label1
             // 
             this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                         | System.Windows.Forms.AnchorStyles.Right)));
-            this.label1.Location = new System.Drawing.Point(19, 22);
+            this.label1.Location = new System.Drawing.Point(14, 16);
             this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(196, 52);
+            this.label1.Size = new System.Drawing.Size(264, 52);
             this.label1.TabIndex = 0;
-            this.label1.Text = "This sample demonstrates outputting the current map to various output formats";
+            this.label1.Text = "This sample demonstrates outputting the current map to various output formats wit" +
+                "h various display parameters\r\n";
             // 
+            // groupBox1
+            // 
+            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                        | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupBox1.Controls.Add(this.btnRenderMap4);
+            this.groupBox1.Controls.Add(this.btnRenderMap3);
+            this.groupBox1.Controls.Add(this.btnRenderMap2);
+            this.groupBox1.Controls.Add(this.btnRenderMap1);
+            this.groupBox1.Location = new System.Drawing.Point(17, 84);
+            this.groupBox1.Name = "groupBox1";
+            this.groupBox1.Size = new System.Drawing.Size(261, 160);
+            this.groupBox1.TabIndex = 1;
+            this.groupBox1.TabStop = false;
+            this.groupBox1.Text = "Render custom views of current map";
+            // 
+            // btnRenderMap4
+            // 
+            this.btnRenderMap4.Location = new System.Drawing.Point(24, 116);
+            this.btnRenderMap4.Name = "btnRenderMap4";
+            this.btnRenderMap4.Size = new System.Drawing.Size(177, 23);
+            this.btnRenderMap4.TabIndex = 3;
+            this.btnRenderMap4.Text = "2048 x 1920 @ 1:7000 (192 DPI)";
+            this.btnRenderMap4.UseVisualStyleBackColor = true;
+            this.btnRenderMap4.Click += new System.EventHandler(this.btnRenderMap4_Click);
+            // 
+            // btnRenderMap3
+            // 
+            this.btnRenderMap3.Location = new System.Drawing.Point(24, 87);
+            this.btnRenderMap3.Name = "btnRenderMap3";
+            this.btnRenderMap3.Size = new System.Drawing.Size(177, 23);
+            this.btnRenderMap3.TabIndex = 2;
+            this.btnRenderMap3.Text = "1920 x 1680 @ 1:6000 (192 DPI)";
+            this.btnRenderMap3.UseVisualStyleBackColor = true;
+            this.btnRenderMap3.Click += new System.EventHandler(this.btnRenderMap3_Click);
+            // 
+            // btnRenderMap2
+            // 
+            this.btnRenderMap2.Location = new System.Drawing.Point(24, 58);
+            this.btnRenderMap2.Name = "btnRenderMap2";
+            this.btnRenderMap2.Size = new System.Drawing.Size(177, 23);
+            this.btnRenderMap2.TabIndex = 1;
+            this.btnRenderMap2.Text = "1024 x 768 @ 1:5000 (96 DPI)";
+            this.btnRenderMap2.UseVisualStyleBackColor = true;
+            this.btnRenderMap2.Click += new System.EventHandler(this.btnRenderMap2_Click);
+            // 
+            // btnRenderMap1
+            // 
+            this.btnRenderMap1.Location = new System.Drawing.Point(24, 29);
+            this.btnRenderMap1.Name = "btnRenderMap1";
+            this.btnRenderMap1.Size = new System.Drawing.Size(177, 23);
+            this.btnRenderMap1.TabIndex = 0;
+            this.btnRenderMap1.Text = "640 x 480 @ 1:4000 (96 DPI)";
+            this.btnRenderMap1.UseVisualStyleBackColor = true;
+            this.btnRenderMap1.Click += new System.EventHandler(this.btnRenderMap1_Click);
+            // 
+            // groupBox2
+            // 
+            this.groupBox2.Controls.Add(this.btnMultiPlot);
+            this.groupBox2.Controls.Add(this.btnSinglePlot);
+            this.groupBox2.Location = new System.Drawing.Point(17, 251);
+            this.groupBox2.Name = "groupBox2";
+            this.groupBox2.Size = new System.Drawing.Size(261, 104);
+            this.groupBox2.TabIndex = 2;
+            this.groupBox2.TabStop = false;
+            this.groupBox2.Text = "Plot current view to DWF";
+            // 
+            // btnSinglePlot
+            // 
+            this.btnSinglePlot.Location = new System.Drawing.Point(24, 29);
+            this.btnSinglePlot.Name = "btnSinglePlot";
+            this.btnSinglePlot.Size = new System.Drawing.Size(177, 23);
+            this.btnSinglePlot.TabIndex = 0;
+            this.btnSinglePlot.Text = "Single-Page plot";
+            this.btnSinglePlot.UseVisualStyleBackColor = true;
+            this.btnSinglePlot.Click += new System.EventHandler(this.btnSinglePlot_Click);
+            // 
+            // btnMultiPlot
+            // 
+            this.btnMultiPlot.Location = new System.Drawing.Point(24, 58);
+            this.btnMultiPlot.Name = "btnMultiPlot";
+            this.btnMultiPlot.Size = new System.Drawing.Size(177, 23);
+            this.btnMultiPlot.TabIndex = 1;
+            this.btnMultiPlot.Text = "Multi-Page plot";
+            this.btnMultiPlot.UseVisualStyleBackColor = true;
+            this.btnMultiPlot.Click += new System.EventHandler(this.btnMultiPlot_Click);
+            // 
             // CustomOutput
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.groupBox2);
+            this.Controls.Add(this.groupBox1);
             this.Controls.Add(this.label1);
             this.Name = "CustomOutput";
-            this.Size = new System.Drawing.Size(231, 436);
+            this.Size = new System.Drawing.Size(295, 436);
+            this.groupBox1.ResumeLayout(false);
+            this.groupBox2.ResumeLayout(false);
             this.ResumeLayout(false);
 
         }
@@ -55,5 +156,13 @@
         #endregion
 
         private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.GroupBox groupBox1;
+        private System.Windows.Forms.Button btnRenderMap4;
+        private System.Windows.Forms.Button btnRenderMap3;
+        private System.Windows.Forms.Button btnRenderMap2;
+        private System.Windows.Forms.Button btnRenderMap1;
+        private System.Windows.Forms.GroupBox groupBox2;
+        private System.Windows.Forms.Button btnMultiPlot;
+        private System.Windows.Forms.Button btnSinglePlot;
     }
 }

Modified: branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.cs	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/SampleExtension/CustomOutput.cs	2012-07-10 12:25:43 UTC (rev 6885)
@@ -6,6 +6,9 @@
 using System.Text;
 using System.Windows.Forms;
 using OSGeo.MapGuide.Viewer;
+using OSGeo.MapGuide.Viewer.Desktop;
+using OSGeo.MapGuide;
+using System.IO;
 
 namespace SampleExtension
 {
@@ -20,6 +23,224 @@
             _viewer = viewer;
         }
 
+        private void btnRenderMap1_Click(object sender, EventArgs e)
+        {
+            //Note we're casting to mg-desktop specific subclasses as this is what mg-desktop rendering APIs expect
+            MgdMap map = (MgdMap)_viewer.GetMap();
+            MgdSelection selection = (MgdSelection)_viewer.GetSelection();
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgdRenderingService renderSvc = (MgdRenderingService)provider.CreateService(MgServiceType.RenderingService);
+            MgPoint centerPt = map.ViewCenter;
+            MgCoordinate centerCoord = centerPt.Coordinate;
 
+            //MgdTransientMapState is a helper class which lets us apply transient state to a map, which is automatically
+            //undone on disposal. This is how we can render custom views of a map with specific display parameters without
+            //permanently changing the display parameters used by the map viewer
+            using (MgdTransientMapState tempState = new MgdTransientMapState(map))
+            {
+                MgdMapDisplayParameters state = new MgdMapDisplayParameters(centerCoord.X, centerCoord.Y, 4000, 640, 480, 96);
+                tempState.PushState(state);
+
+                MgByteReader br = renderSvc.RenderMap(map, selection, "PNG");
+                using (SaveFileDialog save = new SaveFileDialog())
+                {
+                    save.Filter = "Portable Network Graphics (*.png)|*.png";
+                    if (save.ShowDialog() == DialogResult.OK)
+                    {
+                        //MgReadOnlyStream is a stream adapter class that provides a .net stream
+                        //interface to the MgByteReader, allowing MgByteReader objects to be used
+                        //anywhere a System.IO.Stream is expected.
+                        using (MgReadOnlyStream stream = new MgReadOnlyStream(br))
+                        {
+                            Image img = Image.FromStream(stream);
+                            img.Save(save.FileName);
+                            MessageBox.Show("Image saved to: " + save.FileName);
+                        }
+                    }
+                    br.Dispose();
+                }
+            }
+        }
+
+        private void btnRenderMap2_Click(object sender, EventArgs e)
+        {
+            //Note we're casting to mg-desktop specific subclasses as this is what mg-desktop rendering APIs expect
+            MgdMap map = (MgdMap)_viewer.GetMap();
+            MgdSelection selection = (MgdSelection)_viewer.GetSelection();
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgdRenderingService renderSvc = (MgdRenderingService)provider.CreateService(MgServiceType.RenderingService);
+            MgPoint centerPt = map.ViewCenter;
+            MgCoordinate centerCoord = centerPt.Coordinate;
+
+            //MgdTransientMapState is a helper class which lets us apply transient state to a map, which is automatically
+            //undone on disposal. This is how we can render custom views of a map with specific display parameters without
+            //permanently changing the display parameters used by the map viewer
+            using (MgdTransientMapState tempState = new MgdTransientMapState(map))
+            {
+                MgdMapDisplayParameters state = new MgdMapDisplayParameters(centerCoord.X, centerCoord.Y, 5000, 1024, 768, 96);
+                tempState.PushState(state);
+
+                MgByteReader br = renderSvc.RenderMap(map, selection, "PNG");
+                using (SaveFileDialog save = new SaveFileDialog())
+                {
+                    save.Filter = "Portable Network Graphics (*.png)|*.png";
+                    if (save.ShowDialog() == DialogResult.OK)
+                    {
+                        //MgReadOnlyStream is a stream adapter class that provides a .net stream
+                        //interface to the MgByteReader, allowing MgByteReader objects to be used
+                        //anywhere a System.IO.Stream is expected.
+                        using (MgReadOnlyStream stream = new MgReadOnlyStream(br))
+                        {
+                            Image img = Image.FromStream(stream);
+                            img.Save(save.FileName);
+                            MessageBox.Show("Image saved to: " + save.FileName);
+                        }
+                    }
+                    br.Dispose();
+                }
+            }
+        }
+
+        private void btnRenderMap3_Click(object sender, EventArgs e)
+        {
+            //Note we're casting to mg-desktop specific subclasses as this is what mg-desktop rendering APIs expect
+            MgdMap map = (MgdMap)_viewer.GetMap();
+            MgdSelection selection = (MgdSelection)_viewer.GetSelection();
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgdRenderingService renderSvc = (MgdRenderingService)provider.CreateService(MgServiceType.RenderingService);
+            MgPoint centerPt = map.ViewCenter;
+            MgCoordinate centerCoord = centerPt.Coordinate;
+
+            //MgdTransientMapState is a helper class which lets us apply transient state to a map, which is automatically
+            //undone on disposal. This is how we can render custom views of a map with specific display parameters without
+            //permanently changing the display parameters used by the map viewer
+            using (MgdTransientMapState tempState = new MgdTransientMapState(map))
+            {
+                MgdMapDisplayParameters state = new MgdMapDisplayParameters(centerCoord.X, centerCoord.Y, 6000, 1920, 1680, 192);
+                tempState.PushState(state);
+
+                MgByteReader br = renderSvc.RenderMap(map, selection, "PNG");
+                using (SaveFileDialog save = new SaveFileDialog())
+                {
+                    save.Filter = "Portable Network Graphics (*.png)|*.png";
+                    if (save.ShowDialog() == DialogResult.OK)
+                    {
+                        //MgReadOnlyStream is a stream adapter class that provides a .net stream
+                        //interface to the MgByteReader, allowing MgByteReader objects to be used
+                        //anywhere a System.IO.Stream is expected.
+                        using (MgReadOnlyStream stream = new MgReadOnlyStream(br))
+                        {
+                            Image img = Image.FromStream(stream);
+                            img.Save(save.FileName);
+                            MessageBox.Show("Image saved to: " + save.FileName);
+                        }
+                    }
+                    br.Dispose();
+                }
+            }
+        }
+
+        private void btnRenderMap4_Click(object sender, EventArgs e)
+        {
+            //Note we're casting to mg-desktop specific subclasses as this is what mg-desktop rendering APIs expect
+            MgdMap map = (MgdMap)_viewer.GetMap();
+            MgdSelection selection = (MgdSelection)_viewer.GetSelection();
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgdRenderingService renderSvc = (MgdRenderingService)provider.CreateService(MgServiceType.RenderingService);
+            MgPoint centerPt = map.ViewCenter;
+            MgCoordinate centerCoord = centerPt.Coordinate;
+
+            //MgdTransientMapState is a helper class which lets us apply transient state to a map, which is automatically
+            //undone on disposal. This is how we can render custom views of a map with specific display parameters without
+            //permanently changing the display parameters used by the map viewer
+            using (MgdTransientMapState tempState = new MgdTransientMapState(map))
+            {
+                MgdMapDisplayParameters state = new MgdMapDisplayParameters(centerCoord.X, centerCoord.Y, 7000, 2048, 1920, 192);
+                tempState.PushState(state);
+
+                MgByteReader br = renderSvc.RenderMap(map, selection, "PNG");
+                using (SaveFileDialog save = new SaveFileDialog())
+                {
+                    save.Filter = "Portable Network Graphics (*.png)|*.png";
+                    if (save.ShowDialog() == DialogResult.OK)
+                    {
+                        //MgReadOnlyStream is a stream adapter class that provides a .net stream
+                        //interface to the MgByteReader, allowing MgByteReader objects to be used
+                        //anywhere a System.IO.Stream is expected.
+                        using (MgReadOnlyStream stream = new MgReadOnlyStream(br))
+                        {
+                            Image img = Image.FromStream(stream);
+                            img.Save(save.FileName);
+                            MessageBox.Show("Image saved to: " + save.FileName);
+                        }
+                    }
+                    br.Dispose();
+                }
+            }
+        }
+
+        private void btnSinglePlot_Click(object sender, EventArgs e)
+        {
+            MgdMap map = (MgdMap)_viewer.GetMap();
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgdMappingService mappingSvc = (MgdMappingService)provider.CreateService(MgServiceType.MappingService);
+            MgResourceIdentifier layoutId = new MgResourceIdentifier("Library://Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout");
+            using (SaveFileDialog save = new SaveFileDialog())
+            {
+                save.Filter = "DWF Files (*.dwf)|*.dwf";
+                if (save.ShowDialog() == DialogResult.OK)
+                {
+                    MgDwfVersion dwfVer = new MgDwfVersion("6.01", "1.2");
+
+                    MgLayout layout = new MgLayout(layoutId, "City of Sheboygan", MgPageUnitsType.Inches);
+                    MgPlotSpecification plotSpec = new MgPlotSpecification(8.5f, 11.0f, MgPageUnitsType.Inches, 0.5f, 0.5f, 0.5f, 0.5f);
+
+                    MgByteReader result = mappingSvc.GeneratePlot(map, plotSpec, layout, dwfVer);
+                    MgByteSink sink = new MgByteSink(result);
+                    sink.ToFile(save.FileName);
+
+                    MessageBox.Show("Saved to " + save.FileName);
+                }
+            }
+        }
+
+        private void btnMultiPlot_Click(object sender, EventArgs e)
+        {
+            MgdMap map = (MgdMap)_viewer.GetMap();
+            MgMapViewerProvider provider = _viewer.GetProvider();
+            MgdMappingService mappingSvc = (MgdMappingService)provider.CreateService(MgServiceType.MappingService);
+            MgResourceIdentifier layoutId = new MgResourceIdentifier("Library://Samples/Sheboygan/Layouts/SheboyganMap.PrintLayout");
+            using (SaveFileDialog save = new SaveFileDialog())
+            {
+                save.Filter = "DWF Files (*.dwf)|*.dwf";
+                if (save.ShowDialog() == DialogResult.OK)
+                {
+                    MgDwfVersion dwfVer = new MgDwfVersion("6.01", "1.2");
+
+                    MgLayout layout = new MgLayout(layoutId, "City of Sheboygan", MgPageUnitsType.Inches);
+                    MgPlotSpecification plotSpec = new MgPlotSpecification(8.5f, 11.0f, MgPageUnitsType.Inches, 0.5f, 0.5f, 0.5f, 0.5f);
+
+                    MgMapPlotCollection plotCollection = new MgMapPlotCollection();
+
+                    MgMapPlot plot1 = new MgMapPlot(map, plotSpec, layout);
+                    plot1.SetCenterAndScale(map.GetViewCenter().GetCoordinate(), map.GetViewScale() * 2);
+                    plotCollection.Add(plot1);
+
+                    // Create a second map for the second sheet in the DWF. This second sheet uses the print layout
+                    // to display a page title and legend.
+
+                    MgdMap map2 = new MgdMap(map.GetMapDefinition(), "Sheet 2");
+                    MgMapPlot plot2 = new MgMapPlot(map2, plotSpec, layout);
+                    plot2.SetCenterAndScale(map.GetViewCenter().GetCoordinate(), map.GetViewScale());
+                    plotCollection.Add(plot2);
+
+                    MgByteReader result = mappingSvc.GenerateMultiPlot(plotCollection, dwfVer);
+                    MgByteSink sink = new MgByteSink(result);
+                    sink.ToFile(save.FileName);
+
+                    MessageBox.Show("Saved to " + save.FileName);
+                }
+            }
+        }
     }
 }

Modified: branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.Designer.cs	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.Designer.cs	2012-07-10 12:25:43 UTC (rev 6885)
@@ -29,6 +29,11 @@
         private void InitializeComponent()
         {
             this.label1 = new System.Windows.Forms.Label();
+            this.btnPoint = new System.Windows.Forms.Button();
+            this.btnLine = new System.Windows.Forms.Button();
+            this.btnLineString = new System.Windows.Forms.Button();
+            this.btnPolygon = new System.Windows.Forms.Button();
+            this.btnClearRedlines = new System.Windows.Forms.Button();
             this.SuspendLayout();
             // 
             // label1
@@ -41,10 +46,65 @@
             this.label1.TabIndex = 0;
             this.label1.Text = "This sample demonstrates digitizing and redlining";
             // 
+            // btnPoint
+            // 
+            this.btnPoint.Location = new System.Drawing.Point(21, 89);
+            this.btnPoint.Name = "btnPoint";
+            this.btnPoint.Size = new System.Drawing.Size(80, 23);
+            this.btnPoint.TabIndex = 1;
+            this.btnPoint.Text = "Point";
+            this.btnPoint.UseVisualStyleBackColor = true;
+            this.btnPoint.Click += new System.EventHandler(this.btnPoint_Click);
+            // 
+            // btnLine
+            // 
+            this.btnLine.Location = new System.Drawing.Point(21, 118);
+            this.btnLine.Name = "btnLine";
+            this.btnLine.Size = new System.Drawing.Size(80, 23);
+            this.btnLine.TabIndex = 2;
+            this.btnLine.Text = "Line";
+            this.btnLine.UseVisualStyleBackColor = true;
+            this.btnLine.Click += new System.EventHandler(this.btnLine_Click);
+            // 
+            // btnLineString
+            // 
+            this.btnLineString.Location = new System.Drawing.Point(107, 89);
+            this.btnLineString.Name = "btnLineString";
+            this.btnLineString.Size = new System.Drawing.Size(80, 23);
+            this.btnLineString.TabIndex = 3;
+            this.btnLineString.Text = "LineString";
+            this.btnLineString.UseVisualStyleBackColor = true;
+            this.btnLineString.Click += new System.EventHandler(this.btnLineString_Click);
+            // 
+            // btnPolygon
+            // 
+            this.btnPolygon.Location = new System.Drawing.Point(107, 118);
+            this.btnPolygon.Name = "btnPolygon";
+            this.btnPolygon.Size = new System.Drawing.Size(80, 23);
+            this.btnPolygon.TabIndex = 4;
+            this.btnPolygon.Text = "Polygon";
+            this.btnPolygon.UseVisualStyleBackColor = true;
+            this.btnPolygon.Click += new System.EventHandler(this.btnPolygon_Click);
+            // 
+            // btnClearRedlines
+            // 
+            this.btnClearRedlines.Location = new System.Drawing.Point(21, 178);
+            this.btnClearRedlines.Name = "btnClearRedlines";
+            this.btnClearRedlines.Size = new System.Drawing.Size(166, 23);
+            this.btnClearRedlines.TabIndex = 5;
+            this.btnClearRedlines.Text = "Clear Redlines";
+            this.btnClearRedlines.UseVisualStyleBackColor = true;
+            this.btnClearRedlines.Click += new System.EventHandler(this.btnClearRedlines_Click);
+            // 
             // DigitizingAndRedlining
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.btnClearRedlines);
+            this.Controls.Add(this.btnPolygon);
+            this.Controls.Add(this.btnLineString);
+            this.Controls.Add(this.btnLine);
+            this.Controls.Add(this.btnPoint);
             this.Controls.Add(this.label1);
             this.Name = "DigitizingAndRedlining";
             this.Size = new System.Drawing.Size(236, 472);
@@ -55,5 +115,10 @@
         #endregion
 
         private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnPoint;
+        private System.Windows.Forms.Button btnLine;
+        private System.Windows.Forms.Button btnLineString;
+        private System.Windows.Forms.Button btnPolygon;
+        private System.Windows.Forms.Button btnClearRedlines;
     }
 }

Modified: branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.cs	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/SampleExtension/DigitizingAndRedlining.cs	2012-07-10 12:25:43 UTC (rev 6885)
@@ -6,18 +6,212 @@
 using System.Text;
 using System.Windows.Forms;
 using OSGeo.MapGuide.Viewer;
+using OSGeo.MapGuide;
+using OSGeo.MapGuide.Viewer.AppLayoutEngine;
 
 namespace SampleExtension
 {
     public partial class DigitizingAndRedlining : MgControlView
     {
         private IMapViewer _viewer;
+        private MgGeometryFactory _geomFact;
+        private MgWktReaderWriter _wktRW;
+        private MgAgfReaderWriter _agfRW;
+        private MgdLayer _redlineLayer;
 
         public DigitizingAndRedlining(IMapViewer viewer)
         {
             InitializeComponent();
             _viewer = viewer;
+            _geomFact = new MgGeometryFactory();
+            _wktRW = new MgWktReaderWriter();
+            _agfRW = new MgAgfReaderWriter();
             this.Title = "Digitizing and Redlining";
+            _viewer.PropertyChanged += OnViewerPropertyChanged;
+            MgMapBase map = _viewer.GetMap();
+            MgLayerCollection layers = map.GetLayers();
+            if (layers.IndexOf("Redline") >= 0)
+            {
+                _redlineLayer = (MgdLayer)layers.GetItem("Redline");
+            }
+            CheckDigitizingState();
         }
+
+        void OnViewerPropertyChanged(object sender, PropertyChangedEventArgs e)
+        {
+            if (e.PropertyName == "DigitizingType")
+                CheckDigitizingState();
+        }
+
+        private void InsertRedlineGeometry(MgGeometry geom)
+        {
+            MgPropertyCollection feature = new MgPropertyCollection();
+            MgByteReader agf = _agfRW.Write(geom);
+            MgGeometryProperty geomProp = new MgGeometryProperty("Geometry", agf);
+            feature.Add(geomProp);
+
+            _redlineLayer.ForceRefresh();
+            var reader = _redlineLayer.InsertFeatures(feature);
+            int inserted = 0;
+            while (reader.ReadNext())
+            {
+                inserted++;
+            }
+            reader.Close();
+            if (inserted > 0)
+            {
+                _viewer.RefreshMap();
+                IMapLegend legend = Shell.Instance.Legend;
+                if (legend != null)
+                    legend.RefreshLegend();
+            }
+        }
+
+        private void CheckRedlineLayer()
+        {
+            if (_redlineLayer == null)
+            {
+                MgdMap map = (MgdMap)_viewer.GetMap();
+                MgMapViewerProvider provider = _viewer.GetProvider();
+                MgdFeatureService featSvc = (MgdFeatureService)provider.CreateService(MgServiceType.FeatureService);
+                MgResourceService resSvc = (MgResourceService)provider.CreateService(MgServiceType.ResourceService);
+
+                string sessionId = Guid.NewGuid().ToString();
+                MgResourceIdentifier fsId = new MgResourceIdentifier("Session:" + sessionId + "//Redline.FeatureSource");
+                MgResourceIdentifier ldfId = new MgResourceIdentifier("Session:" + sessionId + "//Redline.LayerDefinition");
+                string featureClass = "Default:Redline";
+                string geometry = "Geometry";
+                string xml = string.Format(Layers.Redline, fsId.ToString(), featureClass, geometry);
+
+                //Construct our schema for the redline data store
+                MgFeatureSchema schema = new MgFeatureSchema("Default", "Redline schema");
+                MgClassDefinition cls = new MgClassDefinition();
+                cls.Name = "Redline";
+
+                MgDataPropertyDefinition id = new MgDataPropertyDefinition("ID");
+                id.DataType = MgPropertyType.Int32;
+                id.SetAutoGeneration(true);
+
+                MgGeometricPropertyDefinition geom = new MgGeometricPropertyDefinition(geometry);
+                geom.SpatialContextAssociation = "Default";
+                geom.GeometryTypes = MgFeatureGeometricType.Curve | MgFeatureGeometricType.Point | MgFeatureGeometricType.Solid | MgFeatureGeometricType.Surface;
+
+                MgPropertyDefinitionCollection clsProps = cls.GetProperties();
+                clsProps.Add(id);
+                clsProps.Add(geom);
+
+                MgPropertyDefinitionCollection idProps = cls.GetIdentityProperties();
+                idProps.Add(id);
+
+                cls.DefaultGeometryPropertyName = geometry;
+                MgClassDefinitionCollection classes = schema.GetClasses();
+                classes.Add(cls);
+
+                //Create the feature source
+                MgCreateSdfParams create = new MgCreateSdfParams("Default", map.GetMapSRS(), schema);
+                featSvc.CreateFeatureSource(fsId, create);
+
+                //Then the layer definition
+                byte[] bytes = Encoding.UTF8.GetBytes(xml);
+                MgByteSource source = new MgByteSource(bytes, bytes.Length);
+                resSvc.SetResource(ldfId, source.GetReader(), null);
+
+                //Now create the runtime layer and add to map
+                _redlineLayer = new MgdLayer(ldfId, resSvc);
+                _redlineLayer.LegendLabel = "Redlining";
+                _redlineLayer.Name = "Redline";
+                _redlineLayer.Visible = true;
+                _redlineLayer.Selectable = true;
+                _redlineLayer.DisplayInLegend = true;
+
+                MgLayerCollection layers = map.GetLayers();
+                layers.Insert(0, _redlineLayer);
+            }
+        }
+
+        private void CheckDigitizingState()
+        {
+            btnLine.Enabled = btnLineString.Enabled = btnPoint.Enabled = btnPolygon.Enabled = (_viewer.DigitizingType == MapDigitizationType.None);
+        }
+
+        protected override void SubCleanup()
+        {
+            _geomFact.Dispose();
+            _geomFact = null;
+            _viewer.PropertyChanged -= OnViewerPropertyChanged;
+        }
+
+        private void btnPoint_Click(object sender, EventArgs e)
+        {
+            _viewer.DigitizePoint(OnPointDigitized);
+        }
+
+        private void OnPointDigitized(double x, double y)
+        {
+            CheckRedlineLayer();
+            MgGeometry point = _geomFact.CreatePoint(_geomFact.CreateCoordinateXY(x, y));
+            InsertRedlineGeometry(point);
+        }
+
+        private void btnLine_Click(object sender, EventArgs e)
+        {
+            _viewer.DigitizeLine(OnLineDigitized);
+        }
+
+        private void OnLineDigitized(double x1, double y1, double x2, double y2)
+        {
+            CheckRedlineLayer();
+            MgCoordinateCollection coords = new MgCoordinateCollection();
+            coords.Add(_geomFact.CreateCoordinateXY(x1, y1));
+            coords.Add(_geomFact.CreateCoordinateXY(x2, y2));
+            MgGeometry line = _geomFact.CreateLineString(coords);
+            InsertRedlineGeometry(line);
+        }
+
+        private void btnLineString_Click(object sender, EventArgs e)
+        {
+            _viewer.DigitizeLineString(OnLineStringDigitized);
+        }
+
+        private void OnLineStringDigitized(double[,] coordinates)
+        {
+            CheckRedlineLayer();
+            MgCoordinateCollection coords = new MgCoordinateCollection();
+            for (int i = 0; i < coordinates.GetLength(0); i++)
+            {
+                coords.Add(_geomFact.CreateCoordinateXY(coordinates[i, 0], coordinates[i, 1]));
+            }
+            MgGeometry line = _geomFact.CreateLineString(coords);
+            InsertRedlineGeometry(line);
+        }
+
+        private void btnPolygon_Click(object sender, EventArgs e)
+        {
+            _viewer.DigitizePolygon(OnPolygonDigitized);
+        }
+
+        private void OnPolygonDigitized(double[,] coordinates)
+        {
+            CheckRedlineLayer();
+            MgCoordinateCollection coords = new MgCoordinateCollection();
+            for (int i = 0; i < coordinates.GetLength(0); i++)
+            {
+                coords.Add(_geomFact.CreateCoordinateXY(coordinates[i, 0], coordinates[i, 1]));
+            }
+            coords.Add(_geomFact.CreateCoordinateXY(coordinates[0, 0], coordinates[0, 1]));
+            MgLinearRing ring = _geomFact.CreateLinearRing(coords);
+            MgGeometry poly = _geomFact.CreatePolygon(ring, null);
+            InsertRedlineGeometry(poly);
+        }
+
+        private void btnClearRedlines_Click(object sender, EventArgs e)
+        {
+            if (_redlineLayer != null)
+            {
+                _redlineLayer.DeleteFeatures(""); //Empty string means delete everything
+                _viewer.RefreshMap();
+                MessageBox.Show("Redlines cleared");
+            }
+        }
     }
 }

Modified: branches/2.4/MgDev/Desktop/SampleExtension/Layers.Designer.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Layers.Designer.cs	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Layers.Designer.cs	2012-07-10 12:25:43 UTC (rev 6885)
@@ -256,6 +256,26 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to <?xml version="1.0"?>
+        ///<LayerDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="LayerDefinition-1.0.0.xsd" version="1.0.0">
+        ///  <VectorLayerDefinition>
+        ///    <ResourceId>{0}</ResourceId>
+        ///    <FeatureName>{1}</FeatureName>
+        ///    <FeatureNameType>FeatureClass</FeatureNameType>
+        ///    <Geometry>{2}</Geometry>
+        ///    <VectorScaleRange>
+        ///      <AreaTypeStyle>
+        ///        <AreaRule>
+        ///          <LegendLabel />
+        ///          <AreaSymboliz [rest of string was truncated]";.
+        /// </summary>
+        internal static string Redline {
+            get {
+                return ResourceManager.GetString("Redline", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to <VectorScaleRange>
         ///  <MinScale>%s</MinScale>
         ///  <MaxScale>%s</MaxScale>
@@ -270,6 +290,17 @@
         }
         
         /// <summary>
+        ///   Looks up a localized string similar to If you see this message, it is because I am a component that was automatically invoked by the AppLayout's InvokeOnStartup property. 
+        ///
+        ///These samples requires the Sheboygan dataset loaded. If you haven't loaded this package, you load the package and map after this message from the "File" menu..
+        /// </summary>
+        internal static string StartupText {
+            get {
+                return ResourceManager.GetString("StartupText", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Looks up a localized string similar to <Unit>Points</Unit>
         ///<SizeContext>DeviceUnits</SizeContext>
         ///<SizeX>%s</SizeX>

Modified: branches/2.4/MgDev/Desktop/SampleExtension/Layers.resx
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Layers.resx	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Layers.resx	2012-07-10 12:25:43 UTC (rev 6885)
@@ -157,4 +157,12 @@
   <data name="ParcelMarker" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>Resources\ParcelMarker.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
   </data>
+  <data name="Redline" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\Redline.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+  </data>
+  <data name="StartupText" xml:space="preserve">
+    <value>If you see this message, it is because I am a component that was automatically invoked by the AppLayout's InvokeOnStartup property. 
+
+These samples requires the Sheboygan dataset loaded. If you haven't loaded this package, you load the package and map after this message from the "File" menu.</value>
+  </data>
 </root>
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/SampleExtension/MgStartupComponent.cs
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/MgStartupComponent.cs	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/SampleExtension/MgStartupComponent.cs	2012-07-10 12:25:43 UTC (rev 6885)
@@ -10,7 +10,7 @@
     {
         public override void Invoke()
         {
-            MessageBox.Show("If you see this message. It is because I was automatically invoked by the AppLayout's InvokeOnStartup property", "SampleExtension: MgStartupComponent");
+            MessageBox.Show(Layers.StartupText, "mg-desktop API Samples");
         }
     }
 }

Added: branches/2.4/MgDev/Desktop/SampleExtension/Resources/Redline.txt
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/Resources/Redline.txt	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/SampleExtension/Resources/Redline.txt	2012-07-10 12:25:43 UTC (rev 6885)
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<LayerDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="LayerDefinition-1.0.0.xsd" version="1.0.0">
+  <VectorLayerDefinition>
+    <ResourceId>{0}</ResourceId>
+    <FeatureName>{1}</FeatureName>
+    <FeatureNameType>FeatureClass</FeatureNameType>
+    <Geometry>{2}</Geometry>
+    <VectorScaleRange>
+      <AreaTypeStyle>
+        <AreaRule>
+          <LegendLabel />
+          <AreaSymbolization2D>
+            <Fill>
+              <FillPattern>Solid</FillPattern>
+              <ForegroundColor>ffffffff</ForegroundColor>
+              <BackgroundColor>ffffffff</BackgroundColor>
+            </Fill>
+            <Stroke>
+              <LineStyle>Solid</LineStyle>
+              <Thickness>1</Thickness>
+              <Color>ffff0000</Color>
+              <Unit>Points</Unit>
+            </Stroke>
+          </AreaSymbolization2D>
+        </AreaRule>
+      </AreaTypeStyle>
+      <LineTypeStyle>
+        <LineRule>
+          <LegendLabel />
+          <LineSymbolization2D>
+            <LineStyle>Solid</LineStyle>
+            <Thickness>1</Thickness>
+            <Color>ffff0000</Color>
+            <Unit>Points</Unit>
+          </LineSymbolization2D>
+        </LineRule>
+      </LineTypeStyle>
+      <PointTypeStyle>
+        <DisplayAsText>false</DisplayAsText>
+        <AllowOverpost>false</AllowOverpost>
+        <PointRule>
+          <LegendLabel />
+          <Label>
+            <Unit>Points</Unit>
+            <SizeContext>DeviceUnits</SizeContext>
+            <SizeX>10</SizeX>
+            <SizeY>10</SizeY>
+            <Rotation>0</Rotation>
+            <Text></Text>
+            <FontName>Arial</FontName>
+            <ForegroundColor>ffff0000</ForegroundColor>
+            <BackgroundColor>ffffffff</BackgroundColor>
+            <BackgroundStyle>Ghosted</BackgroundStyle>
+          </Label>
+          <PointSymbolization2D>
+            <Mark>
+              <Unit>Points</Unit>
+              <SizeContext>DeviceUnits</SizeContext>
+              <SizeX>10</SizeX>
+              <SizeY>10</SizeY>
+              <Rotation>0</Rotation>
+              <Shape>Square</Shape>
+              <Fill>
+                <FillPattern>Solid</FillPattern>
+                <ForegroundColor>ffffffff</ForegroundColor>
+                <BackgroundColor>ffffffff</BackgroundColor>
+              </Fill>
+              <Edge>
+                <LineStyle>Solid</LineStyle>
+                <Thickness>1</Thickness>
+                <Color>ffff0000</Color>
+                <Unit>Points</Unit>
+              </Edge>
+            </Mark>
+          </PointSymbolization2D>
+        </PointRule>
+      </PointTypeStyle>
+    </VectorScaleRange>
+  </VectorLayerDefinition>
+</LayerDefinition>
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj
===================================================================
--- branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj	2012-07-09 16:31:59 UTC (rev 6884)
+++ branches/2.4/MgDev/Desktop/SampleExtension/SampleExtension.csproj	2012-07-10 12:25:43 UTC (rev 6885)
@@ -255,6 +255,9 @@
   <ItemGroup>
     <None Include="Resources\ParcelMarker.txt" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\Redline.txt" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.



More information about the mapguide-commits mailing list