User Tools

Site Tools


source_code_serviceseditionsample_splitpolygon_cs_091121.zip

Source Code ServicesEditionSample SplitPolygon CS 091121.zip

Program.cs

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Windows.Forms;  
 
 namespace SplitPolygon  
 {  
     static class Program  
     {  
         /// <summary>  
         /// The main entry point for the application.  
         /// </summary>  
         [STAThread]  
         static void Main()  
         {  
             Application.EnableVisualStyles();  
             Application.SetCompatibleTextRenderingDefault(false);  
             Application.Run(new TestForm());  
         }  
     }  
 }  
 

Splitter.cs

 using System;  
 using System.Collections.ObjectModel;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace SplitPolygon  
 {  
     public static class Splitter  
     {  
         public static Collection<LineShape> GetPerpendicularLines(LineShape lineShape, Collection<PointShape> interceptedPoints, double length)  
         {  
             Collection<LineShape> returnFeatures = new Collection<LineShape>();  
             double halfLength = length / 2;  
             double pi2 = Math.PI / 2;  
             double searchingTolerance = 0.000001;  
             foreach (PointShape interceptedPoint in interceptedPoints)  
             {  
                 RectangleShape searchingArea = new RectangleShape(interceptedPoint.X - searchingTolerance, interceptedPoint.Y + searchingTolerance, interceptedPoint.X + searchingTolerance, interceptedPoint.Y - searchingTolerance);  
 
                 // Check if the intercepted point is the vertex will be ignore, because we can not create perpendicular line crosses vertex.  
                 foreach (Vertex vertex in lineShape.Vertices)  
                 {  
                     if (new PointShape(vertex).IsWithin(searchingArea))  
                     {  
                         continue;  
                     }  
                 }  
 
                 double middleX = interceptedPoint.X;  
                 double middleY = interceptedPoint.Y;  
 
                 Vertex vertex1 = new Vertex();  
                 Vertex vertex2 = new Vertex();  
                 // Find the crossing point is between which two vertices  
                 for (int i = 0; i < lineShape.Vertices.Count - 1; i++)  
                 {  
                     vertex1 = lineShape.Vertices[i];  
                     vertex2 = lineShape.Vertices[i|+ 1];  
                     LineShape currentLine = new LineShape(new Vertex[] { vertex1, vertex2 });  
                     if (searchingArea.Intersects(currentLine))  
                     {  
                         break;  
                     }  
                 }  
 
                 double angle = Math.Atan((vertex1.Y - vertex2.Y) / (vertex1.X - vertex2.X));  
 
                 double x = 0;  
                 double y = 0;  
 
                 if (angle > 0 && angle < pi2)  
                 {  
                     if (vertex1.X > vertex2.X)  
                     {  
                         x = middleX + Math.Sin(angle) * halfLength;  
                         y = middleY - Math.Cos(angle) * halfLength;  
                     }  
                     else  
                     {  
                         x = middleX - Math.Sin(angle) * halfLength;  
                         y = middleY + Math.Cos(angle) * halfLength;  
                     }  
                 }  
                 else  
                 {  
                     if (vertex1.X > vertex2.X)  
                     {  
                         x = middleX + Math.Sin(angle) * halfLength;  
                         y = middleY - Math.Cos(angle) * halfLength;  
                     }  
                     else  
                     {  
                         x = middleX - Math.Sin(angle) * halfLength;  
                         y = middleY + Math.Cos(angle) * halfLength;  
                     }  
                 }  
 
                 Vertex anotherVertex = new Vertex(middleX * 2 - x, middleY * 2 - y);  
                 LineShape line = new LineShape(new Vertex[] { anotherVertex, new Vertex(x, y) });  
                 returnFeatures.Add(line);  
             }  
 
             return returnFeatures;  
         }  
 
         public static PolygonShape SplitPolygonWithTwoLines(PolygonShape processedPolygon, LineShape lineShape1, LineShape lineShape2)  
         {  
             MultipolygonShape resultMultipolygon = Split(processedPolygon, lineShape1);  
             PolygonShape resultShape = new PolygonShape();  
             foreach (PolygonShape polygonShape in resultMultipolygon.Polygons)  
             {  
                 MultipointShape intersectionMultiPoint = lineShape2.GetCrossing(polygonShape.OuterRing);  
                 if (intersectionMultiPoint.Points.Count == 2)  
                 {  
                     MultipolygonShape resultMultipolygon1 = Split(polygonShape, lineShape2);  
                     foreach (PolygonShape polygonShape1 in resultMultipolygon1.Polygons)  
                     {  
                         MultipointShape intersectionMultiPoint1 = lineShape2.GetCrossing(polygonShape.OuterRing);  
                         if (intersectionMultiPoint1.Points.Count == 2)  
                         {  
                             resultShape = polygonShape1;  
                             break;  
                         }  
                     }  
                 }  
             }  
             return resultShape;  
         }  
 
         public static MultipolygonShape Split(PolygonShape processedPolygon, LineShape lineShape)  
         {  
             MultipolygonShape resultShape = new MultipolygonShape();  
             MultipointShape intersectionMultiPoint = lineShape.GetCrossing(processedPolygon.OuterRing);  
 
             if (intersectionMultiPoint.Points.Count == 2)  
             {  
                 PolygonShape polygonShape1 = GetPolygonForSplit(processedPolygon, lineShape, false);  
                 PolygonShape polygonShape2 = GetPolygonForSplit(processedPolygon, lineShape, true);  
                 resultShape.Polygons.Add(polygonShape1);  
                 resultShape.Polygons.Add(polygonShape2);  
             }  
             return resultShape;  
         }  
 
         private static PolygonShape GetPolygonForSplit(PolygonShape processedPolygon, LineShape lineShape, bool changeOrder)  
         {  
             MultipointShape intersectionMultiPoint = lineShape.GetCrossing(processedPolygon.OuterRing);  
             if (changeOrder)  
             {  
                 PointShape tempPointShape = intersectionMultiPoint.Points[0];  
                 intersectionMultiPoint.Points[0] = intersectionMultiPoint.Points[1];  
                 intersectionMultiPoint.Points[1] = tempPointShape;  
             }  
             if (intersectionMultiPoint.Points.Count == 2)  
             {  
                 PolygonShape resultPolygonShape = new PolygonShape();  
                 RingShape resultOuterRing = SplitRing(processedPolygon.OuterRing, intersectionMultiPoint.Points[0], intersectionMultiPoint.Points[1]);  
                 resultPolygonShape.OuterRing = resultOuterRing;  
 
                 foreach (RingShape innerRing in processedPolygon.InnerRings)  
                 {  
                     MultipointShape innerIntersectionMultiPoint = lineShape.GetCrossing(innerRing);  
                     if (innerIntersectionMultiPoint.Points.Count == 2)  
                     {  
                         RingShape resultInnerRing = SplitRing(innerRing, innerIntersectionMultiPoint.Points[0], innerIntersectionMultiPoint.Points[1]);  
                         if (resultPolygonShape.Contains(resultInnerRing))  
                         {  
                             resultPolygonShape.InnerRings.Add(resultInnerRing);  
                         }  
                     }  
                     else  
                     {  
                         if (resultPolygonShape.Contains(innerRing))  
                         {  
                             resultPolygonShape.InnerRings.Add(innerRing);  
                         }  
                     }  
                 }  
                 return resultPolygonShape;  
             }  
             return null;  
         }  
 
         public static bool DoesPointShapeBelongToLineSegment(PointShape pointShape, PointShape linePointShape1, PointShape linePointShape2)  
         {  
             bool result = false;  
             double a = 0;  
             double b = 0;  
 
             if ((pointShape.X == linePointShape1.X & pointShape.Y == linePointShape1.Y) | (pointShape.X == linePointShape2.X & pointShape.Y == linePointShape2.Y))  
             {  
                 result = true;  
             }  
             else  
             {  
                 if (linePointShape1.X != linePointShape2.X)  
                 {  
                     a = (linePointShape2.Y - linePointShape1.Y) / (linePointShape2.X - linePointShape1.X);  
                     b = linePointShape1.Y - (a * linePointShape1.X);  
 
                     if (Math.Round(pointShape.Y, 5) == Math.Round((a * pointShape.X) + b, 5) & pointShape.X >= Math.Min(linePointShape1.X, linePointShape2.X) & pointShape.X <= Math.Max(linePointShape1.X, linePointShape2.X))  
                     {  
                         result = true;  
                     }  
                     else  
                     {  
                         result = false;  
                     }  
                 }  
                 else  
                 {  
                     if (pointShape.X == linePointShape1.X & (pointShape.Y >= Math.Min(linePointShape1.Y, linePointShape2.Y) & pointShape.Y <= Math.Max(linePointShape1.Y, linePointShape2.Y)))  
                     {  
                         result = true;  
                     }  
                     else  
                     {  
                         result = false;  
                     }  
                 }  
             }  
             return result;  
         }  
 
         public static RingShape SplitRing(RingShape processedRing, PointShape intersectionPointShape1, PointShape intersectionPointShape2)  
         {  
             RingShape resultRingShape = new RingShape();  
 
             int i = 0;  
             int totalPointNumber = processedRing.Vertices.Count;  
             while (i < totalPointNumber - 1)  
             {  
                 int indexA = i + 1;  
                 if (DoesPointShapeBelongToLineSegment(intersectionPointShape1, new PointShape(processedRing.Vertices[i]), new PointShape(processedRing.Vertices[indexA])))  
                 {  
                     resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1));  
                     if (DoesPointShapeBelongToLineSegment(intersectionPointShape2, new PointShape(processedRing.Vertices[i]), new PointShape(processedRing.Vertices[indexA])))  
                     {  
                         resultRingShape.Vertices.Add(new Vertex(intersectionPointShape2));  
                         resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1));  
                     }  
                     else  
                     {  
                         for (int j = i + 1; j <= processedRing.Vertices.Count - 1; j++)  
                         {  
                             //- 1  
                             int indexB = j + 1;  
 
                             if (j < processedRing.Vertices.Count - 1)  
                             {  
                                 if (DoesPointShapeBelongToLineSegment(intersectionPointShape2, new PointShape(processedRing.Vertices[j]), new PointShape(processedRing.Vertices[indexB])))  
                                 {  
                                     resultRingShape.Vertices.Add(processedRing.Vertices[j]);  
                                     resultRingShape.Vertices.Add(new Vertex(intersectionPointShape2));  
                                     resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1));  
                                     break; // TODO: might not be correct. Was : Exit For  
                                 }  
                                 else  
                                 {  
                                     resultRingShape.Vertices.Add(processedRing.Vertices[j]);  
                                 }  
                             }  
                             else  
                             {  
                                 for (int k = 0; k < i; k++)  
                                 {  
                                     if (DoesPointShapeBelongToLineSegment(intersectionPointShape2, new PointShape(processedRing.Vertices[k]), new PointShape(processedRing.Vertices[(k|+ 1)])))  
                                     {  
                                         resultRingShape.Vertices.Add(processedRing.Vertices[k]);  
                                         resultRingShape.Vertices.Add(new Vertex(intersectionPointShape2));  
                                         resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1));  
                                         break; // TODO: might not be correct. Was : Exit For  
                                     }  
                                     else  
                                     {  
                                         resultRingShape.Vertices.Add(processedRing.Vertices[k]);  
                                     }  
                                 }  
                                 break; // TODO: might not be correct. Was : Exit For  
                             }  
                         }  
                     }  
 
                     return resultRingShape;  
                 }  
                 i = i + 1;  
             }  
             return null;  
 
         }  
     }  
 }  
 

