Skip to content

Commit b695295

Browse files
authored
Merge pull request #130 from nhibernate/npgsql-4
Use Npgsql's PostGIS/NTS plug-in for Geometry type
2 parents 8f2444b + bcb28ba commit b695295

File tree

7 files changed

+47
-68
lines changed

7 files changed

+47
-68
lines changed

NHibernate.Spatial.PostGis/NHibernate.Spatial.PostGis.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929

3030
<ItemGroup>
3131
<PackageReference Include="NetTopologySuite.IO.PostGis" Version="2.1.0" />
32-
<PackageReference Include="Npgsql" Version="[3.2.7, 4.0)" />
32+
<PackageReference Include="Npgsql" Version="4.1.12" />
33+
<PackageReference Include="Npgsql.NetTopologySuite" Version="4.1.12" />
3334
</ItemGroup>
3435

3536
<ItemGroup>

NHibernate.Spatial.PostGis/Type/PostGisGeometryType.cs

Lines changed: 11 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@
1515
// along with NHibernate.Spatial; if not, write to the Free Software
1616
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1717

18-
using NetTopologySuite.Geometries;
19-
using NetTopologySuite.IO;
2018
using System;
2119
using System.Data.Common;
20+
using NetTopologySuite.Geometries;
2221
using NHibernate.Engine;
2322
using NHibernate.SqlTypes;
2423
using NHibernate.Type;
@@ -28,7 +27,7 @@
2827
namespace NHibernate.Spatial.Type
2928
{
3029
[Serializable]
31-
public class PostGisGeometryType : GeometryTypeBase<byte[]>
30+
public class PostGisGeometryType : GeometryTypeBase<Geometry>
3231
{
3332
private static readonly NullableType GeometryType = new CustomGeometryType();
3433

@@ -45,45 +44,17 @@ public PostGisGeometryType()
4544
/// </summary>
4645
/// <param name="value">The GeoAPI geometry value.</param>
4746
/// <returns></returns>
48-
protected override byte[] FromGeometry(object value)
47+
protected override Geometry FromGeometry(object value)
4948
{
50-
Geometry geometry = value as Geometry;
49+
var geometry = value as Geometry;
5150
if (geometry == null)
5251
{
5352
return null;
5453
}
55-
// PostGIS can't parse a WKB of any empty geometry other than GeomtryCollection
56-
// (throws the error: "geometry requires more points")
57-
// and parses WKT of empty geometries always as GeometryCollection
58-
// (ie. "select AsText(GeomFromText('LINESTRING EMPTY', -1)) = 'GEOMETRYCOLLECTION EMPTY'").
59-
// Force GeometryCollection.Empty to avoid the error.
60-
if (!(geometry is GeometryCollection) && geometry.IsEmpty)
61-
{
62-
geometry = GeometryCollection.Empty;
63-
}
6454

6555
this.SetDefaultSRID(geometry);
6656

67-
// Determine the ordinality of the geometry to ensure 3D and 4D geometries are
68-
// correctly serialized by PostGisWriter (see issue #66)
69-
// NOTE: Cannot use InteriorPoint here as that always returns a 2D point (see #120)
70-
// TODO: Is there a way of getting the ordinates directly from the geometry?
71-
var ordinates = Ordinates.XY;
72-
var coordinate = geometry.Coordinate;
73-
if (coordinate != null && !double.IsNaN(coordinate.Z))
74-
{
75-
ordinates |= Ordinates.Z;
76-
}
77-
if (coordinate != null && !double.IsNaN(coordinate.M))
78-
{
79-
ordinates |= Ordinates.M;
80-
}
81-
82-
var postGisWriter = new PostGisWriter
83-
{
84-
HandleOrdinates = ordinates
85-
};
86-
return postGisWriter.Write(geometry);
57+
return geometry;
8758
}
8859

8960
/// <summary>
@@ -93,15 +64,14 @@ protected override byte[] FromGeometry(object value)
9364
/// <returns></returns>
9465
protected override Geometry ToGeometry(object value)
9566
{
96-
var bytes = value as byte[];
97-
if (bytes == null)
67+
var geometry = value as Geometry;
68+
if (geometry == null)
9869
{
9970
return null;
10071
}
10172

102-
PostGisReader reader = new PostGisReader();
103-
Geometry geometry = reader.Read(bytes);
10473
this.SetDefaultSRID(geometry);
74+
10575
return geometry;
10676
}
10777

@@ -114,16 +84,7 @@ internal CustomGeometryType() : base(new BinarySqlType())
11484

11585
public override object Get(DbDataReader rs, int index, ISessionImplementor session)
11686
{
117-
// Npgsql 3 from the received bytes creates his own PostGisGeometry type.
118-
// As we need to return a byte array that represents the geometry object,
119-
// we will retrive the bytes from the reader instead.
120-
var length = (int)rs.GetBytes(index, 0, null, 0, 0);
121-
var buffer = new byte[length];
122-
if (length > 0)
123-
{
124-
rs.GetBytes(index, 0, buffer, 0, length);
125-
}
126-
return buffer;
87+
return (Geometry)rs.GetValue(index);
12788
}
12889

12990
public override object Get(DbDataReader rs, string name, ISessionImplementor session)
@@ -144,8 +105,8 @@ public override void Set(DbCommand cmd, object value, int index, ISessionImpleme
144105

145106
public override object DeepCopyNotNull(object value)
146107
{
147-
var arr = (byte[]) value;
148-
return arr.Clone();
108+
var obj = (Geometry)value;
109+
return obj.Copy();
149110
}
150111
}
151112
}

NetTopologySuite.TestRunner/Utility/WKTOrWKBReader.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ private static Boolean IsHexDigit(char ch)
3737

3838
public WKTOrWKBReader(NtsGeometryServices ntsGeometryServices)
3939
{
40-
_wktReader = new WKTReader(ntsGeometryServices);
40+
_wktReader = new WKTReader(ntsGeometryServices)
41+
{
42+
IsOldNtsCoordinateSyntaxAllowed = false
43+
};
4144
#pragma warning disable 612
4245
_wkbReader = new WKBReader();
4346
#pragma warning restore 612

Tests.NHibernate.Spatial.PostGis/TestConfiguration.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using NHibernate.Cfg;
44
using NHibernate.Driver;
55
using NHibernate.Spatial.Dialect;
6+
using Npgsql;
67
using System.Collections.Generic;
78

89
namespace Tests.NHibernate.Spatial
@@ -29,6 +30,10 @@ public static void Configure(Configuration configuration)
2930
[Environment.ConnectionString] = _configurationRoot.GetConnectionString("PostGis")
3031
};
3132
configuration.SetProperties(properties);
33+
34+
// Use NTS plugin for mapping PostGIS types; see:
35+
// https://www.npgsql.org/doc/release-notes/4.0.html#improved-spatial-support-postgis
36+
NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite();
3237
}
3338
}
3439
}

