コード例 #1
0
        private MultiPolygon MergeInnerIntoOuterPolygon(List <Polygon> outerPolygons, List <Polygon> innerPolygons)
        {
            var newOuterPolygons = new List <Polygon>();

            outerPolygons = MergePolygons(outerPolygons);
            foreach (var outerPolygon in outerPolygons)
            {
                // remove all inner holes from outer polygon
                var newOuterPolygon = _geometryFactory.CreatePolygon((LinearRing)outerPolygon.ExteriorRing.Copy());
                // get inner polygons
                var currentInnerPolygons = innerPolygons.Where(p => p.Within(newOuterPolygon)).ToArray();
                if (!currentInnerPolygons.Any())
                {
                    newOuterPolygons.Add(newOuterPolygon);
                    continue;
                }
                var holesPolygons        = currentInnerPolygons.Select(p => _geometryFactory.CreatePolygon(p.ExteriorRing.Copy() as LinearRing)).ToArray();
                var holesUnifiedGeometry = CascadedPolygonUnion.Union(holesPolygons);
                // adding the difference between the outer polygon and all the holes inside it
                newOuterPolygons.Add(newOuterPolygon.Difference(holesUnifiedGeometry) as Polygon);
                // update list for next loop cycle
                innerPolygons = innerPolygons.Except(currentInnerPolygons).ToList();
            }
            return(_geometryFactory.CreateMultiPolygon(newOuterPolygons.Union(innerPolygons).ToArray()));
        }
        public void PerformCascadedPolygonUnion()
        {
            var reader     = new ShapefileReader("tnp_pol.shp");
            var collection = reader.ReadAll().Where(e => e is IPolygon).ToList();
            var u1         = collection[0];

            for (var i = 1; i < collection.Count; i++)
            {
                u1 = SnapIfNeededOverlayOp.Overlay(u1, collection[i], SpatialFunction.Union);
            }
            var u2 = CascadedPolygonUnion.Union(collection);

            if (!u1.Equals(u2))
            {
                Assert.Fail("failure");
            }
        }
コード例 #3
0
 private List <Polygon> MergePolygons(List <Polygon> polygons)
 {
     if (!polygons.Any())
     {
         return(polygons);
     }
     try
     {
         var merged = CascadedPolygonUnion.Union(polygons.ToArray());
         if (merged is MultiPolygon multipolygon)
         {
             return(multipolygon.Geometries.Cast <Polygon>().ToList());
         }
         return(new List <Polygon> {
             merged as Polygon
         });
     }
     catch
     {
         return(polygons);
     }
 }
