L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Données et recherche · SKILL.md

nettopologysuite

nettopologysuite

Use when performing 2D computational geometry in .NET — spatial predicates, overlay operations, buffering, WKT/WKB I/O. NetTopologySuite: the .NET port of JTS, available via NuGet for spatial analysis in C# applications.

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: nettopologysuite description: "Use when performing 2D computational geometry in .NET — spatial predicates, overlay operations, buffering, WKT/WKB I/O. NetTopologySuite: the .NET port of JTS, available via NuGet for spatial analysis in C# applications." tags:

  • dotnet
  • csharp
  • geometry
  • spatial
  • wkt
  • wkb
  • geojson
  • ef-core
  • npgsql

项目地址: https://github.com/NetTopologySuite/NetTopologySuite

NuGet: NetTopologySuite(最新稳定版 2.6.0,截至2026年)

官方文档: https://nettopologysuite.github.io/NetTopologySuite/

许可证: BSD-3-Clause

概述

NTS 与 JTS API 几乎一一对应(C# 命名风格):

  • 几何模型:Point/LineString/Polygon/Multi*/GeometryCollection
  • 空间关系:Equals/Contains/Within/Intersects/Touches/Crosses/Overlaps/Disjoint/Relate
  • 集合运算:Intersection/Union/Difference/SymmetricDifference/Buffer
  • 几何分析:ConvexHull/Centroid/Area/Length/Distance/IsValid/Simplify
  • 空间索引:STRtree/Quadtree
  • 格式读写:WKT、WKB、GeoJSON、Shapefile(独立 NuGet)
  • EF Core 集成:SqlServer 与 PostgreSQL 自动翻译为空间 SQL

环境准备

dotnet add package NetTopologySuite
dotnet add package NetTopologySuite.IO.GeoJSON
dotnet add package NetTopologySuite.IO.ShapeFile
dotnet add package ProjNet                          # 坐标变换(可选)

.NET 6+ 推荐。


几何工厂

using NetTopologySuite.Geometries;

var gf = new GeometryFactory(new PrecisionModel(), 4326);

var p  = gf.CreatePoint(new Coordinate(116.397, 39.908));
var ls = gf.CreateLineString(new[] {
    new Coordinate(116, 39), new Coordinate(117, 40)
});
var poly = gf.CreatePolygon(new[] {
    new Coordinate(0,0), new Coordinate(10,0),
    new Coordinate(10,10), new Coordinate(0,10), new Coordinate(0,0)
});

空间关系与运算

bool b   = polyA.Intersects(polyB);
var inter = polyA.Intersection(polyB);
var union = polyA.Union(polyB);
var diff  = polyA.Difference(polyB);

var buf  = p.Buffer(100);
var hull = mp.ConvexHull();
double area = poly.Area;
double len  = ls.Length;
double dist = polyA.Distance(polyB);

string rel = polyA.Relate(polyB).ToString();
bool ok    = polyA.Relate(polyB, "T*F**F***");

WKT / WKB / GeoJSON

using NetTopologySuite.IO;

var rdr = new WKTReader();
var g = rdr.Read("POINT (116.4 39.9)");

string wkt = new WKTWriter().Write(g);
byte[] wkb = new WKBWriter().Write(g);

using NetTopologySuite.IO.Converters;
using System.Text.Json;
var opts = new JsonSerializerOptions();
opts.Converters.Add(new GeoJsonConverterFactory());
string json = JsonSerializer.Serialize(g, opts);
var g2 = JsonSerializer.Deserialize<Geometry>(json, opts);

Shapefile

using NetTopologySuite.IO.Esri;
foreach (var f in Shapefile.ReadAllFeatures("input.shp"))
    Console.WriteLine(quot;{f.Geometry} {f.Attributes["NAME"]}");

Shapefile.WriteAllFeatures(features, "output.shp");

空间索引

using NetTopologySuite.Index.Strtree;

var tree = new STRtree<Geometry>();
foreach (var g in geometries)
    tree.Insert(g.EnvelopeInternal, g);
tree.Build();

var hits   = tree.Query(queryEnv);
var nearby = tree.NearestNeighbour(p.EnvelopeInternal, p, new GeometryItemDistance());

几何修复与简化

using NetTopologySuite.Operation.Valid;
using NetTopologySuite.Simplify;
using NetTopologySuite.Geometries.Utilities;

if (!poly.IsValid)
    poly = (Polygon)GeometryFixer.Fix(poly);

var simp = TopologyPreservingSimplifier.Simplify(poly, 0.001);

EF Core + SQL Server / PostgreSQL

dotnet add package Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite
# 或
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite
public class City {
    public int Id { get; set; }
    public string Name { get; set; }
    public Point Location { get; set; }
    public Geometry Boundary { get; set; }
}

services.AddDbContext<AppDb>(o =>
    o.UseSqlServer(conn, x => x.UseNetTopologySuite()));

var nearby = db.Cities
    .Where(c => c.Location.Distance(target) < 5000)
    .OrderBy(c => c.Location.Distance(target))
    .Take(10)
    .ToList();   // 自动翻译为空间 SQL

坐标系转换(ProjNet)

using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;

var src = GeographicCoordinateSystem.WGS84;
var tgt = ProjectedCoordinateSystem.WebMercator;
var ct  = new CoordinateTransformationFactory()
            .CreateFromCoordinateSystems(src, tgt);
double[] xy = ct.MathTransform.Transform(new[] { 116.397, 39.908 });

性能优化

  1. 共享 GeometryFactory,固定 SRID
  2. 大批量空间查询用 STRtree
  3. WKB 比 WKT 更快更紧凑
  4. 多次空间关系判断使用 PreparedGeometry:
using NetTopologySuite.Geometries.Prepared;
var prep = PreparedGeometryFactory.Prepare(largePoly);
foreach (var p in points) if (prep.Contains(p)) ...

常见问题

问题解决
TopologyExceptionGeometryFixer.Fix 修复无效几何
EF Core 类型冲突用 UseNetTopologySuite() 而非 Microsoft.SqlServer.Types
Z/M 坐标丢失配置 WKBWriter 的 HandleOrdinates
Buffer 慢减小 quadrantSegments、并行处理

AI 使用建议

推荐工作流

  1. 创建几何工厂:使用 new GeometryFactory(new PrecisionModel(), 4326) 创建工厂,SRID 指定坐标系
  2. 创建几何对象:通过工厂方法 CreatePoint()、CreateLineString()、CreatePolygon() 创建几何
  3. 空间运算:直接调用几何对象方法 Intersects()、Intersection()、Buffer() 等
  4. 格式读写:使用 WKTReader/WKTWriter、GeoJsonConverterFactory 进行序列化
  5. EF Core 集成:UseNetTopologySuite() 启用空间查询翻译为 SQL

关键注意事项

  • GeometryFactory 共享:固定 SRID,复用 GeometryFactory 实例
  • 拓扑异常修复:无效几何使用 GeometryFixer.Fix() 修复
  • PreparedGeometry:重复空间关系判断时使用 PreparedGeometryFactory.Prepare() 大幅提速
  • STRtree 批量查询:先 Build() 再 Query(),大数据量场景优于逐几何判断
  • WKB vs WKT:WKB 比 WKT 更快更紧凑,数据库交互优先使用 WKB
  • Z/M 坐标:WKBWriter 需配置 HandleOrdinates 保留 Z/M 坐标

相关技能

参考资源

Skills enregistrées