/// <summary>
 /// Function to read a <see cref="IPoint"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
 /// </summary>
 /// <param name="reader">The reader to use</param>
 /// <param name="ordinates">The ordinates to read</param>
 /// <returns>The read point geometry</returns>
 protected IGeometry ReadPoint(BinaryReader reader, Ordinates ordinates)
 {
     var buffer = new CoordinateBuffer(1, ShapeFileConstants.NoDataBorder, true);
     ReadCoordinates(reader, 1, new[] { 0 }, ordinates, buffer);
     IGeometry point = _factory.CreatePoint(buffer.ToSequence());
     return point;
 }
Example #2
0
        /// <summary>
        /// Translates the <paramref name="ordinates"/>-flag to a number of dimensions.
        /// </summary>
        /// <param name="ordinates">The ordinates flag</param>
        /// <returns>The number of dimensions</returns>
        public static int OrdinatesToDimension(Ordinates ordinates)
        {
            var ret = 2;
            if ((ordinates & Ordinates.Z) != 0) ret++;
            if ((ordinates & Ordinates.M) != 0) ret++;

            return ret;
        }
 /// <summary>
 /// Writes a binary encoded PostGIS of the given <paramref name="geometry"/> to to an array of bytes.
 /// </summary>
 /// <param name="geometry">The geometry</param>
 /// <param name="ordinates">The ordinates of each geometry's coordinate. <see cref="Ordinates.XY"/> area always written.</param>
 /// <returns>An array of bytes.</returns>
 private byte[] Write(IGeometry geometry, Ordinates ordinates)
 {
     var coordinateSpace = 8*OrdinatesUtility.OrdinatesToDimension(ordinates);
     var bytes = GetBytes(geometry, coordinateSpace);
     Write(geometry, ordinates, new MemoryStream(bytes));
     
     return bytes;
 }
Example #4
0
 /// <summary>
 /// Converts an <see cref="Ordinates"/> encoded flag to an array of <see cref="Ordinate"/> indices.
 /// </summary>
 /// <param name="ordinates">The ordinate flags</param>
 /// <param name="maxEval">The maximum oridinate flag that is to be checked</param>
 /// <returns>The ordinate indices</returns>
 public static Ordinate[] ToOrdinateArray(Ordinates ordinates, int maxEval = 4)
 {
     if (maxEval > 32) maxEval = 32;
     var intOrdinates = (int) ordinates;
     var ordinateList = new List<Ordinate>(maxEval);
     for (var i = 0; i < maxEval; i++)
     {
         if ((intOrdinates & (1<<i)) != 0) ordinateList.Add((Ordinate)i);
     }
     return ordinateList.ToArray();
 }
        /// <summary>
        /// Function to read a <see cref="ILineString"/> or <see cref="IMultiLineString"/> from a ShapeFile stream using the specified <paramref name="reader"/>.
        /// </summary>
        /// <param name="reader">The reader to use</param>
        /// <param name="ordinates">The ordinates to read</param>
        /// <returns>The read lineal geometry</returns>
        protected IGeometry ReadLineString(BinaryReader reader, Ordinates ordinates)
        {
            /*var bbox = */ ReadBoundingBox(reader); // Jump boundingbox

            var numParts = ReadNumParts(reader);
            var numPoints = ReadNumPoints(reader);
            var indexParts = ReadIndexParts(reader, numParts, numPoints);

            var buffer = new CoordinateBuffer(numPoints, ShapeFileConstants.NoDataBorder, true);
            ReadCoordinates(reader, numPoints, indexParts, ordinates, buffer);

            if (numParts == 1)
                return _factory.CreateLineString(buffer.ToSequence());
            return CreateMultiLineString(buffer.ToSequences());
        }
 /// <summary>
 /// Writes a binary encoded PostGIS of the given <paramref name="geometry"/> to <paramref name="stream"/>.
 /// </summary>
 /// <param name="geometry">The geometry</param>
 /// <param name="ordinates">The ordinates of each geometry's coordinate. <see cref="Ordinates.XY"/> area always written.</param>
 /// <param name="stream">The stream to write to</param>
 private void Write(IGeometry geometry, Ordinates ordinates, Stream stream)
 {
     BinaryWriter writer = null;
     try
     {
         writer = EncodingType == ByteOrder.LittleEndian
             ? new BinaryWriter(stream) 
             : new BEBinaryWriter(stream);
         Write(geometry, ordinates, EncodingType, writer);
     }
     finally
     {
         if (writer != null)
             writer.Close();
     }
 }
        /// <summary>
        /// Constructs a sequence of a given size, populated with new Coordinates.
        /// </summary>
        /// <param name="size">The size of the sequence to create.</param>
        /// <param name="ordinates">The kind of ordinates.</param>
        public DotSpatialAffineCoordinateSequence(int size, Ordinates ordinates)
        {
            _xy = new double[2 * size];
            _ordinates = ordinates;
            if ((ordinates & Ordinates.Z) != 0)
            {
                _z = new double[size];
                for (var i = 0; i < size; i++)
                    _z[i] = Coordinate.NullOrdinate;
            }

            if ((ordinates & Ordinates.M) != 0)
            {
                _m = new double[size];
                for (var i = 0; i < size; i++)
                    _m[i] = Coordinate.NullOrdinate;
            }
        }
        /// <summary>
        /// Inititalizes this instance based on an <see cref="OgcGeometryType"/> and an SRID indicator
        /// </summary>
        /// <param name="ogcGeometryType">The OGC geometry type</param>
        /// <param name="ordinates">The ordinates flag.</param>
        /// <param name="hasSrid">Indicator if a SRID is supplied.</param>
        public GeometryType(OgcGeometryType ogcGeometryType, Ordinates ordinates, bool hasSrid)
        {
            _geometrytype = (uint) ogcGeometryType;
            
            if ((ordinates & Ordinates.Z) != 0)
            {
                HasWkbZ = true;
                HasEwkbM = true;
            }

            if ((ordinates & Ordinates.M) != 0)
            {
                HasWkbZ = true;
                HasEwkbM = true;
            }

            HasEwkbSrid = hasSrid;
        }
        /// <summary>
        /// Creates an instance of this class
        /// </summary>
        /// <param name="coordinates">The</param>
        public DotSpatialAffineCoordinateSequence(IList<Coordinate> coordinates)
        {
            if (coordinates == null)
            {
                _xy = new double[0];
                return;
            }
            _xy = new double[2 * coordinates.Count];
            _z = new double[coordinates.Count];

            var j = 0;
            for (var i = 0; i < coordinates.Count; i++)
            {
                XY[j++] = coordinates[i].X;
                XY[j++] = coordinates[i].Y;
                Z[i] = coordinates[i].Z;
            }

            _ordinates = Ordinates.XYZ;
        }
        public PostGis2GeometryHeader(IGeometry geometry, Ordinates handleOrdinates, bool isGeodetic)
        {
            Srid = geometry.SRID;

            HasM = (handleOrdinates & Ordinates.Z) == Ordinates.Z; // geometry.HasM();
            HasZ = (handleOrdinates & Ordinates.M) == Ordinates.M; // geometry.HasZ();

            if (geometry.OgcGeometryType != OgcGeometryType.Point)
            {
                HasBoundingBox = true;
                _envelope = geometry.EnvelopeInternal;
                if (HasM)
                    _mInterval = geometry.GetMRange();
                if (HasZ | isGeodetic)
                    _zInterval = geometry.GetZRange();
            }

            ComputeSize(geometry);
            _factory = geometry.Factory;
        }
        protected void WriteCoordinates(ICoordinateSequence sequence, BinaryWriter writer, Ordinates ordinates)
        {
            for (var i = 0; i < sequence.Count; i++)
            {
                writer.Write(sequence.GetX(i));
                writer.Write(sequence.GetY(i));
            }

            if ((ordinates & Ordinates.Z) == Ordinates.Z)
            {
                WriteInterval(sequence, Ordinate.Z, writer);                
                for (var i = 0; i < sequence.Count; i++)
                    writer.Write(GetOrdinate(sequence, Ordinate.Z, i));
            }

            if ((ordinates & Ordinates.M) == Ordinates.M)
            {
                WriteInterval(sequence, Ordinate.M, writer);
                for (var i = 0; i < sequence.Count; i++)
                    writer.Write(GetOrdinate(sequence, Ordinate.M, i));
            }
        }
