/// <summary>
        /// Ensures that a CoordinateSequence forms a valid ring,
        /// returning a new closed sequence of the correct length if required.
        /// If the input sequence is already a valid ring, it is returned
        /// without modification.
        /// If the input sequence is too short or is not closed,
        /// it is extended with one or more copies of the start point.
        /// </summary>
        /// <param name="fact">The CoordinateSequenceFactory to use to create the new sequence</param>
        /// <param name="seq">The sequence to test</param>
        /// <returns>The original sequence, if it was a valid ring, or a new sequence which is valid.</returns>
        public static CoordinateSequence EnsureValidRing(CoordinateSequenceFactory fact, CoordinateSequence seq)
        {
            int n = seq.Count;

            // empty sequence is valid
            if (n == 0)
            {
                return(seq);
            }
            // too short - make a new one
            if (n <= 3)
            {
                return(CreateClosedRing(fact, seq, 4));
            }

            bool isClosed = seq.GetOrdinate(0, 0) == seq.GetOrdinate(n - 1, 0) &&
                            seq.GetOrdinate(0, 1) == seq.GetOrdinate(n - 1, 1);

            if (isClosed)
            {
                return(seq);
            }
            // make a new closed ring
            return(CreateClosedRing(fact, seq, n + 1));
        }
示例#2
0
        /// <summary>
        /// Converts the contents of this <see cref="CoordinateBuffer"/> to a coordinate sequence.
        /// </summary>
        /// <returns>A coordinate sequence</returns>
        public CoordinateSequence ToSequence(CoordinateSequenceFactory factory = null)
        {
            // Set the coordinate sequence factory, if not assigned
            if (factory == null)
            {
                factory = _factory ?? (_factory = NtsGeometryServices.Instance.DefaultCoordinateSequenceFactory);
            }

            // determine ordinates to apply
            var  useOrdinates = _definedOrdinates & factory.Ordinates;
            bool useZ         = useOrdinates.HasFlag(Ordinates.Z);
            bool useM         = useOrdinates.HasFlag(Ordinates.M);

            // create the sequence
            var sequence = factory.Create(_coordinates.Count, useOrdinates);

            for (int i = 0; i < _coordinates.Count; i++)
            {
                var coord = _coordinates[i];
                sequence.SetX(i, coord.X);
                sequence.SetY(i, coord.Y);
                if (useZ)
                {
                    sequence.SetZ(i, coord.Z);
                }

                if (useM)
                {
                    sequence.SetM(i, coord.M);
                }
            }
            return(sequence);
        }
        /// <summary>
        /// Ensures that a CoordinateSequence forms a valid ring,
        /// returning a new closed sequence of the correct length if required.
        /// If the input sequence is already a valid ring, it is returned
        /// without modification.
        /// If the input sequence is too short or is not closed,
        /// it is extended with one or more copies of the start point.
        /// </summary>
        /// <param name="fact">The CoordinateSequenceFactory to use to create the new sequence</param>
        /// <param name="seq">The sequence to test</param>
        /// <returns>The original sequence, if it was a valid ring, or a new sequence which is valid.</returns>
        public static CoordinateSequence EnsureValidRing(CoordinateSequenceFactory fact, CoordinateSequence seq)
        {
            var n = seq.Count;

            // empty sequence is valid
            if (n == 0)
            {
                return(seq);
            }
            // too short - make a new one
            if (n <= 3)
            {
                return(CreateClosedRing(fact, seq, 4));
            }

            var isClosed = Math.Abs(seq.GetOrdinate(0, Ordinate.X) - seq.GetOrdinate(n - 1, Ordinate.X)) < double.Epsilon &&
                           Math.Abs(seq.GetOrdinate(0, Ordinate.Y) - seq.GetOrdinate(n - 1, Ordinate.Y)) < double.Epsilon;

            if (isClosed)
            {
                return(seq);
            }
            // make a new closed ring
            return(CreateClosedRing(fact, seq, n + 1));
        }
