private static CoordinateSequence CreateCircularString(CoordinateSequenceFactory factory, int dimension,
                                                               Coordinate center, double radius, double startAngle,
                                                               int numPoints)
        {
            const int    numSegmentsCircle = 48;
            const double angleCircle       = 2 * Math.PI;
            const double angleStep         = angleCircle / numSegmentsCircle;

            var    sequence = factory.Create(numPoints, dimension, 0);
            var    pm       = new PrecisionModel(100);
            double angle    = startAngle;

            for (int i = 0; i < numPoints; i++)
            {
                double dx = Math.Cos(angle) * radius;
                sequence.SetOrdinate(i, Ordinate.X, pm.MakePrecise(center.X + dx));
                double dy = Math.Sin(angle) * radius;
                sequence.SetOrdinate(i, Ordinate.Y, pm.MakePrecise(center.Y + dy));

                // set other ordinate values to predictable values
                for (int j = 2; j < dimension; j++)
                {
                    sequence.SetOrdinate(i, j, Math.Pow(10, j - 1) * i);
                }

                angle += angleStep;
                angle %= angleCircle;
            }

            return(sequence);
        }
Exemple #2
0
 /// <summary>
 /// "Fixes" this Coordinate to the PrecisionModel grid.
 /// </summary>
 public virtual void MakePrecise(PrecisionModel precisionModel)
 {
     if (precisionModel != null)
     {
         m_dX = precisionModel.MakePrecise(m_dX);
         m_dY = precisionModel.MakePrecise(m_dY);
     }
 }
Exemple #3
0
 /// <summary>
 /// Get Envelope in external coordinates.
 /// </summary>
 /// <param name="precisionModel">The precision model to use</param>
 /// <param name="envelope">The envelope to get</param>
 /// <returns></returns>
 public static Envelope GetEnvelopeExternal(PrecisionModel precisionModel, Envelope envelope)
 {
     // Get envelope in external coordinates
     return(new Envelope(
                x1: precisionModel.MakePrecise(envelope.MinX),
                x2: precisionModel.MakePrecise(envelope.MaxX),
                y1: precisionModel.MakePrecise(envelope.MinY),
                y2: precisionModel.MakePrecise(envelope.MaxY)));
 }
Exemple #4
0
 /// <summary> "Fixes" this Coordinate to the PrecisionModel grid.</summary>
 public override void MakePrecise(PrecisionModel precisionModel)
 {
     if (precisionModel != null)
     {
         m_dX = precisionModel.MakePrecise(m_dX);
         m_dY = precisionModel.MakePrecise(m_dY);
         m_dZ = precisionModel.MakePrecise(m_dZ);
     }
 }
Exemple #5
0
        private static ICoordinateSequence CreateRandomTestSequence(ICoordinateSequenceFactory csFactory, int size, int dim,
                                                                    Random rnd, Envelope range, PrecisionModel pm)
        {
            var cs = csFactory.Create(size, dim);

            for (int i = 0; i < size; i++)
            {
                cs.SetOrdinate(i, Ordinate.X, pm.MakePrecise(range.Width * rnd.NextDouble() + range.MinX));
                cs.SetOrdinate(i, Ordinate.Y, pm.MakePrecise(range.Height * rnd.NextDouble() + range.MinY));
            }

            return(FillNonPlanarDimensions(cs));
        }