Example #12
0
        /// <summary>
        /// Writes a linestring without the preceding type information.
        /// </summary>
        /// <param name="linestring"></param>
        /// <param name="ordinates"></param>
        /// <param name="reversePointOrder"></param>
        protected void WriteLinestringCore([NotNull] IPointList linestring,
                                           Ordinates ordinates,
                                           bool reversePointOrder = false)
        {
            int pointCount = linestring.PointCount;

            Writer.Write(pointCount);

            if (reversePointOrder)
            {
                for (int i = pointCount - 1; i >= 0; i--)
                {
                    WritePointCore(linestring, i, ordinates);
                }
            }
            else
            {
                for (int i = 0; i < pointCount; i++)
                {
                    WritePointCore(linestring, i, ordinates);
                }
            }
        }
Example #13
0
            private static IGeometry CreateMultiLineString(Ordinates ordinates, bool empty)
            {
                if (empty)
                {
                    Factory.CreateMultiLineString(null);
                }

                int numLineStrings = Rnd.Next(0, 11);

                if (numLineStrings <= 2)
                {
                    numLineStrings = 0;
                }

                var lineString = new ILineString[numLineStrings];

                for (int i = 0; i < numLineStrings; i++)
                {
                    lineString[i] = (ILineString)CreateLineString(ordinates, false);
                }

                return(Factory.CreateMultiLineString(lineString));
            }
Example #14
0
        /// <summary>
        /// Sets the value for a given ordinate of a coordinate in this sequence.
        /// </summary>
        /// <param name="index">The coordinate index in the sequence.</param>
        /// <param name="ordinate">The ordinate index in the coordinate (in range [0, dimension-1]).</param>
        /// <param name="value">The new ordinate value.</param>
        public void SetOrdinate(int index, Ordinates ordinate, double value)
        {
            switch (ordinate)
            {
            case Ordinates.X:
                coordinates[index].X = value;
                break;

            case Ordinates.Y:
                coordinates[index].Y = value;
                break;

            case Ordinates.Z:
                coordinates[index].Z = value;
                break;

            case Ordinates.M:
                coordinates[index].M = value;
                break;

            default:
                break;
            }
        }
        /// <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(
            this NpgsqlDbContextOptionsBuilder optionsBuilder,
            CoordinateSequenceFactory? coordinateSequenceFactory = null,
            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;
        }
Example #16
0
        public byte[] WriteMultiLinestring([NotNull] MultiLinestring multiLinestring,
                                           Ordinates ordinates = Ordinates.Xyz)
        {
            // TODO: Initialize with the proper size or allow providing the actual byte[]
            MemoryStream memoryStream = InitializeWriter();

            if (multiLinestring.Count == 1)
            {
                WriteLinestring(multiLinestring.GetLinestring(0), ordinates);
            }
            else
            {
                WriteWkbType(WkbGeometryType.MultiLineString, ordinates);

                Writer.Write(multiLinestring.Count);

                foreach (Linestring linestring in multiLinestring.GetLinestrings())
                {
                    WriteLinestring(linestring, ordinates);
                }
            }

            return(memoryStream.ToArray());
        }
        /**
         * @see com.vividsolutions.jts.geom.CoordinateSequence#SetOrdinate(int,int,double)
         */
        public void SetOrdinate(int index, Ordinates ordinateIndex, double value)
        {
            switch (ordinateIndex)
            {
            case Ordinates.X:
                coordinates[index].X = value;
                break;

            case Ordinates.Y:
                coordinates[index].Y = value;
                break;

            case Ordinates.Z:
                coordinates[index].Z = value;
                break;

            case Ordinates.M:
                coordinates[index].M = value;
                break;

            default:
                throw new ArgumentException("invalid ordinateIndex");
            }
        }
Example #18
0
        /**
         * TODO: I'd like to see this method added to the base Coordinate class Sets
         * the value for a given ordinate. This should be specified using the
         * CoordinateSequence ordinate index constants.
         *
         * @param ordinateIndex
         *            the desired ordinate index.
         * @param value
         *            the new ordinate value
         * @throws IllegalArgumentException
         *             if the ordinateIndex value is incorrect
         * @see #GetOrdinate(int)
         */

        public void SetOrdinate(Ordinates ordinateIndex, double value)
        {
            switch (ordinateIndex)
            {
            case Ordinates.X:
                this.X = value;
                break;

            case Ordinates.Y:
                this.Y = value;
                break;

            case Ordinates.Z:
                this.Z = value;
                break;

            case Ordinates.M:
                M = value;
                break;

            default:
                throw new ArgumentException("ordinateIndex");
            }
        }
