示例#1
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));
        }
示例#2
0
        public static List <ObjectId> PolygonizeLineStrings(Database database, IEnumerable <ObjectId> polylineIdCollection,
                                                            String outLayerName = "0",
                                                            AcadColor color     = null, double precision = 0.00001)
        {
            var result = new List <ObjectId>();

            using (var tr = database.TransactionManager.StartTransaction())
            {
                // 读入多边形数据
                var lineStringList = new List <IGeometry>();
                foreach (ObjectId polylineId in polylineIdCollection)
                {
                    var curve = tr.GetObject(polylineId, OpenMode.ForRead) as Curve;

                    var reader     = new DwgReader();
                    var lineString = reader.ReadGeometry(curve, tr) as LineString;

                    if (lineString != null && lineString.IsEmpty == false)
                    {
                        lineStringList.Add(lineString);
                    }
                }

#if TryManualUnion
                // 创建节点
                var nodedContours = new List <List <IGeometry> >();
                var scale         = 1.0 / precision;
                var geomNoder     = new NetTopologySuite.Noding.Snapround.GeometryNoder(new PrecisionModel(scale));

                var nodedList = geomNoder.Node(lineStringList);
                // 这里可能可以用nodedList.Count来计算一个gourp的size来限定线程数量
                var maxCountInGroup = 200;

                foreach (var c in nodedList)
                {
                    //Coordinate[] linePts = CoordinateArrays.RemoveRepeatedPoints(c.Coordinates);
                    //if (linePts.Count() > 1)
                    //    nodedContours.Add(c.Factory.CreateLineString(linePts));
                    //c.Buffer(0.001);
                    // 将所有的线段每maxCountInGroup个分成一组.
                    var groupCount = nodedContours.Count;
                    if (groupCount == 0)
                    {
                        nodedContours.Add(new List <IGeometry>());
                    }
                    var itemCount = nodedContours[nodedContours.Count - 1].Count;
                    if (itemCount < maxCountInGroup)
                    {
                        nodedContours[nodedContours.Count - 1].Add(c);
                    }
                    else
                    {
                        nodedContours.Add(new List <IGeometry>());
                        nodedContours[nodedContours.Count - 1].Add(c);
                    }
                }

                var workers    = new List <Worker>();
                var threadList = new List <Thread>();
                // 为每组geometry开一个线程做union.
                foreach (List <IGeometry> nodedContour in nodedContours)
                {
                    // Start a thread.
                    var worker = new Worker(nodedContour);
                    workers.Add(worker);
                    var thread = new Thread(worker.Execute);
                    threadList.Add(thread);
                    thread.Start();
                }

                // 等待所有线程运行结束
                foreach (Thread thread in threadList)
                {
                    thread.Join();
                }

                // 最后将每组union得到的IGeometry再做一次union
                var nodedLineString = workers[0].Geometry;
                for (int i = 1; i < workers.Count; i++)
                {
                    nodedLineString = nodedLineString.Union(workers[i].Geometry);
                }
#else
                // 开始做Union
                var nodedLineString = UnaryUnionOp.Union(lineStringList, new GeometryFactory(new PrecisionModel(0.9d)));

                //var nodedLineString = lineStringList[0];
                //for (int i = 1; i < lineStringList.Count; i++)
                //{
                //    nodedLineString = nodedLineString.Union(lineStringList[i]);
                //}
#endif

                //造区
                Polygonizer polygonizer = new Polygonizer();
                polygonizer.Add(nodedLineString);

                var polys            = polygonizer.GetPolygons();
                var dangles          = polygonizer.GetDangles();
                var cuts             = polygonizer.GetCutEdges();
                var writer           = new DwgWriter();
                var modelSpaceId     = SymbolUtilityServices.GetBlockModelSpaceId(database);
                var blockTableRecord = (BlockTableRecord)tr.GetObject(modelSpaceId, OpenMode.ForWrite, false);
                // 多边形
                foreach (IGeometry geometry in polys)
                {
                    var polygon = geometry as Polygon;
                    if (polygon != null)
                    {
                        var polylines = writer.WritePolyline(polygon);
                        foreach (Polyline polyline in polylines)
                        {
                            if (color != null)
                            {
                                polyline.Color = color;
                            }
                            polyline.Layer = outLayerName;
                            // 输出到CAD
                            var polylineId = blockTableRecord.AppendEntity(polyline);
                            result.Add(polylineId);
                            tr.AddNewlyCreatedDBObject(polyline, true);
                        }
                    }
                }

                //// 悬挂线
                //foreach (ILineString lineString in dangles)
                //{
                //    if (lineString != null)
                //    {
                //        var polyline = writer.WritePolyline(lineString);
                //        if (color != null)
                //            polyline.Color = color;
                //        polyline.Layer = outLayerName;
                //        // 输出到CAD
                //        blockTableRecord.AppendEntity(polyline);
                //        tr.AddNewlyCreatedDBObject(polyline, true);
                //    }
                //}

                //// 裁剪线
                //foreach (ILineString lineString in cuts)
                //{
                //    if (lineString != null)
                //    {
                //        var polyline = writer.WritePolyline(lineString);
                //        if (color != null)
                //            polyline.Color = color;
                //        polyline.Layer = outLayerName;
                //        // 输出到CAD
                //        blockTableRecord.AppendEntity(polyline);
                //        tr.AddNewlyCreatedDBObject(polyline, true);
                //    }
                //}

                tr.Commit();
            }
            return(result);
        }