Example #1
0
        /// <summary>
        /// Add a <c>LineString</c> forming an edge of the polygon graph.
        /// </summary>
        /// <param name="line">The line to add.</param>
        public void AddEdge(ILineString line)
        {
            if (line.IsEmpty)
            {
                return;
            }

            ICoordinate[] linePts = CoordinateArrays.RemoveRepeatedPoints(line.Coordinates);
            ICoordinate   startPt = linePts[0];
            ICoordinate   endPt   = linePts[linePts.Length - 1];

            Node nStart = GetNode(startPt);
            Node nEnd   = GetNode(endPt);

            DirectedEdge de0  = new PolygonizeDirectedEdge(nStart, nEnd, linePts[1], true);
            DirectedEdge de1  = new PolygonizeDirectedEdge(nEnd, nStart, linePts[linePts.Length - 2], false);
            Edge         edge = new PolygonizeEdge(line);

            edge.SetDirectedEdges(de0, de1);
            Add(edge);
        }
        public void TestScroll()
        {
            // arrange
            var sequence = CreateCircularString(new Coordinate(20, 20), 7d,
                                                0.1, 22);
            var scrolled = CreateCircularString(new Coordinate(20, 20), 7d,
                                                0.1, 22);;

            // act
            CoordinateArrays.Scroll(scrolled, 12);

            // assert
            int io = 12;

            for (int isc = 0; isc < scrolled.Length - 1; isc++)
            {
                CheckCoordinateAt(sequence, io, scrolled, isc);
                io++;
                io %= scrolled.Length;
            }
        }
Example #3
0
        public void TestEqualsInHashBasedCollection()
        {
            var p0 = new Coordinate(0, 0);
            var p1 = new Coordinate(0, 1);
            var p2 = new Coordinate(1, 0);

            Coordinate[] exactEqualRing1 = { p0, p1, p2, p0 };
            var          exactEqualRing2 = CoordinateArrays.CopyDeep(exactEqualRing1);

            Coordinate[] rotatedRing1 = { p1, p2, p0, p1 };
            Coordinate[] rotatedRing2 = { p2, p0, p1, p2 };

            var exactEqualRing1Poly = geometryFactory.CreatePolygon(exactEqualRing1);
            var exactEqualRing2Poly = geometryFactory.CreatePolygon(exactEqualRing2);
            var rotatedRing1Poly    = geometryFactory.CreatePolygon(rotatedRing1);
            var rotatedRing2Poly    = geometryFactory.CreatePolygon(rotatedRing2);

            // IGeometry equality in hash-based collections should be based on
            // EqualsExact semantics, as it is in JTS.
            var hashSet1 = new HashSet <IGeometry>
            {
                exactEqualRing1Poly,
                exactEqualRing2Poly,
                rotatedRing1Poly,
                rotatedRing2Poly,
            };

            Assert.AreEqual(3, hashSet1.Count);

            // same as IPolygon equality.
            var hashSet2 = new HashSet <IPolygon>
            {
                exactEqualRing1Poly,
                exactEqualRing2Poly,
                rotatedRing1Poly,
                rotatedRing2Poly,
            };

            Assert.AreEqual(3, hashSet2.Count);
        }
