====== Source Code ServicesEditionSample CorrectingNodes CS 090923.zip ====== ====NodeLineStyle.cs==== using System; using System.Collections.Generic; using System.Linq; using System.Text; using ThinkGeo.MapSuite.Core; using System.Collections.ObjectModel; namespace CorrectingNodes { class NodeLineStyle : LineStyle { private PointStyle nodePointStyle; private LineStyle lineStyle; public NodeLineStyle() : this(new PointStyle(), new LineStyle()) { } public NodeLineStyle(PointStyle NodePointStyle, LineStyle LineStyle) { this.nodePointStyle = NodePointStyle; this.lineStyle = LineStyle; } //PointStyle for the end and start nodes of the line. public PointStyle NodePointStyle { get { return nodePointStyle; } set { nodePointStyle = value; } } protected override void DrawCore(IEnumerable features, GeoCanvas canvas, System.Collections.ObjectModel.Collection labelsInThisLayer, System.Collections.ObjectModel.Collection labelsInAllLayers) { foreach (Feature feature in features) { MultilineShape multilineShape = (MultilineShape)feature.GetShape(); //Gets the PointShape of the start node. PointShape startPointShape = new PointShape(multilineShape.Lines[0].Vertices[0].X, multilineShape.Lines[0].Vertices[0].Y); //Gets the PointShape of the end node. int vertexCount = multilineShape.Lines[0].Vertices.Count; PointShape endPointShape = new PointShape(multilineShape.Lines[0].Vertices[vertexCount|- 1].X, multilineShape.Lines[0].Vertices[vertexCount|- 1].Y); //Displays the line and the start/end nodes according to the LineSymbol and PointSymbol set. canvas.DrawLine(multilineShape, lineStyle.OuterPen, DrawingLevel.LevelOne); canvas.DrawEllipse(startPointShape, nodePointStyle.SymbolSize, nodePointStyle.SymbolSize, nodePointStyle.SymbolSolidBrush, DrawingLevel.LevelOne); canvas.DrawEllipse(endPointShape, nodePointStyle.SymbolSize, nodePointStyle.SymbolSize, nodePointStyle.SymbolSolidBrush, DrawingLevel.LevelOne); } } } } ====Program.cs==== using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace CorrectingNodes { static class Program { /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new TestForm()); } } } ====TestForm.cs==== using System; using System.Drawing; using System.Windows.Forms; using ThinkGeo.MapSuite.Core; using System.Collections.ObjectModel; using System.IO; namespace CorrectingNodes { public partial class TestForm : Form { private MapEngine mapEngine = new MapEngine(); private Bitmap bitmap = null; ShapeFileFeatureLayer lineLayer = null; public TestForm() { InitializeComponent(); } private void TestForm_Load(object sender, EventArgs e) { // Set the full extent and the background color mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-97.7452,30.3030,-97.7432,30.3012), Map.Width, Map.Height); mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.StandardColors.LightGoldenrodYellow); // Add the static layers to the MapEngine lineLayer = new ShapeFileFeatureLayer(@"..\..\Data\lines.shp", ShapeFileReadWriteMode.ReadOnly); lineLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear(); //Adds custom NodeLineStyle NodeLineStyle nodeLineStyle = new NodeLineStyle(new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.StandardColors.Red),8), new LineStyle(new GeoPen(GeoColor.StandardColors.Black,2))); lineLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(nodeLineStyle); lineLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("lineLayer", lineLayer); DrawImage(); } private ShapeFileFeatureLayer CorrectNodes(ShapeFileFeatureLayer LineShapeFileFeatureLayer, string CorrectedLineShapeFileFeatureLayerPath) { LineShapeFileFeatureLayer.Open(); //Gets the columns from the line based shapefile and we add the columns to the new line based shapefile. Collection lineDbfColumns = ((ShapeFileFeatureSource)LineShapeFileFeatureLayer.FeatureSource).GetDbfColumns(); //Creates the new line based shapefile. ShapeFileFeatureLayer.CreateShapeFile(ShapeFileType.Polyline, CorrectedLineShapeFileFeatureLayerPath, lineDbfColumns); //Creates the new shapefile feature source. ShapeFileFeatureSource correctedLineShapeFileFeatureSource = new ShapeFileFeatureSource(CorrectedLineShapeFileFeatureLayerPath, ShapeFileReadWriteMode.ReadWrite); //Gets all the features from the line shapefile. Collection features = LineShapeFileFeatureLayer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns); LineShapeFileFeatureLayer.Close(); correctedLineShapeFileFeatureSource.Open(); correctedLineShapeFileFeatureSource.BeginTransaction(); //Collection of the adjusted PointShapes for the corrected Layer. Collection newPointShapes = new Collection(); //Loops thru the features of the line based layer to get the adjusted start and end nodes according to the tolerance. for (int i = 0 ; i < features.Count - 1; i += 1) { MultilineShape multiLineShape = (MultilineShape)features[i].GetShape(); int vertexCount = multiLineShape.Lines[0].Vertices.Count; PointShape endPointShape = new PointShape(multiLineShape.Lines[0].Vertices[vertexCount|- 1].X, multiLineShape.Lines[0].Vertices[vertexCount|- 1].Y); MultilineShape multiLineShape2 = (MultilineShape)features[i|+ 1].GetShape(); int vertexCount2 = multiLineShape2.Lines[0].Vertices.Count; PointShape startPointShape2 = new PointShape(multiLineShape2.Lines[0].Vertices[0].X, multiLineShape2.Lines[0].Vertices[0].Y); PointShape adjustedPointShape = null; double distEndStart = endPointShape.GetDistanceTo(startPointShape2, GeographyUnit.DecimalDegree, DistanceUnit.Meter); //Compares the position of the end vertex with the position of the start vertex of the next line. //If the two vertices are within the tolerance, get the mid point. if (distEndStart > 0) { LineShape lineShape = new LineShape(); lineShape.Vertices.Add(new Vertex(endPointShape)); lineShape.Vertices.Add(new Vertex(startPointShape2)); adjustedPointShape = lineShape.GetPointOnALine(StartingPoint.FirstPoint, 50); } if (adjustedPointShape == null) { newPointShapes.Add(new PointShape(multiLineShape.Lines[0].Vertices[vertexCount|- 1])); } else { newPointShapes.Add(adjustedPointShape); } } //Loops thru the features to add the new features with the adjusted PointShapes. for (int j = 0; j <= features.Count - 1 ; j++) { MultilineShape multilineShape = (MultilineShape)features[j].GetShape(); int vertexCount = multilineShape.Lines[0].Vertices.Count; if (j == 0) { multilineShape.Lines[0].Vertices[vertexCount|- 1] = new Vertex(newPointShapes[j]); } else if (j == features.Count - 1) { multilineShape.Lines[0].Vertices[0] = new Vertex(newPointShapes[j|- 1]); } else { multilineShape.Lines[0].Vertices[0] = new Vertex(newPointShapes[j|- 1]); multilineShape.Lines[0].Vertices[vertexCount|- 1] = new Vertex(newPointShapes[j]); } multilineShape.Id = features[j].Id; features[j] = new Feature(multilineShape); correctedLineShapeFileFeatureSource.AddFeature(features[j]); } correctedLineShapeFileFeatureSource.CommitTransaction(); correctedLineShapeFileFeatureSource.Close(); ShapeFileFeatureLayer correctedLineShapeFileFeatureLayer = new ShapeFileFeatureLayer(CorrectedLineShapeFileFeatureLayerPath); return correctedLineShapeFileFeatureLayer; } private void btnCorrect_Click(object sender, EventArgs e) { //deletes the files if they already exist. if (File.Exists(@"..\..\Data\correctedlines.shp")) { DeleteCorrectedFiles(); } //Calls CorrectNodes function to create the new shapefile with the corrected nodes. ShapeFileFeatureLayer correctedLineFeatureLayer = CorrectNodes(lineLayer, @"..\..\Data\correctedlines.shp"); mapEngine.StaticLayers.Remove("lineLayer"); //Adds the new shapefile ShapeFileFeatureLayer correctedLineLayer = new ShapeFileFeatureLayer(@"..\..\Data\correctedlines.shp", ShapeFileReadWriteMode.ReadOnly); NodeLineStyle nodeLineStyle = new NodeLineStyle(new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.StandardColors.Red), 8), new LineStyle(new GeoPen(GeoColor.StandardColors.Black, 2))); correctedLineLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(nodeLineStyle); correctedLineLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("correctedLineLayer", correctedLineLayer); btnCorrect.Enabled = false; DrawImage(); } private void DeleteCorrectedFiles() { File.Delete(@"..\..\Data\correctedlines.shp"); File.Delete(@"..\..\Data\correctedlines.ids"); File.Delete(@"..\..\Data\correctedlines.idx"); File.Delete(@"..\..\Data\correctedlines.dbf"); File.Delete(@"..\..\Data\correctedlines.shx"); } private void DrawImage() { if (bitmap != null) { bitmap.Dispose(); } bitmap = new Bitmap(Map.Width, Map.Height); mapEngine.OpenAllLayers(); mapEngine.DrawStaticLayers(bitmap, GeographyUnit.DecimalDegree); mapEngine.CloseAllLayers(); Map.Image = bitmap; } private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e) { switch (e.Button.Tag.ToString()) { case "Zoom In": mapEngine.CurrentExtent.ScaleDown(50); break; case "Zoom Out": mapEngine.CurrentExtent.ScaleUp(50); break; case "Full Extent": mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-180.0, 83.0, 180.0, -90.0), Map.Width, Map.Height); break; case "Pan Left": mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Left, 20); break; case "Pan Right": mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Right, 20); break; case "Pan Up": mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Up, 20); break; case "Pan Down": mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Down, 20); break; default: break; } DrawImage(); } private void btnClose_Click(object sender, EventArgs e) { this.Close(); } } }