Example #19
0
        public PostGis2GeometryHeader(IGeometry geometry, Ordinates handleOrdinates, bool isGeodetic)
        {
            Srid = geometry.SRID;

            HasM = (handleOrdinates & Ordinates.Z) == Ordinates.Z; // geometry.HasM();
            HasZ = (handleOrdinates & Ordinates.M) == Ordinates.M; // geometry.HasZ();

            if (geometry.OgcGeometryType != OgcGeometryType.Point)
            {
                HasBoundingBox = true;
                _envelope      = geometry.EnvelopeInternal;
                if (HasM)
                {
                    _mInterval = geometry.GetMRange();
                }
                if (HasZ | isGeodetic)
                {
                    _zInterval = geometry.GetZRange();
                }
            }

            ComputeSize(geometry);
            _factory = geometry.Factory;
        }
Example #20
0
        public byte[] WriteMultipatch([NotNull] IMultiPatch multipatch,
                                      bool groupPartsByPointIDs = false)
        {
            Assert.True(GeometryUtils.IsRingBasedMultipatch(multipatch),
                        "Unsupported (non-ring-based) multipatch.");

            // TODO: Initialize with the proper size or allow providing the actual byte[]
            MemoryStream memoryStream = InitializeWriter();

            Ordinates ordinates = GetOrdinatesDimension(multipatch);

            WriteWkbType(WkbGeometryType.MultiSurface, ordinates);

            var geometryParts =
                GeometryPart.FromGeometry(multipatch, groupPartsByPointIDs).ToList();

            Writer.Write(geometryParts.Count);

            foreach (GeometryPart part in geometryParts)
            {
                WriteWkbType(WkbGeometryType.PolyhedralSurface, ordinates);

                List <List <IRing> > polygonGroup = GetPolygons(multipatch, part).ToList();

                Writer.Write(polygonGroup.Count);

                foreach (List <IRing> rings in polygonGroup)
                {
                    WriteWkbType(WkbGeometryType.Polygon, ordinates);

                    WriteLineStringsCore(GetAsPointList(rings).ToList(), ordinates);
                }
            }

            return(memoryStream.ToArray());
        }
            private static IGeometry CreateMultiLineString(Ordinates ordinates, bool empty)
            {
                if (empty)
                {
                    Factory.CreateMultiLineString(null);
                }

                var numLineStrings = Rnd.Next(0, 11);
                if (numLineStrings <= 2)
                    numLineStrings = 0;

                var lineString = new ILineString[numLineStrings];
                for (var i = 0; i < numLineStrings; i++)
                    lineString[i] = (ILineString)CreateLineString(ordinates, false);

                return Factory.CreateMultiLineString(lineString);
            }
Example #22
0
 public static PropertyBuilder <TProperty> ForSqliteHasDimension <TProperty>(
     [NotNull] this PropertyBuilder <TProperty> propertyBuilder,
     Ordinates ordinates)
 => propertyBuilder.HasSpatialDimension(ordinates);
Example #23
0
 /// <summary>
 /// Initializes writer with the specified byte order.
 /// </summary>
 /// <param name="encodingType">Encoding type</param>
 public PostGisWriter(ByteOrder encodingType)
 {
     EncodingType    = encodingType;
     HandleOrdinates = Ordinates.None;
 }
Example #24
0
 /// <summary>
 /// Writes a 'MultiPolygon' to the stream.
 /// </summary>
 /// <param name="multiPolygon">The polygon to write.</param>
 /// <param name="ordinates">The ordinates to write. <see cref="Ordinates.XY"/> are always written.</param>
 /// <param name="byteOrder">The byte order.</param>
 /// <param name="writer">The writer to use.</param>
 private void Write(IMultiPolygon multiPolygon, Ordinates ordinates, ByteOrder byteOrder, BinaryWriter writer)
 {
     WriteHeader(PostGisGeometryType.MultiPolygon, HandleSRID ? multiPolygon.SRID : -1, ordinates, byteOrder, writer);
     writer.Write(multiPolygon.NumGeometries);
     Write(multiPolygon.Geometries, ordinates, byteOrder, writer);
 }
Example #25
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="linearRing"></param>
 /// <param name="ordinates"></param>
 /// <param name="writer"></param>
 private void Write(ILinearRing linearRing, Ordinates ordinates, BinaryWriter writer)
 {
     Write(linearRing.CoordinateSequence, ordinates, writer, false);
 }
Example #26
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="byteOrder"></param>
 /// <param name="point"></param>
 /// <param name="ordinates"></param>
 /// <param name="writer"></param>
 private void Write(IPoint point, Ordinates ordinates, ByteOrder byteOrder, BinaryWriter writer)
 {
     WriteHeader(PostGisGeometryType.Point, HandleSRID ? point.SRID : -1, ordinates, byteOrder, writer);
     Write(point.CoordinateSequence, ordinates, writer, true);
 }
