Gdal.Npgsql 8.1.0

There is a newer version of this package available.
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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Gdal.Npgsql" Version="8.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Gdal.Npgsql" Version="8.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Gdal.Npgsql" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Gdal.Npgsql --version 8.1.0
                    
#r "nuget: Gdal.Npgsql, 8.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Gdal.Npgsql@8.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Gdal.Npgsql&version=8.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Gdal.Npgsql&version=8.1.0
                    
Install as a Cake Tool

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(). Only CreateGeometry() 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:

  • M values of POINTM/LINESTRINGM geometries were written as 0;
  • 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.2.0 138 9/1/2026
8.1.0 114 9/1/2026
8.0.3.2 699 7/15/2024
8.0.3.1 241 7/15/2024
8.0.3 254 7/15/2024
8.0.2.2 255 5/3/2024
8.0.2.1 250 5/3/2024
8.0.2 235 5/3/2024

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.