/// <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; }
/// <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; }
/// <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)); } }
/// <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); } } }
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)); }
/// <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; }
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"); } }
/** * 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"); } }
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; }
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); }
public static PropertyBuilder <TProperty> ForSqliteHasDimension <TProperty>( [NotNull] this PropertyBuilder <TProperty> propertyBuilder, Ordinates ordinates) => propertyBuilder.HasSpatialDimension(ordinates);
/// <summary> /// Initializes writer with the specified byte order. /// </summary> /// <param name="encodingType">Encoding type</param> public PostGisWriter(ByteOrder encodingType) { EncodingType = encodingType; HandleOrdinates = Ordinates.None; }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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) { }
/** * 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; }
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); }
/// <summary> /// Clears the contents of this buffer /// </summary> public void Clear() { _coordinates.Clear(); _definedOrdinates = Ordinates.XY; }
/// <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)); }
/// <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); }
/// <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); }
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); }
/// <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); }
/// <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); }
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; } }
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)); }
private GaiaImport(GetDoubleFunction getDouble, GetDoublesFunction getDoubles, GetSingleFunction getSingle, GetSinglesFunction getSingles, GetInt32Function getInt32, Ordinates handleOrdinates) : this(0, getDouble, getDoubles, getSingle, getSingles, getInt32, handleOrdinates) { }
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); } }