Example #27
0
		/**
	 * TODO: I'd like to see this method added to the base Coordinate class Sets
	 * the value for a given ordinate. This should be specified using the
	 * CoordinateSequence ordinate index constants.
	 * 
	 * @param ordinateIndex
	 *            the desired ordinate index.
	 * @param value
	 *            the new ordinate value
	 * @throws IllegalArgumentException
	 *             if the ordinateIndex value is incorrect
	 * @see #GetOrdinate(int)
	 */

		public void SetOrdinate(Ordinates ordinateIndex, double value)
		{
			switch (ordinateIndex)
			{
				case Ordinates.X:
					this.X = value;
					break;
				case Ordinates.Y:
					this.Y = value;
					break;
				case Ordinates.Z:
					this.Z = value;
					break;
				case Ordinates.M:
					M = value;
					break;
				default:
					throw new ArgumentException("ordinateIndex");
			}
		}
 /// <summary>
 /// Creates a <see cref="ICoordinateSequence" /> of the specified size and ordinates.
 /// For this to be useful, the <see cref="ICoordinateSequence" /> implementation must be mutable.
 /// </summary>
 /// <param name="size">The number of coordinates.</param>
 /// <param name="ordinates">
 /// The ordinates each coordinate has. <see cref="GeoAPI.Geometries.Ordinates.XY"/> is fix, 
 /// <see cref="GeoAPI.Geometries.Ordinates.Z"/> and <see cref="GeoAPI.Geometries.Ordinates.M"/> can be set.
 /// </param>
 /// <returns>A coordinate sequence.</returns>
 public ICoordinateSequence Create(int size, Ordinates ordinates)
 {
     return new DotSpatialAffineCoordinateSequence(size, Ordinates & ordinates);
 }
            private static IGeometry CreateMultiPolygon(Ordinates ordinates, bool empty)
            {
                if (empty)
                {
                    Factory.CreateMultiPolygon(null);
                }

                switch (Rnd.Next(2))
                {
                    case 0:
                        var numPolygons = Rnd.Next(4);
                        var polygons = new IPolygon[numPolygons];
                        for (var i = 0; i < numPolygons; i++)
                            polygons[i] = (IPolygon)CreatePolygon(ordinates, false);
                        return Factory.BuildGeometry(new Collection<IGeometry>(polygons)).Union();

                    case 1:
                        polygons = new IPolygon[2];
                        var radius = 5 * Rnd.NextDouble();
                        var x = RandomOrdinate(Ordinate.X, Factory.PrecisionModel);
                        var y = RandomOrdinate(Ordinate.Y, Factory.PrecisionModel);
                        var shell = CreateCircleRing(ordinates, x, y, radius);
                        var hole = CreateCircleRing(ordinates, x, y, 0.66 * radius, true);
                        polygons[0] = Factory.CreatePolygon(shell, new[] { hole });
                        shell = CreateCircleRing(ordinates, x, y, 0.5 * radius);
                        hole = CreateCircleRing(ordinates, x, y, 0.15 * radius, true);
                        polygons[1] = Factory.CreatePolygon(shell, new[] { hole });
                        return Factory.CreateMultiPolygon(polygons);

                    default:
                        throw new NotSupportedException();
                }
            }
            private static ILinearRing CreateRectangleRing(Ordinates ordinates, double x, double y, double width, double height, bool reverse = false)
            {
                var dx = Factory.PrecisionModel.MakePrecise(width / 2);
                var dy = Factory.PrecisionModel.MakePrecise(height / 2);

                var seq = CsFactory.Create(5, ordinates);

                seq.SetOrdinate(0, Ordinate.X, Factory.PrecisionModel.MakePrecise(x - dx));
                seq.SetOrdinate(0, Ordinate.Y, Factory.PrecisionModel.MakePrecise(y - dy));
                seq.SetOrdinate(1, Ordinate.X, Factory.PrecisionModel.MakePrecise(x - dx));
                seq.SetOrdinate(1, Ordinate.Y, Factory.PrecisionModel.MakePrecise(y + dy));
                seq.SetOrdinate(2, Ordinate.X, Factory.PrecisionModel.MakePrecise(x + dx));
                seq.SetOrdinate(2, Ordinate.Y, Factory.PrecisionModel.MakePrecise(y + dy));
                seq.SetOrdinate(3, Ordinate.X, Factory.PrecisionModel.MakePrecise(x + dx));
                seq.SetOrdinate(3, Ordinate.Y, Factory.PrecisionModel.MakePrecise(y - dy));
                seq.SetOrdinate(4, Ordinate.X, Factory.PrecisionModel.MakePrecise(x - dx));
                seq.SetOrdinate(4, Ordinate.Y, Factory.PrecisionModel.MakePrecise(y - dy));

                if ((ordinates & (Ordinates.Z | Ordinates.M)) != Ordinates.None)
                {
                    var k = 0;
                    for (; k < 4; k++)
                    {
                        if ((ordinates & Ordinates.Z) == Ordinates.Z)
                            seq.SetOrdinate(k, Ordinate.Z, RandomOrdinate(Ordinate.Z, Factory.PrecisionModel));
                        if ((ordinates & Ordinates.Z) == Ordinates.Z)
                            seq.SetOrdinate(k, Ordinate.M, RandomOrdinate(Ordinate.M, Factory.PrecisionModel));
                    }
                    if ((ordinates & Ordinates.Z) == Ordinates.Z)
                        seq.SetOrdinate(k, Ordinate.Z, seq.GetOrdinate(0, Ordinate.Z));
                    if ((ordinates & Ordinates.M) == Ordinates.M)
                        seq.SetOrdinate(k, Ordinate.M, seq.GetOrdinate(0, Ordinate.M));
                }

                return Factory.CreateLinearRing(reverse ? seq.Reversed() : seq);
            }
            private static ILinearRing CreateCircleRing(Ordinates ordinates, double x, double y, double radius, bool reverse = false)
            {
                var seq = CsFactory.Create(4 * 12 + 1, ordinates);
                var angle = Math.PI * 2;
                const double quandrantStep = Math.PI / 2d / 12d;
                var k = 0;
                for (var i = 0; i < 4; i++)
                {
                    for (var j = 0; j < 12; j++)
                    {
                        var dx = radius * Math.Cos(angle);
                        var dy = radius * Math.Sin(angle);
                        seq.SetOrdinate(k, Ordinate.X, Factory.PrecisionModel.MakePrecise(x + dx));
                        seq.SetOrdinate(k, Ordinate.Y, Factory.PrecisionModel.MakePrecise(y + dy));
                        if ((ordinates & Ordinates.Z) == Ordinates.Z)
                            seq.SetOrdinate(k, Ordinate.Z, RandomOrdinate(Ordinate.Z, Factory.PrecisionModel));
                        if ((ordinates & Ordinates.Z) == Ordinates.Z)
                            seq.SetOrdinate(k, Ordinate.M, RandomOrdinate(Ordinate.M, Factory.PrecisionModel));
                        k++;
                        angle -= quandrantStep;
                    }
                }
                seq.SetOrdinate(k, Ordinate.X, seq.GetOrdinate(0, Ordinate.X));
                seq.SetOrdinate(k, Ordinate.Y, seq.GetOrdinate(0, Ordinate.Y));
                if ((ordinates & Ordinates.Z) == Ordinates.Z)
                    seq.SetOrdinate(k, Ordinate.Z, seq.GetOrdinate(0, Ordinate.Z));
                if ((ordinates & Ordinates.M) == Ordinates.M)
                    seq.SetOrdinate(k, Ordinate.M, seq.GetOrdinate(0, Ordinate.M));

                return Factory.CreateLinearRing(reverse ? seq.Reversed() : seq);
            }
            private static IGeometry CreatePolygon(Ordinates ordinates, bool empty, int nextKind = -1)
            {
                if (empty)
                {
                    Factory.CreatePolygon((ICoordinateSequence)null);
                }
                if (nextKind == -1) nextKind = Rnd.Next(0, 5);

                var x = RandomOrdinate(Ordinate.X, Factory.PrecisionModel);
                var y = RandomOrdinate(Ordinate.Y, Factory.PrecisionModel);

                switch (nextKind)
                {
                    case 0: // circle
                        var ring = CreateCircleRing(ordinates, x, y, 3 * Rnd.NextDouble());
                        return Factory.CreatePolygon(ring, null);
                    case 1: // rectangle
                        ring = CreateRectangleRing(ordinates, x, y, 6 * Rnd.NextDouble(), 3 * Rnd.NextDouble());
                        return Factory.CreatePolygon(ring, null);
                    case 2: // cirle with hole
                        var radius = 3 * Rnd.NextDouble();
                        var shell = CreateCircleRing(ordinates, x, y, radius);
                        var hole = CreateCircleRing(ordinates, x, y, 0.66 * radius, true);
                        return Factory.CreatePolygon(shell, new[] { hole });
                    case 3: // rectanglee with hole
                        var width = 6 * Rnd.NextDouble();
                        var height = 3 * Rnd.NextDouble();
                        shell = CreateRectangleRing(ordinates, x, y, width, height);
                        hole = CreateRectangleRing(ordinates, x, y, 0.66 * width, 0.66 * height, true);
                        return Factory.CreatePolygon(shell, new[] { hole });
                    case 4: // rectanglee with hole
                        width = 6 * Rnd.NextDouble();
                        height = 3 * Rnd.NextDouble();
                        shell = CreateRectangleRing(ordinates, x, y, width, height);
                        hole = CreateCircleRing(ordinates, x, y, 0.33 * Math.Min(width, height), true);
                        return Factory.CreatePolygon(shell, new[] { hole });
                    default:
                        throw new NotSupportedException();
                }
            }
 private static IGeometry CreatePolygonal(Ordinates ordinates, bool empty)
 {
     if (Rnd.Next(2) == 0)
         return CreatePolygon(ordinates, empty);
     return CreateMultiPolygon(ordinates, empty);
 }
