Exemplo n.º 1
0
 /**
  * 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));
 }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 4
0
        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
        }
Exemplo n.º 14
0
 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);
            }
        }
Exemplo n.º 18
0
 /// <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));
 }
Exemplo n.º 19
0
        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));
        }
Exemplo n.º 23
0
        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);
            }
        }
Exemplo n.º 30
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 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()));
        }