/** * Constructs a MLineString using the given Coordinates; a null or empty * array will create an empty MLineString. * * @param coordinates * array of MCoordinate defining this geometry's vertices * @see #createLineString(com.vividsolutions.jts.geom.Coordinate[]) * @return An instance of MLineString containing the coordinates */ public MLineString CreateMLineString(MCoordinate[] coordinates) { return(CreateMLineString( coordinates != null ? CoordinateSequenceFactory.Create(coordinates) : null)); }
/// <summary> /// Use NetTopologySuite to access SQL Server spatial data. /// </summary> /// <returns> /// The options builder so that further configuration can be chained. /// </returns> public static NpgsqlDbContextOptionsBuilder UseNetTopologySuite( [NotNull] this NpgsqlDbContextOptionsBuilder optionsBuilder, [CanBeNull] CoordinateSequenceFactory coordinateSequenceFactory = null, [CanBeNull] PrecisionModel precisionModel = null, Ordinates handleOrdinates = Ordinates.None, bool geographyAsDefault = false) { Check.NotNull(optionsBuilder, nameof(optionsBuilder)); // TODO: Global-only setup at the ADO.NET level for now, optionally allow per-connection? NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite(coordinateSequenceFactory, precisionModel, handleOrdinates, geographyAsDefault); var coreOptionsBuilder = ((IRelationalDbContextOptionsBuilderInfrastructure)optionsBuilder).OptionsBuilder; var extension = coreOptionsBuilder.Options.FindExtension <NpgsqlNetTopologySuiteOptionsExtension>() ?? new NpgsqlNetTopologySuiteOptionsExtension(); if (geographyAsDefault) { extension = extension.WithGeographyDefault(); } ((IDbContextOptionsBuilderInfrastructure)coreOptionsBuilder).AddOrUpdateExtension(extension); return(optionsBuilder); }
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); }
protected static CoordinateSequence AddCoordinateToSequence(CoordinateSequence sequence, CoordinateSequenceFactory factory, double x, double y, double?z, double?m) { // Create a new sequence var newSequence = factory.Create(sequence.Count + 1, sequence.Dimension, sequence.Measures); // Copy old values int maxDim = sequence.Dimension; for (int i = 0; i < sequence.Count; i++) { for (int dim = 0; dim < maxDim; dim++) { newSequence.SetOrdinate(i, dim, sequence.GetOrdinate(i, dim)); } } // new coordinate newSequence.SetX(sequence.Count, x); newSequence.SetY(sequence.Count, y); if (z.HasValue) { newSequence.SetZ(sequence.Count, z.Value); } if (m.HasValue) { newSequence.SetM(sequence.Count, m.Value); } return(newSequence); }
public void CheckDim4(CoordinateSequenceFactory factory) { var seq = factory.Create(5, 4, 0); InitProgression(seq); Assert.AreEqual(4, seq.Dimension, "Dimension should be 4"); Assert.IsTrue(seq.HasZ, "Z should be present"); Assert.IsTrue(!seq.HasM, "M should not be present"); var coord = seq.GetCoordinate(4); Assert.AreEqual(4.0, coord.X); Assert.AreEqual(4.0, coord.Y); Assert.AreEqual(4.0, coord.Z); Assert.AreEqual(4.0, coord[Ordinate.Spatial4]); var array = seq.ToCoordinateArray(); Assert.AreEqual(coord, array[4]); Assert.IsTrue(coord != array[4]); Assert.IsTrue(IsEqual(seq, array)); var copy = factory.Create(array); Assert.IsTrue(IsEqual(copy, array)); var copy2 = factory.Create(seq); Assert.IsTrue(IsEqual(copy2, array)); }
private void CheckDim4_M1(CoordinateSequenceFactory factory) { var seq = factory.Create(5, 4, 1); InitProgression(seq); Assert.AreEqual(4, seq.Dimension, "Dimension should be 4"); Assert.IsTrue(seq.HasZ, "Z should be present"); Assert.IsTrue(seq.HasM, "M should be present"); var coord = seq.GetCoordinate(4); Assert.IsTrue(coord is CoordinateZM); var coordZM = (CoordinateZM)coord; Assert.AreEqual(4.0, coord.X); Assert.AreEqual(4.0, coord.Y); Assert.AreEqual(4.0, coordZM.Z); Assert.AreEqual(4.0, coordZM.M); var array = seq.ToCoordinateArray(); Assert.AreEqual(coord, array[4]); Assert.IsTrue(coord != array[4]); Assert.IsTrue(IsEqual(seq, array)); var copy = factory.Create(array); Assert.IsTrue(IsEqual(copy, array)); var copy2 = factory.Create(seq); Assert.IsTrue(IsEqual(copy2, array)); }
private void CheckDim2(int size, CoordinateSequenceFactory factory) { var seq = factory.Create(size, 2, 0); InitProgression(seq); Assert.AreEqual(2, seq.Dimension, "Dimension should be 2"); Assert.IsTrue(!seq.HasZ, "Z should not be present"); Assert.IsTrue(!seq.HasM, "M should not be present"); int indexLast = size - 1; double valLast = indexLast; var coord = seq.GetCoordinate(indexLast); Assert.IsTrue(coord.GetType() == typeof(Coordinate)); Assert.AreEqual(valLast, coord.X); Assert.AreEqual(valLast, coord.Y); var array = seq.ToCoordinateArray(); Assert.AreEqual(coord, array[indexLast]); Assert.IsTrue(coord != array[indexLast]); Assert.IsTrue(IsEqual(seq, array)); var copy = factory.Create(array); Assert.IsTrue(IsEqual(copy, array)); var copy2 = factory.Create(seq); Assert.IsTrue(IsEqual(copy2, array)); }
internal NetTopologySuiteTypeHandlerResolver( NpgsqlConnector connector, CoordinateSequenceFactory coordinateSequenceFactory, PrecisionModel precisionModel, Ordinates handleOrdinates, bool geographyAsDefault) { _databaseInfo = connector.DatabaseInfo; _geographyAsDefault = geographyAsDefault; var(pgGeometryType, pgGeographyType) = (PgType("geometry"), PgType("geography")); // TODO: In multiplexing, these are used concurrently... not sure they're thread-safe :( var reader = new PostGisReader(coordinateSequenceFactory, precisionModel, handleOrdinates); var writer = new PostGisWriter(); if (pgGeometryType is not null) { _geometryHandler = new NetTopologySuiteHandler(pgGeometryType, reader, writer); } if (pgGeographyType is not null) { _geographyHandler = new NetTopologySuiteHandler(pgGeographyType, reader, writer); } }
/// <summary> /// Initialize reader with the given <c>GeometryFactory</c>. /// </summary> /// <param name="coordinateSequenceFactory"></param> /// <param name="precisionModel"> </param> /// <param name="handleOrdinates">The ordinates to handle</param> public PostGisReader(CoordinateSequenceFactory coordinateSequenceFactory, PrecisionModel precisionModel, Ordinates handleOrdinates) { _coordinateSequenceFactory = coordinateSequenceFactory; _precisionModel = precisionModel; HandleOrdinates = handleOrdinates; }
private static int GetDimensionAndMeasures(Coordinate[] coords, out int measures) { int dimension; (_, dimension, measures) = CoordinateSequenceFactory.GetCommonSequenceParameters(coords); return(dimension); }
private void CheckDim3(CoordinateSequenceFactory factory) { var seq = factory.Create(5, 3, 0); InitProgression(seq); Assert.AreEqual(3, seq.Dimension, "Dimension should be 3"); Assert.IsTrue(seq.HasZ, "Z should be present"); Assert.IsTrue(!seq.HasM, "M should not be present"); var coord = seq.GetCoordinate(4); Assert.IsTrue(coord.GetType() == typeof(CoordinateZ)); var coordZ = (CoordinateZ)coord; Assert.AreEqual(4.0, coord.X); Assert.AreEqual(4.0, coord.Y); Assert.AreEqual(4.0, coordZ.Z); var array = seq.ToCoordinateArray(); Assert.AreEqual(coord, array[4]); Assert.IsTrue(coord != array[4]); Assert.IsTrue(IsEqual(seq, array)); var copy = factory.Create(array); Assert.IsTrue(IsEqual(copy, array)); var copy2 = factory.Create(seq); Assert.IsTrue(IsEqual(copy2, array)); }
private static void DoTestIsRing(CoordinateSequenceFactory factory, int dimension) { // arrange var ring = CreateCircle(factory, dimension, new Coordinate(), 5); var noRing = CreateCircularString(factory, dimension, new Coordinate(), 5, 0.1, 22); var empty = CreateAlmostRing(factory, dimension, 0); var incomplete1 = CreateAlmostRing(factory, dimension, 1); var incomplete2 = CreateAlmostRing(factory, dimension, 2); var incomplete3 = CreateAlmostRing(factory, dimension, 3); var incomplete4a = CreateAlmostRing(factory, dimension, 4); var incomplete4b = CoordinateSequences.EnsureValidRing(factory, incomplete4a); // act bool isRingRing = CoordinateSequences.IsRing(ring); bool isRingNoRing = CoordinateSequences.IsRing(noRing); bool isRingEmpty = CoordinateSequences.IsRing(empty); bool isRingIncomplete1 = CoordinateSequences.IsRing(incomplete1); bool isRingIncomplete2 = CoordinateSequences.IsRing(incomplete2); bool isRingIncomplete3 = CoordinateSequences.IsRing(incomplete3); bool isRingIncomplete4a = CoordinateSequences.IsRing(incomplete4a); bool isRingIncomplete4b = CoordinateSequences.IsRing(incomplete4b); // assert Assert.IsTrue(isRingRing); Assert.IsTrue(!isRingNoRing); Assert.IsTrue(isRingEmpty); Assert.IsTrue(!isRingIncomplete1); Assert.IsTrue(!isRingIncomplete2); Assert.IsTrue(!isRingIncomplete3); Assert.IsTrue(!isRingIncomplete4a); Assert.IsTrue(isRingIncomplete4b); }
private static void DoTestCopy(CoordinateSequenceFactory factory, int dimension) { // arrange var sequence = CreateSequenceFromOrdinates(factory, dimension); if (sequence.Count <= 7) { TestContext.WriteLine("sequence has a size of " + sequence.Count + ". Execution of this test needs a sequence " + "with more than 6 coordinates."); return; } var fullCopy = factory.Create(sequence.Count, dimension, 0); var partialCopy = factory.Create(sequence.Count - 5, dimension, 0); // act CoordinateSequences.Copy(sequence, 0, fullCopy, 0, sequence.Count); CoordinateSequences.Copy(sequence, 2, partialCopy, 0, partialCopy.Count); // assert for (int i = 0; i < fullCopy.Count; i++) { CheckCoordinateAt(sequence, i, fullCopy, i, dimension); } for (int i = 0; i < partialCopy.Count; i++) { CheckCoordinateAt(sequence, 2 + i, partialCopy, i, dimension); } // ToDo test if dimensions don't match }
protected override GeometryFactory CreateGeometryFactoryCore(PrecisionModel precisionModel, int srid, CoordinateSequenceFactory coordinateSequenceFactory) { return(new GeometryFactoryEx(precisionModel, srid, coordinateSequenceFactory) { OrientationOfExteriorRing = LinearRingOrientation.CCW }); }
private void CheckAll(CoordinateSequenceFactory factory) { CheckDim2(1, factory); CheckDim2(5, factory); CheckDim3(factory); CheckDim3_M1(factory); CheckDim4_M1(factory); CheckDimInvalid(factory); }
/// <summary> /// Reads a coordinate sequence from the stream, which length is not yet known. /// </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="receivedOrdinates">The ordinates to read. <see cref="Ordinates.XY"/> are always read.</param> /// <returns>The coordinate sequence</returns> protected CoordinateSequence ReadCoordinateSequenceRing(BinaryReader reader, CoordinateSequenceFactory factory, PrecisionModel precisionModel, Ordinates receivedOrdinates) { int numPoints = reader.ReadInt32(); var sequence = ReadCoordinateSequence(reader, factory, precisionModel, numPoints, receivedOrdinates); return(!RepairRings || CoordinateSequences.IsRing(sequence) ? sequence : CoordinateSequences.EnsureValidRing(factory, sequence)); }
public void General(CoordinateSequenceFactory factory) { var geomFactory = new GeometryFactory(pm, 0, factory); for (int i = 0; i < testset.Length; i++) { General(geomFactory, testset[i], -1); General(geomFactory, testset[i], SRID); } }
/// <summary> /// Creates an instance of this class, using the provided <see cref="CoordinateSequenceFactory"/>, /// <see cref="PrecisionModel"/>, a spatial reference Id (<paramref name="srid"/>) and /// a <see cref="Geometries.GeometryOverlay"/>. /// </summary> /// <param name="coordinateSequenceFactory">The coordinate sequence factory to use.</param> /// <param name="precisionModel">The precision model.</param> /// <param name="srid">The default spatial reference ID</param> /// <param name="geometryOverlay">The geometry overlay function set to use.</param> /// <param name="coordinateEqualityComparer">The equality comparer for coordinates</param> public NtsGeometryServices(CoordinateSequenceFactory coordinateSequenceFactory, PrecisionModel precisionModel, int srid, GeometryOverlay geometryOverlay, CoordinateEqualityComparer coordinateEqualityComparer) { DefaultCoordinateSequenceFactory = coordinateSequenceFactory ?? throw new ArgumentNullException(nameof(coordinateSequenceFactory)); DefaultPrecisionModel = precisionModel ?? throw new ArgumentNullException(nameof(precisionModel)); DefaultSRID = srid; GeometryOverlay = geometryOverlay ?? throw new ArgumentNullException(nameof(geometryOverlay)); CoordinateEqualityComparer = coordinateEqualityComparer ?? throw new ArgumentNullException(nameof(coordinateEqualityComparer)); }
public WKBReader(NtsGeometryServices services) { services = services ?? NtsGeometryServices.Instance; _geometryServices = services; _precisionModel = services.DefaultPrecisionModel; _sequenceFactory = services.DefaultCoordinateSequenceFactory; HandleSRID = true; HandleOrdinates = AllowedOrdinates; }
private void CheckDimInvalid(CoordinateSequenceFactory factory) { try { var seq = factory.Create(5, 2, 1); Assert.Fail("Dimension=2/Measure=1 (XM) not supported"); } catch (ArgumentException) { } }
public NetTopologySuiteTypeHandlerResolverFactory( CoordinateSequenceFactory?coordinateSequenceFactory, PrecisionModel?precisionModel, Ordinates handleOrdinates, bool geographyAsDefault) { _coordinateSequenceFactory = coordinateSequenceFactory ?? NtsGeometryServices.Instance.DefaultCoordinateSequenceFactory;; _precisionModel = precisionModel ?? NtsGeometryServices.Instance.DefaultPrecisionModel; _handleOrdinates = handleOrdinates == Ordinates.None ? _coordinateSequenceFactory.Ordinates : handleOrdinates; _geographyAsDefault = geographyAsDefault; }
private static CoordinateSequence CreateSequenceFromOrdinates(CoordinateSequenceFactory csFactory, int dim) { var sequence = csFactory.Create(ordinateValues.Length, dim, 0); for (int i = 0; i < ordinateValues.Length; i++) { sequence.SetOrdinate(i, Ordinate.X, ordinateValues[i][0]); sequence.SetOrdinate(i, Ordinate.Y, ordinateValues[i][1]); } return(FillNonPlanarDimensions(sequence)); }
public WKTReadWriteTest() { // We deliberately chose a coordinate sequence factory that can handle 4 dimensions _csFactory = PackedCoordinateSequenceFactory.DoubleFactory; _geometryFactory = new GeometryFactory(_csFactory); _reader = new WKTReader(_geometryFactory); _writer = new WKTWriter(4) { OutputOrdinates = Ordinates.XY }; }
public WKTReadWriteTest() { // We deliberately chose a coordinate sequence factory that can handle 4 dimensions _csFactory = PackedCoordinateSequenceFactory.DoubleFactory; var gs = new NtsGeometryServices(_csFactory, PrecisionModel.Floating.Value, 0); _reader = new WKTReader(gs); _writer = new WKTWriter(4) { OutputOrdinates = Ordinates.XY }; }
private static void DoTestIndexOf(CoordinateSequenceFactory factory, int dimension) { // arrange var sequence = CreateSequenceFromOrdinates(factory, dimension); // act & assert var coordinates = sequence.ToCoordinateArray(); for (int i = 0; i < sequence.Count; i++) { Assert.AreEqual(i, CoordinateSequences.IndexOf(coordinates[i], sequence)); } }
private static CoordinateSequence CreateTestSequence(CoordinateSequenceFactory csFactory, int size, int dim) { var cs = csFactory.Create(size, dim, 0); // initialize with a data signature where coords look like [1, 10, 100, ...] for (int i = 0; i < size; i++) { for (int d = 0; d < dim; d++) { cs.SetOrdinate(i, d, i * Math.Pow(10, d)); } } return(cs); }
private static CoordinateSequence CreateCircle(CoordinateSequenceFactory factory, int dimension, Coordinate center, double radius) { // Get a complete circular string var res = CreateCircularString(factory, dimension, center, radius, 0d, 49); // ensure it is closed for (int i = 0; i < dimension; i++) { res.SetOrdinate(48, (Ordinate)i, res.GetOrdinate(0, (Ordinate)i)); } return(res); }
/// <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 CoordinateSequence EnsureClosedSequence(CoordinateSequence sequence, CoordinateSequenceFactory 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); int 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.SetX(lastIndex, start.X); sequence.SetY(lastIndex, start.Y); return(sequence); } // 2. Close the sequence by adding a new point, this is heavier var newSequence = factory.Create(sequence.Count + 1, sequence.Dimension, sequence.Measures); int maxDim = sequence.Dimension; for (int i = 0; i < sequence.Count; i++) { for (int dim = 0; dim < maxDim; dim++) { newSequence.SetOrdinate(i, dim, sequence.GetOrdinate(i, dim)); } } for (int dim = 0; dim < maxDim; dim++) { newSequence.SetOrdinate(sequence.Count, dim, sequence.GetOrdinate(0, dim)); } return(newSequence); }
private static void DoTestReverse(CoordinateSequenceFactory factory, int dimension) { // arrange var sequence = CreateSequenceFromOrdinates(factory, dimension); var reversed = sequence.Copy(); // act CoordinateSequences.Reverse(reversed); // assert for (int i = 0; i < sequence.Count; i++) { CheckCoordinateAt(sequence, i, reversed, sequence.Count - i - 1, dimension); } }
/// <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 virtual 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++) { points.Add(CreatePoint(coordinates.GetCoordinate(i))); } return(new MultiPoint(points.ToArray())); }