Example #34
0
 /// <summary>
 /// Inititalizes this instance based on a geometry and an Ordinates flag.
 /// </summary>
 /// <param name="geometry">The geometry.</param>
 /// <param name="ordinates">The ordinates flag.</param>
 public GeometryType(Geometry geometry, Ordinates ordinates)
     : this(geometry.OgcGeometryType, ordinates, geometry.SRID >= 0)
 {
 }
Example #35
0
		/**
	 * TODO: I'd like to see this method added to the base Coordinate class
	 * Returns the ordinate value specified in this Coordinate instance. The
	 * index of the desired ordinates are specified in the CoordinateSequence
	 * class; hence CoodinateSequence.X returns the x ordinate,
	 * CoodinateSequence.Y the y ordinate, CoodinateSequence.Z the z ordinate,
	 * and CoodinateSequence.M the M ordinate. Note that the dimension may not
	 * imply the desired ordinate in the case where one is using a 2 dimensional
	 * geometry with a measure value. Therefore, these constants are highly
	 * recommended.
	 * 
	 * @param ordinateIndex
	 *            the desired ordinate index.
	 * @return the value of stored in the ordinate index. Incorrect or unused
	 *         indexes shall return Double.NaN
	 */

		public double GetOrdinate(Ordinates ordinateIndex)
		{
			switch (ordinateIndex)
			{
				case Ordinates.X:
					return this.X;
				case Ordinates.Y:
					return this.Y;
				case Ordinates.Z:
					return this.Z;
				case Ordinates.M:
					return M;
			}
			return Double.NaN;
		}
Example #36
0
 public ICoordinateSequence Create(int size, Ordinates ordinates)
 {
     throw new NotImplementedException();
 }
        private ICoordinateSequence ToSequence(SpatialLite.Core.API.ICoordinateList list, Ordinates kind)
        {
            var res = _factory.Create(list.Count, kind);

            kind = res.Ordinates;

            for (var i = 0; i < list.Count; i++)
            {
                var c = list[i];
                res.SetOrdinate(i, Ordinate.X, c.X);
                res.SetOrdinate(i, Ordinate.Y, c.Y);
                if ((kind & Ordinates.Z) == Ordinates.Z)
                {
                    res.SetOrdinate(i, Ordinate.Z, c.Z);
                }
                if ((kind & Ordinates.M) == Ordinates.M)
                {
                    res.SetOrdinate(i, Ordinate.M, c.M);
                }
            }
            return(res);
        }
Example #38
0
 /// <summary>
 /// Clears the contents of this buffer
 /// </summary>
 public void Clear()
 {
     _coordinates.Clear();
     _definedOrdinates = Ordinates.XY;
 }
Example #39
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="lineString"></param>
 /// <param name="ordinates"></param>
 /// <param name="byteOrder">The byte order.</param>
 /// <param name="writer"></param>
 private void Write(ILineString lineString, Ordinates ordinates, ByteOrder byteOrder, BinaryWriter writer)
 {
     WriteHeader(PostGisGeometryType.LineString, HandleSRID ? lineString.SRID : -1, ordinates, byteOrder, writer);
     Write(lineString.CoordinateSequence, ordinates, writer, false);
 }
 public ICoordinateSequence Create(int size, Ordinates ordinates)
 {
     return new CoordinateArraySequence(size, OrdinatesUtility.OrdinatesToDimension(ordinates));
 }
Example #41
0
 /// <summary>
 /// Writes a 'MultiLineString' to the stream.
 /// </summary>
 /// <param name="multiLineString">The polygon to write.</param>
 /// <param name="ordinates">The ordinates to write. <see cref="Ordinates.XY"/> are always written.</param>
 /// <param name="byteOrder">The byte order.</param>
 /// <param name="writer">The writer to use.</param>
 private void Write(IMultiLineString multiLineString, Ordinates ordinates, ByteOrder byteOrder, BinaryWriter writer)
 {
     WriteHeader(PostGisGeometryType.MultiLineString, HandleSRID ? multiLineString.SRID : -1, ordinates, byteOrder, writer);
     writer.Write(multiLineString.NumGeometries);
     Write(multiLineString.Geometries, ordinates, byteOrder, writer);
 }
            public static IGeometryCollection CreateShapes(OgcGeometryType type, Ordinates ordinates, int number = 50)
            {
                var empty = new bool[number];
                empty[Rnd.Next(2, number / 2)] = true;
                empty[Rnd.Next(number / 2, number)] = true;

                var result = new IGeometry[number];
                for (var i = 0; i < number; i++)
                {
                    switch (type)
                    {
                        case OgcGeometryType.Point:
                            result[i] = CreatePoint(ordinates, empty[i]);
                            break;
                        case OgcGeometryType.MultiPoint:
                            result[i] = CreateMultiPoint(ordinates, empty[i]);
                            break;

                        case OgcGeometryType.LineString:
                        case OgcGeometryType.MultiLineString:
                            result[i] = CreateLineal(ordinates, empty[i]);
                            break;
                        case OgcGeometryType.Polygon:
                        case OgcGeometryType.MultiPolygon:
                            result[i] = CreatePolygonal(ordinates, empty[i]);
                            break;
                    }

                    /*
                    // Ensure no empty elements
                    if (result[i] == null || (result[i].IsEmpty && result[i].OgcGeometryType == OgcGeometryType.GeometryCollection))
                        i--;
                    */
                    // Ensure not null and not geometry collection
                    if (result[i] == null || result[i].OgcGeometryType == OgcGeometryType.GeometryCollection)
                        i--;
                }

                return Factory.CreateGeometryCollection(result);
            }
