public IGeometry Union()
        {
            PointLocator locater = new PointLocator();
            // use a set to eliminate duplicates, as required for union
            var exteriorCoords = new HashSet <Coordinate>();

            foreach (IPoint point in PointExtracter.GetPoints(_pointGeom))
            {
                Coordinate coord = point.Coordinate;
                Location   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);
            ICoordinateSequence coords = _geomFact.CoordinateSequenceFactory.Create(exteriorCoordsArray);
            IGeometry           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));
        }
Example #2
0
        private void SaveClick(object sender, RoutedEventArgs e)
        {
            if (canvas.GetVisuals().Count == 0)
            {
                return;
            }

            var dialog = new SaveFileDialog();

            dialog.DefaultExt = "nts";
            dialog.Filter     = "NTS Geometry File|*.nts";
            if (dialog.ShowDialog() == true)
            {
                using (var stream = dialog.OpenFile())
                {
                    GeometryCombiner.SkipEmpty = true;
                    var visuals = canvas.GetVisuals();
                    paths.ForEach(p => visuals.Remove(p));

                    var geom   = GeometryCombiner.Combine(visuals.Select(d => d.ToNTSGeometry()));
                    var writer = new StreamWriter(stream);
                    writer.Write(geom.ToString());
                    writer.Flush();
                }
            }
        }
        public IGeometry Union()
        {
            ComputeInteracting();

            // check for all interacting or none interacting!

            IGeometry int0 = ExtractElements(_g0, _interacts0, true);
            IGeometry int1 = ExtractElements(_g1, _interacts1, true);

            //		System.out.println(int0);
            //		System.out.println(int1);

            if (int0.IsEmpty || int1.IsEmpty)
            {
                Console.WriteLine("found empty!");
                //			computeInteracting();
            }
            //		if (! int0.isValid()) {
            //System.out.println(int0);
            //throw new RuntimeException("invalid geom!");
            //		}

            IGeometry union = int0.Union(int1);
            //Geometry union = BufferUnion(int0, int1);

            IGeometry disjoint0 = ExtractElements(_g0, _interacts0, false);
            IGeometry disjoint1 = ExtractElements(_g1, _interacts1, false);

            IGeometry overallUnion = GeometryCombiner.Combine(union, disjoint0, disjoint1);

            return(overallUnion);
        }
Example #4
0
        /// <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);
        }
        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);
        }
        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));
        }
Example #8
0
        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);
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }
Example #12
0
        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));
        }
Example #13
0
        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);
            }
        }