/// <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)); }
/// <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)); }
/// <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); }
/// <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())); }
/// <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) { }
/// <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; }
/// <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)); }
/// <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)); }
/// <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)); }
public OgcCompliantGeometryFactory(PrecisionModel pm, int srid, CoordinateSequenceFactory factory) : base(pm, srid, factory) { }
/// <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) { }