Tests.NHibernate.Spatial.PostGis20/TestConfiguration.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using NHibernate.Cfg;
44
using NHibernate.Driver;
55
using NHibernate.Spatial.Dialect;
6+
using Npgsql;
67
using System.Collections.Generic;
78

89
namespace Tests.NHibernate.Spatial
@@ -29,6 +30,10 @@ public static void Configure(Configuration configuration)
2930
[Environment.ConnectionString] = _configurationRoot.GetConnectionString("PostGis20")
3031
};
3132
configuration.SetProperties(properties);
33+
34+
// Use NTS plugin for mapping PostGIS types; see:
35+
// https://www.npgsql.org/doc/release-notes/4.0.html#improved-spatial-support-postgis
36+
NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite();
3237
}
3338
}
3439
}

Tests.NHibernate.Spatial/AbstractFixture.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ namespace Tests.NHibernate.Spatial
2424
public abstract class AbstractFixture
2525
{
2626
private static readonly ILog Log = LogManager.GetLogger(typeof(AbstractFixture));
27-
protected static readonly WKTReader Wkt = new WKTReader();
27+
protected static readonly WKTReader Wkt = new WKTReader()
28+
{
29+
IsOldNtsCoordinateSyntaxAllowed = false
30+
};
2831
protected Configuration configuration;
2932
protected ISessionFactory sessions;
3033
private ISpatialDialect spatialDialect;

appveyor.yml

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,19 @@ install:
3737
# - ps: if ($isWindows) { (Get-Content $iniPath).replace('port=3306', 'port=3307') | Set-Content $iniPath }
3838

3939
# install PostgreSQL 8.4
40-
- cmd: curl -L -O -S -s https://get.enterprisedb.com/postgresql/postgresql-8.4.22-1-windows.exe
41-
- cmd: postgresql-8.4.22-1-windows.exe --mode unattended --superpassword Password12! --serverport 5431
40+
# - cmd: curl -L -O -S -s https://get.enterprisedb.com/postgresql/postgresql-8.4.22-1-windows.exe
41+
# - cmd: postgresql-8.4.22-1-windows.exe --mode unattended --superpassword Password12! --serverport 5431
4242

4343
# install PostGIS 1.5.5 for PostgreSQL 8.4
44-
- cmd: curl -L -O -S -s http://download.osgeo.org/postgis/windows/pg84/postgis-pg84-binaries-1.5.5.zip
45-
- cmd: 7z x postgis-pg84-binaries-1.5.5.zip > nul
46-
- cmd: xcopy /s /y /q postgis-pg84-binaries-1.5.5 "C:\Program Files (x86)\PostgreSQL\8.4"
47-
- cmd: SET PGPASSWORD=Password12!
48-
- cmd: SET PGDIR=C:\Program Files (x86)\PostgreSQL\8.4
49-
- cmd: SET PATH=%PGDIR%\bin;%PATH%
50-
- cmd: createdb -p 5431 -U postgres template_postgis
51-
- cmd: psql -q -p 5431 -U postgres -d template_postgis -f "%PGDIR%\share\contrib\postgis-1.5\postgis.sql"
52-
- cmd: psql -q -p 5431 -U postgres -d template_postgis -f "%PGDIR%\share\contrib\postgis-1.5\spatial_ref_sys.sql"
44+
# - cmd: curl -L -O -S -s http://download.osgeo.org/postgis/windows/pg84/postgis-pg84-binaries-1.5.5.zip
45+
# - cmd: 7z x postgis-pg84-binaries-1.5.5.zip > nul
46+
# - cmd: xcopy /s /y /q postgis-pg84-binaries-1.5.5 "C:\Program Files (x86)\PostgreSQL\8.4"
47+
# - cmd: SET PGPASSWORD=Password12!
48+
# - cmd: SET PGDIR=C:\Program Files (x86)\PostgreSQL\8.4
49+
# - cmd: SET PATH=%PGDIR%\bin;%PATH%
50+
# - cmd: createdb -p 5431 -U postgres template_postgis
51+
# - cmd: psql -q -p 5431 -U postgres -d template_postgis -f "%PGDIR%\share\contrib\postgis-1.5\postgis.sql"
52+
# - cmd: psql -q -p 5431 -U postgres -d template_postgis -f "%PGDIR%\share\contrib\postgis-1.5\spatial_ref_sys.sql"
5353

5454
# install PostGIS 2.3.2 for PostgreSQL 9.6 on Windows
5555
- cmd: curl -L -O -S -s http://download.osgeo.org/postgis/windows/pg96/archive/postgis-bundle-pg96-2.3.2x64.zip
@@ -106,12 +106,13 @@ before_test:
106106
# - cmd: '%mysql% -P 3307 -u root < Tests.NHibernate.Spatial.MySQL57\nhsp_test.sql'
107107

108108
# setup PostgreSQL 8.4
109-
- cmd: SET psql="C:\Program Files (x86)\PostgreSQL\8.4\bin\psql.exe"
110-
- cmd: '%psql% -q -p 5431 -U postgres -f Tests.NHibernate.Spatial.PostGis\nhsp_test.sql'
109+
# - cmd: SET psql="C:\Program Files (x86)\PostgreSQL\8.4\bin\psql.exe"
110+
# - cmd: '%psql% -q -p 5431 -U postgres -f Tests.NHibernate.Spatial.PostGis\nhsp_test.sql'
111111

112112
# setup PostgreSQL 9.6 on Windows
113113
- cmd: net start postgresql-x64-9.6
114114
- cmd: SET psql="C:\Program Files\PostgreSQL\9.6\bin\psql.exe"
115+
- cmd: SET PGPASSWORD=Password12!
115116
- cmd: '%psql% -q -p 5432 -U postgres -f Tests.NHibernate.Spatial.PostGis20\nhsp_test.sql'
116117

117118
# setup PostgreSQL 9.6 on Ubuntu
@@ -125,7 +126,7 @@ test_script:
125126
# Disable MySQL tests until issue #87 is resolved
126127
# - cmd: dotnet test -c Release --no-build --logger "trx;LogFileName=MySQL.trx" --results-directory %APPVEYOR_BUILD_FOLDER% Tests.NHibernate.Spatial.MySQL
127128
# - cmd: dotnet test -c Release --no-build --logger "trx;LogFileName=MySQL57.trx" --results-directory %APPVEYOR_BUILD_FOLDER% Tests.NHibernate.Spatial.MySQL57
128-
- cmd: dotnet test -c Release --no-build --logger "trx;LogFileName=PostGis.trx" --results-directory %APPVEYOR_BUILD_FOLDER% Tests.NHibernate.Spatial.PostGis
129+
# - cmd: dotnet test -c Release --no-build --logger "trx;LogFileName=PostGis.trx" --results-directory %APPVEYOR_BUILD_FOLDER% Tests.NHibernate.Spatial.PostGis
129130
- ps: dotnet test -c Release --no-build --logger "trx;LogFileName=PostGis20.trx" --results-directory $env:APPVEYOR_BUILD_FOLDER Tests.NHibernate.Spatial.PostGis20
130131

131132
after_test:
@@ -135,5 +136,5 @@ after_test:
135136
- ps: if ($isWindows) { $wc.UploadFile($uri, (Resolve-Path MsSql2012.trx)) }
136137
# - ps: $wc.UploadFile($uri, (Resolve-Path MySQL.trx))
137138
# - ps: $wc.UploadFile($uri, (Resolve-Path MySQL57.trx))
138-
- ps: if ($isWindows) { $wc.UploadFile($uri, (Resolve-Path PostGis.trx)) }
139+
# - ps: if ($isWindows) { $wc.UploadFile($uri, (Resolve-Path PostGis.trx)) }
139140
- ps: $wc.UploadFile($uri, (Resolve-Path PostGis20.trx))

0 commit comments

Comments
 (0)