Gdal.Npgsql
8.1.0
See the version list below for details.
dotnet add package Gdal.Npgsql --version 8.1.0
NuGet\Install-Package Gdal.Npgsql -Version 8.1.0
<PackageReference Include="Gdal.Npgsql" Version="8.1.0" />
<PackageVersion Include="Gdal.Npgsql" Version="8.1.0" />
<PackageReference Include="Gdal.Npgsql" />
paket add Gdal.Npgsql --version 8.1.0
#r "nuget: Gdal.Npgsql, 8.1.0"
#:package Gdal.Npgsql@8.1.0
#addin nuget:?package=Gdal.Npgsql&version=8.1.0
#tool nuget:?package=Gdal.Npgsql&version=8.1.0
The package is an Npgsql plugin that allows you to interact with spatial data provided by the PostgreSQL PostGIS extension. On the .NET side, the plugin adds support for geometry types from the GDAL(OGR) library, allowing you to read and write them directly to PostgreSQL.
GDAL is connected via the nuget package MaxRev.Gdal.Core
Usage
Add a dependency on this package, then register the plugin on an NpgsqlDataSource. PostGIS
geometry and geography columns — and arrays of them — are mapped to PgGeometry.
using Npgsql;
using Npgsql.Gdal;
using OSGeo.OGR;
var dataSourceBuilder = new NpgsqlDataSourceBuilder(connectionString);
dataSourceBuilder.UseGdal();
var dataSource = dataSourceBuilder.Build();
using (var conn = await dataSource.OpenConnectionAsync())
{
using var point = Geometry.CreateFromWkt("POINT (30 10)");
using (var cmd = new NpgsqlCommand("INSERT INTO data (geom) VALUES (@p)", conn))
{
cmd.Parameters.AddWithValue("@p", PgGeometry.FromGeometry(point, srid: 4326));
cmd.ExecuteNonQuery();
}
using (var cmd = new NpgsqlCommand("SELECT geom FROM data", conn))
using (var reader = cmd.ExecuteReader())
{
reader.Read();
var value = reader.GetFieldValue<PgGeometry>(0);
Console.WriteLine(value.GeometryType); // no OGR object is created
Console.WriteLine(value.SRID);
using var geometry = value.CreateGeometry(); // you own it, you dispose it
}
}
Why PgGeometry and not Geometry
OSGeo.OGR.Geometry wraps native memory and has to be disposed. If a query result were mapped
straight to it, every geometry read from the database would be created with no owner — including
the ones your code never looks at. Their memory is invisible to the .NET garbage collector, so it
is released late and unpredictably.
PgGeometry holds the geometry as EWKB bytes instead:
- reading a row costs a buffer copy, and no native object is created at all;
CreateGeometry()builds the OGR object only when you ask for one, and the caller owns it;FromGeometry(geometry, srid)serialises immediately — the geometry you pass stays yours;- the type is immutable, so it is safe to cache, store and pass between threads;
- the database path never touches native GDAL, so reading and writing works without
GdalBase.ConfigureAll(). OnlyCreateGeometry()requires the native libraries.
PgGeometry also accepts standard ISO WKB in FromWkb, and preserves whatever byte order the
input used.
Migration from 8.0.x
Version 8.1.0 is a breaking change.
| 8.0.x | 8.1.0 |
|---|---|
UseGdal() mapping to OSGeo.OGR.Geometry |
removed — use UseGdal() with PgGeometry |
UseGdalExt() |
removed — UseGdal() now registers PgGeometry |
ExtGeometry |
PgGeometry |
ExtGeometry.Create(geometry, srid) |
PgGeometry.FromGeometry(geometry, srid) |
extGeometry.Geometry |
pgGeometry.CreateGeometry() — returns a new object you must dispose |
ExtGeometry.SRID (int?, null when unset) |
PgGeometry.SRID (int, 0 when unset) |
Reading a column now looks like this:
// 8.0.x
var eg = (reader[0] as ExtGeometry)!;
DoSomething(eg.Geometry); // never disposed
// 8.1.0
var value = reader.GetFieldValue<PgGeometry>(0);
using var geometry = value.CreateGeometry();
DoSomething(geometry);
Fixed along the way:
Mvalues ofPOINTM/LINESTRINGMgeometries were written as0;- the SRID of a geometry was read from the database but never written back to it;
- array mappings (
geometry[],geography[]) were registered but never took effect; - rings and sub-geometries were cloned and leaked while reading collections.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- MaxRev.Gdal.Core (>= 3.10.0.306)
- Npgsql (>= 8.0.3 && < 9.0.0)
- System.Memory (>= 4.5.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
8.1.0 is a breaking change. ExtGeometry and the direct mapping to OSGeo.OGR.Geometry are replaced by the immutable PgGeometry, which holds the geometry as EWKB bytes and creates an OGR object only when explicitly asked. Fixes M values being written as zero, the SRID never being written back to the database, and array mappings never taking effect. See the Migration section in the README.