Example #43
0
 /// <summary>
 /// Writes a 'GeometryCollection' to the stream.
 /// </summary>
 /// <param name="geomCollection">The polygon to write.</param>
 /// <param name="ordinates">The ordinates to write. <see cref="Ordinates.XY"/> are always written.</param>
 /// <param name="byteOrder">The byte order.</param>
 /// <param name="writer">The writer to use.</param>
 private void Write(IGeometryCollection geomCollection, Ordinates ordinates, ByteOrder byteOrder, BinaryWriter writer)
 {
     WriteHeader(PostGisGeometryType.GeometryCollection, HandleSRID ? geomCollection.SRID  :-1, ordinates, byteOrder, writer);
     writer.Write(geomCollection.NumGeometries);
     Write(geomCollection.Geometries, ordinates, byteOrder, writer);
 }
Example #44
0
        private IMultiPatch ReadMultipatch(BinaryReader reader,
                                           Ordinates expectedOrdinates,
                                           bool groupPartsByPointIDs = false)
        {
            IMultiPatch result = new MultiPatchClass();

            if (groupPartsByPointIDs)
            {
                GeometryUtils.MakePointIDAware(result);
            }

            int polyhedraCount = checked ((int)reader.ReadUInt32());

            for (int i = 0; i < polyhedraCount; i++)
            {
                WkbGeometryType geometryType;
                Ordinates       ordinates;
                ReadWkbType(reader, false,
                            out geometryType, out ordinates);

                Assert.AreEqual(WkbGeometryType.PolyhedralSurface, geometryType,
                                "Unexpected geometry type");

                Assert.AreEqual(expectedOrdinates, ordinates,
                                "Unexpected ordinates dimension");

                int polygonCount = checked ((int)reader.ReadUInt32());

                for (int p = 0; p < polygonCount; p++)
                {
                    ReadWkbType(reader, false,
                                out geometryType, out expectedOrdinates);

                    Assert.AreEqual(WkbGeometryType.Polygon, geometryType,
                                    "Unexpected geometry type");

                    var rings = ReadSingleExteriorRingPolygon(reader, ordinates, false).ToList();

                    if (rings.Count == 0)
                    {
                        continue;
                    }

                    if (groupPartsByPointIDs)
                    {
                        AssignPointIds(rings, i);
                    }

                    var outerRingType = rings.Count > 1
                                                                    ? esriMultiPatchRingType.esriMultiPatchOuterRing
                                                                    : p == 0 || groupPartsByPointIDs
                                                                            ? esriMultiPatchRingType.esriMultiPatchFirstRing
                                                                            : esriMultiPatchRingType.esriMultiPatchRing;

                    IRing outerRing = rings[0];
                    GeometryFactory.AddRingToMultiPatch(outerRing, result, outerRingType);

                    if (rings.Count > 1)
                    {
                        for (int r = 1; r < rings.Count; r++)
                        {
                            IRing innerRing = rings[r];
                            GeometryFactory.AddRingToMultiPatch(
                                innerRing, result, esriMultiPatchRingType.esriMultiPatchInnerRing);
                        }
                    }
                }
            }

            return(result);
        }
Example #45
0
 /// <summary>
 ///     Configures the dimension of the column that the property maps to when targeting SQLite.
 /// </summary>
 /// <param name="propertyBuilder"> The builder for the property being configured. </param>
 /// <param name="ordinates"> The dimension ordinates. </param>
 /// <returns> The same builder instance so that multiple calls can be chained. </returns>
 public static PropertyBuilder <TProperty> HasSpatialDimension <TProperty>(
     [NotNull] this PropertyBuilder <TProperty> propertyBuilder,
     Ordinates ordinates)
 => (PropertyBuilder <TProperty>)HasSpatialDimension((PropertyBuilder)propertyBuilder, ordinates);
 private static IGeometry CreateLineal(Ordinates ordinates, bool empty)
 {
     switch (Rnd.Next(2))
     {
         case 0:
             return CreateLineString(ordinates, empty);
         default:
             return CreateMultiLineString(ordinates, empty);
     }
 }
 public PostGis2GeometryHeader(IGeometry geometry, Ordinates handleOrdinates)
     : this(geometry, handleOrdinates, false)
 {}
            private static IGeometry CreateLineString(Ordinates ordinates, bool empty)
            {
                if (empty)
                {
                    return Factory.CreateLineString((ICoordinateSequence)null);
                }

                var numPoints = Rnd.Next(75, 101);
                var seq = CsFactory.Create(numPoints, ordinates);
                for (var i = 0; i < numPoints; i++)
                    foreach (var o in OrdinatesUtility.ToOrdinateArray(ordinates))
                        seq.SetOrdinate(i, o, RandomOrdinate(o, Factory.PrecisionModel));

                return Factory.CreateLineString(seq);
            }