Example #4
0
        /// <summary>
        /// The left and right topological location arguments assume that the ring is oriented CW.
        /// If the ring is in the opposite orientation,
        /// the left and right locations must be interchanged.
        /// </summary>
        /// <param name="lr"></param>
        /// <param name="cwLeft"></param>
        /// <param name="cwRight"></param>
        private void AddPolygonRing(ILinearRing lr, Locations cwLeft, Locations cwRight)
        {
            ICoordinate[] coord = CoordinateArrays.RemoveRepeatedPoints(lr.Coordinates);
            if (coord.Length < 4)
            {
                hasTooFewPoints = true;
                invalidPoint    = coord[0];
                return;
            }
            Locations left  = cwLeft;
            Locations right = cwRight;

            if (CGAlgorithms.IsCCW(coord))
            {
                left  = cwRight;
                right = cwLeft;
            }
            Edge e = new Edge(coord, new Label(argIndex, Locations.Boundary, left, right));

            lineEdgeMap[lr] = e;
            InsertEdge(e);
            // insert the endpoint as a node, to mark that it is on the boundary
            InsertPoint(argIndex, coord[0], Locations.Boundary);
        }
        public static Geometry FindNodes(Geometry geom)
        {
            var intPts = FastNodingValidator.ComputeIntersections(SegmentStringUtil.ExtractNodedSegmentStrings(geom));

            return(FunctionsUtil.GetFactoryOrDefault((Geometry)null).CreateMultiPointFromCoords(CoordinateArrays.ToCoordinateArray(intPts)));
        }
        private void ComputeCirclePoints()
        {
            Coordinate[] pts;
            // handle degenerate or trivial cases
            if (_input.IsEmpty)
            {
                _extremalPts = new Coordinate[0];
                return;
            }
            if (_input.NumPoints == 1)
            {
                pts          = _input.Coordinates;
                _extremalPts = new[] { new Coordinate(pts[0]) };
                return;
            }

            /**
             * The problem is simplified by reducing to the convex hull.
             * Computing the convex hull also has the useful effect of eliminating duplicate points
             */
            var convexHull = _input.ConvexHull();

            // check for degenerate or trivial cases
            var hullPts = convexHull.Coordinates;

            // strip duplicate final point, if any
            pts = hullPts;
            if (hullPts[0].Equals2D(hullPts[hullPts.Length - 1]))
            {
                pts = new Coordinate[hullPts.Length - 1];
                CoordinateArrays.CopyDeep(hullPts, 0, pts, 0, hullPts.Length - 1);
            }

            /**
             * Optimization for the trivial case where the CH has fewer than 3 points
             */
            if (pts.Length <= 2)
            {
                _extremalPts = CoordinateArrays.CopyDeep(pts);
                return;
            }

            // find a point P with minimum Y ordinate
            var P = LowestPoint(pts);

            // find a point Q such that the angle that PQ makes with the x-axis is minimal
            var Q = PointWitMinAngleWithX(pts, P);

            /**
             * Iterate over the remaining points to find
             * a pair or triplet of points which determine the minimal circle.
             * By the design of the algorithm,
             * at most <tt>pts.length</tt> iterations are required to terminate
             * with a correct result.
             */
            for (int i = 0; i < pts.Length; i++)
            {
                var R = PointWithMinAngleWithSegment(pts, P, Q);

                // if PRQ is obtuse, then MBC is determined by P and Q
                if (AngleUtility.IsObtuse(P, R, Q))
                {
                    _extremalPts = new Coordinate[] { new Coordinate(P), new Coordinate(Q) };
                    return;
                }
                // if RPQ is obtuse, update baseline and iterate
                if (AngleUtility.IsObtuse(R, P, Q))
                {
                    P = R;
                    continue;
                }
                // if RQP is obtuse, update baseline and iterate
                if (AngleUtility.IsObtuse(R, Q, P))
                {
                    Q = R;
                    continue;
                }
                // otherwise all angles are acute, and the MBC is determined by the triangle PQR
                _extremalPts = new Coordinate[] { new Coordinate(P), new Coordinate(Q), new Coordinate(R) };
                return;
            }
            Assert.ShouldNeverReachHere("Logic failure in Minimum Bounding Circle algorithm!");
        }
 public void ExtractTest2()
 {
     Coordinate[] result = CoordinateArrays.Extract(array, 1, 10);
     Assert.IsNull(result);
 }
 public void TestIntersection_coords_emptyEnvelope()
 {
     Assert.IsTrue(CoordinateArrays.Equals(
                       CoordinateArrays.Intersection(Coords1, new Envelope()), Empty)
                   );
 }
 /// <summary>
 /// Constructs a sequence based on the given array of <see cref="Coordinate"/>s.
 /// The coordinate dimension defaults to 2
 /// </summary>
 /// <remarks>
 /// The array is not copied.
 /// </remarks>
 /// <param name="coordinates">The coordinate array that will be referenced.</param>
 public CoordinateArraySequence(Coordinate[] coordinates)
     : this(coordinates, CoordinateArrays.Dimension(coordinates), CoordinateArrays.Measures(coordinates))
 {
 }