コード例 #4
0
        /// <summary>
        ///  Converts a flat path to a <see cref="IGeometry"/>.
        /// </summary>
        ///  <param name="wpfGeometry">The geometry to convert</param>
        /// <returns>A Geometry representing the path</returns>
        public IGeometry Read(WpfGeometry wpfGeometry)
        {
            var pathGeometry = PathGeometry.CreateFromGeometry(wpfGeometry);

            /*
             * .Item1 ... Closed
             * .Item2 ... Filled
             * .Item3 ... List<Coordinate[]>
             */
            var pathPtSeq = ToCoordinates(pathGeometry);

            var geoms = new List <IGeometry>();

            var seqIndex = 0;

            while (seqIndex < pathPtSeq.Count)
            {
                // assume next seq is shell
                // TODO: test this
                var pts = pathPtSeq[seqIndex];
                if (pts.Item3.Length == 1)
                {
                    geoms.Add(_geometryFactory.CreatePoint(pts.Item3[0]));
                    seqIndex++;
                }
                else if (!(pts.Item1 || pts.Item2)) // neither closed nor filled
                {
                    geoms.Add(_geometryFactory.CreateLineString(pts.Item3));
                    seqIndex++;
                }
                else
                {
                    if (!pts.Item2)
                    {
                        geoms.Add(_geometryFactory.CreateLineString(pts.Item3));
                        continue;
                    }

                    var ringPts = ClosedCoordinateRing(pts.Item3);
                    var rings   = new List <IGeometry>(new[] { _geometryFactory.CreateLinearRing(ringPts) });
                    seqIndex++;

                    //if (seqIndex < pathPtSeq.Count)
                    //{
                    //    if (!(pathPtSeq[seqIndex].Item1 || pathPtSeq[seqIndex].Item2)) continue;

                    Coordinate[] holePts;
                    // add holes as long as rings are CCW
                    while (seqIndex < pathPtSeq.Count &&
                           (pathPtSeq[seqIndex].Item1 || pathPtSeq[seqIndex].Item2) &&
                           IsHole(holePts = pathPtSeq[seqIndex].Item3))
                    {
                        rings.Add(_geometryFactory.CreateLinearRing(holePts));
                        seqIndex++;
                    }

                    var noder         = new NetTopologySuite.Noding.Snapround.GeometryNoder(new NetTopologySuite.Geometries.PrecisionModel(100000000.0));
                    var nodedLinework = noder.Node(rings);

                    // Use the polygonizer
                    var p = new Polygonizer(pathGeometry.FillRule == FillRule.EvenOdd);
                    p.Add(nodedLinework.ToList <IGeometry>());
                    var tmpPolygons = p.GetPolygons();
                    if (pathGeometry.FillRule == FillRule.Nonzero)
                    {
                        var unionized =
                            CascadedPolygonUnion.Union(NetTopologySuite.Geometries.GeometryFactory.ToPolygonArray(tmpPolygons));
                        tmpPolygons = new List <IGeometry>(new[] { unionized });
                    }
                    geoms.AddRange(tmpPolygons);
                    //}
                }
            }

            return(BuildGeometry(geoms));
        }
コード例 #5
0
 public Geometry UnionCascaded(IList <Geometry> geoms)
 {
     return(CascadedPolygonUnion.Union(geoms));
 }
コード例 #6
0
ファイル: NtsUtils.cs プロジェクト: simsimzone/Tomato
        public static ObjectId UnionPolygonCascaded(ObjectId[] plineIds)
        {
            if (plineIds.Count() == 0)
            {
                return(ObjectId.Null);
            }

            var      deletePolyIds = new List <ObjectId>();
            var      database      = plineIds[0].Database;
            var      geometries    = new List <IGeometry>();
            ObjectId polygonId     = ObjectId.Null;

            using (var tr = database.TransactionManager.StartTransaction())
            {
                var reader = new DwgReader()
                {
                    PrecisionScale = 100000
                };
                foreach (var plineId in plineIds)
                {
                    var pline = tr.GetObject(plineId, OpenMode.ForRead) as Curve;
                    if (pline != null && pline.Closed)
                    {
                        var geomerty = reader.ReadCurveAsPolygon(tr, pline);
                        geomerty.Buffer(0);
                        geometries.Add(geomerty);
                        deletePolyIds.Add(plineId);
                    }
                }

                // 合并
                var resultPolygon = CascadedPolygonUnion.Union(geometries);
                var writer        = new DwgWriter()
                {
                    PrecisionScale = 100000
                };
                var polygon = resultPolygon as Polygon;
                if (polygon != null)
                {
                    var polyline = writer.WritePolyline(polygon.Shell);

                    var modelspaceId = SymbolUtilityServices.GetBlockModelSpaceId(database);
                    var modelspace   = (BlockTableRecord)tr.GetObject(modelspaceId, OpenMode.ForWrite);
                    polygonId = modelspace.AppendEntity(polyline);
                    tr.AddNewlyCreatedDBObject(polyline, true);

                    // 删除已经形成多边形的地块
                    foreach (var plineId in deletePolyIds)
                    {
                        var pline    = tr.GetObject(plineId, OpenMode.ForWrite) as Curve;
                        var geomerty = reader.ReadCurveAsPolygon(tr, pline);
                        if (pline != null && geomerty != null && polygon.Contains(geomerty))
                        {
                            pline.Erase(true);
                        }
                    }
                }
                tr.Commit();
            }

            return(polygonId);
        }