示例#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(ICoordinateSequence ring)
        {
            var n = ring.Count;

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

            /**
             * Based on the Shoelace formula.
             * http://en.wikipedia.org/wiki/Shoelace_formula
             */
            var p0 = new Coordinate();
            var p1 = new Coordinate();
            var p2 = new Coordinate();

            ring.GetCoordinate(0, p1);
            ring.GetCoordinate(1, p2);
            var x0 = p1.X;

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

            for (var i = 1; i < n - 1; i++)
            {
                p0.Y = p1.Y;
                p1.X = p2.X;
                p1.Y = p2.Y;
                ring.GetCoordinate(i + 1, p2);
                p2.X -= x0;
                sum  += p1.X * (p0.Y - 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(ICoordinateSequence pts)
        {
            // optimized for processing CoordinateSequences
            int n = pts.Count;

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

            double len = 0.0;

            var p = new Coordinate();

            pts.GetCoordinate(0, p);
            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);
        }
 public void Filter(ICoordinateSequence seq, int i)
 {
     if (i == 0) return;
     seq.GetCoordinate(i - 1, p0);
     seq.GetCoordinate(i, p1);
     rcc.CountSegment(p0, p1);
 }
            public void Filter(ICoordinateSequence seq, int index)
            {
                /**
                 * This logic also handles skipping Point geometries
                 */
                if (index == 0)
                {
                    return;
                }

                var p0 = seq.GetCoordinate(index - 1);
                var p1 = seq.GetCoordinate(index);

                var delx = (p1.X - p0.X) / _numSubSegs;
                var dely = (p1.Y - p0.Y) / _numSubSegs;

                for (var i = 0; i < _numSubSegs; i++)
                {
                    var x  = p0.X + i * delx;
                    var y  = p0.Y + i * dely;
                    var pt = new Coordinate(x, y);
                    _minPtDist.Initialize();
                    DistanceToPoint.ComputeDistance(_geom, pt, _minPtDist);
                    _maxPtDist.SetMaximum(_minPtDist);
                }
            }
        private static void WriteCompressedXY(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw)
        {
            var wd = export.WriteDouble;

            // Write initial coordinate
            var cprev = coordinateSequence.GetCoordinate(0);

            wd(bw, cprev.X, cprev.Y);

            var ws       = export.WriteSingle;
            var maxIndex = coordinateSequence.Count - 1;

            if (maxIndex <= 0)
            {
                return;
            }

            for (var i = 1; i < maxIndex; i++)
            {
                var c  = coordinateSequence.GetCoordinate(i);
                var fx = (float)(c.X - cprev.X);
                var fy = (float)(c.Y - cprev.Y);
                ws(bw, fx, fy);
                cprev = c;
            }

            // Write last coordinate
            cprev = coordinateSequence.GetCoordinate(maxIndex);
            wd(bw, cprev.X, cprev.Y);
        }
        private static void WriteCompressedXYZM(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw)
        {
            var wd = export.WriteDouble;

            // Write initial coordinate
            var cprev = coordinateSequence.GetCoordinate(0);
            var mprev = coordinateSequence.GetOrdinate(0, Ordinate.M);

            wd(bw, cprev.X, cprev.Y, cprev.Z, mprev);

            var maxIndex = coordinateSequence.Count - 1;

            if (maxIndex <= 0)
            {
                return;
            }

            var ws = export.WriteSingle;

            for (var i = 1; i < maxIndex; i++)
            {
                var c  = coordinateSequence.GetCoordinate(i);
                var fx = (float)(c.X - cprev.X);
                var fy = (float)(c.Y - cprev.Y);
                var fz = (float)(c.Z - cprev.Z);
                var fm = (float)(coordinateSequence.GetOrdinate(i, Ordinate.M) - mprev);
                ws(bw, fx, fy, fz, fm);
                cprev = c;
            }
            cprev = coordinateSequence.GetCoordinate(maxIndex);
            mprev = coordinateSequence.GetOrdinate(maxIndex, Ordinate.M);
            wd(bw, cprev.X, cprev.Y, cprev.Z, mprev);
        }
        public void TestClone()
        {
            ICoordinateSequence s1 = CoordinateArraySequenceFactory.Instance.Create(
                new[] { new Coordinate(1, 2), new Coordinate(3, 4) });
            ICoordinateSequence s2 = (ICoordinateSequence)s1.Clone();

            Assert.IsTrue(s1.GetCoordinate(0).Equals(s2.GetCoordinate(0)));
            Assert.IsTrue(s1.GetCoordinate(0) != s2.GetCoordinate(0));
        }
示例#8
0
 public void Filter(ICoordinateSequence seq, int i)
 {
     if (i == 0)
     {
         return;
     }
     seq.GetCoordinate(i - 1, p0);
     seq.GetCoordinate(i, p1);
     rcc.CountSegment(p0, p1);
 }
示例#9
0
        /// <summary>
        /// Tests for equality using all supported accessors,
        /// to provides test coverage for them.
        /// </summary>
        /// <param name="seq"></param>
        /// <param name="coords"></param>
        /// <returns></returns>
        bool IsEqual(ICoordinateSequence seq, Coordinate[] coords)
        {
            if (seq.Count != coords.Length)
            {
                return(false);
            }

            Coordinate p = new Coordinate();

            for (int i = 0; i < seq.Count; i++)
            {
                if (!coords[i].Equals(seq.GetCoordinate(i)))
                {
                    return(false);
                }

                // Ordinate named getters
                if (coords[i].X != seq.GetX(i))
                {
                    return(false);
                }
                if (coords[i].Y != seq.GetY(i))
                {
                    return(false);
                }

                // Ordinate indexed getters
                if (coords[i].X != seq.GetOrdinate(i, Ordinate.X))
                {
                    return(false);
                }
                if (coords[i].Y != seq.GetOrdinate(i, Ordinate.Y))
                {
                    return(false);
                }
                if (coords[i].Z != seq.GetOrdinate(i, Ordinate.Z))
                {
                    return(false);
                }

                // Coordinate getter
                seq.GetCoordinate(i, p);
                if (coords[i].X != p.X)
                {
                    return(false);
                }
                if (coords[i].Y != p.Y)
                {
                    return(false);
                }
                //TODO: Remove commented line below when NTS supports Z ordinates in CoordinateArraySequence.GetCoordinate and PackedCoordinateSequence.GetCoordinate
                //if (coords[i].Z != p.Z) return false;
            }
            return(true);
        }
示例#10
0
        private void Add(ILineString lineString)
        {
            ICoordinateSequence seq = lineString.CoordinateSequence;

            for (int i = 1; i < seq.Count; i++)
            {
                Coordinate prev = seq.GetCoordinate(i - 1);
                Coordinate curr = seq.GetCoordinate(i);
                graph.AddEdge(prev, curr);
            }
        }
            public void Filter(ICoordinateSequence seq, int i)
            {
                // compare to vertex
                CheckVertexDistance(seq.GetCoordinate(i));

                // compare to segment, if this is one
                if (i > 0)
                {
                    CheckSegmentDistance(seq.GetCoordinate(i - 1), seq.GetCoordinate(i));
                }
            }
        private static ICoordinateSequence InsertTopologyExceptionPoint(Coordinate coord, ICoordinateSequence seq, ICoordinateSequenceFactory factory)
        {
            var res = factory.Create(2 * seq.Count, seq.Ordinates);

            if (Replace(seq.GetCoordinate(0), coord))
            {
                res.SetOrdinate(0, Ordinate.X, coord.X);
                res.SetOrdinate(0, Ordinate.Y, coord.Y);
                res.SetOrdinate(0, Ordinate.Z, coord.Z);
            }
            else
            {
                res.SetOrdinate(0, Ordinate.X, seq.GetOrdinate(0, Ordinate.X));
                res.SetOrdinate(0, Ordinate.Y, seq.GetOrdinate(0, Ordinate.Y));
                res.SetOrdinate(0, Ordinate.Z, seq.GetOrdinate(0, Ordinate.Z));
            }

            var last = res.GetCoordinate(0);
            int off  = 0;

            for (int i = 1; i < seq.Count; i++)
            {
                var  curr = seq.GetCoordinate(i);
                bool add  = true;
                if (Replace(curr, coord))
                {
                    res.SetOrdinate(i + off, Ordinate.X, coord.X);
                    res.SetOrdinate(i + off, Ordinate.Y, coord.Y);
                    res.SetOrdinate(i + off, Ordinate.Z, coord.Z);
                    add = false;
                }
                else if (last.Distance(coord) + coord.Distance(curr) <= 1.000000000000000000001 * last.Distance(curr))
                {
                    res.SetOrdinate(i + off, Ordinate.X, coord.X);
                    res.SetOrdinate(i + off, Ordinate.Y, coord.Y);
                    res.SetOrdinate(i + off, Ordinate.Z, coord.Z);
                    off += 1;
                }

                if (add)
                {
                    res.SetOrdinate(i + off, Ordinate.X, seq.GetOrdinate(i, Ordinate.X));
                    res.SetOrdinate(i + off, Ordinate.Y, seq.GetOrdinate(i, Ordinate.Y));
                    res.SetOrdinate(i + off, Ordinate.Z, seq.GetOrdinate(i, Ordinate.Z));
                }
                last = curr;
            }

            var tmp = factory.Create(seq.Count + off, seq.Ordinates);

            CoordinateSequences.Copy(res, 0, tmp, 0, tmp.Count);
            return(tmp);
        }
        private void ExtractPoints(ILineString line, double offsetDistance, IList <Coordinate> offsetPts)
        {
            ICoordinateSequence coordinateSequence = line.CoordinateSequence;
            int maxIndex = coordinateSequence.Count - 1;

            for (int i = 0; i < maxIndex; i++)
            {
                ComputeOffsetPoints(
                    coordinateSequence.GetCoordinate(i),
                    coordinateSequence.GetCoordinate(i + 1), offsetDistance, offsetPts);
            }
        }
        public void TestCloneDimension2()
        {
            ICoordinateSequence s1 = CoordinateArraySequenceFactory.Instance.Create(2, 2);

            s1.SetOrdinate(0, Ordinate.X, 1);
            s1.SetOrdinate(0, Ordinate.Y, 2);
            s1.SetOrdinate(1, Ordinate.X, 3);
            s1.SetOrdinate(1, Ordinate.Y, 4);

            ICoordinateSequence s2 = (ICoordinateSequence)s1.Clone();

            Assert.IsTrue(s1.Dimension == s2.Dimension);
            Assert.IsTrue(s1.GetCoordinate(0).Equals(s2.GetCoordinate(0)));
            Assert.IsTrue(s1.GetCoordinate(0) != s2.GetCoordinate(0));
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="geom"></param>
        protected override void Visit(IGeometry geom)
        {
            if (!(geom is Polygon))
            {
                return;
            }
            IEnvelope elementEnv = geom.EnvelopeInternal;

            if (!rectEnv.Intersects(elementEnv))
            {
                return;
            }
            // test each corner of rectangle for inclusion
            Coordinate rectPt = new Coordinate();

            for (int i = 0; i < 4; i++)
            {
                rectSeq.GetCoordinate(i, rectPt);
                if (!elementEnv.Contains(rectPt))
                {
                    continue;
                }
                // check rect point in poly (rect is known not to touch polygon at this point)
                if (SimplePointInAreaLocator.ContainsPointInPolygon(rectPt, (Polygon)geom))
                {
                    containsPoint = true;
                    return;
                }
            }
        }
示例#16
0
        /// <summary>
        /// Computes the length of a linestring specified by a sequence of points.
        /// </summary>
        /// <param name="pts">The points specifying the linestring.</param>
        /// <returns>The length of the linestring.</returns>
        public static double Length(ICoordinateSequence pts)
        {
            if (pts.Count < 1)
            {
                return(0.0);
            }

            double sum = 0.0;

            for (int i = 1; i < pts.Count; i++)
            {
                sum += pts.GetCoordinate(i).Distance(pts.GetCoordinate(i - 1));
            }

            return(sum);
        }
        /// <summary>
        /// Determines the <see cref="Location"/> of a point in a ring.
        /// </summary>
        /// <param name="p">The point to test</param>
        /// <param name="ring">A coordinate sequence forming a ring</param>
        /// <returns>The location of the point in the ring</returns>
        public static Location LocatePointInRing(Coordinate p, ICoordinateSequence ring)
        {
            var counter = new RayCrossingCounter(p);

            var p1 = new Coordinate();
            var p2 = new Coordinate();
            for (var i = 1; i < ring.Count; i++)
            {
                ring.GetCoordinate(i, p1);
                ring.GetCoordinate(i - 1, p2);
                counter.CountSegment(p1, p2);
                if (counter.IsOnSegment)
                    return counter.Location;
            }
            return counter.Location;
        }
示例#18
0
        /// <summary>
        /// Function to return a coordinate sequence that is ensured to be closed.
        /// </summary>
        /// <param name="sequence">The base sequence</param>
        /// <param name="factory">The factory to use in case we need to create a new sequence</param>
        /// <returns>A closed coordinate sequence</returns>
        private static ICoordinateSequence EnsureClosedSequence(ICoordinateSequence sequence,
                                                                ICoordinateSequenceFactory factory)
        {
            //This sequence won't serve a valid linear ring
            if (sequence.Count < 3)
            {
                return(null);
            }

            //The sequence is closed
            var start     = sequence.GetCoordinate(0);
            var lastIndex = sequence.Count - 1;
            var end       = sequence.GetCoordinate(lastIndex);

            if (start.Equals2D(end))
            {
                return(sequence);
            }

            // The sequence is not closed
            // 1. Test for a little offset, in that case simply correct x- and y- ordinate values
            const double eps = 1E-7;

            if (start.Distance(end) < eps)
            {
                sequence.SetOrdinate(lastIndex, Ordinate.X, start.X);
                sequence.SetOrdinate(lastIndex, Ordinate.Y, start.Y);
                return(sequence);
            }

            // 2. Close the sequence by adding a new point, this is heavier
            var newSequence = factory.Create(sequence.Count + 1, sequence.Ordinates);
            var ordinates   = OrdinatesUtility.ToOrdinateArray(sequence.Ordinates);

            for (var i = 0; i < sequence.Count; i++)
            {
                foreach (var ordinate in ordinates)
                {
                    newSequence.SetOrdinate(i, ordinate, sequence.GetOrdinate(i, ordinate));
                }
            }
            foreach (var ordinate in ordinates)
            {
                newSequence.SetOrdinate(sequence.Count, ordinate, sequence.GetOrdinate(0, ordinate));
            }
            return(newSequence);
        }
            public void Filter(ICoordinateSequence seq, int index)
            {
                if (index == 0)
                {
                    return;
                }

                var p0    = seq.GetCoordinate(index - 1);
                var p1    = seq.GetCoordinate(index);
                var midPt = new Coordinate(
                    (p0.X + p1.X) / 2,
                    (p0.Y + p1.Y) / 2);

                minPtDist.Initialize();
                DistanceToPointFinder.ComputeDistance(geom, midPt, minPtDist);
                maxPtDist.SetMaximum(minPtDist);
            }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="seq0"></param>
 /// <param name="seq1"></param>
 /// <returns></returns>
 public bool HasIntersection(ICoordinateSequence seq0, ICoordinateSequence seq1) 
 {
     for (int i = 1; i < seq0.Count && ! hasIntersection; i++) 
     {
         seq0.GetCoordinate(i - 1, pt00);
         seq0.GetCoordinate(i, pt01);
         for (int j = 1; j < seq1.Count && ! hasIntersection; j++) 
         {
             seq1.GetCoordinate(j - 1, pt10);
             seq1.GetCoordinate(j, pt11);
             li.ComputeIntersection(pt00, pt01, pt10, pt11);
             if (li.HasIntersection)
                 hasIntersection = true;
         }
     }
     return hasIntersection;
 }
示例#21
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        private bool IsLineStringContainedInBoundary(ILineString line)
        {
            ICoordinateSequence seq = line.CoordinateSequence;
            ICoordinate         p0  = new Coordinate();
            ICoordinate         p1  = new Coordinate();

            for (int i = 0; i < seq.Count - 1; i++)
            {
                seq.GetCoordinate(i, p0);
                seq.GetCoordinate(i + 1, p1);
                if (!IsLineSegmentContainedInBoundary(p0, p1))
                {
                    return(false);
                }
            }
            return(true);
        }
		public static MCoordinate[] Copy(ICoordinateSequence coordSeq)
		{
			MCoordinate[] copy = new MCoordinate[coordSeq.Count];
			for (int i = 0; i < coordSeq.Count; i++)
			{
				copy[i] = new MCoordinate(coordSeq.GetCoordinate(i));
			}
			return copy;
		}
 public static MCoordinate[] Copy(ICoordinateSequence coordSeq)
 {
     MCoordinate[] copy = new MCoordinate[coordSeq.Count];
     for (int i = 0; i < coordSeq.Count; i++)
     {
         copy[i] = new MCoordinate(coordSeq.GetCoordinate(i));
     }
     return(copy);
 }
示例#24
0
        /// <summary>
        /// Tests whether a point lies on the line defined by a list of
        /// coordinates.
        /// </summary>
        /// <param name="p">The point to test</param>
        /// <param name="line">The line coordinates</param>
        /// <returns>
        /// <c>true</c> if the point is a vertex of the line or lies in the interior
        /// of a line segment in the line
        /// </returns>
        public static bool IsOnLine(Coordinate p, ICoordinateSequence line)
        {
            var lineIntersector = new RobustLineIntersector();
            var p0 = new Coordinate();
            var p1 = new Coordinate();
            int n  = line.Count;

            for (int i = 1; i < n; i++)
            {
                line.GetCoordinate(i - 1, p0);
                line.GetCoordinate(i, p1);
                lineIntersector.ComputeIntersection(p, p0, p1);
                if (lineIntersector.HasIntersection)
                {
                    return(true);
                }
            }
            return(false);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="seq0"></param>
 /// <param name="seq1"></param>
 /// <returns></returns>
 public bool HasIntersection(ICoordinateSequence seq0, ICoordinateSequence seq1)
 {
     for (int i = 1; i < seq0.Count && !_hasIntersection; i++)
     {
         seq0.GetCoordinate(i - 1, pt00);
         seq0.GetCoordinate(i, pt01);
         for (int j = 1; j < seq1.Count && !_hasIntersection; j++)
         {
             seq1.GetCoordinate(j - 1, pt10);
             seq1.GetCoordinate(j, pt11);
             li.ComputeIntersection(pt00, pt01, pt10, pt11);
             if (li.HasIntersection)
             {
                 _hasIntersection = true;
             }
         }
     }
     return(_hasIntersection);
 }
        private static void WriteXYZM(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw)
        {
            var wd = export.WriteDouble;

            for (var i = 0; i < coordinateSequence.Count; i++)
            {
                var c = coordinateSequence.GetCoordinate(i);
                wd(bw, c.X, c.Y, c.Z, coordinateSequence.GetOrdinate(i, Ordinate.M));
            }
        }
示例#27
0
        /// <summary>
        /// Determines the <see cref="Location"/> of a point in a ring.
        /// </summary>
        /// <param name="p">The point to test</param>
        /// <param name="ring">A coordinate sequence forming a ring</param>
        /// <returns>The location of the point in the ring</returns>
        public static Location LocatePointInRing(Coordinate p, ICoordinateSequence ring)
        {
            var counter = new RayCrossingCounter(p);

            var p1 = new Coordinate();
            var p2 = new Coordinate();

            for (var i = 1; i < ring.Count; i++)
            {
                ring.GetCoordinate(i, p1);
                ring.GetCoordinate(i - 1, p2);
                counter.CountSegment(p1, p2);
                if (counter.IsOnSegment)
                {
                    return(counter.Location);
                }
            }
            return(counter.Location);
        }
示例#28
0
 private bool IsWithinToleranceOfBoundary(Coordinate pt)
 {
     for (int i = 0; i < _linework.NumGeometries; i++)
     {
         ILineString         line = (ILineString)_linework.GetGeometryN(i);
         ICoordinateSequence seq  = line.CoordinateSequence;
         for (int j = 0; j < seq.Count - 1; j++)
         {
             seq.GetCoordinate(j, _seg.P0);
             seq.GetCoordinate(j + 1, _seg.P1);
             double dist = _seg.Distance(pt);
             if (dist <= _boundaryDistanceTolerance)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
示例#29
0
 /**
  * Adds a double array to list.
  *
  * <p>
  * The double array will contain all the ordinates in the Coordiante
  * sequence.
  * </p>
  *
  * @param list
  * @param sequence
  */
 private static void AddCoordinates(List <double[]> list, ICoordinateSequence sequence)
 {
     for (int i = 0; i < sequence.Count; i++)
     {
         Coordinate coord = sequence.GetCoordinate(i);
         list.Add(Double.IsNaN(coord.Z)
         ? new[] { coord.X, coord.Y }
         : new[] { coord.X, coord.Y, coord.Z });
     }
 }
 /**
  * Computes an average normal vector from a list of polygon coordinates.
  * Uses Newell's method, which is based
  * on the fact that the vector with components
  * equal to the areas of the projection of the polygon onto 
  * the Cartesian axis planes is normal.
  * 
  * @param seq the sequence of coordinates for the polygon
  * @return a normal vector
  */
 private static Vector3D AverageNormal(ICoordinateSequence seq)
 {
     var n = seq.Count;
     var sum = new Coordinate(0, 0, 0);
     var p1 = new Coordinate(0, 0, 0);
     var p2 = new Coordinate(0, 0, 0);
     for (var i = 0; i < n - 1; i++)
     {
         seq.GetCoordinate(i, p1);
         seq.GetCoordinate(i + 1, p2);
         sum.X += (p1.Y - p2.Y) * (p1.Z + p2.Z);
         sum.Y += (p1.Z - p2.Z) * (p1.X + p2.X);
         sum.Z += (p1.X - p2.X) * (p1.Y + p2.Y);
     }
     sum.X /= n;
     sum.Y /= n;
     sum.Z /= n;
     var norm = Vector3D.Create(sum).Normalize();
     return norm;
 }
        public IGeometry Densify(double segLength)
        {
            newCoords = new CoordinateList();

            ICoordinateSequence seq = inputLine.CoordinateSequence;

            Coordinate p0 = new Coordinate();
            Coordinate p1 = new Coordinate();

            seq.GetCoordinate(0, p0);
            newCoords.Add(new Coordinate(p0));

            for (int i = 0; i < seq.Count - 1; i++)
            {
                seq.GetCoordinate(i, p0);
                seq.GetCoordinate(i + 1, p1);
                Densify(p0, p1, segLength);
            }
            Coordinate[] newPts = newCoords.ToCoordinateArray();
            return(inputLine.Factory.CreateLineString(newPts));
        }
示例#32
0
        private void Add(ILineString lineString)
        {
            if (_factory == null)
            {
                _factory = lineString.Factory;
            }
            ICoordinateSequence seq = lineString.CoordinateSequence;

            for (int i = 1; i < seq.Count; i++)
            {
                Coordinate       prev = seq.GetCoordinate(i - 1);
                Coordinate       curr = seq.GetCoordinate(i);
                DissolveHalfEdge e    = (DissolveHalfEdge)_graph.AddEdge(prev, curr);
                // Record source initial segments, so that they can be reflected in output when needed
                // (i.e. during formation of isolated rings)
                if (i == 1)
                {
                    e.SetStart();
                }
            }
        }
示例#33
0
        /**
         * Computes an average normal vector from a list of polygon coordinates.
         * Uses Newell's method, which is based
         * on the fact that the vector with components
         * equal to the areas of the projection of the polygon onto
         * the Cartesian axis planes is normal.
         *
         * @param seq the sequence of coordinates for the polygon
         * @return a normal vector
         */
        private static Vector3D AverageNormal(ICoordinateSequence seq)
        {
            var n   = seq.Count;
            var sum = new Coordinate(0, 0, 0);
            var p1  = new Coordinate(0, 0, 0);
            var p2  = new Coordinate(0, 0, 0);

            for (var i = 0; i < n - 1; i++)
            {
                seq.GetCoordinate(i, p1);
                seq.GetCoordinate(i + 1, p2);
                sum.X += (p1.Y - p2.Y) * (p1.Z + p2.Z);
                sum.Y += (p1.Z - p2.Z) * (p1.X + p2.X);
                sum.Z += (p1.X - p2.X) * (p1.Y + p2.Y);
            }
            sum.X /= n;
            sum.Y /= n;
            sum.Z /= n;
            var norm = Vector3D.Create(sum).Normalize();

            return(norm);
        }
示例#34
0
        /// <summary>
        /// Returns the minimum coordinate, using the usual lexicographic comparison.
        /// </summary>
        /// <param name="seq">The coordinate sequence to search</param>
        /// <returns>The minimum coordinate in the sequence, found using <see cref="Coordinate.CompareTo(Coordinate)"/></returns>
        public static Coordinate MinCoordinate(ICoordinateSequence seq)
        {
            Coordinate minCoord = null;

            for (int i = 0; i < seq.Count; i++)
            {
                var testCoord = seq.GetCoordinate(i);
                if (minCoord == null || minCoord.CompareTo(testCoord) > 0)
                {
                    minCoord = testCoord;
                }
            }
            return(minCoord);
        }
示例#35
0
        /// <summary>
        /// Computes the distance from a point to a sequence of line segments.
        /// </summary>
        /// <param name="p">A point</param>
        /// <param name="line">A sequence of contiguous line segments defined by their vertices</param>
        /// <returns>The minimum distance between the point and the line segments</returns>
        public static double PointToSegmentString(Coordinate p, ICoordinateSequence line)
        {
            if (line.Count == 0)
            {
                throw new ArgumentException(
                          "Line array must contain at least one vertex");
            }
            // this handles the case of length = 1
            var    lastStart   = line.GetCoordinate(0);
            double minDistance = p.Distance(lastStart);

            for (int i = 1; i < line.Count - 1; i++)
            {
                var    currentEnd = line.GetCoordinate(i);
                double dist       = DistanceComputer.PointToSegment(p, lastStart, currentEnd);
                if (dist < minDistance)
                {
                    minDistance = dist;
                }
                lastStart = currentEnd;
            }
            return(minDistance);
        }
        private static void DoTest(ICoordinateSequence forward, ICoordinateSequence reversed)
        {
            const double eps = 1e-12;

            Assert.AreEqual(forward.Count, reversed.Count, "Coordinate sequences don't have same size");
            Assert.AreEqual(forward.Ordinates, reversed.Ordinates, "Coordinate sequences don't serve same ordinate values");

            var ordinates = OrdinatesUtility.ToOrdinateArray(forward.Ordinates);
            var j = forward.Count;
            for (var i = 0; i < forward.Count; i++)
            {
                j--;
                foreach(var ordinate in ordinates)
                    Assert.AreEqual(forward.GetOrdinate(i, ordinate), reversed.GetOrdinate(j, ordinate), eps, string.Format("{0} values are not within tolerance", ordinate));
                var cf = forward.GetCoordinate(i);
                var cr = reversed.GetCoordinate(j);

                Assert.IsFalse(ReferenceEquals(cf, cr), "Coordinate sequences deliver same coordinate instances");
                Assert.IsTrue(cf.Equals(cr), "Coordinate sequences do not provide equal coordinates");
            }
        }
        private static void WriteCompressedXY(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw)
        {
            var wd = export.WriteDouble;

            // Write initial coordinate
            var cprev = coordinateSequence.GetCoordinate(0);
            wd(bw, cprev.X, cprev.Y);

            var ws = export.WriteSingle;
            var maxIndex = coordinateSequence.Count - 1;
            if (maxIndex <= 0) return;

            for (var i = 1; i < maxIndex; i++)
            {
                var c = coordinateSequence.GetCoordinate(i);
                var fx = (float)(c.X - cprev.X);
                var fy = (float)(c.Y - cprev.Y);
                ws(bw, fx, fy);
                cprev = c;
            }

            // Write last coordinate
            cprev = coordinateSequence.GetCoordinate(maxIndex);
            wd(bw, cprev.X, cprev.Y);
        }
        private static void WriteCompressedXYZM(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw)
        {
            var wd = export.WriteDouble;

            // Write initial coordinate
            var cprev = coordinateSequence.GetCoordinate(0);
            var mprev = coordinateSequence.GetOrdinate(0, Ordinate.M);
            wd(bw, cprev.X, cprev.Y, cprev.Z, mprev);

            var maxIndex = coordinateSequence.Count - 1;
            if (maxIndex <= 0) return;

            var ws = export.WriteSingle;
            for (var i = 1; i < maxIndex; i++)
            {
                var c = coordinateSequence.GetCoordinate(i);
                var fx = (float)(c.X - cprev.X);
                var fy = (float)(c.Y - cprev.Y);
                var fz = (float)(c.Z - cprev.Z);
                var fm = (float)(coordinateSequence.GetOrdinate(i, Ordinate.M) - mprev);
                ws(bw, fx, fy, fz, fm);
                cprev = c;
            }
            cprev = coordinateSequence.GetCoordinate(maxIndex);
            mprev = coordinateSequence.GetOrdinate(maxIndex, Ordinate.M);
            wd(bw, cprev.X, cprev.Y, cprev.Z, mprev);
        }
        /// <summary>
        /// Tests for equality using all supported accessors,
        /// to provides test coverage for them.
        /// </summary>
        /// <param name="seq"></param>
        /// <param name="coords"></param>
        /// <returns></returns>
        bool IsEqual(ICoordinateSequence seq, Coordinate[] coords)
        {
            if (seq.Count != coords.Length)
                return false;

            Coordinate p = new Coordinate();

            for (int i = 0; i < seq.Count; i++)
            {
                if (!coords[i].Equals(seq.GetCoordinate(i)))
                    return false;

                // Ordinate named getters
                if (coords[i].X != seq.GetX(i))
                    return false;
                if (coords[i].Y != seq.GetY(i))
                    return false;

                // Ordinate indexed getters
                if (coords[i].X != seq.GetOrdinate(i, Ordinate.X))
                    return false;
                if (coords[i].Y != seq.GetOrdinate(i, Ordinate.Y))
                    return false;
                if (coords[i].Z != seq.GetOrdinate(i, Ordinate.Z))
                    return false;

                // Coordinate getter
                seq.GetCoordinate(i, p);
                if (coords[i].X != p.X)
                    return false;
                if (coords[i].Y != p.Y)
                    return false;
                //TODO: Remove commented line below when NTS supports Z ordinates in CoordinateArraySequence.GetCoordinate and PackedCoordinateSequence.GetCoordinate
                //if (coords[i].Z != p.Z) return false;

            }
            return true;
        }
            public void Filter(ICoordinateSequence seq, int index)
            {
                if (index == 0)
                    return;

                var p0 = seq.GetCoordinate(index - 1);
                var p1 = seq.GetCoordinate(index);
                var midPt = new Coordinate(
                        (p0.X + p1.X) / 2,
                        (p0.Y + p1.Y) / 2);

                minPtDist.Initialize();
                DistanceToPointFinder.ComputeDistance(geom, midPt, minPtDist);
                maxPtDist.SetMaximum(minPtDist);
            }
 /**
  * Adds a double array to list.
  * 
  * <p>
  * The double array will contain all the ordinates in the Coordiante
  * sequence.
  * </p>
  *
  * @param list
  * @param sequence
  */
 private static void AddCoordinates(List<double[]> list, ICoordinateSequence sequence)
 {
     for (int i = 0; i < sequence.Count; i++)
     {
         Coordinate coord = sequence.GetCoordinate(i);
         list.Add(Double.IsNaN(coord.Z) 
             ? new[] {coord.X, coord.Y} 
             : new[] {coord.X, coord.Y, coord.Z});
     }
 }
            public void Filter(ICoordinateSequence seq, int index)
            {
                /**
                 * This logic also handles skipping Point geometries
                 */
                if (index == 0)
                    return;

                var p0 = seq.GetCoordinate(index - 1);
                var p1 = seq.GetCoordinate(index);

                var delx = (p1.X - p0.X) / _numSubSegs;
                var dely = (p1.Y - p0.Y) / _numSubSegs;

                for (var i = 0; i < _numSubSegs; i++)
                {
                    var x = p0.X + i * delx;
                    var y = p0.Y + i * dely;
                    var pt = new Coordinate(x, y);
                    _minPtDist.Initialize();
                    DistanceToPoint.ComputeDistance(_geom, pt, _minPtDist);
                    _maxPtDist.SetMaximum(_minPtDist);
                }


            }
示例#43
0
        /// <summary>
        /// Computes the length of a linestring specified by a sequence of points.
        /// </summary>
        /// <param name="pts">The points specifying the linestring</param>
        /// <returns>The length of the linestring</returns>
        public static double Length(ICoordinateSequence pts)
        {
            // optimized for processing CoordinateSequences
            int n = pts.Count;
            if (n <= 1) return 0.0;

            double len = 0.0;

            var p0 = pts.GetCoordinate(0);

            for (int i = 1; i < n; i++)
            {
                var p1 = pts.GetCoordinate(i);
                len += p1.Distance(p0);

                p0 = p1;
            }
            return len;
        }
示例#44
0
        /// <summary>
        /// Computes the length of a linestring specified by a sequence of points.
        /// </summary>
        /// <param name="pts">The points specifying the linestring</param>
        /// <returns>The length of the linestring</returns>
        public static double Length(ICoordinateSequence pts)
        {
            // optimized for processing CoordinateSequences
            int n = pts.Count;
            if (n <= 1) return 0.0;

            double len = 0.0;

            var p = new Coordinate();
            pts.GetCoordinate(0, p);
            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;
        }
示例#45
0
 /// <summary> 
 /// Computes the length of a linestring specified by a sequence of points.
 /// </summary>
 /// <param name="pts">The points specifying the linestring.</param>
 /// <returns>The length of the linestring.</returns>
 public static double Length(ICoordinateSequence pts) 
 {
     if (pts.Count < 1) 
         return 0.0;
     
     double sum = 0.0;
     for (int i = 1; i < pts.Count; i++) 
         sum += pts.GetCoordinate(i).Distance(pts.GetCoordinate(i - 1));
     
     return sum;
 }
示例#46
0
 /// <summary>
 /// Computes the signed area for a ring.
 /// <remarks>
 /// <para>
 /// The signed area is
 /// </para>  
 /// <list type="Table">
 /// <item>positive</item><description>if the ring is oriented CW</description>
 /// <item>negative</item><description>if the ring is oriented CCW</description>
 /// <item>zero</item><description>if the ring is degenerate or flat</description>
 /// </list>
 /// </remarks>
 /// </summary>
 /// <param name="ring">The coordinates forming the ring</param>
 /// <returns>The signed area of the ring</returns>
 public static double SignedArea(ICoordinateSequence ring)
 {
     var n = ring.Count;
     if (n < 3)
         return 0.0;
     /**
      * Based on the Shoelace formula.
      * http://en.wikipedia.org/wiki/Shoelace_formula
      */
     var p0 = new Coordinate();
     var p1 = new Coordinate();
     var p2 = new Coordinate();
     ring.GetCoordinate(0, p1);
     ring.GetCoordinate(1, p2);
     var x0 = p1.X;
     p2.X -= x0;
     var sum = 0.0;
     for (var i = 1; i < n - 1; i++)
     {
         p0.Y = p1.Y;
         p1.X = p2.X;
         p1.Y = p2.Y;
         ring.GetCoordinate(i + 1, p2);
         p2.X -= x0;
         sum += p1.X * (p0.Y - p2.Y);
     }
     return sum / 2.0;
 }
 private static void WriteXYZM(ICoordinateSequence coordinateSequence, GaiaExport export, BinaryWriter bw)
 {
     var wd = export.WriteDouble;
     for (var i = 0; i < coordinateSequence.Count; i++)
     {
         var c = coordinateSequence.GetCoordinate(i);
         wd(bw, c.X, c.Y, c.Z, coordinateSequence.GetOrdinate(i, Ordinate.M));
     }
 }
        bool IsAllCoordsEqual(ICoordinateSequence seq, Coordinate coord)
        {
            for (int i = 0; i < seq.Count; i++)
            {
                if (!coord.Equals(seq.GetCoordinate(i)))
                    return false;

                if (coord.X != seq.GetOrdinate(i, Ordinate.X))
                    return false;
                if (coord.Y != seq.GetOrdinate(i, Ordinate.Y))
                    return false;
                if (coord.Z != seq.GetOrdinate(i, Ordinate.Z))
                    return false;
            }
            return true;
        }
示例#49
0
 public ICoordinateSequence Transform(ICoordinateSequence coordinateSequence)
 {
     var clone = new Coordinate();
     for (var i = 0; i < coordinateSequence.Count; i++)
     {
         clone.CoordinateValue = coordinateSequence.GetCoordinate(i);
         clone = Transform(clone);
         coordinateSequence.SetOrdinate(i, Ordinate.X, clone.X);
         coordinateSequence.SetOrdinate(i, Ordinate.Y, clone.Y);
         if (DimTarget > 2)
             coordinateSequence.SetOrdinate(i, Ordinate.Z, clone.Z);
     }
     return coordinateSequence;
 }
示例#50
0
        /// <summary> 
        /// Creates a MultiPoint using the given CoordinateSequence; a null or empty CoordinateSequence will
        /// create an empty MultiPoint.
        /// </summary>
        /// <param name="coordinates">A CoordinateSequence possibly empty, or null.</param>
        public IMultiPoint CreateMultiPoint(ICoordinateSequence coordinates)
        {
            if (coordinates == null)
                coordinates = CoordinateSequenceFactory.Create(new ICoordinate[] { });

            List<IPoint> points = new List<IPoint>();
            for (int i = 0; i < coordinates.Count; i++)
                points.Add(CreatePoint(coordinates.GetCoordinate(i)));

            return CreateMultiPoint(points.ToArray());
        }
示例#51
0
        /// <summary>
        /// Function to return a coordinate sequence that is ensured to be closed.
        /// </summary>
        /// <param name="sequence">The base sequence</param>
        /// <param name="factory">The factory to use in case we need to create a new sequence</param>
        /// <returns>A closed coordinate sequence</returns>
        private static ICoordinateSequence EnsureClosedSequence(ICoordinateSequence sequence,
                                                                ICoordinateSequenceFactory factory)
        {
            //This sequence won't serve a valid linear ring
            if (sequence.Count < 3)
                return null;

            //The sequence is closed
            var start = sequence.GetCoordinate(0);
            var lastIndex = sequence.Count - 1;
            var end = sequence.GetCoordinate(lastIndex);
            if (start.Equals2D(end))
                return sequence;

            // The sequence is not closed
            // 1. Test for a little offset, in that case simply correct x- and y- ordinate values
            const double eps = 1E-7;
            if (start.Distance(end) < eps)
            {
                sequence.SetOrdinate(lastIndex, Ordinate.X, start.X);
                sequence.SetOrdinate(lastIndex, Ordinate.Y, start.Y);
                return sequence;
            }

            // 2. Close the sequence by adding a new point, this is heavier
            var newSequence = factory.Create(sequence.Count + 1, sequence.Ordinates);
            var ordinates = OrdinatesUtility.ToOrdinateArray(sequence.Ordinates);
            for (var i = 0; i < sequence.Count; i++)
            {
                foreach (var ordinate in ordinates)
                    newSequence.SetOrdinate(i, ordinate, sequence.GetOrdinate(i, ordinate));
            }
            foreach (var ordinate in ordinates)
                newSequence.SetOrdinate(sequence.Count, ordinate, sequence.GetOrdinate(0, ordinate));
            return newSequence;
        }
            public void Filter(ICoordinateSequence seq, int i)
            {
                // compare to vertex
                CheckVertexDistance(seq.GetCoordinate(i));

                // compare to segment, if this is one
                if (i > 0)
                {
                    CheckSegmentDistance(seq.GetCoordinate(i - 1), seq.GetCoordinate(i));
                }
            }