Example #10
0
        /*
         * (non-Javadoc)
         *
         * @see org.hibernatespatial.mgeom.IMGeometry#GetCoordinatesBetween(double,double)
         */
        public ICoordinateSequence[] GetCoordinatesBetween(double fromM, double toM)
        {
            if (!this.IsMonotone(false))
            {
                throw new ApplicationException("MGeometryException.OPERATION_REQUIRES_MONOTONE");
            }

            if (this.IsEmpty || !this.IsMonotone(false))
            {
                return(new MCoordinateSequence[0]);
            }
            else
            {
                double[] mval = this.GetMeasures();

                // determin upper and lower boundaries for the MLineString Measures
                double lb = Math.Min(mval[0], mval[mval.Length - 1]);
                double up = Math.Max(mval[0], mval[mval.Length - 1]);

                // set fromM and toM to maximal/minimal values when they exceed
                // lowerbound-upperbound
                fromM = Math.Max(lb, Math.Min(fromM, up));
                toM   = Math.Max(lb, Math.Min(toM, up));

                // if at this point the fromM and toM are equal, then return an
                // empty MCoordinateSequence
                if (DoubleComparator.Equals(fromM, toM))
                {
                    return(new MCoordinateSequence[0]);
                }
                MCoordinate[] mcoords = (MCoordinate[])this.Coordinates;
                // ensure that we traverse the coordinate array in ascending M-order
                if (GetMeasureDirection() == MGeometryType.Decreasing)
                {
                    CoordinateArrays.Reverse(mcoords);
                }

                double             minM    = Math.Min(fromM, toM);
                double             maxM    = Math.Max(fromM, toM);
                List <MCoordinate> mcolist = new List <MCoordinate>();
                for (int i = 0; i < mcoords.Length; i++)
                {
                    if (mcolist.Count == 0 && mcoords[i].M >= minM)
                    {
                        MCoordinate mco2 = mcoords[i];
                        if (DoubleComparator.Equals(mcoords[i].M, minM))
                        {
                            mcolist.Add(mco2);
                        }
                        else
                        {
                            MCoordinate mco1 = mcoords[i - 1];
                            double      r    = (minM - mco1.M) / (mco2.M - mco1.M);
                            Debug.Assert(DoubleComparator.Equals(mco1.M + r * (mco2.M - mco1.M), minM), "Error on assumption on r");
                            MCoordinate mc = new MCoordinate(
                                mco1.X + r * (mco2.X - mco1.X),
                                mco1.Y + r * (mco2.Y - mco1.Y),
                                mco1.Z + r * (mco2.Z - mco1.Z),
                                minM);
                            mcolist.Add(mc);
                        }
                    }
                    else if (mcoords[i].M >= minM && mcoords[i].M <= maxM)
                    {
                        mcolist.Add(mcoords[i]);
                        if (DoubleComparator.Equals(mcoords[i].M, maxM))
                        {
                            break;
                        }
                    }
                    else if (mcoords[i].M > maxM)
                    {
                        // mcoords[i] > Math.max(fromM, toM
                        Debug.Assert(i > 0, "mistaken assumption");
                        MCoordinate mco2 = mcoords[i];
                        MCoordinate mco1 = mcoords[i - 1];
                        double      r    = (maxM - mco1.M) / (mco2.M - mco1.M);
                        MCoordinate mc   = new MCoordinate(
                            mco1.X + r * (mco2.X - mco1.X),
                            mco1.Y + r * (mco2.Y - mco1.Y),
                            mco1.Z + r * (mco2.Z - mco1.Z),
                            maxM
                            );
                        mcolist.Add(mc);
                        break;
                    }
                }
                // copy over, but only to the length of numPnts
                MCoordinate[] h = new MCoordinate[mcolist.Count];
                for (int i = 0; i < mcolist.Count; i++)
                {
                    h[i] = (MCoordinate)mcolist[i];
                }

                if (!DoubleComparator.Equals(minM, fromM))
                {
                    CoordinateArrays.Reverse(h);
                }

                MCoordinateSequence mc2 = new MCoordinateSequence(h);
                return(new MCoordinateSequence[] { mc2 });
            }
        }
 public void TestEnvelopeEmpty()
 {
     Assert.AreEqual(CoordinateArrays.Envelope(Empty), new Envelope());
 }
 public void TestEnvelope1()
 {
     Assert.AreEqual(CoordinateArrays.Envelope(Coords1), new Envelope(1, 3, 1, 3));
 }
 /// <summary>
 /// Constructs a sequence based on the given array
 /// of <see cref="Coordinate"/>s.
 /// </summary>
 /// <remarks>The Array is not copied</remarks>
 /// <param name="coordinates">The coordinate array that will be referenced.</param>
 /// <param name="dimension">The dimension of the coordinates</param>
 public CoordinateArraySequence(Coordinate[] coordinates, int dimension)
     : this(coordinates, dimension, CoordinateArrays.Measures(coordinates))
 {
 }
 /// <summary>
 /// Sets the sites (point or vertices) which will be diagrammed
 /// from a collection of <see cref="Coordinate"/>s.
 /// </summary>
 /// <param name="coords">a collection of Coordinates.</param>
 public void SetSites(ICollection <Coordinate> coords)
 {
     // remove any duplicate points (they will cause the triangulation to fail)
     _siteCoords = DelaunayTriangulationBuilder.Unique(CoordinateArrays.ToCoordinateArray(coords));
 }
 public void TestIntersection_envelopeDisjoint()
 {
     Assert.IsTrue(CoordinateArrays.Equals(
                       CoordinateArrays.Intersection(Coords1, new Envelope(10, 20, 10, 20)), Empty)
                   );
 }
 /// <summary>
 /// Computes the canonical orientation for a coordinate array.
 /// </summary>
 /// <param name="pts"></param>
 /// <returns>
 /// <c>true</c> if the points are oriented forwards <br/>
 /// or <c>false</c>if the points are oriented in reverse.
 /// </returns>
 private static bool Orientation(Coordinate[] pts)
 {
     return(CoordinateArrays.IncreasingDirection(pts) == 1);
 }
 public void TestIntersection_empty_envelope()
 {
     Assert.IsTrue(CoordinateArrays.Equals(
                       CoordinateArrays.Intersection(Empty, new Envelope(1, 2, 1, 2)), Empty)
                   );
 }
Example #18
0
 /// <summary>
 /// Computes the canonical orientation for a coordinate array.
 /// </summary>
 /// <param name="pts"></param>
 /// <returns>
 /// <c>true</c> if the points are oriented forwards, or
 /// <c>false</c>if the points are oriented in reverse.
 /// </returns>
 private static bool Orientation(IList<Coordinate> pts)
 {
     return CoordinateArrays.IncreasingDirection(pts) == 1;
 }
        public static IGeometry FindNodePoints(IGeometry geom)
        {
            IList <Coordinate> intPts = FastNodingValidator.ComputeIntersections(SegmentStringUtil.ExtractNodedSegmentStrings(geom));

            return(FunctionsUtil.GetFactoryOrDefault(null).CreateMultiPoint(CoordinateArrays.ToCoordinateArray(intPts)));
        }