示例#4
0
        /// <summary>
        /// Converts the contents of this <see cref="CoordinateBuffer"/> to a coordinate sequence.
        /// </summary>
        /// <returns>A coordinate sequence</returns>
        public CoordinateSequence[] ToSequences(CoordinateSequenceFactory factory = null)
        {
            // Set the coordinate sequence factory, if not assigned
            if (factory == null)
            {
                factory = _factory ?? (_factory = NtsGeometryServices.Instance.DefaultCoordinateSequenceFactory);
            }

            // Copy the markers, append if necessary
            var markers = new List <int>(_markers);

            if (markers.Count == 0 || markers[markers.Count - 1] < _coordinates.Count)
            {
                markers.Add(_coordinates.Count);
            }

            // determine ordinates to apply
            var  useOrdinates = _definedOrdinates & factory.Ordinates;
            bool useZ         = useOrdinates.HasFlag(Ordinates.Z);
            bool useM         = useOrdinates.HasFlag(Ordinates.M);

            var res    = new CoordinateSequence[markers.Count];
            int offset = 0;

            //Iterate over all sections
            for (int s = 0; s < markers.Count; s++)
            {
                // compute the length of the current sequence
                int length = markers[s] - offset;

                // create a sequence of the appropriate size
                var sequence = res[s] = factory.Create(length, useOrdinates);

                // fill the sequence
                for (int i = 0; i < length; i++)
                {
                    var coord = _coordinates[offset + i];
                    sequence.SetX(i, coord.X);
                    sequence.SetY(i, coord.Y);
                    if (useZ)
                    {
                        sequence.SetZ(i, coord.Z);
                    }

                    if (useM)
                    {
                        sequence.SetM(i, coord.M);
                    }
                }
                //Move the offset
                offset = offset + length;
            }
            return(res);
        }
        private static CoordinateSequence CreateClosedRing(CoordinateSequenceFactory fact, CoordinateSequence seq, int size)
        {
            var newseq = fact.Create(size, seq.Dimension, seq.Measures);
            int n      = seq.Count;

            Copy(seq, 0, newseq, 0, n);
            // fill remaining coordinates with start point
            for (int i = n; i < size; i++)
            {
                Copy(seq, 0, newseq, i, 1);
            }
            return(newseq);
        }
        /// <summary>
        /// Extends a given <see cref="CoordinateSequence"/>.
        /// <para/>
        /// Because coordinate sequences are fix in size, extending is done by
        /// creating a new coordinate sequence of the requested size.
        /// <para/>
        /// The new, trailing coordinate entries (if any) are filled with the last
        /// coordinate of the input sequence
        /// </summary>
        /// <param name="fact">The factory to use when creating the new sequence.</param>
        /// <param name="seq">The sequence to extend.</param>
        /// <param name="size">The required size of the extended sequence</param>
        /// <returns>The extended sequence</returns>
        public static CoordinateSequence Extend(CoordinateSequenceFactory fact, CoordinateSequence seq, int size)
        {
            var newSeq = fact.Create(size, seq.Ordinates);
            int n      = seq.Count;

            Copy(seq, 0, newSeq, 0, n);
            // fill remaining coordinates with end point, if it exists
            if (n > 0)
            {
                for (int i = n; i < size; i++)
                {
                    Copy(seq, n - 1, newSeq, i, 1);
                }
            }
            return(newSeq);
        }
