====== 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();
}
}
}