Cut a polygon geomery with a line geometry

Jul 23, 2012 at 7:10 AM

I constructed a DotSpatial.Topology.Geometry.Polygon and DotSpatial.Topology.Geometry.line geometry.

How to Cut the polygon geometry with a line so that i get two polygon geometries.

Developer
Jul 23, 2012 at 7:19 PM

Create a LineFeature and make an intersection between it and the polygon. It will create a FeatureList of new polygons.

Jul 24, 2012 at 5:40 AM

var c = new DotSpatial.Topology.Coordinate[5];
          
            c[0] = new DotSpatial.Topology.Coordinate(0, 0);
            c[1] = new DotSpatial.Topology.Coordinate(5, 0);
            c[2] = new DotSpatial.Topology.Coordinate(5, 5);
            c[3] = new DotSpatial.Topology.Coordinate(0, 5);
            c[4] = new DotSpatial.Topology.Coordinate(0, 0);
            var polygon = new DotSpatial.Topology.Polygon(c);
            var centroid = polygon.Centroid;
            var area = polygon.Area;
            var length = polygon.Length;

            var c2 = new DotSpatial.Topology.Coordinate[2];
            c2[0] = new DotSpatial.Topology.Coordinate(0, 0);
            c2[1] = new DotSpatial.Topology.Coordinate(5, 5);

            var linestring = new DotSpatial.Topology.LineString(c2);
            var linestrings = new List<DotSpatial.Topology.LineString>();
            linestrings.Add(linestring);
           
            var multilinestring = new DotSpatial.Topology.MultiLineString(linestrings);
           
            var cutpolygon = polygon.Intersection(multilinestring);

Result:

 cutpolygon    {LINESTRING (0.0000000000000000 0.0000000000000000, 5.0000000000000000 5.0000000000000000)}    DotSpatial.Topology.IGeometry {DotSpatial.Topology.LineString}

It returns the intersecting line...

Any way to get two cut polygons?

Jul 24, 2012 at 8:20 PM

I think that you have to implement this method..

Developer
Jul 25, 2012 at 1:42 PM

I do this in my application.  I don't have time at this very minute to look up how it was done.  I will try to respond later today.

Kyle

Developer
Jul 25, 2012 at 1:59 PM

Here is the code we use.  You will need to take out the Globals.whatever calls which are just used to report progress and errors.  The usual disclaimers apply ;-)

HTH,

Kyle

using DotSpatial.Data;
using DotSpatial.Projections;
using DotSpatial.Symbology;
using DotSpatial.Tools;
using DotSpatial.Topology;
using PointShape = DotSpatial.Symbology.PointShape;


        public static List<IGeometry> SegmentPolygons(List<IGeometry> alLines, List<IGeometry> alPolygons)
        {
            try
            {
                List<IGeometry> alSegments = new List<IGeometry>();

                // This algorithm must work in a divide and conquer way.  As I loop through each of the input lines, I will segment
                // the polygons and get back a FeatureSet.  If a "cut" is made, I will add the created segments
                // to the result FeatureSet.  Otherwise, I will simply add the feature to result FeatureSet.  After looping through all the "knife" lines,
                // the list of MyFeatureSet objects will contain all the segmented Features.  Any that are still "original" are not needed, since 
                // they are not segmented.

                Globals.ProgressBarEnable();

                // Create a list of FeatureSets from each poly
                List<MyFeatureSet> listCurrentFeatureSets = new List<MyFeatureSet>();
                for (int k = 0; k < alPolygons.Count; k++)
                {
                    IFeatureSet ifsTemp = new FeatureSet();
                    ifsTemp.Features.Add(new Feature(alPolygons[k]));
                    listCurrentFeatureSets.Add(new MyFeatureSet(ifsTemp, true));  // these are the originals
                }

                for (int i = 0; i < alLines.Count; i++)
                {
                    Globals.ProgressBarUpdate(GCStrings.GetString("Segmenting Polygons... "), (int)(((double)(i + 1) / (double)alLines.Count) * 100), false);

                    IGeometry dsLine = alLines[i];
                    List<MyFeatureSet> listNewFeatureSets = new List<MyFeatureSet>();
                    foreach (MyFeatureSet listCurrentFeatureSet in listCurrentFeatureSets)
                    {
                        foreach (IFeature feature in listCurrentFeatureSet.m_fs.Features)
                        {
                            IFeature fPoly = new Feature(feature);
                            IFeature fLine = new Feature(dsLine);
                            IFeatureSet ifsResult = new FeatureSet();

                            if (ClipPolygonWithLine.Accurate_ClipPolygonWithLine(ref fPoly, ref fLine, ref ifsResult))
                            {
                                listNewFeatureSets.Add(new MyFeatureSet(ifsResult, false)); // not an original anymore
                            }
                            else  // no intersection between Poly and Line
                            {
                                IFeatureSet ifsTemp = new FeatureSet();
                                ifsTemp.Features.Add(fPoly);
                                listNewFeatureSets.Add(new MyFeatureSet(ifsTemp, listCurrentFeatureSet.m_bOriginal));
                            }
                        }
                    }

                    // Now replace the current list
                    listCurrentFeatureSets = listNewFeatureSets;
                }

                // Now loop through and add any non-original features to the List<IGeometry>
                foreach (MyFeatureSet fsCurrent in listCurrentFeatureSets)
                {
                    foreach (IFeature feature in fsCurrent.m_fs.Features)
                    {
                        if (fsCurrent.m_bOriginal == false)
                        {
                            alSegments.Add(Geometry.FromBasicGeometry(feature.BasicGeometry));
                        }
                    }
                }

                Globals.ProgressBarDisable();

                return alSegments;
            }
            catch (Exception exc)
            {
                Globals.ProgressBarDisable();
                Globals.MessageBoxException("An error occurred segmenting the selected polygons(s).",
                    exc.ToString(), "GeoAnalysis Error");
                return null;
            }
        }

Developer
Jul 25, 2012 at 2:02 PM

Oops.  Forgot this simple class:


    public class MyFeatureSet
    {
        public bool m_bOriginal = true;
        public IFeatureSet m_fs = new FeatureSet();

        public MyFeatureSet(IFeatureSet fsInput, bool bOrig)
        {
            m_bOriginal = bOrig;
            m_fs = fsInput;
        }
    }

Jan 27, 2013 at 2:06 PM

Is there anyway to get the output of cutpolygonbyline in polygon format?