示例#7
0
        /// <summary>
        /// Creates a <see cref="IMultiPoint"/> using the given CoordinateSequence.
        /// A null or empty CoordinateSequence will create an empty MultiPoint.
        /// </summary>
        /// <param name="coordinates">A CoordinateSequence (possibly empty), or <c>null</c>.</param>
        /// <returns>A <see cref="IMultiPoint"/> object</returns>
        public IMultiPoint CreateMultiPoint(ICoordinateSequence coordinates)
        {
            if (coordinates == null)
            {
                coordinates = CoordinateSequenceFactory.Create(new Coordinate[] { });
            }

            List <IPoint> points = new List <IPoint>();

            for (int i = 0; i < coordinates.Count; i++)
            {
                ICoordinateSequence seq = CoordinateSequenceFactory.Create(1, coordinates.Ordinates);
                CoordinateSequences.Copy(coordinates, i, seq, 0, 1);
                points.Add(CreatePoint(seq));
            }
            return(CreateMultiPoint(points.ToArray()));
        }
示例#8
0
 /// <summary>
 /// Constructs a GeometryFactory that generates Geometries having the given
 /// CoordinateSequence implementation, a double-precision floating PrecisionModel and a
 /// spatial-reference ID of 0.
 /// </summary>
 public GeometryFactory(CoordinateSequenceFactory coordinateSequenceFactory) :
     this(new PrecisionModel(), 0, coordinateSequenceFactory)
 {
 }
示例#9
0
 /// <summary>
 /// Constructs a GeometryFactory that generates Geometries having the given
 /// PrecisionModel, spatial-reference ID, and CoordinateSequence implementation.
 /// </summary>
 public GeometryFactory(PrecisionModel precisionModel, int srid, CoordinateSequenceFactory coordinateSequenceFactory)
 {
     _precisionModel            = precisionModel;
     _coordinateSequenceFactory = coordinateSequenceFactory;
     _srid = srid;
 }
示例#10
0
 /// <summary>
 /// Creates a <see cref="IMultiPoint"/> using the given Coordinates.
 /// A null or empty array will create an empty MultiPoint.
 /// </summary>
 /// <param name="coordinates">An array (without null elements), or an empty array, or <c>null</c></param>
 /// <returns>A <see cref="IMultiPoint"/> object</returns>
 public IMultiPoint CreateMultiPoint(Coordinate[] coordinates)
 {
     return(CreateMultiPoint(coordinates != null ? CoordinateSequenceFactory.Create(coordinates) : null));
 }
示例#11
0
 /// <summary>
 /// Creates a <c>LinearRing</c> using the given <c>Coordinates</c>; a null or empty array
 /// creates an empty LinearRing. The points must form a closed and simple
 /// linestring. Consecutive points must not be equal.
 /// </summary>
 /// <param name="coordinates">An array without null elements, or an empty array, or null.</param>
 /// <returns>A <see cref="ILinearRing"/> object</returns>
 /// <exception cref="ArgumentException"> If the ring is not closed, or has too few points</exception>
 public ILinearRing CreateLinearRing(Coordinate[] coordinates)
 {
     return(CreateLinearRing(coordinates != null ? CoordinateSequenceFactory.Create(coordinates) : null));
 }
示例#12
0
 /// <summary>
 /// Creates a Point using the given Coordinate.
 /// A <c>null</c> coordinate creates an empty Geometry.
 /// </summary>
 /// <param name="coordinate">a Coordinate, or null</param>
 /// <returns>A <see cref="IPoint"/> object</returns>
 public IPoint CreatePoint(Coordinate coordinate)
 {
     return(CreatePoint(coordinate != null ? CoordinateSequenceFactory.Create(new[] { coordinate }) : null));
 }
示例#13
0
 public OgcCompliantGeometryFactory(PrecisionModel pm, int srid, CoordinateSequenceFactory factory)
     : base(pm, srid, factory)
 {
 }
示例#14
0
 /// <summary>
 /// Creates an instance of this class using the default
 /// values for <see cref="GeometryFactory.SRID"/>,
 /// <see cref="GeometryFactory.PrecisionModel"/>,
 /// but the specified <paramref name="factory"/>.
 /// </summary>
 public OgcCompliantGeometryFactory(CoordinateSequenceFactory factory)
     : base(factory)
 {
 }