TestForm.cs

 using System;  
 using System.Collections.ObjectModel;  
 using System.Drawing;  
 using System.Windows.Forms;  
 using ThinkGeo.MapSuite.Core;  
 
 namespace SplitPolygon  
 {  
     public partial class TestForm : Form  
     {  
         private MapEngine mapEngine = new MapEngine();  
         private Bitmap bitmap = null;  
 
        public TestForm()  
         {  
             InitializeComponent();  
         }  
 
         private void TestForm_Load(object sender, EventArgs e)  
         {  
             // Set the extent and the background color  
             mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-97.7521,30.3097,-97.7396,30.3025), Map.Width, Map.Height);  
             mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);  
 
             //Displays the World Map Kit as a background.  
             ThinkGeo.MapSuite.Core.WorldMapKitLayer worldMapKitLayer = new ThinkGeo.MapSuite.Core.WorldMapKitLayer();  
             mapEngine.StaticLayers.Add(worldMapKitLayer);  
 
             //LineShape for the street center line.  
             LineShape lineShape = new LineShape();  
             lineShape.Vertices.Add(new Vertex(-97.7441,30.3057));  
             lineShape.Vertices.Add(new Vertex(-97.7457 ,30.3064));  
             lineShape.Vertices.Add(new Vertex(-97.7464 ,30.3067));  
             lineShape.Vertices.Add(new Vertex(-97.7475 ,30.3071));  
             lineShape.Vertices.Add(new Vertex(-97.7481 ,30.3073));  
             lineShape.Vertices.Add(new Vertex(-97.7487 ,30.3073));  
             lineShape.Vertices.Add(new Vertex(-97.7491 ,30.3073));  
             lineShape.Vertices.Add(new Vertex(-97.7495 ,30.3072));  
             lineShape.Vertices.Add(new Vertex(-97.7497 ,30.3068));  
             lineShape.Vertices.Add(new Vertex(-97.7499 ,30.3065));  
             lineShape.Vertices.Add(new Vertex(-97.7495 ,30.3061));  
             lineShape.Vertices.Add(new Vertex(-97.7492 ,30.3058));  
             lineShape.Vertices.Add(new Vertex(-97.7493 ,30.3056));  
             lineShape.Vertices.Add(new Vertex(-97.7493 ,30.3053));  
             lineShape.Vertices.Add(new Vertex(-97.7493 ,30.305));  
             lineShape.Vertices.Add(new Vertex(-97.7488 ,30.3048));  
             lineShape.Vertices.Add(new Vertex(-97.7486 ,30.3046));  
             lineShape.Vertices.Add(new Vertex(-97.7473 ,30.304));  
             lineShape.Vertices.Add(new Vertex(-97.7469 ,30.3037));  
             lineShape.Vertices.Add(new Vertex(-97.7471 ,30.3034));  
 
             //Buffers the street center line to get a polygon representing the street.  
             MultipolygonShape bufferMultiPolygonShape = lineShape.Buffer(10, GeographyUnit.DecimalDegree, DistanceUnit.Meter);  
             PolygonShape polygonShape = new PolygonShape(bufferMultiPolygonShape.Polygons[0].OuterRing);  
 
             //Gets the two points on the center line.  
             PointShape pointShape1 = lineShape.GetPointOnALine(StartingPoint.FirstPoint, 200, GeographyUnit.DecimalDegree, DistanceUnit.Meter);  
             PointShape pointShape2 = lineShape.GetPointOnALine(StartingPoint.FirstPoint, 850, GeographyUnit.DecimalDegree, DistanceUnit.Meter);  
             Collection<PointShape> interceptedPointShapes = new Collection<PointShape>();  
             interceptedPointShapes.Add(pointShape1);  
             interceptedPointShapes.Add(pointShape2);  
 
             //Gets the lines perpenticular to the center line.  
             Collection<LineShape> perpendicularLines = Splitter.GetPerpendicularLines(lineShape, interceptedPointShapes, 0.0005);  
 
             //Splits the street polygon.  
             PolygonShape splitPolygonShape = Splitter.SplitPolygonWithTwoLines(polygonShape, perpendicularLines[1], perpendicularLines[0]);  
 
             //InMemoryFeatureLayers for displaying the center line, the points on line, the perpenticular lines, the street polygon  
             //and the split street polygon.  
             InMemoryFeatureLayer centerLineInMemoryFeatureLayer = new InMemoryFeatureLayer();  
             centerLineInMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Red, 2, true);  
             centerLineInMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
             centerLineInMemoryFeatureLayer.InternalFeatures.Add(new Feature(lineShape));  
             mapEngine.DynamicLayers.Add("CenterLineLayer", centerLineInMemoryFeatureLayer);  
 
             InMemoryFeatureLayer inMemoryFeatureLayer = new InMemoryFeatureLayer();  
             inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(80, GeoColor.StandardColors.Red), GeoColor.StandardColors.Black);  
             inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.Green, 10);  
             inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.DarkCyan, 2, true);  
             inMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
             inMemoryFeatureLayer.InternalFeatures.Add("Area", new Feature(polygonShape));  
             inMemoryFeatureLayer.InternalFeatures.Add("Point1", new Feature(pointShape1));  
             inMemoryFeatureLayer.InternalFeatures.Add("Point2", new Feature(pointShape2));  
 
             foreach (LineShape perpendicularLineShape in perpendicularLines)  
             {  
                 inMemoryFeatureLayer.InternalFeatures.Add(new Feature(perpendicularLineShape));  
             }  
 
             mapEngine.DynamicLayers.Add("AreaLayer", inMemoryFeatureLayer);  
 
             InMemoryFeatureLayer inMemoryFeatureLayer2 = new InMemoryFeatureLayer();  
             inMemoryFeatureLayer2.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(150, GeoColor.StandardColors.Yellow), GeoColor.StandardColors.Black);  
             inMemoryFeatureLayer2.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
             inMemoryFeatureLayer2.InternalFeatures.Add("Result", new Feature(splitPolygonShape)); //ellipseShape1)); //polygonShape));  
             mapEngine.DynamicLayers.Add("ResultLayer", inMemoryFeatureLayer2);  
 
             DrawImage();  
         }  
 
 
         private void DrawImage()  
         {  
             if (bitmap != null) { bitmap.Dispose(); }  
             bitmap = new Bitmap(Map.Width, Map.Height);  
             mapEngine.OpenAllLayers();  
             mapEngine.DrawStaticLayers(bitmap, GeographyUnit.DecimalDegree);  
             mapEngine.DrawDynamicLayers(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();  
         }  
 
         private void Map_MouseMove(object sender, MouseEventArgs e)  
         {  
             //Displays the X and Y in screen coordinates.  
             statusStrip1.Items["toolStripStatusLabelScreen"].Text = "X:" + e.X + " Y:" + e.Y;  
 
             //Gets the PointShape in world coordinates from screen coordinates.  
             PointShape pointShape = ExtentHelper.ToWorldCoordinate(mapEngine.CurrentExtent, new ScreenPointF(e.X, e.Y), Map.Width, Map.Height);  
 
             //Displays world coordinates.  
             statusStrip1.Items["toolStripStatusLabelWorld"].Text = "(world) X:" + Math.Round(pointShape.X, 4) + " Y:" + Math.Round(pointShape.Y, 4);  
         }  
 
         private void Map_MouseUp(object sender, MouseEventArgs e)  
         {  
             //Gets the PointShape in world coordinates from screen coordinates.  
             PointShape pointShape = ExtentHelper.ToWorldCoordinate(mapEngine.CurrentExtent, new ScreenPointF(e.X, e.Y), Map.Width, Map.Height);  
 
             //Displays world coordinates.  
             System.Diagnostics.Debug.WriteLine(" X:" + Math.Round(pointShape.X, 4) + " Y:" + Math.Round(pointShape.Y, 4));  
         }  
 
 
     }  
 }  
 
source_code_serviceseditionsample_splitpolygon_cs_091121.zip.txt · Last modified: 2015/09/08 05:37 by admin