private static Geometry Combine(Geometry unionGeom, List <Geometry> disjointPolys) { if (disjointPolys.Count <= 0) { return(unionGeom); } disjointPolys.Add(unionGeom); var result = GeometryCombiner.Combine(disjointPolys); return(result); }
/// <summary> /// Unions two polygonal geometries, restricting computation /// to the envelope intersection where possible. /// The case of MultiPolygons is optimized to union only /// the polygons which lie in the intersection of the two geometry's envelopes. /// Polygons outside this region can simply be combined with the union result, /// which is potentially much faster. /// This case is likely to occur often during cascaded union, and may also /// occur in real world data (such as unioning data for parcels on different street blocks). /// </summary> /// <param name="g0">A polygonal geometry</param> /// <param name="g1">A polygonal geometry</param> /// <param name="common">The intersection of the envelopes of the inputs</param> /// <returns>The union of the inputs</returns> private IGeometry UnionUsingEnvelopeIntersection(IGeometry g0, IGeometry g1, Envelope common) { var disjointPolys = new List <IGeometry>(); var g0Int = ExtractByEnvelope(common, g0, disjointPolys); var g1Int = ExtractByEnvelope(common, g1, disjointPolys); var union = UnionActual(g0Int, g1Int); disjointPolys.Add(union); var overallUnion = GeometryCombiner.Combine(disjointPolys); return(overallUnion); }
public void TestEnvelopeCombine(ICollection <Geometry> geoms) { var actual = EnvelopeCombiner.Combine(geoms); // JTS doesn't usually bother doing anything special about nulls, // so our ports of their stuff will suffer the same. geoms = geoms?.Where(g => g != null).ToArray() ?? Array.Empty <Geometry>(); var combinedGeometry = GeometryCombiner.Combine(geoms); // JTS also doesn't fear giving us nulls back from its algorithms. var expected = combinedGeometry?.EnvelopeInternal ?? new Envelope(); Assert.AreEqual(expected, actual); }
private IGeometry UnionOptimized(IGeometry g0, IGeometry g1) { var g0Env = g0.EnvelopeInternal; var g1Env = g1.EnvelopeInternal; if (!g0Env.Intersects(g1Env)) { var combo = GeometryCombiner.Combine(g0, g1); return(combo); } if (g0.NumGeometries <= 1 && g1.NumGeometries <= 1) { return(UnionActual(g0, g1)); } var commonEnv = g0Env.Intersection(g1Env); return(UnionUsingEnvelopeIntersection(g0, g1, commonEnv)); }
public IGeometry Union() { ComputeInteracting(); // check for all interacting or none interacting! var int0 = ExtractElements(_g0, _interacts0, true); var int1 = ExtractElements(_g1, _interacts1, true); if (int0.IsEmpty || int1.IsEmpty) { Debug.WriteLine("found empty!"); } var union = int0.Union(int1); var disjoint0 = ExtractElements(_g0, _interacts0, false); var disjoint1 = ExtractElements(_g1, _interacts1, false); var overallUnion = GeometryCombiner.Combine(union, disjoint0, disjoint1); return(overallUnion); }
public IGeometry Union() { ComputeInteracting(); // check for all interacting or none interacting! IGeometry int0 = ExtractElements(_g0, _interacts0, true); IGeometry int1 = ExtractElements(_g1, _interacts1, true); #if !PCL && !NETSTANDARD1_6 if (int0.IsEmpty || int1.IsEmpty) { Debug.WriteLine("found empty!"); } #endif IGeometry union = int0.Union(int1); IGeometry disjoint0 = ExtractElements(_g0, _interacts0, false); IGeometry disjoint1 = ExtractElements(_g1, _interacts1, false); IGeometry overallUnion = GeometryCombiner.Combine(union, disjoint0, disjoint1); return(overallUnion); }
public void TestStaticAggregation(ICollection <Geometry> geoms) { var actual = ConvexHull.Create(geoms); // JTS doesn't usually bother doing anything special about nulls, // so our ports of their stuff will suffer the same. geoms = geoms?.Where(g => g != null).ToArray() ?? Array.Empty <Geometry>(); var combinedGeometry = GeometryCombiner.Combine(geoms); // JTS also doesn't fear giving us nulls back from its algorithms. var expected = combinedGeometry?.ConvexHull(); if (expected?.IsEmpty == false) { Assert.That(expected.EqualsTopologically(actual)); } else { Assert.That(actual.IsEmpty); } }
/// <summary> /// Union a pair of geometries, /// using the more performant overlap union algorithm if possible. /// </summary> /// <returns>The union of the inputs</returns> public Geometry Union() { var overlapEnv = OverlapEnvelope(_g0, _g1); /** * If no overlap, can just combine the geometries */ if (overlapEnv.IsNull) { var g0Copy = _g0.Copy(); var g1Copy = _g1.Copy(); return(GeometryCombiner.Combine(g0Copy, g1Copy)); } var disjointPolys = new List <Geometry>(); var g0Overlap = ExtractByEnvelope(overlapEnv, _g0, disjointPolys); var g1Overlap = ExtractByEnvelope(overlapEnv, _g1, disjointPolys); //Console.WriteLine($"# geoms in common: {intersectingPolys.Count}"); var unionGeom = UnionFull(g0Overlap, g1Overlap); Geometry result; IsUnionOptimized = IsBorderSegmentsSame(unionGeom, overlapEnv); if (!IsUnionOptimized) { // overlap union changed border segments... need to do full union //System.out.println("OverlapUnion: Falling back to full union"); result = UnionFull(_g0, _g1); } else { //System.out.println("OverlapUnion: fast path"); result = Combine(unionGeom, disjointPolys); } return(result); }
public Geometry Union() { var locater = new PointLocator(); // use a set to eliminate duplicates, as required for union var exteriorCoords = new HashSet <Coordinate>(); foreach (Point point in PointExtracter.GetPoints(_pointGeom)) { var coord = point.Coordinate; var loc = locater.Locate(coord, _otherGeom); if (loc == Location.Exterior) { exteriorCoords.Add(coord); } } // if no points are in exterior, return the other geom if (exteriorCoords.Count == 0) { return(_otherGeom); } // make a puntal geometry of appropriate size var exteriorCoordsArray = new Coordinate[exteriorCoords.Count]; exteriorCoords.CopyTo(exteriorCoordsArray, 0); Array.Sort(exteriorCoordsArray); var coords = _geomFact.CoordinateSequenceFactory.Create(exteriorCoordsArray); var ptComp = coords.Count == 1 ? (Geometry)_geomFact.CreatePoint(coords) : _geomFact.CreateMultiPoint(coords); // add point component to the other geometry return(GeometryCombiner.Combine(ptComp, _otherGeom)); }
public IGeometry Union() { PointLocator locater = new PointLocator(); // use a set to eliminate duplicates, as required for union #if Goletas HashSet <ICoordinate> exteriorCoords = new HashSet <ICoordinate>(); #else TreeSet exteriorCoords = new TreeSet(); #endif foreach (IPoint point in PointExtracter.GetPoints(_pointGeom)) { ICoordinate coord = point.Coordinate; Locations loc = locater.Locate(coord, _otherGeom); if (loc == Locations.Exterior) { exteriorCoords.Add(coord); } } // if no points are in exterior, return the other geom if (exteriorCoords.Count == 0) { return(_otherGeom); } // make a puntal geometry of appropriate size IGeometry ptComp = null; ICoordinateSequence coords = _geomFact.CoordinateSequenceFactory.Create(exteriorCoords.ToArray()); ptComp = coords.Count == 1 ? (IGeometry)_geomFact.CreatePoint(coords.GetCoordinate(0)) : _geomFact.CreateMultiPoint(coords); // add point component to the other geometry return(GeometryCombiner.Combine(ptComp, _otherGeom)); }
private void ComputeShorestPath() { var components = canvas.GetDrawingComponents(); var points = components.OfType <DrawingPoint>().ToList(); if (points.Count < 2) { if (paths.Count > 0) { paths.ForEach(p => canvas.RemoveVisual(p)); paths.Clear(); } return; } if (points.Count % 2 != 0) { points.RemoveAt(points.Count - 1); } var pointsCount = points.Count; if (preVersion == -1 || (preVersion != canvas._version)) { var geom = GeometryCombiner.Combine(components.Where(c => !c.IsReadOnly && !(c is DrawingPoint)).Select(c => c.ToNTSGeometry())); finder = new ShortestAvoidancePathFinder(geom); finder.BufferDistance = finderSettings.BufferDistance; finder.InternalPointBehavior = (BreakThroughObstaclesBahavior)finderSettings.ObstacleBehavior; finder.BuildVisualGraph(); preVersion = canvas._version; } finder.InternalPointBehavior = (BreakThroughObstaclesBahavior)finderSettings.ObstacleBehavior; int pathIndex = 0; for (int i = 0; i < pointsCount; i += 2, pathIndex++) { var path = finderSettings.PathCategory == 0 ? finder.FindShortestPath(points[i].Point.ToCoordinate(), points[i + 1].Point.ToCoordinate()) : finder.FindAlongShortestPath(points[i].Point.ToCoordinate(), points[i + 1].Point.ToCoordinate()); if (path.Count == 0) { pathIndex--; continue; } var coos = path.Select(l => l.P0).ToList(); coos.Add(path.Last().P1); var targetPoints = coos.Select(c => c.ToPoint()); if (pathIndex < paths.Count) { paths[pathIndex].Update(targetPoints, false); paths[pathIndex].Render(DrawingCanvas.HighLightPen); } else { var drawingLineString = new DrawingLineString(targetPoints, false); drawingLineString.IsReadOnly = true; drawingLineString.Render(DrawingCanvas.HighLightPen); canvas.AddVisual(drawingLineString); paths.Add(drawingLineString); } } if (pathIndex < paths.Count) { for (int i = pathIndex; i < paths.Count; i++) { canvas.RemoveVisual(paths[i]); } paths.RemoveRange(pathIndex, paths.Count - pathIndex); } }