예제 #1
0
        /// <summary>
        /// Computes the signed area for a ring. The signed area is positive if the
        /// <list type="Table">
        /// <listheader>
        /// <term>value</term>
        /// <description>meaning</description>
        /// </listheader>
        /// <item><term>&gt; 0</term>
        /// <description>The ring is oriented clockwise (CW)</description></item>
        /// <item><term>&lt; 0</term>
        /// <description>The ring is oriented counter clockwise (CCW)</description></item>
        /// <item><term>== 0</term>
        /// <description>The ring is degenerate or flat</description></item>
        /// </list>
        /// ring is oriented CW, negative if the ring is oriented CCW, and zero if the
        /// ring is degenerate or flat.
        /// </summary>
        /// <param name="ring">The coordinates forming the ring</param>
        /// <returns>The signed area of the ring</returns>
        public static double OfRingSigned(CoordinateSequence ring)
        {
            int n = ring.Count;

            if (n < 3)
            {
                return(0.0);
            }

            /**
             * Based on the Shoelace formula.
             * http://en.wikipedia.org/wiki/Shoelace_formula
             */
            var    p1 = ring.GetCoordinateCopy(0);
            var    p2 = ring.GetCoordinateCopy(1);
            double x0 = p1.X;

            p2.X -= x0;
            double sum = 0.0;

            for (int i = 1; i < n - 1; i++)
            {
                double p0Y = p1.Y;
                p1.X = p2.X;
                p1.Y = p2.Y;
                ring.GetCoordinate(i + 1, p2);
                p2.X -= x0;
                sum  += p1.X * (p0Y - p2.Y);
            }
            return(sum / 2.0);
        }
예제 #2
0
        /// <summary>
        /// Computes the length of a <c>LineString</c> specified by a sequence of points.
        /// </summary>
        /// <param name="pts">The points specifying the <c>LineString</c></param>
        /// <returns>The length of the <c>LineString</c></returns>
        public static double OfLine(CoordinateSequence pts)
        {
            // optimized for processing CoordinateSequences
            int n = pts.Count;

            if (n <= 1)
            {
                return(0.0);
            }

            double len = 0.0;

            var    p  = pts.GetCoordinateCopy(0);
            double x0 = p.X;
            double y0 = p.Y;

            for (int i = 1; i < n; i++)
            {
                pts.GetCoordinate(i, p);
                double x1 = p.X;
                double y1 = p.Y;
                double dx = x1 - x0;
                double dy = y1 - y0;

                len += Math.Sqrt(dx * dx + dy * dy);

                x0 = x1;
                y0 = y1;
            }
            return(len);
        }
예제 #3
0
        /// <summary>
        /// Computes the locations of the nearest points between this sequence
        /// and another sequence.
        /// The locations are presented in the same order as the input sequences.
        /// </summary>
        /// <returns>A pair of <see cref="GeometryLocation"/>s for the nearest points.</returns>
        public GeometryLocation[] NearestLocations(FacetSequence facetSeq)
        {
            bool isPoint      = IsPoint;
            bool isPointOther = facetSeq.IsPoint;
            var  locs         = new GeometryLocation[2];

            if (isPoint && isPointOther)
            {
                // DEVIATION (minor): JTS uses "new Coordinate(GetCoordinate(int))", which is worse
                // than "GetCoordinateCopy(int)" for two reasons: 1) doesn't copy M (or, in NTS, Z),
                // and 2) might allocate two Coordinate instances instead of one.
                var pt    = _pts.GetCoordinateCopy(_start);
                var seqPt = facetSeq._pts.GetCoordinateCopy(facetSeq._start);
                locs[0] = new GeometryLocation(_geom, _start, pt);
                locs[1] = new GeometryLocation(facetSeq._geom, facetSeq._start, seqPt);
            }
            else if (isPoint)
            {
                var pt = _pts.GetCoordinateCopy(_start);
                ComputeDistancePointLine(pt, facetSeq, locs);
            }
            else if (isPointOther)
            {
                var seqPt = facetSeq._pts.GetCoordinateCopy(facetSeq._start);
                ComputeDistancePointLine(seqPt, this, locs);

                // unflip the locations
                (locs[0], locs[1]) = (locs[1], locs[0]);
            }
            else
            {
                ComputeDistanceLineLine(facetSeq, locs);
            }

            return(locs);
        }
        /// <summary>
        /// Creates a new sequence based on a deep copy of the given <see cref="CoordinateSequence"/>.
        /// </summary>
        /// <param name="coordSeq">The coordinate sequence that will be copied</param>
        public CoordinateArraySequence(CoordinateSequence coordSeq)
            : base(coordSeq?.Count ?? 0, coordSeq?.Dimension ?? 2, coordSeq?.Measures ?? 0)
        {
            if (coordSeq == null)
            {
                Coordinates = new Coordinate[0];
                return;
            }

            Coordinates = new Coordinate[coordSeq.Count];

            for (int i = 0; i < Coordinates.Length; i++)
            {
                Coordinates[i] = coordSeq.GetCoordinateCopy(i);
            }
        }