Example #49
0
        /// <summary>
        /// Creates an instance of SpatiaLite provider
        /// </summary>
        /// <param name="connectionStr">Connection String to SQLite database file 
        /// ("http://www.connectionstrings.com/sqlite")</param>
        /// <param name="tablename">Name of the table with geometry information</param>
        /// <param name="geometryColumnName">Name of the desired geometry column</param>
        /// <param name="oidColumnName">Name of the object Id column</param>
        public ManagedSpatiaLite(string connectionStr, string tablename, string geometryColumnName, string oidColumnName)
            : base(-2)
        {
            ConnectionString = connectionStr;
            Table = tablename;
            GeometryColumn = geometryColumnName; //Name of column to store geometry
            ObjectIdColumn = oidColumnName; //Name of object ID column

            try
            {
                var op = UseLike ? "LIKE" : "=";
                using (var cn = new SQLiteConnection(connectionStr))
                {
                    cn.Open();
                    using (var cm = new SQLiteCommand(
                        String.Format(
                            "SELECT \"srid\", \"coord_dimension\", \"spatial_index_enabled\" FROM \"geometry_columns\" WHERE(lower(\"f_table_name\") {2} lower('{0}') AND lower(\"f_geometry_column\") {2} lower('{1}'));",
                            tablename, geometryColumnName, op), cn))
                    {
                        using (var dr = cm.ExecuteReader())
                        {
                            if (dr.HasRows)
                            {
                                dr.Read();
                                SRID = dr.GetInt32(0);

                                var coordDim = dr.GetFieldType(1) == typeof (long)
                                    ? dr.GetInt64(1).ToString(NumberFormatInfo.InvariantInfo)
                                    : dr.GetString(1);

                                switch (coordDim)
                                {
                                    case "2":
                                    case "XY":
                                        _ordinates = Ordinates.XY;
                                        break;
                                    case "3":
                                    case "XYZ":
                                        _ordinates = Ordinates.XYZ;
                                        break;
                                    case "XYM":
                                        _ordinates = Ordinates.XYM;
                                        break;
                                    case "4":
                                    case "XYZM":
                                        _ordinates = Ordinates.XYZM;
                                        break;
                                    default:
                                        throw new Exception("Cannot evaluate number of ordinate dimensions");

                                }

                                switch (dr.GetInt32(2))
                                {
                                    case 1: //RTree
                                        var indexName = string.Format(@"idx_{0}_{1}", tablename, geometryColumnName);
                                        const string whereClause = @"xmin < {0} AND xmax > {1} AND ymin < {2} AND ymax > {3}";
                                        _spatiaLiteIndexClause = string.Format(@"ROWID IN (SELECT pkid FROM {0} WHERE {1})", indexName, whereClause);
                                        _spatiaLiteIndex = SpatiaLiteIndex.RTree;
                                        _useSpatialIndex = true;
                                        break;
                                }
                            }
                            dr.Close();
                        }
                    }
                }

                GetNonSpatialColumns();
            }
            catch (Exception)
            {
                SRID = -1;
                _spatiaLiteIndex = SpatiaLiteIndex.None;
                _useSpatialIndex = false;
            }
        }
            private static IGeometry CreatePoint(Ordinates ordinates, bool empty)
            {
                if (empty)
                {
                    return Factory.CreatePoint((ICoordinateSequence)null);
                }

                var seq = CsFactory.Create(1, ordinates);
                foreach (var o in OrdinatesUtility.ToOrdinateArray(ordinates))
                    seq.SetOrdinate(0, o, RandomOrdinate(o, Factory.PrecisionModel));
                return Factory.CreatePoint(seq);
            }
Example #51
0
        private static void DoTest(IGeometryCollection geomsWrite, Ordinates ordinates, bool testGetOrdinate = true)
        {
            string fileName = string.Empty;

            try
            {
                fileName = Path.GetTempFileName();
                fileName = Path.ChangeExtension(fileName, "shp");
                ShapefileWriter.WriteGeometryCollection(fileName, geomsWrite);
                var reader    = new ShapefileReader(fileName, ShapeFileShapeFactory.FactoryRead);
                var geomsRead = reader.ReadAll();

                // This tests x- and y- values
                if (!geomsWrite.EqualsExact(geomsRead))
                {
                    Assert.AreEqual(geomsWrite.NumGeometries, geomsRead.NumGeometries);
                    //
                    // This akward test is necessary since EqualsTopologically throws currently exceptions
                    bool equal = true;
                    for (int i = 0; i < geomsRead.NumGeometries; i++)
                    {
                        var gw = geomsWrite.GetGeometryN(i);
                        var gr = geomsRead.GetGeometryN(i);
                        if (gw.IsEmpty && gr.IsEmpty)
                        {
                            if ((gw is ILineal && gr is ILineal) ||
                                (gw is IPolygonal && gr is IPolygonal))
                            {
                                // suppose these are equal
                            }
                            else
                            {
                                Console.WriteLine(string.Format("Geometries don't match at index {0}", i));
                                Console.WriteLine(string.Format("  written: {0}", gw.AsText()));
                                Console.WriteLine(string.Format("  read   : {0}", gr.AsText()));
                                equal = false;
                                Assert.IsTrue(equal, "Differenced found in geometries written and read!");
                            }
                        }
                        else if (!gw.EqualsExact(gr))
                        {
                            double hsm = new HausdorffSimilarityMeasure().Measure(gw, gr);
                            double asm = new AreaSimilarityMeasure().Measure(gw, gr);
                            double smc = SimilarityMeasureCombiner.Combine(hsm, asm);
                            if (!gw.EqualsNormalized(gr) || (1d - smc) > 1e-7)
                            {
                                Console.WriteLine(string.Format("Geometries don't match at index {0}", i));
                                Console.WriteLine(string.Format("  written: {0}", gw.AsText()));
                                Console.WriteLine(string.Format("  read   : {0}", gr.AsText()));
                                equal = false;
                                Assert.IsTrue(equal, "Differenced found in geometries written and read!");
                            }
                        }
                    }

                    //For polygons this has a tendency to fail, since the polygonhandler might rearrange the whole thing
                    if (testGetOrdinate)
                    {
                        if ((ordinates & Ordinates.Z) == Ordinates.Z)
                        {
                            double[] writeZ = geomsWrite.GetOrdinates(Ordinate.Z);
                            double[] readZ  = geomsRead.GetOrdinates(Ordinate.Z);
                            Assert.IsTrue(ArraysEqual(writeZ, readZ));
                        }

                        if ((ordinates & Ordinates.M) == Ordinates.M)
                        {
                            double[] writeM = geomsWrite.GetOrdinates(Ordinate.M);
                            double[] readM  = geomsRead.GetOrdinates(Ordinate.M);
                            Assert.IsTrue(ArraysEqual(writeM, readM));
                        }
                    }
                }

                // delete sample files
                File.Delete(fileName);
                File.Delete(Path.ChangeExtension(fileName, "shx"));
                File.Delete(Path.ChangeExtension(fileName, "dbf"));
            }
            catch (AssertionException ex)
            {
                Console.WriteLine("Failed test with {0}", ordinates);
                Console.WriteLine(ex.Message);
                Console.WriteLine("  Testfile '{0}' not deleted!", fileName);
                throw;
            }
        }
