VOOZH about

URL: https://deepwiki.com/npgsql/efcore.pg/6.5-spatial-data-with-nettopologysuite

⇱ Spatial Data with NetTopologySuite | npgsql/efcore.pg | DeepWiki


Loading...
Menu

Spatial Data with NetTopologySuite

The NetTopologySuite (NTS) plugin enables spatial data support in the Npgsql EF Core provider by integrating with PostgreSQL's PostGIS extension. This plugin provides type mappings between NTS geometry types and PostGIS spatial types, and translates LINQ spatial operations into PostGIS SQL functions.

Overview

The NTS plugin is a separate package (Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite) that extends the core provider through the plugin architecture. It registers spatial type mappings via IRelationalTypeMappingSourcePlugin and translates spatial method calls via IMethodCallTranslatorPlugin.

NetTopologySuite Plugin Architecture


The plugin integrates at several extension points:

  1. Type Mapping: NpgsqlNetTopologySuiteTypeMappingSourcePlugin registers mappings for NTS types (Point, Polygon, etc.) to PostGIS types (geometry, geography).
  2. Query Translation: Method, aggregate, and member translators convert LINQ spatial operations to PostGIS functions like ST_Distance, ST_Intersects, and ST_Collect.

Sources: src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteServiceCollectionExtensions.cs13-37 src/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs14-15

Setup

Installation

The NTS plugin is distributed as a separate NuGet package that references both the core Npgsql EF Core provider and the Npgsql.NetTopologySuite ADO.NET plugin. The PostGIS extension must be installed in your PostgreSQL database:


Plugin Configuration

Enable the NTS plugin by calling UseNetTopologySuite() on the NpgsqlDbContextOptionsBuilder:


Configuration options are managed via NpgsqlNetTopologySuiteOptionsExtension and INpgsqlNetTopologySuiteSingletonOptions:

OptionDescriptionFile Reference
HandleOrdinatesSpecifies which coordinate dimensions to handle (X, Y, Z, M)src/EFCore.PG.NTS/Infrastructure/Internal/NpgsqlNetTopologySuiteOptionsExtension.cs39
IsGeographyDefaultMaps CLR types to geography instead of geometrysrc/EFCore.PG.NTS/Infrastructure/Internal/NpgsqlNetTopologySuiteOptionsExtension.cs47
PrecisionModelNTS Precision model to use for geometriessrc/EFCore.PG.NTS/Infrastructure/Internal/NpgsqlNetTopologySuiteOptionsExtension.cs31

Sources: src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.cs1-30 src/EFCore.PG.NTS/Infrastructure/Internal/NpgsqlNetTopologySuiteOptionsExtension.cs13-55

Type Mappings

CLR Type to PostgreSQL Type Mappings

The plugin registers mappings for NetTopologySuite types through NpgsqlNetTopologySuiteTypeMappingSourcePlugin. It parses PostGIS store type names to determine the correct CLR type and metadata (SRID, Ordinates).

NTS CLR TypePostGIS Subtype NameFile Reference
PointPOINTsrc/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs24
LineStringLINESTRINGsrc/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs25
PolygonPOLYGONsrc/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs26
MultiPointMULTIPOINTsrc/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs27
MultiLineStringMULTILINESTRINGsrc/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs28
MultiPolygonMULTIPOLYGONsrc/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs29
GeometryCollectionGEOMETRYCOLLECTIONsrc/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs30
GeometryGEOMETRYsrc/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs31

The NpgsqlGeometryTypeMapping<TGeometry> class handles the generation of SQL literals, including SRID prefixes (e.g., GEOMETRY 'SRID=4326;POINT(0 0)').

Sources: src/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs20-36 src/EFCore.PG.NTS/Storage/Internal/NpgsqlGeometryTypeMapping.cs76-98

Store Type Parsing

The provider can parse complex PostGIS store types using TryParseStoreTypeName. This allows it to extract:

  • Whether it is a geometry or geography type.
  • The subtype (e.g., Point, LineString).
  • The SRID (e.g., 4326).
  • Ordinates (e.g., Z, M).

Sources: src/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs117-182

Query Translation

Translation Components

The plugin provides three primary translation plugins that bridge the gap between .NET NTS calls and PostGIS functions:

  1. NpgsqlNetTopologySuiteMethodCallTranslatorPlugin: Translates instance methods on Geometry and its subclasses.
  2. NpgsqlNetTopologySuiteMemberTranslatorPlugin: Translates property access (like Point.X or Geometry.Area).
  3. NpgsqlNetTopologySuiteAggregateMethodCallTranslatorPlugin: Translates LINQ aggregates like GeometryCombiner.Combine or ConvexHull.Create.

Translated NTS Methods

NTS MethodPostGIS Function / OperatorSource File
Distance(other)ST_Distancesrc/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs135
Intersects(other)ST_Intersectstest/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeographyTest.cs191
Buffer(distance)ST_Buffertest/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs71
Contains(other)ST_Containstest/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs132
Enumerable.ElementAt(x)ST_GeometryN(collection, x + 1)src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs93-99

Translated Properties

NTS PropertyPostGIS FunctionSource File
Point.XST_Xsrc/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMemberTranslatorPlugin.cs121
Point.YST_Ysrc/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMemberTranslatorPlugin.cs122
Geometry.AreaST_Areatest/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs27
Geometry.CentroidST_Centroidtest/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs93

EF.Functions Extensions

NpgsqlNetTopologySuiteDbFunctionsExtensions provides access to PostGIS-specific features that don't have direct NTS equivalents:

Extension MethodSQL TranslationPurpose
Transform(geom, srid)ST_TransformCoordinate system conversion
IntersectsBbox(g1, g2)&& operatorBounding box intersection check
DistanceKnn(g1, g2)<-> operatorIndex-assisted nearest-neighbor distance
IsWithinDistanceST_DWithinEfficient distance check

Sources: src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbFunctionsExtensions.cs8-83 src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs104-141

Aggregate Translations

Aggregate translations are handled by NpgsqlNetTopologySuiteAggregateMethodTranslator. It maps NTS utility classes to PostGIS aggregate functions:

  • GeometryCombiner.Combine maps to ST_Collect.
  • ConvexHull.Create maps to ST_ConvexHull(ST_Collect(...)).
  • EnvelopeCombiner.CombineAsGeometry maps to ST_Extent (with a cast to geometry).

Sources: src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteAggregateMethodCallTranslatorPlugin.cs52-143

Translation Data Flow

The following diagram illustrates how a LINQ query is processed by the spatial translators:


Sources: src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs73-102 src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMemberTranslatorPlugin.cs100-111

Testing and Validation

The provider includes extensive functional tests for both geometry and geography types.

  • SpatialQueryNpgsqlGeometryTest: Validates translations for standard geometry operations like ST_Area, ST_Buffer, and ST_Contains.
  • SpatialQueryNpgsqlGeographyTest: Validates translations for geography-specific behavior, including spheroid distance calculations via ST_Distance(..., useSpheroid).

Sources: test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeometryTest.cs10-41 test/EFCore.PG.FunctionalTests/Query/SpatialQueryNpgsqlGeographyTest.cs99-123