ThinkGeo.com    |     Documentation    |     Premium Support

Split polygon with a line

 Hi, 


I have one question about split a polygon with a line.


So far, I used the class split of the example "split example" to split a polygon with a line.


This works well if the line has only 2 points. But in the case the line has more than 2 points, the split is not really correct


Example with a line which has more than 2 points : 



 


The result is  : 


 


I have this result because the line built for the cut is in fact (I drew the red line with paint to show what happens => GetCrosses())


Question :  


Is it possible to obtain the 2 polygons from the drawn line blue ?


I see in an other post (gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/12/aft/6021/afv/topic/Default.aspx), the same question was put. And in 2009, you didn't have  the API to directly do the splitting.


And now , is there an Api (with the splitting) which exists ?


If not, it there an easy way to do that ?


Thanks a lot for your help.


Regards.


Steph.


 




Hi Steph


We've updated our “splitter class” in split sample, please get the lasted version and have a try. Here is the sample code we tested:



            Map1.MapUnit = GeographyUnit.DecimalDegree;
            Map1.CurrentExtent = new RectangleShape(-30, 30, 30, -30);

            InMemoryFeatureLayer inmLayer = new InMemoryFeatureLayer();
            inmLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Water1;
            inmLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            PolygonShape polygonShape = new PolygonShape("Polygon((-20 20,20 20,20 -20,-20 -20,-20 20))");
            LineShape splitLine = new LineShape("LineString(15 30,0 0,15 -30)");
            MultipolygonShape polygons = Splitter.Split(polygonShape, splitLine);

            //inmLayer.InternalFeatures.Add(new Feature(polygonShape));//unComment this can show Polygon
            inmLayer.InternalFeatures.Add(new Feature(polygons.Polygons[0]));
            //inmLayer.InternalFeatures.Add(new Feature(polygons.Polygons[1]));//unComment this can show another splitted polygon

            LayerOverlay layerOverlay = new LayerOverlay();
            layerOverlay.Layers.Add(inmLayer);
            Map1.Overlays.Add(layerOverlay);
            Map1.Refresh();

Hope it helps,


Edgar


 



Hi Edgar,



Thanks for your help.



I downloaded the "splitter class" to this adress wiki.thinkgeo.com/wiki/File:ServicesEditionSample_SplitPolygon_CS_091121.zip.

The sample is a winform sample.



And When I use the splitter class with WPF, the enum Clockwise doesn't exist in wpf version.  

So I created it but the Method GetWellKnownText with a parameter doesn't implement in wpf version.




PolygonShape orderedPolygon = new PolygonShape(processedPolygon.GetWellKnownText(RingOrder.Clockwise));




Have I downloaded the new class "splitter" in the wrong place ?





Thanks a lor for your help.



Regards.



Steph.


 


 



Hi Steph,


Sorry about this, we uploaded a version that uses the features in dev build, and we've uploaded a new one. So please get it at the same page and have an another try.


Regards,


Edgar



 Hi Edgar, 


Thanks for your help but I have one case where there is a problem.



If I cut the polygon on the one single side,



I have this result



 


The result is 2 equals polygons.


 


So I did some modifications in the class splitter


 



  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);




  if (polygonShape1.IsWithin(polygonShape2))


                {


                    polygonShape2 = processedPolygon.OuterRing.GetDifference(polygonShape1).Polygons[0];


                    foreach (RingShape ii in processedPolygon.InnerRings)


                    {


                        polygonShape2.InnerRings.Add(ii);


                    }


                }


.....



}





 



So I changed too the SplitRing Method  because I believed that the problem came because we did not use the intersection point in the creation of the new polygon (intersectionPointShape2)



  public static RingShape SplitRing(RingShape processedRing, Collection<PointShape> intersectionPointShapes)


        {



 RingShape resultRingShape = new RingShape();


            PointShape intersectionPointShape1 = intersectionPointShapes[0];


            PointShape intersectionPointShape2 = intersectionPointShapes[intersectionPointShapes.Count - 1];





            int i = 0;


            int totalPointNumber = processedRing.Vertices.Count;


            while (i < totalPointNumber - 1)


            {


                int indexA = i + 1;


                if (DoesPointShapeBelongToLineSegment(intersectionPointShape1, new PointShape(processedRing.Vertices), new PointShape(processedRing.Vertices[indexA])))


                {


                    resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1));                    


                    if (DoesPointShapeBelongToLineSegment(intersectionPointShape2, new PointShape(processedRing.Vertices), new PointShape(processedRing.Vertices[indexA])))


                    {




   resultRingShape.Vertices.Add(new Vertex(intersectionPointShape2));


                        for (int shapeIndex = intersectionPointShapes.Count - 2; shapeIndex > 0; shapeIndex--)


                        { resultRingShape.Vertices.Add(new Vertex(intersectionPointShapes[shapeIndex])); }


                        resultRingShape.Vertices.Add(new Vertex(intersectionPointShape1));


...


}


But I still have the problem ;-( and sometimes the new polygon is not correct (form butterfly .....)




 


But the other polygon is correct



So I don't understand why the GetDifference function gives this result .. ?


May be it's not necessary to use the GetDifference function to solve the problem of cutting of a polygon on a single side ?


Thanks a lots for your help.


 


Regards.


Stéphanie.


 





 Hi Steph,


 
We didn't recreate this issue in the latest version. I think maybe it's a bug which has been fixed already. Please download the latest version(6.0.277.0 or later) and try again.
 
Here attached a Wpf split sample(The splitter calss has been modified according to your code)
 
Thanks,
 
Gary

Post10992.zip (11.7 KB)

Hi Gary,  
  
 Sorry for the response time. 
 I downloaded the dll and I have still the pb.  
 But don’t worry , I found a workaround. It is just necessary to add a node on the side of the polygon and the cutting works. 
  
 Thanks a lot for your help. 
  
 Regards. 
  
 Steph.

Thanks Steph, any question please let us know. 
  
 Regards, 
 Johnny

Hi, 



I have a problem with the split a polygon which has a hole.

Step1 : the polygon has this shape (cf. Capture.Split_20130701_Step1.png)





Step2 : I split the polygon with a line and one point of the line is in the hole of the polygon (cf. Capture.Split_20130701_Step2.png)





Steph3 : And the result is cf. Capture.Split_20130701_Step3.png. So the hole disappears ;-(





Have you ever met and solved this case?



I joined too the class split that I used. (the class that i use is based on the example Split polygon)



Thanks a lot for your help.



Regards.



Steph




Splitter.cs (10.3 KB)

Hi Steph, 
  
 Thanks for your detail information so that I reprodce it quickly.  
  
 I think this issue casued by logic problem of SplitRing function.  
  
 In your case, when your line split innerRing, it just ignore the turning point so the splitted polygon cannot be contained in the splitted outerPolygon, then it losed. 
  
 Please try changing the logic of SplitRing function follow the logic of GetPolygonForSplit function, because the outerPolygon splitted correct. 
  
 Any question please let me know. 
  
 Regards, 
  
 Don

Hi Don,  
  
 Thanks, I changed the splitring function and i resolved my issue 
  
 Regards. 
  
 Stéphanie.

Hi Steph, 
  
 Great to hear it is sorted out, if you have any more question, please feel free to let us know. 
  
 Best Regards 
  
 Summer