Ejemplo n.º 1
0
 /// <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();
     }
 }
Ejemplo n.º 2
0
        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();
                }
        }
Ejemplo n.º 3
0
 public static Polygon2 <double> ToGeom(PostgisPolygon geom)
 {
     if (geom != null)
     {
         return(ToGeom(Points(geom)));
     }
     return(null);
 }
Ejemplo n.º 4
0
        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]);
        }
Ejemplo n.º 8
0
 public Task Write(PostgisPolygon value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async)
 => Write((PostgisGeometry)value, buf, lengthCache, parameter, async);
Ejemplo n.º 9
0
 public int ValidateAndGetLength(PostgisPolygon value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter)
 => value.GetLen(true);
Ejemplo n.º 10
0
        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.");
            }
        }
Ejemplo n.º 11
0
 public bool Read(out PostgisPolygon result) => ReadConcrete(out result);
Ejemplo n.º 12
0
 public Task Write(PostgisPolygon value, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async, CancellationToken cancellationToken = default)
 => Write((PostgisGeometry)value, buf, lengthCache, parameter, async, cancellationToken);
Ejemplo n.º 13
0
        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.");
            }
        }