Exemple #6
0
        private Coordinate Round(Coordinate pt)
        {
            var p2 = pt.Copy();

            _pm.MakePrecise(p2);
            return(p2);
        }
        private Point CopyPoint(Point pt)
        {
            // if pm is floating, the point coordinate is not changed
            if (OverlayUtility.IsFloating(_pm))
            {
                return((Point)pt.Copy());
            }

            // pm is fixed.  Round off X&Y ordinates, copy other ordinates unchanged
            var seq  = pt.CoordinateSequence;
            var seq2 = seq.Copy();

            seq2.SetOrdinate(0, Ordinate.X, _pm.MakePrecise(seq.GetX(0)));
            seq2.SetOrdinate(0, Ordinate.Y, _pm.MakePrecise(seq.GetY(0)));
            return(_geometryFactory.CreatePoint(seq2));
        }
        /// <summary>
        /// Computes the centroid based on both the shell and the holes.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">
        /// The number of coordinates in less than 3.
        /// or
        /// The coordinates do not represent a surface.
        /// </exception>
        protected void ComputeForShellAndHoles()
        {
            Double resultX = 0, resultY = 0, resultZ = 0;

            _area = 0;

            _baseCoordinate = _shell[0];
            resultZ         = _shell[0].Z;

            AddCoordinates(_shell, 1, ref resultX, ref resultY);

            foreach (IList <Coordinate> hole in _holes)
            {
                if (hole == null)
                {
                    continue;
                }

                AddCoordinates(hole, -1, ref resultX, ref resultY);
            }

            resultX = resultX / 3 / _area;
            resultY = resultY / 3 / _area;

            _result    = PrecisionModel.MakePrecise(new Coordinate(resultX, resultY, resultZ));
            _hasResult = true;
        }
        /// <summary>
        /// Sets the coordinate at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the coordinate to set.</param>
        /// <param name="coordinate">The coordinate.</param>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// The index is less than 0.
        /// or
        /// Index is equal to or greater than the number of coordinates.
        /// </exception>
        public override void SetCoordinate(Int32 index, Coordinate coordinate)
        {
            if (index < 0)
            {
                throw new ArgumentOutOfRangeException("index", "The index is less than 0.");
            }
            if (index >= _coordinates.Count)
            {
                throw new ArgumentOutOfRangeException("index", "Index is equal to or greater than the number of coordinates.");
            }
            if (_coordinates[index].Equals(coordinate))
            {
                return;
            }

            if (index == 0 || index == _coordinates.Count - 1)
            {
                _coordinates[0] = PrecisionModel.MakePrecise(coordinate);
                _coordinates[_coordinates.Count - 1] = _coordinates[0];
            }
            else
            {
                _coordinates[index] = PrecisionModel.MakePrecise(coordinate);
            }

            OnGeometryChanged();
        }
        /// <summary>
        /// Densifies a coordinate sequence.
        /// </summary>
        /// <param name="pts">The coordinate sequence to densify</param>
        /// <param name="distanceTolerance">The distance tolerance (<see cref="DistanceTolerance"/>)</param>
        /// <param name="precModel">The precision model to apply on the new coordinates</param>
        /// <returns>The densified coordinate sequence</returns>
        private static Coordinate[] DensifyPoints(Coordinate[] pts,
                                                  double distanceTolerance, PrecisionModel precModel)
        {
            var seg       = new LineSegment();
            var coordList = new CoordinateList();

            for (int i = 0; i < pts.Length - 1; i++)
            {
                seg.P0 = pts[i];
                seg.P1 = pts[i + 1];
                coordList.Add(seg.P0, false);
                double len = seg.Length;
                int    densifiedSegCount = (int)(len / distanceTolerance) + 1;
                if (densifiedSegCount > 1)
                {
                    double densifiedSegLen = len / densifiedSegCount;
                    for (int j = 1; j < densifiedSegCount; j++)
                    {
                        double segFract = (j * densifiedSegLen) / len;
                        var    p        = seg.PointAlong(segFract);
                        precModel.MakePrecise(p);
                        coordList.Add(p, false);
                    }
                }
            }
            coordList.Add(pts[pts.Length - 1], false);
            return(coordList.ToCoordinateArray());
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="tokens"></param>
        /// <param name="skipExtraParenthesis"></param>
        /// <returns></returns>
        private Coordinate GetPreciseCoordinate(IList tokens, Boolean skipExtraParenthesis)
        {
            var     coord = new CoordinateZM();
            Boolean extraParenthesisFound = false;

            if (skipExtraParenthesis)
            {
                extraParenthesisFound = IsStringValueNext(tokens, "("); //NOXLATE
                if (extraParenthesisFound)
                {
                    index++;
                }
            }
            coord.X = GetNextNumber(tokens);
            coord.Y = GetNextNumber(tokens);
            if (IsNumberNext(tokens))
            {
                coord.Z = GetNextNumber(tokens);
            }
            if (IsNumberNext(tokens))
            {
                coord.M = GetNextNumber(tokens);
            }

            if (skipExtraParenthesis &&
                extraParenthesisFound &&
                IsStringValueNext(tokens, ")")) //NOXLATE
            {
                index++;
            }

            precisionModel.MakePrecise((Coordinate)coord);
            return(coord);
        }
        /// <summary>
        /// Computes the centroid based on the shell.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">
        /// The number of coordinates in less than 3.
        /// or
        /// The coordinates do not represent a surface.
        /// </exception>
        protected void ComputeForShell()
        {
            Double resultX = 0, resultY = 0;

            _area = 0;

            if (_shell.Count < 3) // if there are not enough coordinates
            {
                _hasResult = true;
                return;
            }

            for (Int32 i = 0; i < _shell.Count - 1; i++)
            {
                resultX += (_shell[i].X + _shell[i + 1].X) * (_shell[i].X * _shell[i + 1].Y - _shell[i + 1].X * _shell[i].Y);
                resultY += (_shell[i].Y + _shell[i + 1].Y) * (_shell[i].X * _shell[i + 1].Y - _shell[i + 1].X * _shell[i].Y);
                _area   += _shell[i].X * _shell[i + 1].Y - _shell[i + 1].X * _shell[i].Y;
            }

            _area /= 2;

            resultX /= (6 * _area);
            resultY /= (6 * _area);

            _result    = PrecisionModel.MakePrecise(new Coordinate(resultX, resultY, _shell[0].Z));
            _hasResult = true;
        }
        private Coordinate[] ReduceCompress(CoordinateSequence coordinates)
        {
            var noRepeatCoordList = new CoordinateList();

            // copy coordinates and reduce
            for (int i = 0; i < coordinates.Count; i++)
            {
                var coord = coordinates.GetCoordinate(i).Copy();
                _targetPm.MakePrecise(coord);
                noRepeatCoordList.Add(coord, false);
            }

            // remove repeated points, to simplify returned geometry as much as possible
            var noRepeatCoords = noRepeatCoordList.ToCoordinateArray();

            return(noRepeatCoords);
        }
        /// <summary>
        /// Writes a single coordinate to JSON
        /// </summary>
        /// <param name="writer">The writer</param>
        /// <param name="coordinate">The coordinate</param>
        protected void WriteJsonCoordinate(JsonWriter writer, Coordinate coordinate)
        {
            writer.WriteStartArray();

            double value = _precisionModel.MakePrecise(coordinate.X);

            writer.WriteValue(value);
            value = _precisionModel.MakePrecise(coordinate.Y);
            writer.WriteValue(value);

            if (_dimension > 2 && !double.IsNaN(coordinate.Z))
            {
                writer.WriteValue(coordinate.Z);
            }

            writer.WriteEndArray();
        }
        public override Coordinate[] Edit(Coordinate[] coordinates, Geometry geom)
        {
            if (coordinates.Length == 0)
            {
                return(null);
            }

            var reducedCoords = new Coordinate[coordinates.Length];

            // copy coordinates and reduce
            for (int i = 0; i < coordinates.Length; i++)
            {
                var coord = coordinates[i].Copy();
                _targetPrecModel.MakePrecise(coord);
                reducedCoords[i] = coord;
            }
            // remove repeated points, to simplify returned geometry as much as possible
            var noRepeatedCoordList = new CoordinateList(reducedCoords,
                                                         false);
            var noRepeatedCoords = noRepeatedCoordList.ToCoordinateArray();

            /**
             * Check to see if the removal of repeated points collapsed the coordinate
             * List to an invalid length for the type of the parent geometry. It is not
             * necessary to check for Point collapses, since the coordinate list can
             * never collapse to less than one point. If the length is invalid, return
             * the full-length coordinate array first computed, or null if collapses are
             * being removed. (This may create an invalid geometry - the client must
             * handle this.)
             */
            int minLength = 0;

            if (geom is LineString)
            {
                minLength = 2;
            }
            if (geom is LinearRing)
            {
                minLength = LinearRing.MinimumValidSize;
            }

            var collapsedCoords = reducedCoords;

            if (_removeCollapsed)
            {
                collapsedCoords = null;
            }

            // return null or original length coordinate array
            if (noRepeatedCoords.Length < minLength)
            {
                return(collapsedCoords);
            }

            // ok to return shorter coordinate array
            return(noRepeatedCoords);
        }
Exemple #16
0
 private Coordinate MakePrecise(Coordinate coord)
 {
     if (_precModel == null)
     {
         return(coord);
     }
     _precModel.MakePrecise(coord);
     return(coord);
 }
Exemple #17
0
        private Coordinate computePoint(LineSegment seg, double dist)
        {
            double dx  = seg.P1.X - seg.P0.X;
            double dy  = seg.P1.Y - seg.P0.Y;
            double len = seg.Length;
            var    pt  = new Coordinate(dist * dx / len, dist * dy / len);

            pm.MakePrecise(pt);
            return(pt);
        }
        /// <summary>
        /// Reads a <see cref="CoordinateSequence"/> from the stream
        /// </summary>
        /// <param name="reader">The binary reader</param>
        /// <param name="factory">The geometry factory to use for geometry creation.</param>
        /// <param name="precisionModel">The precision model used to make x- and y-ordinates precise.</param>
        /// <param name="numPoints">The number of points in the coordinate sequence.</param>
        /// <param name="receivedOrdinates">The ordinates to read. <see cref="Ordinates.XY"/> are always read.</param>
        /// <returns>The coordinate sequence</returns>
        protected CoordinateSequence ReadCoordinateSequence(BinaryReader reader, CoordinateSequenceFactory factory, PrecisionModel precisionModel, int numPoints, Ordinates receivedOrdinates)
        {
            var outputOrdinates = receivedOrdinates;

            if (HandleOrdinates != Ordinates.None)
            {
                outputOrdinates &= HandleOrdinates;
            }

            var sequence = factory.Create(numPoints, outputOrdinates);

            bool receivedZ   = receivedOrdinates.HasFlag(Ordinates.Z);
            bool receivedM   = receivedOrdinates.HasFlag(Ordinates.M);
            bool outputtingZ = outputOrdinates.HasFlag(Ordinates.Z) && sequence.HasZ;
            bool outputtingM = outputOrdinates.HasFlag(Ordinates.M) && sequence.HasM;

            for (int i = 0; i < numPoints; i++)
            {
                sequence.SetX(i, precisionModel.MakePrecise(reader.ReadDouble()));
                sequence.SetY(i, precisionModel.MakePrecise(reader.ReadDouble()));

                if (receivedZ)
                {
                    double z = reader.ReadDouble();
                    if (outputtingZ)
                    {
                        sequence.SetZ(i, z);
                    }
                }

                if (receivedM)
                {
                    double m = reader.ReadDouble();
                    if (outputtingM)
                    {
                        sequence.SetM(i, m);
                    }
                }
            }

            return(sequence);
        }
            private static double RandomOrdinate(Ordinate o, PrecisionModel pm)
            {
                switch (o)
                {
                case Ordinate.X:
                    return(pm.MakePrecise(-180 + 360 * Rnd.NextDouble()));

                case Ordinate.Y:
                    return(pm.MakePrecise(-90 + 180 * Rnd.NextDouble()));

                case Ordinate.Z:
                    return(200 * Rnd.NextDouble());

                case Ordinate.M:
                    return(200 + 200 * Rnd.NextDouble());

                default:
                    throw new NotSupportedException();
                }
            }
 /// <summary>
 /// Inserts a coordinate into the linear ring at the specified index.
 /// </summary>
 /// <param name="index">The zero-based index at which the coordinate should be inserted.</param>
 /// <param name="coordinate">The coordinate.</param>
 /// <exception cref="System.ArgumentOutOfRangeException">
 /// The index is less than 0.
 /// or
 /// Index is greater than the number of coordinates.
 /// </exception>
 public override void Insert(Int32 index, Coordinate coordinate)
 {
     if (index == 0) // insertion of new starting coordinate
     {
         _coordinates[_coordinates.Count - 1] = PrecisionModel.MakePrecise(coordinate);
         base.Insert(0, coordinate);
     }
     else // insertion of new inner coordinate
     {
         base.Insert(index, PrecisionModel.MakePrecise(coordinate));
     }
 }
        private static void PreciseCoordinateTester(PrecisionModel pm,
                                                    double x1, double y1,
                                                    double x2, double y2)
        {
            var p = new Coordinate(x1, y1);

            pm.MakePrecise(p);

            var pPrecise = new Coordinate(x2, y2);

            Assert.IsTrue(p.Equals2D(pPrecise), "Expected {0}, but got {1}", pPrecise, p);
        }
Exemple #22
0
        /// <summary>
        /// Add a hole to the polygon.
        /// </summary>
        /// <param name="hole">The hole.</param>
        /// <exception cref="System.ArgumentNullException">The hole is null.</exception>
        public virtual void AddHole(IEnumerable <Coordinate> hole)
        {
            if (hole == null)
            {
                throw new ArgumentNullException("hole", "The hole is null.");
            }

            _holes.Add(Factory.CreateLinearRing(hole.Select(coordinate => PrecisionModel.MakePrecise(coordinate))));
            _holes[_holes.Count - 1].GeometryChanged += new EventHandler(Hole_GeometryChanged); // add event handler

            OnGeometryChanged();
        }
        /// <summary>
        /// This method computes the actual value of the intersection point.
        /// To obtain the maximum precision from the intersection calculation,
        /// the coordinates are normalized by subtracting the minimum
        /// ordinate values (in absolute value).  This has the effect of
        /// removing common significant digits from the calculation to
        /// maintain more bits of precision.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="q1"></param>
        /// <param name="q2"></param>
        /// <returns></returns>
        private Coordinate Intersection(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2)
        {
            Coordinate n1     = new Coordinate(p1);
            Coordinate n2     = new Coordinate(p2);
            Coordinate n3     = new Coordinate(q1);
            Coordinate n4     = new Coordinate(q2);
            Coordinate normPt = new Coordinate();

            NormalizeToEnvCentre(n1, n2, n3, n4, normPt);

            Coordinate intPt = HCoordinate.Intersection(n1, n2, n3, n4);

            intPt.X += normPt.X;
            intPt.Y += normPt.Y;

            /*
             *
             * MD - May 4 2005 - This is still a problem.  Here is a failure case:
             *
             * LINESTRING (2089426.5233462777 1180182.3877339689, 2085646.6891757075 1195618.7333999649)
             * LINESTRING (1889281.8148903656 1997547.0560044837, 2259977.3672235999 483675.17050843034)
             * int point = (2097408.2633752143, 1144595.8008114607)
             */
            if (!IsInSegmentEnvelopes(intPt))
            {
                Trace.WriteLine("Intersection outside segment envelopes: " + intPt);
            }

            /*
             * // disabled until a better solution is found
             * if (!IsInSegmentEnvelopes(intPt))
             * {
             *  Trace.WriteLine("first value outside segment envelopes: " + intPt);
             *
             *  IteratedBisectionIntersector ibi = new IteratedBisectionIntersector(p1, p2, q1, q2);
             *  intPt = ibi.Intersection;
             * }
             * if (!IsInSegmentEnvelopes(intPt))
             * {
             *  Trace.WriteLine("ERROR - outside segment envelopes: " + intPt);
             *
             *  IteratedBisectionIntersector ibi = new IteratedBisectionIntersector(p1, p2, q1, q2);
             *  Coordinate testPt = ibi.Intersection;
             * }
             */

            if (PrecisionModel != null)
            {
                PrecisionModel.MakePrecise(intPt);
            }

            return(intPt);
        }
 public void PrecisionModelMakePreciseTest()
 {
     for (Int32 i = 0; i < _values.Length; i++)
     {
         Assert.AreEqual(_values[i], _defaultModel.MakePrecise(_values[i]));
         Assert.AreEqual(_values[i], _floatingModel.MakePrecise(_values[i]));
         Assert.AreEqual((Single)_values[i], _floatingSingleModel.MakePrecise(_values[i]));
         Assert.AreEqual(Math.Round(_values[i], 3), _fixedLargeModel1.MakePrecise(_values[i]));
         Assert.AreEqual(Math.Round(_values[i], 12), _fixedLargeModel2.MakePrecise(_values[i]));
         Assert.AreEqual(Math.Round(_values[i] / 1000) * 1000, _fixedSmallModel1.MakePrecise(_values[i]));
         Assert.AreEqual(Math.Round(_values[i] / 1000000000000) * 1000000000000, _fixedSmallModel2.MakePrecise(_values[i]));
     }
 }
        /// <summary>
        /// Round the key point if precision model is fixed.
        /// Note: return value is only copied if rounding is performed.
        /// </summary>
        static Coordinate RoundCoord(Point pt, PrecisionModel pm)
        {
            var p = pt.Coordinate;

            if (pm.IsFloating)
            {
                return(p);
            }
            var p2 = p.Copy();

            pm.MakePrecise(p2);
            return(p2);
        }
Exemple #26
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="tokens"></param>
        /// <returns></returns>
        private Coordinate GetPreciseCoordinate(IList tokens)
        {
            Coordinate coord = new Coordinate();

            coord.X = GetNextNumber(tokens);
            coord.Y = GetNextNumber(tokens);
            if (IsNumberNext(tokens))
            {
                coord.Z = GetNextNumber(tokens);
            }
            precisionModel.MakePrecise(coord);
            return(coord);
        }
Exemple #27
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LineString" /> class.
        /// </summary>
        /// <param name="source">The source coordinates.</param>
        /// <param name="factory">The factory of the line string.</param>
        /// <param name="metadata">The metadata.</param>
        /// <exception cref="System.ArgumentNullException">
        /// The source is null.
        /// or
        /// The factory is null.
        /// </exception>
        /// <exception cref="System.ArgumentException">The specified factory is invalid.</exception>
        public LineString(IEnumerable <Coordinate> source, IGeometryFactory factory, IDictionary <String, Object> metadata)
            : base(factory, metadata)
        {
            if (source == null)
            {
                _coordinates = new List <Coordinate>();
            }
            else
            {
                _coordinates = new List <Coordinate>(source.Select(coordinate => PrecisionModel.MakePrecise(coordinate)));
            }

            _version = 0;
        }
        /// <summary>
        /// Round the key point if precision model is fixed.
        /// Note: return value is only copied if rounding is performed.
        /// </summary>
        /// <param name="pt">The point to round</param>
        /// <param name="pm">The precision model to use</param>
        /// <returns>The rounded point coordinate, or null if empty</returns>
        public static Coordinate Round(Point pt, PrecisionModel pm)
        {
            if (pt.IsEmpty)
            {
                return(null);
            }
            var p = pt.Coordinate.Copy();

            if (!pm.IsFloating)
            {
                pm.MakePrecise(p);
            }
            return(p);
        }
        private static Coordinate[] CreateCircularString(Coordinate center, double radius, double startAngle,
                                                         int numPoints)
        {
            const int    numSegmentsCircle = 48;
            const double angleCircle       = 2 * Math.PI;
            const double angleStep         = angleCircle / numSegmentsCircle;

            var    sequence = new Coordinate[numPoints];
            var    pm       = new PrecisionModel(1000);
            double angle    = startAngle;

            for (int i = 0; i < numPoints; i++)
            {
                double dx = Math.Cos(angle) * radius;
                double dy = Math.Sin(angle) * radius;
                sequence[i] = new Coordinate(pm.MakePrecise(center.X + dx), pm.MakePrecise(center.Y + dy));

                angle += angleStep;
                angle %= angleCircle;
            }

            return(sequence);
        }
        private void CheckLine45(int width, int nPts, double precision)
        {
            var p1 = new Coordinate(0, width);
            var p2 = new Coordinate(width, 0);

            for (int i = 0; i <= nPts; i++)
            {
                double d  = width / (double)nPts;
                var    q  = new Coordinate(0.0 + i * d, width - i * d);
                var    pm = new PrecisionModel(precision);
                pm.MakePrecise(q);
                CheckPointOnSeg(p1, p2, q);
            }
        }