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