Example #52
0
 internal static GaiaImport Create(bool conversionNeeded, Ordinates handleOrdinates)
 {
     return(conversionNeeded
         ? new GaiaImport(GetConvertedDouble, GetConvertedDoubles, GetConvertedSingle, GetConvertedSingles, GetConvertedInt32, handleOrdinates)
         : new GaiaImport(GetUnconvertedDouble, GetUnconvertedDoubles, GetUnconvertedSingle, GetUnconvertedSingles, GetUnconvertedInt32, handleOrdinates));
 }
        /// <summary>
        /// Creates an instance of this class
        /// </summary>
        /// <param name="coordinates">The coordinates</param>
        /// <param name="ordinates"></param>
        public DotSpatialAffineCoordinateSequence(IReadOnlyCollection <Coordinate> coordinates, Ordinates ordinates)
            : base(coordinates?.Count ?? 0, OrdinatesUtility.OrdinatesToDimension(ordinates & Ordinates.XYZM), OrdinatesUtility.OrdinatesToMeasures(ordinates & Ordinates.XYZM))
        {
            coordinates = coordinates ?? Array.Empty <Coordinate>();

            _xy = new double[2 * coordinates.Count];
            if (HasZ)
            {
                _z = new double[coordinates.Count];
            }

            if (HasM)
            {
                _m = new double[coordinates.Count];
            }

            var xy = MemoryMarshal.Cast <double, XYStruct>(_xy);

            using (var coordinatesEnumerator = coordinates.GetEnumerator())
            {
                for (int i = 0; i < xy.Length; i++)
                {
                    if (!coordinatesEnumerator.MoveNext())
                    {
                        ThrowForInconsistentCount();
                    }

                    var coordinate = coordinatesEnumerator.Current;

                    xy[i].X = coordinate.X;
                    xy[i].Y = coordinate.Y;
                    if (_z != null)
                    {
                        _z[i] = coordinate.Z;
                    }

                    if (_m != null)
                    {
                        _m[i] = coordinate.M;
                    }
                }

                if (coordinatesEnumerator.MoveNext())
                {
                    ThrowForInconsistentCount();
                }
            }

            void ThrowForInconsistentCount() => throw new ArgumentException("IReadOnlyCollection<T>.Count is inconsistent with IEnumerable<T> implementation.", nameof(coordinates));
        }
Example #54
0
 private GaiaImport(GetDoubleFunction getDouble, GetDoublesFunction getDoubles, GetSingleFunction getSingle, GetSinglesFunction getSingles, GetInt32Function getInt32, Ordinates handleOrdinates)
     : this(0, getDouble, getDoubles, getSingle, getSingles, getInt32, handleOrdinates)
 {
 }
	    public ICoordinateSequence Create(int size, Ordinates ordinates)
	    {
	        throw new NotImplementedException();
	    }
Example #56
0
 private GaiaImport(GaiaGeoGeometry geometryType, GetDoubleFunction getDouble, GetDoublesFunction getDoubles, GetSingleFunction getSingle, GetSinglesFunction getSingles, GetInt32Function getInt32, Ordinates handleOrdinates)
     : base(geometryType)
 {
     GetDouble       = getDouble;
     GetDoubles      = getDoubles;
     GetSingle       = getSingle;
     GetSingles      = getSingles;
     GetInt32        = getInt32;
     HandleOrdinates = handleOrdinates;
 }
 /// <summary>
 /// Creates a <see cref="ICoordinateSequence" /> of the specified size and ordinates.
 /// For this to be useful, the <see cref="ICoordinateSequence" /> implementation must be mutable.
 /// </summary>
 /// <param name="size">The number of coordinates</param>
 /// <param name="ordinates">
 /// The ordinates each coordinate has. <see cref="Ordinates.XY"/> is fix, <see cref="Ordinates.Z"/> and <see cref="Ordinates.M"/> can be set.
 /// </param>
 /// <returns></returns>
 public ICoordinateSequence Create(int size, Ordinates ordinates)
 {
     return(Create(size, OrdinatesUtility.OrdinatesToDimension(ordinates)));
 }
 /// <summary>
 /// Returns the ordinate of a coordinate in this sequence.
 /// Ordinate indices 0 and 1 are assumed to be X and Y.
 /// Ordinates indices greater than 1 have user-defined semantics
 /// (for instance, they may contain other dimensions or measure values).
 /// </summary>
 /// <param name="index">The coordinate index in the sequence.</param>
 /// <param name="ordinate">The ordinate index in the coordinate (in range [0, dimension-1]).</param>
 /// <returns></returns>
 public double GetOrdinate(int index, Ordinates ordinate)
 {
     switch (ordinate) 
     {
         case Ordinates.X:  
             return coordinates[index].X;
         case Ordinates.Y:  
             return coordinates[index].Y;
         case Ordinates.Z:  
             return coordinates[index].Z;
         default:
             return Double.NaN;
     }            
 }
 /// <summary>
 ///     Configures the dimension of the column that the property maps to when targeting SQLite.
 /// </summary>
 /// <param name="propertyBuilder"> The builder for the property being configured. </param>
 /// <param name="ordinates"> The dimension ordinates. </param>
 /// <returns> The same builder instance so that multiple calls can be chained. </returns>
 public static PropertyBuilder <TProperty> ForSqliteHasDimension <TProperty>(
     [NotNull] this PropertyBuilder <TProperty> propertyBuilder,
     Ordinates ordinates)
 => (PropertyBuilder <TProperty>)ForSqliteHasDimension((PropertyBuilder)propertyBuilder, ordinates);
 /// <summary>
 /// Sets the value for a given ordinate of a coordinate in this sequence.
 /// </summary>
 /// <param name="index">The coordinate index in the sequence.</param>
 /// <param name="ordinate">The ordinate index in the coordinate (in range [0, dimension-1]).</param>
 /// <param name="value">The new ordinate value.</param>
 public void SetOrdinate(int index, Ordinates ordinate, double value)
 {
     switch (ordinate) 
     {
         case Ordinates.X:  
             coordinates[index].X = value;
             break;
         case Ordinates.Y: 
             coordinates[index].Y = value;
             break;
         case Ordinates.Z: 
             coordinates[index].Z = value;
             break;
         default:
             throw new ArgumentException("invalid ordinate index: " + ordinate);
     }
 }