/// <summary> /// From OpenGIS : http://schemas.opengis.net/sf/1.0/simple_features_geometries.rdf /// A Polygon is a planar Surface defined by 1 exterior boundary (counterclock) and 0 or more interior boundaries(reverse counterclock). /// Each interior boundary defines a hole in the Polygon. /// a) Polygons are topologically closed; /// b) The boundary of a Polygon consists of a set of LinearRings that make up its exterior and interior boundaries; /// c) No two Rings in the boundary cross and the Rings in the boundary of a Polygon may intersect at a Point but only as a tangent. /// d) A Polygon may not have cut lines, spikes or punctures. /// e) The interior of every Polygon is a connected point set; /// f) The exterior of a Polygon with 1 or more holes is not connected. Each hole defines a connected component of the exterior /// Can throw the following Exceptions : /// - ArgumentNullException /// 1- Iterate through PostGisRings /// 1.1- Convert the first one in Exterior ring /// 1.2- Convert others into interior rings. /// 2- Create a NetTopology Polygon with all Rings created from previous steps /// </summary> /// <param name="geometry">a PostGisPolygon. No restriction.</param> /// <returns>a NetTopology Polygon</returns> private static Geometry ProcessPolygon(PostgisPolygon geometry) { if (geometry != null) { int ringCount = geometry.RingCount; LinearRing exteriorNetTopoRing = null; LinearRing[] holeNetTopoRings = null; //1- for (int i = 0; i < ringCount; i++) { Coordinate[] netTopoCoord = ConvertCoordinates2D(geometry[i]); //1.1- if (i == 0) { exteriorNetTopoRing = new LinearRing(netTopoCoord); } //1.2- else { if (holeNetTopoRings == null) { holeNetTopoRings = new LinearRing[ringCount - 1]; } holeNetTopoRings[i - 1] = new LinearRing(netTopoCoord); } } //2- return(new Polygon(exteriorNetTopoRing, holeNetTopoRings)); } else { throw new ArgumentNullException(); } }
public void SubGeometriesWithSRID() { var point = new PostgisPoint(1, 1) { SRID = 4326 }; var lineString = new PostgisLineString(new[] { new Coordinate2D(2, 2), new Coordinate2D(3, 3) }) { SRID = 4326 }; var polygon = new PostgisPolygon(new[] { new[] { new Coordinate2D(4, 4), new Coordinate2D(5, 5), new Coordinate2D(6, 6), new Coordinate2D(4, 4) } }) { SRID = 4326 }; var collection = new PostgisGeometryCollection(new PostgisGeometry[] { point, lineString, polygon }) { SRID = 4326 }; using (var conn = OpenConnection()) using (var cmd = new NpgsqlCommand("SELECT :p", conn)) { cmd.Parameters.AddWithValue("p", collection); cmd.ExecuteNonQuery(); } }
public static Polygon2 <double> ToGeom(PostgisPolygon geom) { if (geom != null) { return(ToGeom(Points(geom))); } return(null); }
public void FindInRectangle() { using (var db = GetDbConnection()) { var area = new PostgisPolygon( new[] { new[] { new Coordinate2D(12, 49), new Coordinate2D(17, 49), new Coordinate2D(17, 54), new Coordinate2D(12, 54), new Coordinate2D(12, 49), } }) { SRID = (uint)SRID_WGS_84 }; // TODO: Optimize and speed-up query, takes now ~400ms var areaProjected = db.OwmCities .Select(gt => area.StTransform(SRID_WGS84_Web_Mercator)) .First(); ////var areaProjected = new PostgisPolygon( //// new[] //// { //// new[] //// { //// new Coordinate2D(1335833.88951928, 6274861.39400658), //// new Coordinate2D(1892431.34348565, 6274861.39400658), //// new Coordinate2D(1892431.34348565, 7170156.29399995), //// new Coordinate2D(1335833.88951928, 7170156.29399995), //// new Coordinate2D(1335833.88951928, 6274861.39400658), //// } //// }) { SRID = SRID_WGS84_Web_Mercator }; var sw = Stopwatch.StartNew(); var list = db.OwmCities .Where(gt => areaProjected.StContains(gt.Geometry)) .OrderBy(gt => gt.Name) .ToList(); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); Assert.AreEqual(2, list.Count); Assert.IsTrue(list.Any(c => c.Name == "Berlin")); Assert.IsTrue(list.Any(c => c.Name == "Prague")); // TODO: Check if spatial index was used // http://postgis.net/docs/manual-1.3/ch03.html // https://gis.stackexchange.com/questions/130856/postgis-doesnt-use-spatial-index-with-st-intersects } }
public void ContainsTest() { var p = new PostgisPoint(1D, 1D); var svcs = CreatePostgisServices(); var pol = new PostgisPolygon(new Coordinate2D[1][] { new Coordinate2D[5] { new Coordinate2D(0D, 0D), new Coordinate2D(5D, 0D), new Coordinate2D(5D, 5D), new Coordinate2D(0D, 5D), new Coordinate2D(0D, 0D) } }); Assert.True(svcs.Contains(svcs.GeometryFromProviderValue(pol), svcs.GeometryFromProviderValue(p))); }
public void TestPostGisPolygonReturnPolygonWithCoordinatesAndSRS() { StubFieldValueGetter valueGetter = new StubFieldValueGetter(); valueGetter.OrdinalToStub = 0; valueGetter.FieldCount = 1; //Polygon with one hole, first element is exterior ring. Declaration with a jagged Array. PostgisPolygon postGisPolygon1 = CreatePostGisPolygon(1); valueGetter.GeometryToStub = postGisPolygon1; valueGetter.GeometryToStub.SRID = _SRID; Geometry geomResult = HRConverterPostGisToNetTopologySuite.ConvertFrom(valueGetter); Assert.NotNull(geomResult); Assert.IsType <Polygon>(geomResult); Polygon polygonResult = (Polygon)geomResult; Assert.Equal(_SRID, polygonResult.SRID); CheckIsPolygonRightConverted(1, polygonResult); }
public void TestPostGisMultiPolygonReturnMultiPolygonWithCoordinatesAndSRS() { StubFieldValueGetter valueGetter = new StubFieldValueGetter(); valueGetter.OrdinalToStub = 0; valueGetter.FieldCount = 1; PostgisPolygon[] postGisPolygons = new PostgisPolygon[] { CreatePostGisPolygon(1), CreatePostGisPolygon(2) }; valueGetter.GeometryToStub = new PostgisMultiPolygon(postGisPolygons); valueGetter.GeometryToStub.SRID = _SRID; Geometry geomResult = HRConverterPostGisToNetTopologySuite.ConvertFrom(valueGetter); Assert.NotNull(geomResult); Assert.IsType <MultiPolygon>(geomResult); MultiPolygon multiPolygonResult = (MultiPolygon)geomResult; Assert.Equal(_SRID, multiPolygonResult.SRID); Assert.Equal(2, multiPolygonResult.Count); Assert.IsType <Polygon>(multiPolygonResult[0]); Assert.IsType <Polygon>(multiPolygonResult[1]); CheckIsPolygonRightConverted(1, (Polygon)multiPolygonResult[0]); CheckIsPolygonRightConverted(2, (Polygon)multiPolygonResult[1]); }
public Task Write(PostgisPolygon value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) => Write((PostgisGeometry)value, buf, lengthCache, parameter, async);
public int ValidateAndGetLength(PostgisPolygon value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => value.GetLen(true);
public override bool Read([CanBeNull] out PostgisGeometry result) { Contract.Assert(_inByteaMode != true); if (!_inByteaMode.HasValue) { _inByteaMode = false; } result = default(PostgisGeometry); if (_id == 0) { if (_readBuf.ReadBytesLeft < 5) { return(false); } _bo = (ByteOrder)_readBuf.ReadByte(); _id = _readBuf.ReadUInt32(_bo); } if (!_srid.HasValue) { if ((_id & (uint)EwkbModifier.HasSRID) != 0) { if (_readBuf.ReadBytesLeft < 4) { return(false); } _srid = _readBuf.ReadUInt32(_bo); } else { _srid = 0; } } switch ((WkbIdentifier)(_id & 7)) { case WkbIdentifier.Point: _lastId = _id; if (_readBuf.ReadBytesLeft < 16) { return(false); } result = new PostgisPoint(_readBuf.ReadDouble(_bo), _readBuf.ReadDouble(_bo)) { SRID = _srid.Value }; return(true); case WkbIdentifier.LineString: _lastId = _id; if (_ipts == -1) { if (_readBuf.ReadBytesLeft < 4) { return(false); } _points = new Coordinate2D[_readBuf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _points.Length; _ipts++) { if (_readBuf.ReadBytesLeft < 16) { return(false); } _points[_ipts] = new Coordinate2D(_readBuf.ReadDouble(_bo), _readBuf.ReadDouble(_bo)); } result = new PostgisLineString(_points) { SRID = _srid.Value }; return(true); case WkbIdentifier.Polygon: _lastId = _id; if (_irng == -1) { if (_readBuf.ReadBytesLeft < 4) { return(false); } _rings = new Coordinate2D[_readBuf.ReadInt32(_bo)][]; _irng = 0; } for (; _irng < _rings.Length; _irng++) { if (_ipts == -1) { if (_readBuf.ReadBytesLeft < 4) { return(false); } _rings[_irng] = new Coordinate2D[_readBuf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _rings[_irng].Length; _ipts++) { if (_readBuf.ReadBytesLeft < 16) { return(false); } _rings[_irng][_ipts] = new Coordinate2D(_readBuf.ReadDouble(_bo), _readBuf.ReadDouble(_bo)); } _ipts = -1; } result = new PostgisPolygon(_rings) { SRID = _srid.Value }; return(true); case WkbIdentifier.MultiPoint: _lastId = _id; if (_ipts == -1) { if (_readBuf.ReadBytesLeft < 4) { return(false); } _points = new Coordinate2D[_readBuf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _points.Length; _ipts++) { if (_readBuf.ReadBytesLeft < 21) { return(false); } _readBuf.Skip(5); _points[_ipts] = new Coordinate2D(_readBuf.ReadDouble(_bo), _readBuf.ReadDouble(_bo)); } result = new PostgisMultiPoint(_points) { SRID = _srid.Value }; return(true); case WkbIdentifier.MultiLineString: _lastId = _id; if (_irng == -1) { if (_readBuf.ReadBytesLeft < 4) { return(false); } _rings = new Coordinate2D[_readBuf.ReadInt32(_bo)][]; _irng = 0; } for (; _irng < _rings.Length; _irng++) { if (_ipts == -1) { if (_readBuf.ReadBytesLeft < 9) { return(false); } _readBuf.Skip(5); _rings[_irng] = new Coordinate2D[_readBuf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _rings[_irng].Length; _ipts++) { if (_readBuf.ReadBytesLeft < 16) { return(false); } _rings[_irng][_ipts] = new Coordinate2D(_readBuf.ReadDouble(_bo), _readBuf.ReadDouble(_bo)); } _ipts = -1; } result = new PostgisMultiLineString(_rings) { SRID = _srid.Value }; return(true); case WkbIdentifier.MultiPolygon: _lastId = _id; if (_ipol == -1) { if (_readBuf.ReadBytesLeft < 4) { return(false); } _pols = new Coordinate2D[_readBuf.ReadInt32(_bo)][][]; _ipol = 0; } for (; _ipol < _pols.Length; _ipol++) { if (_irng == -1) { if (_readBuf.ReadBytesLeft < 9) { return(false); } _readBuf.Skip(5); _pols[_ipol] = new Coordinate2D[_readBuf.ReadInt32(_bo)][]; _irng = 0; } for (; _irng < _pols[_ipol].Length; _irng++) { if (_ipts == -1) { if (_readBuf.ReadBytesLeft < 4) { return(false); } _pols[_ipol][_irng] = new Coordinate2D[_readBuf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _pols[_ipol][_irng].Length; _ipts++) { if (_readBuf.ReadBytesLeft < 16) { return(false); } _pols[_ipol][_irng][_ipts] = new Coordinate2D(_readBuf.ReadDouble(_bo), _readBuf.ReadDouble(_bo)); } _ipts = -1; } _irng = -1; } result = new PostgisMultiPolygon(_pols) { SRID = _srid.Value }; return(true); case WkbIdentifier.GeometryCollection: PostgisGeometry[] g; int i; if (_icol.Count == 0) { if (_readBuf.ReadBytesLeft < 4) { _lastId = _id; return(false); } g = new PostgisGeometry[_readBuf.ReadInt32(_bo)]; i = 0; if (_newGeom) // We need to know whether we're in a nested geocoll or not. { _id = 0; _newGeom = false; } else { _id = _lastId; _lastId = 0; } } else { g = _geoms.Pop(); i = _icol.Pop(); if (_icol.Count == 0) { _id = _lastId; _lastId = 0; } } for (; i < g.Length; i++) { PostgisGeometry geom; if (!Read(out geom)) { _icol.Push(i); _geoms.Push(g); _id = (uint)WkbIdentifier.GeometryCollection; return(false); } g[i] = geom; Reset(); } result = new PostgisGeometryCollection(g) { SRID = _srid.Value }; return(true); default: throw new InvalidOperationException("Unknown Postgis identifier."); } }
public bool Read(out PostgisPolygon result) => ReadConcrete(out result);
public Task Write(PostgisPolygon value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default) => Write((PostgisGeometry)value, buf, lengthCache, parameter, async, cancellationToken);
public bool Read(out PostgisGeometry result) { result = default(PostgisGeometry); if (_id == 0) { if (_buf.ReadBytesLeft < 5) { return(false); } _bo = (ByteOrder)_buf.ReadByte(); _id = _buf.ReadUInt32(_bo); } if (!_srid.HasValue) { if ((_id & (uint)EwkbModifier.HasSRID) != 0) { if (_buf.ReadBytesLeft < 4) { return(false); } _srid = _buf.ReadUInt32(_bo); } else { _srid = 0; } } switch ((WkbIdentifier)(_id & (uint)7)) { case WkbIdentifier.Point: if (_buf.ReadBytesLeft < 16) { return(false); } result = new PostgisPoint(_buf.ReadDouble(_bo), _buf.ReadDouble(_bo)) { SRID = _srid.Value }; return(true); case WkbIdentifier.LineString: if (_ipts == -1) { if (_buf.ReadBytesLeft < 4) { return(false); } _points = new Coordinate2D[_buf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _points.Length; _ipts++) { if (_buf.ReadBytesLeft < 16) { return(false); } _points[_ipts] = new Coordinate2D(_buf.ReadDouble(_bo), _buf.ReadDouble(_bo)); } result = new PostgisLineString(_points) { SRID = _srid.Value }; return(true); case WkbIdentifier.Polygon: if (_irng == -1) { if (_buf.ReadBytesLeft < 4) { return(false); } _rings = new Coordinate2D[_buf.ReadInt32(_bo)][]; _irng = 0; } for (; _irng < _rings.Length; _irng++) { if (_ipts == -1) { if (_buf.ReadBytesLeft < 4) { return(false); } _rings[_irng] = new Coordinate2D[_buf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _rings[_irng].Length; _ipts++) { if (_buf.ReadBytesLeft < 16) { return(false); } _rings[_irng][_ipts] = new Coordinate2D(_buf.ReadDouble(_bo), _buf.ReadDouble(_bo)); } _ipts = -1; } result = new PostgisPolygon(_rings) { SRID = _srid.Value }; return(true); case WkbIdentifier.MultiPoint: if (_ipts == -1) { if (_buf.ReadBytesLeft < 4) { return(false); } _points = new Coordinate2D[_buf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _points.Length; _ipts++) { if (_buf.ReadBytesLeft < 21) { return(false); } _buf.Skip(5); _points[_ipts] = new Coordinate2D(_buf.ReadDouble(_bo), _buf.ReadDouble(_bo)); } result = new PostgisMultiPoint(_points) { SRID = _srid.Value }; return(true); case WkbIdentifier.MultiLineString: if (_irng == -1) { if (_buf.ReadBytesLeft < 4) { return(false); } _rings = new Coordinate2D[_buf.ReadInt32(_bo)][]; _irng = 0; } for (; _irng < _rings.Length; _irng++) { if (_ipts == -1) { if (_buf.ReadBytesLeft < 9) { return(false); } _buf.Skip(5); _rings[_irng] = new Coordinate2D[_buf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _rings[_irng].Length; _ipts++) { if (_buf.ReadBytesLeft < 16) { return(false); } _rings[_irng][_ipts] = new Coordinate2D(_buf.ReadDouble(_bo), _buf.ReadDouble(_bo)); } _ipts = -1; } result = new PostgisMultiLineString(_rings) { SRID = _srid.Value }; return(true); case WkbIdentifier.MultiPolygon: if (_ipol == -1) { if (_buf.ReadBytesLeft < 4) { return(false); } _pols = new Coordinate2D[_buf.ReadInt32(_bo)][][]; _ipol = 0; } for (; _ipol < _pols.Length; _ipol++) { if (_irng == -1) { if (_buf.ReadBytesLeft < 9) { return(false); } _buf.Skip(5); _pols[_ipol] = new Coordinate2D[_buf.ReadInt32(_bo)][]; _irng = 0; } for (; _irng < _pols[_ipol].Length; _irng++) { if (_ipts == -1) { if (_buf.ReadBytesLeft < 4) { return(false); } _pols[_ipol][_irng] = new Coordinate2D[_buf.ReadInt32(_bo)]; _ipts = 0; } for (; _ipts < _pols[_ipol][_irng].Length; _ipts++) { if (_buf.ReadBytesLeft < 16) { return(false); } _pols[_ipol][_irng][_ipts] = new Coordinate2D(_buf.ReadDouble(_bo), _buf.ReadDouble(_bo)); } _ipts = -1; } _irng = -1; } result = new PostgisMultiPolygon(_pols) { SRID = _srid.Value }; return(true); case WkbIdentifier.GeometryCollection: if (_newGeom) { if (_buf.ReadBytesLeft < 4) { return(false); } _geoms.Push(new PostgisGeometry[_buf.ReadInt32(_bo)]); _icol.Push(new Counter()); } _id = 0; var g = _geoms.Peek(); var i = _icol.Peek(); for (; i < g.Length; i.Increment()) { PostgisGeometry geom; if (!Read(out geom)) { _newGeom = false; return(false); } g[i] = geom; Reset(); } result = new PostgisGeometryCollection(g) { SRID = _srid.Value }; _geoms.Pop(); _icol.Pop(); return(true); default: throw new InvalidOperationException("Unknown Postgis identifier."); } }