public void CascadedUnionError() { String[] wkt = { //MULTIPOLYGON (((-2.775 -37.382, -2.7694818956884695 -37.302294048833446, -4.381 -37.19, -4.379 -37.16, -2.7674053419183364 -37.272299383264858, -2.766 -37.252, -2.703 -37.257, -2.712 -37.386, -2.775 -37.382)), ((-0.558 -16.355, -0.556624473051351 -16.33528411373603, -2.168 -16.223, -2.165 -16.193, -0.55452706181921063 -16.305221219408683, -0.549 -16.226, -0.485 -16.23, -0.494 -16.36, -0.558 -16.355))) "MULTIPOLYGON (((-2.775 -37.382, -2.7694818956884695 -37.302294048833446, -4.381 -37.19, -4.379 -37.16, -2.7674053419183364 -37.272299383264858, -2.766 -37.252, -2.703 -37.257, -2.712 -37.386, -2.775 -37.382)), ((-0.558 -16.355, -0.556624473051351 -16.33528411373603, -2.168 -16.223, -2.165 -16.193, -0.55452706181921063 -16.305221219408683, -0.549 -16.226, -0.485 -16.23, -0.494 -16.36, -0.558 -16.355)))", //MULTIPOLYGON (((-4.218 -16.08, -4.216 -16.05, -2.924 -16.14, -2.926 -16.17, -4.218 -16.08)), ((-5.291 -18.097, -5.243 -17.415, -5.239 -17.352, -5.15929328747628 -17.357518157020873, -5.071 -16.091, -5.041 -16.093, -5.1292306097055169 -17.359599419328081, -5.109 -17.361, -5.114 -17.424, -5.161 -18.106, -5.291 -18.097))) "MULTIPOLYGON (((-4.218 -16.08, -4.216 -16.05, -2.924 -16.14, -2.926 -16.17, -4.218 -16.08)), ((-5.291 -18.097, -5.243 -17.415, -5.239 -17.352, -5.15929328747628 -17.357518157020873, -5.071 -16.091, -5.041 -16.093, -5.1292306097055169 -17.359599419328081, -5.109 -17.361, -5.114 -17.424, -5.161 -18.106, -5.291 -18.097)))" }; IList <IGeometry> items = new List <IGeometry>(); IGeometryFactory factory = GeometryFactory.Default; WKTReader reader = new WKTReader(factory); IGeometry geoms = reader.Read(wkt[0]); for (int i = 0; i < geoms.NumGeometries; i++) { IGeometry geom = geoms.GetGeometryN(i); items.Add(geom); } geoms = reader.Read(wkt[1]); for (int i = 0; i < geoms.NumGeometries; i++) { IGeometry geom = geoms.GetGeometryN(i); items.Add(geom); } UnaryUnionOp op = new UnaryUnionOp(items, new GeometryFactory(new PrecisionModel(100))); IGeometry result = op.Union(); Assert.IsNotNull(result); }
/** * This "pages" through standard geo boundaries offset by multiples of 360 * longitudinally that intersect geom, and the intersecting results of a page * and the geom are shifted into the standard -180 to +180 and added to a new * geometry that is returned. */ private static IGeometry CutUnwrappedGeomInto360(IGeometry geom) { Envelope geomEnv = geom.EnvelopeInternal; if (geomEnv.MinX >= -180 && geomEnv.MaxX <= 180) { return(geom); } Debug.Assert(geom.IsValid); //TODO support geom's that start at negative pages; will avoid need to previously shift in unwrapDateline(geom). var geomList = new List <IGeometry>(); //page 0 is the standard -180 to 180 range for (int page = 0; true; page++) { double minX = -180 + page * 360; if (geomEnv.MaxX <= minX) { break; } var rect = (Geometry)geom.Factory.ToGeometry(new Envelope(minX, minX + 360, -90, 90)); Debug.Assert(rect.IsValid); var pageGeom = (Geometry)rect.Intersection(geom); //JTS is doing some hard work Debug.Assert(pageGeom.IsValid); ShiftGeomByX(pageGeom, page * -360); geomList.Add(pageGeom); } return(UnaryUnionOp.Union(geomList)); }
public static bool IsCovered(this BoundingBox bbox, IEnumerable <BoundingBox> bboxTiles) { if (bboxTiles == null || !bboxTiles.Any()) { return(false); } IGeometry bboxPoly = bbox.ToPolygon(); IGeometry tilesPolygon = UnaryUnionOp.Union(bboxTiles.Select(t => t.ToPolygon()).ToList()); var inside = tilesPolygon.Contains(bboxPoly); if (inside) { return(inside); } else { tilesPolygon = UnaryUnionOp.Union(bboxTiles.Select(t => (IGeometry)(new LineString(t.ToRing().Coordinates))).ToList()); var dbgString = @"declare @b geometry = geometry::STGeomFromText('{bbox.WKT}',2154) select @b,'Bbox'"; var wkts = bboxTiles.Select(t => new Polygon(t.ToRing()).ToText()); dbgString = dbgString.Replace("{bbox.WKT}", bbox.WKT); dbgString += string.Join(" ", wkts.Select(s => $"union all select geometry::STGeomFromText('{s}',2154) , 'Tiles'")); System.Diagnostics.Debug.WriteLine(dbgString); return(inside); } }
/// <summary> /// /// </summary> /// <param name="fileName"></param> /// <returns></returns> private static IGeometry CheckShapefile(string fileName) { //int count = 0; var geoms = new List <IGeometry>(); using (var reader = new ShapefileDataReader(fileName, GeometryFactory.Floating)) { while (reader.Read()) { var current = reader.Geometry; if (!current.IsValid) { Debug.WriteLine("Imvalid geometry found: " + current); continue; } geoms.Add(current); //if (result == null) // result = current; //else result = result.Union(current); //Debug.WriteLine("Iteration => " + ++count); } } var result = UnaryUnionOp.Union(geoms); var write = new WKTWriter { Formatted = true, MaxCoordinatesPerLine = 3, Tab = 2 }; Debug.WriteLine("Operation result: " + write.Write(result)); return(result); }
public void CascadedUnionError() { String[] wkt = { //MULTIPOLYGON (((-2.775 -37.382, -2.7694818956884695 -37.302294048833446, -4.381 -37.19, -4.379 -37.16, -2.7674053419183364 -37.272299383264858, -2.766 -37.252, -2.703 -37.257, -2.712 -37.386, -2.775 -37.382)), ((-0.558 -16.355, -0.556624473051351 -16.33528411373603, -2.168 -16.223, -2.165 -16.193, -0.55452706181921063 -16.305221219408683, -0.549 -16.226, -0.485 -16.23, -0.494 -16.36, -0.558 -16.355))) "MULTIPOLYGON (((-2.775 -37.382, -2.7694818956884695 -37.302294048833446, -4.381 -37.19, -4.379 -37.16, -2.7674053419183364 -37.272299383264858, -2.766 -37.252, -2.703 -37.257, -2.712 -37.386, -2.775 -37.382)), ((-0.558 -16.355, -0.556624473051351 -16.33528411373603, -2.168 -16.223, -2.165 -16.193, -0.55452706181921063 -16.305221219408683, -0.549 -16.226, -0.485 -16.23, -0.494 -16.36, -0.558 -16.355)))", //MULTIPOLYGON (((-4.218 -16.08, -4.216 -16.05, -2.924 -16.14, -2.926 -16.17, -4.218 -16.08)), ((-5.291 -18.097, -5.243 -17.415, -5.239 -17.352, -5.15929328747628 -17.357518157020873, -5.071 -16.091, -5.041 -16.093, -5.1292306097055169 -17.359599419328081, -5.109 -17.361, -5.114 -17.424, -5.161 -18.106, -5.291 -18.097))) "MULTIPOLYGON (((-4.218 -16.08, -4.216 -16.05, -2.924 -16.14, -2.926 -16.17, -4.218 -16.08)), ((-5.291 -18.097, -5.243 -17.415, -5.239 -17.352, -5.15929328747628 -17.357518157020873, -5.071 -16.091, -5.041 -16.093, -5.1292306097055169 -17.359599419328081, -5.109 -17.361, -5.114 -17.424, -5.161 -18.106, -5.291 -18.097)))" }; IList<IGeometry> items = new List<IGeometry>(); IGeometryFactory factory = GeometryFactory.Default; WKTReader reader = new WKTReader(factory); IGeometry geoms = reader.Read(wkt[0]); for (int i = 0; i < geoms.NumGeometries; i++) { IGeometry geom = geoms.GetGeometryN(i); items.Add(geom); } geoms = reader.Read(wkt[1]); for (int i = 0; i < geoms.NumGeometries; i++) { IGeometry geom = geoms.GetGeometryN(i); items.Add(geom); } UnaryUnionOp op = new UnaryUnionOp(items, new GeometryFactory(new PrecisionModel(100))); IGeometry result = op.Union(); Assert.IsNotNull(result); }
private void DoTest(string inputWKT, string expectedWKT) { var geom = Read(inputWKT); var result = UnaryUnionOp.Union(geom); CheckEqual(Read(expectedWKT), result); }
public static Dictionary <ObjectId, IList <Point3d> > FindDanglingLine(IList <ObjectId> objectIds) { var dictionary = new Dictionary <ObjectId, IList <Point3d> >(); //var points = new List<Point3d>(); var database = objectIds[0].Database; using (var tr = database.TransactionManager.StartTransaction()) { var reader = new DwgReader(); // var pmFixed3 = new PrecisionModel(3); // 读入多边形数据 foreach (ObjectId objectId in objectIds) { if (!objectId.IsValid) { continue; } IGeometry geom = reader.ReadEntityAsGeometry(tr, objectId); if (geom == null) { continue; } // 开始做Union var nodedLineString = UnaryUnionOp.Union(geom); var polygonizer = new Polygonizer(); polygonizer.Add(nodedLineString); var polygons = polygonizer.GetPolygons(); // 悬挂线 var points = new List <Point3d>(); foreach (ILineString lineString in polygons) { foreach (var coordinate in lineString.Coordinates) { // 如果是NaN直接设定为0 if (double.IsNaN(coordinate.Z)) { coordinate.Z = 0; } points.Add(new Point3d(coordinate.X, coordinate.Y, coordinate.Z)); } } if (points.Any()) { dictionary.Add(objectId, points); } } tr.Commit(); } return(dictionary); }
private static IEnumerable <IGeometry> DoMerge(IGeometryCollection coll) { if (coll == null) { throw new ArgumentNullException("coll"); } IEnumerable <IGeometry> items = GetItems(coll); yield return(UnaryUnionOp.Union(items.ToArray())); }
public static bool IsCovered(this BoundingBox bbox, IEnumerable <BoundingBox> bboxTiles) { if (bboxTiles == null || !bboxTiles.Any()) { return(false); } IGeometry bboxPoly = bbox.ToPolygon(); IGeometry tilesPolygon = UnaryUnionOp.Union(bboxTiles.Select(GeometryService.ToPolygon).ToList()); var inside = tilesPolygon.Contains(bboxPoly); return(inside); }
// Union adjacent polygons to make an invalid MultiPolygon valid private System.Collections.Generic.ICollection <NetTopologySuite.Geometries.Geometry> unionAdjacentPolygons(ICollection <NetTopologySuite.Geometries.Geometry> list) { UnaryUnionOp op = new UnaryUnionOp(list); var result = op.Union(); if (result.NumGeometries < list.Count) { list.Clear(); for (int i = 0; i < result.NumGeometries; i++) { list.Add(result.GetGeometryN(i)); } } return(list); }
private void DoTest(string[] inputWKT, string expectedWKT) { IGeometry result; var geoms = GeometryUtils.ReadWKT(inputWKT); if (geoms.Count == 0) { result = UnaryUnionOp.Union(geoms, geomFact); } else { result = UnaryUnionOp.Union(geoms); } Assert.IsTrue(GeometryUtils.IsEqual(GeometryUtils.ReadWKT(expectedWKT), result)); }
/// <summary> /// Computes unary union using robust computation. /// </summary> /// <param name="geom">The geometry to union</param> /// <returns>The union result</returns> public static Geometry Union(Geometry geom) { if (geom == null) { throw new ArgumentNullException(nameof(geom)); } var unionSRFun = new UnionStrategy((g0, g1) => Overlay(g0, g1, SpatialFunction.Union), true); var op = new UnaryUnionOp(geom) { UnionStrategy = unionSRFun }; return(op.Union()); }
private void DoTest(string[] inputWKT, string expectedWKT) { Geometry result; var geoms = ReadList(inputWKT); if (geoms.Count == 0) { result = UnaryUnionOp.Union(geoms, geomFact); } else { result = UnaryUnionOp.Union(geoms); } CheckEqual(Read(expectedWKT), result); }
/// <summary> /// Unions a collection of geometries /// using a given precision model. /// <para/> /// This class is most useful for performing UnaryUnion using /// a fixed-precision model. /// For unary union using floating precision, /// <see cref="OverlayNGRobust.Union(Geometry)"/> should be used. /// </summary> /// <param name="geom">The geometry to union</param> /// <param name="pm">The precision model to use</param> /// <returns>The union of the geometries</returns> /// <seealso cref="OverlayNGRobust"/> public static Geometry Union(Geometry geom, PrecisionModel pm) { if (geom == null) { throw new ArgumentNullException(nameof(geom)); } var unionSRFun = new UnionStrategy((g0, g1) => OverlayNG.Overlay(g0, g1, SpatialFunction.Union, pm), OverlayUtility.IsFloating(pm)); var op = new UnaryUnionOp(geom) { UnionStrategy = unionSRFun }; return(op.Union()); }
private void SearchByGreeneryArea() { var area1 = _preferences.PowierzchniaZieleni1; var area2 = _preferences.PowierzchniaZieleni2; if (area1.HasValue || area2.HasValue) { var greeneryCollection = _zielenController.GetSpecifiedArea(area1.Value, area2.Value); Geometry specifiedGreenery = UnaryUnionOp.Union(greeneryCollection.Result); var drillingsCollection = _searchedSet.ToListAsync(); var drillingIds = new List <short?>(); foreach (var drilling in drillingsCollection.Result) { if (Within(drilling, specifiedGreenery)) { drillingIds.Add(drilling.Id); } } _searchedSet = _searchedSet.Where(item => drillingIds.Contains(item.Id)); } }
private List <Polygon> MergePolygons(List <Polygon> polygons) { if (!polygons.Any()) { return(polygons); } try { var merged = UnaryUnionOp.Union(polygons.Cast <Geometry>().ToList()); if (merged is MultiPolygon multipolygon) { return(multipolygon.Geometries.Cast <Polygon>().ToList()); } return(new List <Polygon> { merged as Polygon }); } catch { return(polygons); } }
/** * Node a LinearRing and return a MultiPolygon containing * <ul> * <li>a single Polygon if the LinearRing is simple</li> * <li>several Polygons if the LinearRing auto-intersects</li> * </ul> * This is used to repair auto-intersecting Polygons */ private NetTopologySuite.Geometries.Geometry getArealGeometryFromLinearRing(LinearRing ring) { if (ring.IsSimple) { return(ring.Factory.CreateMultiPolygon(new Polygon[] { ring.Factory.CreatePolygon(ring, EMPTY_RING_ARRAY) })); } else { // Node input LinearRing and extract unique segments ISet <LineString> lines = nodeLineString(ring.Coordinates, ring.Factory); lines = getSegments(lines); // Polygonize the line network Polygonizer polygonizer = new Polygonizer(); polygonizer.Add((ICollection <NetTopologySuite.Geometries.Geometry>)lines); // Computes intersections to determine the status of each polygon ICollection <NetTopologySuite.Geometries.Geometry> geoms = new List <NetTopologySuite.Geometries.Geometry>(); foreach (NetTopologySuite.Geometries.Geometry g in polygonizer.GetPolygons()) { Polygon polygon = (Polygon)g; Coordinate p = polygon.InteriorPoint.Coordinate; var location = RayCrossingCounter.LocatePointInRing(p, ring.CoordinateSequence); if (location == NetTopologySuite.Geometries.Location.Interior) { geoms.Add(polygon); } } NetTopologySuite.Geometries.Geometry unionPoly = UnaryUnionOp.Union(geoms); NetTopologySuite.Geometries.Geometry unionLines = UnaryUnionOp.Union(lines).Difference(unionPoly.Boundary); geoms.Clear(); decompose(unionPoly, geoms); decompose(unionLines, geoms); return(ring.Factory.BuildGeometry(geoms)); } }
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 override Geometry Union(Geometry a) { return(UnaryUnionOp.Union(a)); }
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); }