private static TopologyData BuildTopology(ObjectId[] objectIds) { var topoData = new TopologyData(); var database = objectIds[0].Database; using (var tr = database.TransactionManager.StartTransaction()) { var reader = new DwgReader(); foreach (ObjectId objectId in objectIds) { // 如果没有 var curve = tr.GetObject(objectId, OpenMode.ForRead) as Curve; if (curve == null || !curve.Visible) { continue; } // 图层关闭,继续,因为有可能是图幅层 var layer = (LayerTableRecord)tr.GetObject(curve.LayerId, OpenMode.ForRead); if (layer.IsOff) { continue; } // 目前只处理封闭的和大于3的多边形 // http://192.168.0.6:8080/browse/LCLIBCAD-903 // 否则会弹出points must form a closed linestring异常 if (curve.Closed && reader.NumberOfVerticesMoreThan3(curve)) { var geom = reader.ReadCurveAsPolygon(tr, curve) as IGeometry; geom = geom.Buffer(0); if (!geom.IsValid) { topoData.InvalidObjects.Add(objectId); System.Diagnostics.Trace.WriteLine(geom.ToString()); } // 没有包围盒,无法进入空间索引 else if (geom.EnvelopeInternal.IsNull) { topoData.WrongEnvelopeObjects.Add(objectId); } else { //geom = SimpleGeometryPrecisionReducer.Reduce(geom, pmFixed3); geom.UserData = objectId; topoData.Quadtree.Insert(geom.EnvelopeInternal, geom); topoData.Geometries.Add(geom); topoData.GeometryDictionary[objectId] = geom; } } } tr.Commit(); } return(topoData); }
public bool ContainsHole(ObjectId holeId) { using (var tr = ObjectId.Database.TransactionManager.StartTransaction()) { var curve = tr.GetObject(ObjectId, OpenMode.ForRead) as Curve; var hole = tr.GetObject(holeId, OpenMode.ForRead) as Curve; if (curve != null && curve.Closed && hole != null && hole.Closed) { var reader = new DwgReader(); var polygon1 = reader.ReadCurveAsPolygon(tr, curve); var polygon2 = reader.ReadCurveAsPolygon(tr, hole); if (polygon1.Contains(polygon2)) { return(true); } } } return(false); }
public IPolygon GetPolygon(Transaction tr) { var curve = tr.GetObject(ObjectId, OpenMode.ForRead) as Curve; if (curve != null && curve.Closed) { var holeIds = FindHolesInEntity(tr, curve); var reader = new DwgReader(); var polygon = reader.ReadCurveAsPolygon(tr, curve); var linearRings = new List <ILinearRing>(); foreach (var holeId in holeIds) { // 处理洞 var insideCurve = tr.GetObject(holeId, OpenMode.ForRead) as Curve; if (insideCurve != null && curve.Closed) { var insidePolygon = reader.ReadCurveAsPolygon(tr, insideCurve); if (polygon.Contains(insidePolygon)) { ILinearRing linearRing = reader.GeometryFactory.CreateLinearRing(insidePolygon.ExteriorRing.CoordinateSequence); if (!linearRing.IsCCW) { linearRing.Reverse(); } linearRings.Add(linearRing); } } } if (!linearRings.Any()) { return(polygon); } // 返回新建的多边形 IPolygon newPolygon = reader.GeometryFactory.CreatePolygon(polygon.Shell, linearRings.ToArray()); return(newPolygon); } return(null); }
public static Dictionary <Curve, IList <Curve> > GetNearGeometries(IEnumerable <Curve> curves, double buffer, bool forceClosed = true) { var dictionary = new Dictionary <Curve, IList <Curve> >(); var quadtree = new Quadtree <IGeometry>(); var reader = new DwgReader(); var geometries = new List <IGeometry>(); foreach (var curve in curves) { // 目前只处理封闭的和大于3的多边形 // http://192.168.0.6:8080/browse/LCLIBCAD-903 // 否则会弹出“points must form a closed linestring”异常 if (forceClosed && !curve.Closed || !reader.NumberOfVerticesMoreThan3(curve)) { continue; } var geom = reader.ReadCurveAsPolygon(null, curve) as Polygon; if (geom == null) { continue; } geom.UserData = curve; quadtree.Insert(geom.EnvelopeInternal, geom); geometries.Add(geom); } foreach (var geom in geometries) { var nearGeoms = GetNearGeometries(geom, quadtree, buffer); var curve = (Curve)geom.UserData; var nearCurves = new List <Curve>(); foreach (var geometry in nearGeoms) { var nearCurve = (Curve)geometry.UserData; if (nearCurve != curve) { nearCurves.Add(nearCurve); } } dictionary[curve] = nearCurves; } return(dictionary); }
static void AddHolesToParcel(ObjectId parcelId, ObjectId groupId, ObjectId[] holeIds) { Database database = parcelId.Database; // 将扣除的孔洞等图形放到孔洞图层,以绿色醒目显示 var layerId = LayerUtils.GetLayerByName(database, "孔洞"); if (!layerId.IsValid) { layerId = LayerUtils.AddNewLayer(database, "孔洞", "Continuous", /*GREEN*/ 3); } // 看看选择的地块是不是真的在地块里面了 var availableHoles = new List <ObjectId>(); using (var tr = database.TransactionManager.StartTransaction()) { var reader = new DwgReader(); var curve = tr.GetObject(parcelId, OpenMode.ForRead) as Curve; if (curve != null && curve.Closed) { var polygon1 = reader.ReadCurveAsPolygon(tr, curve); foreach (var holeId in holeIds) { var hole = tr.GetObject(holeId, OpenMode.ForRead) as Curve; // 只添加地块为封闭的 if (hole == null || !hole.Closed) { continue; } // 继续,看看是不是在地块中间,不在就跳过 var polygon2 = reader.ReadCurveAsPolygon(tr, hole); if (!polygon1.Contains(polygon2)) { continue; } // 如果是,添加地块 hole.UpgradeOpen(); CadUtils.SetCassFlag(hole, CassFlagIsland); hole.LayerId = layerId; availableHoles.Add(holeId); // 如果组不是空,直接加入组 if (!groupId.IsNull) { GroupUtils.AppendEntityIntoGroup(database, groupId, holeId); } } } tr.Commit(); } // 如果没有group,创建group if (groupId.IsNull) { var ids = new ObjectIdCollection() { parcelId }; foreach (var availableHole in availableHoles) { ids.Add(availableHole); } GroupUtils.CreateNewGroup(database, "*A", ids); } }
public static List <ObjectId> SplitPolygon(ObjectId plineId, ObjectId lineId) { var polyIds = new List <ObjectId>(); if (plineId.IsNull && lineId.IsNull) { return(polyIds); } var database = plineId.Database; using (var tr = database.TransactionManager.StartTransaction()) { var reader = new DwgReader() { PrecisionScale = 100000 }; var pline = tr.GetObject(plineId, OpenMode.ForRead) as Curve; if (pline == null || !pline.Closed) { return(polyIds); } var lineObj = tr.GetObject(lineId, OpenMode.ForRead) as Curve; if (lineObj == null) { return(polyIds); } var splitGeometry = reader.ReadCurveAsPolygon(tr, pline); splitGeometry.Buffer(0); var lineGeometry = reader.ReadGeometry(lineObj, tr); lineGeometry.Buffer(0); // 合并 var resultPolygons = SplitPolygon(splitGeometry, lineGeometry); var writer = new DwgWriter() { PrecisionScale = 100000 }; var multiPolygon = resultPolygons as MultiPolygon; if (multiPolygon != null) { var polylines = writer.WritePolyline(multiPolygon); // 加入数据库 foreach (var polyline in polylines) { var modelspaceId = SymbolUtilityServices.GetBlockModelSpaceId(database); var modelspace = (BlockTableRecord)tr.GetObject(modelspaceId, OpenMode.ForWrite); var polyId = modelspace.AppendEntity(polyline); tr.AddNewlyCreatedDBObject(polyline, true); polyIds.Add(polyId); } } tr.Commit(); } return(polyIds); }
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); }
public static void FindDanglingLine(Database database) { var polylineIds = CadUtils.FindAllPolylines(Application.DocumentManager.MdiActiveDocument); using (var tr = database.TransactionManager.StartTransaction()) { var pmFixed3 = new PrecisionModel(3); // 读入多边形数据 var lineStringList = new List <IGeometry>(); foreach (ObjectId polylineId in polylineIds) { var curve = tr.GetObject(polylineId, OpenMode.ForRead) as Curve; var reader = new DwgReader(); IGeometry lineString; try { lineString = reader.ReadCurveAsPolygon(tr, curve) as Polygon; } catch (Exception) { lineString = reader.ReadCurveAsLineString(tr, curve) as LineString; } if (lineString != null && lineString.IsEmpty == false) { lineString = SimpleGeometryPrecisionReducer.Reduce(lineString, pmFixed3); lineStringList.Add(lineString); } } // 开始做Union var nodedLineString = UnaryUnionOp.Union(lineStringList); var 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 (ILineString lineString in dangles) { //if (lineString != null) //{ // var polyline = writer.WritePolyline(lineString); // polyline.ColorIndex = 3; // //polyline.Layer = ""; // // 输出到CAD // blockTableRecord.AppendEntity(polyline); // tr.AddNewlyCreatedDBObject(polyline, true); //} } tr.Commit(); } }
public static Dictionary <ObjectId, IList <ObjectId> > GetNearGeometries(IList <ObjectId> objectIds, double buffer, bool forceClosed = true) { var dictionary = new Dictionary <ObjectId, IList <ObjectId> >(); var database = objectIds[0].Database; var quadtree = new Quadtree <IGeometry>(); var geometries = new List <IGeometry>(); using (var tr = database.TransactionManager.StartTransaction()) { var reader = new DwgReader(); foreach (ObjectId objectId in objectIds) { if (!objectId.IsValid) { continue; } Debug.WriteLine("{0}", objectId.Handle); var curve = tr.GetObject(objectId, OpenMode.ForRead) as Curve; if (curve == null) { continue; } // 目前只处理封闭的和大于3的多边形 // http://192.168.0.6:8080/browse/LCLIBCAD-903 // 否则会弹出“points must form a closed linestring”异常 if (forceClosed && !curve.Closed || !reader.NumberOfVerticesMoreThan3(curve)) { continue; } var geom = reader.ReadCurveAsPolygon(tr, curve) as Polygon; if (geom == null) { continue; } geom.UserData = objectId; quadtree.Insert(geom.EnvelopeInternal, geom); geometries.Add(geom); } foreach (var geom in geometries) { var nearGeoms = GetNearGeometries(geom, quadtree, buffer); var objectId = (ObjectId)geom.UserData; var ids = new List <ObjectId>(); foreach (var geometry in nearGeoms) { var nearId = (ObjectId)geometry.UserData; if (nearId != objectId) { ids.Add(nearId); } } dictionary[objectId] = ids; } tr.Commit(); } return(dictionary); }