Nettopologysuite logo

Nettopologysuite

Community
znlgis
nettopologysuite

Use when doing 2D computational geometry in .NET with NuGet NetTopologySuite 2.6.0 — GeometryFactory with SRID, Contains/Intersects predicates, Intersection/Union/Buffer overlays, STRtree, GeometryFixer, WKT/WKB/GeoJSON I/O, Shapefile via IO.Esri, and EF Core spatial queries on SQL Server/Npgsql.

Overview

Publisherznlgis
Repositoryopengis-skills
Skill namenettopologysuite
Stars
76
Forks
12
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by znlgis on GitHub. Read the source before you install it.

Installation

Install the Nettopologysuite AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/znlgis/opengis-skills/tree/main/gis/nettopologysuite
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/znlgis/opengis-skills.git /tmp/opengis-skills
mkdir -p .claude/skills
cp -r /tmp/opengis-skills/gis/nettopologysuite .claude/skills/nettopologysuite
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Nettopologysuite in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Nettopologysuite on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Nettopologysuite is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

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

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

官方文档: 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

环境准备

bash
dotnet add package NetTopologySuite --version 2.6.0

# GeoJSON:按序列化框架二选一(不要同时装)
dotnet add package NetTopologySuite.IO.GeoJSON --version 4.0.0       # Newtonsoft.Json
dotnet add package NetTopologySuite.IO.GeoJSON4STJ --version 4.0.0    # System.Text.Json

dotnet add package NetTopologySuite.IO.Esri.Shapefile --version 1.2.0 # Shapefile 读写
dotnet add package ProjNet --version 2.1.0                            # 坐标变换(可选)

.NET 6+ 推荐;各 IO 包需与主库 2.6 对齐(IO.GeoJSON / IO.GeoJSON4STJ / IO.Esri.Shapefile 均为 4.0.0、1.2.0 一档,ProjNet 2.1.0)。


核心 API:几何工厂

csharp
using NetTopologySuite;
using NetTopologySuite.Geometries;

// 推荐:由 NtsGeometryServices 提供工厂(也可继续用 new GeometryFactory(new PrecisionModel(), 4326))
var gf = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);

// 等价旧写法: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)
});

空间关系与运算

csharp
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

csharp
using NetTopologySuite;
using NetTopologySuite.IO;

// NTS 2.6 起推荐由 NtsGeometryServices 提供工厂(WKTReader(GeometryFactory) 已标记过时)
var services = NtsGeometryServices.Instance;
var rdr = new WKTReader(services);
var g = rdr.Read("POINT (116.4 39.9)");

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

GeoJSON 有两种包,按序列化框架二选一(两者都需与主库 2.6 对齐,均取 4.0.0):

包序列化框架用法
NetTopologySuite.IO.GeoJSONNewtonsoft.Json 13.xnew GeoJsonReader() / new GeoJsonWriter()
NetTopologySuite.IO.GeoJSON4STJSystem.Text.Jsonopts.Converters.Add(new GeoJsonConverterFactory())
csharp
using NetTopologySuite.IO.Converters;   // 来自 NetTopologySuite.IO.GeoJSON4STJ
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);

Newtonsoft 方案:

csharp
using NetTopologySuite.IO;

var writer = new GeoJsonWriter();
string json2 = writer.Write(g);
var g3 = new GeoJsonReader().Read(json2);

Shapefile

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

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

空间索引

csharp
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());

几何修复与简化

csharp
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

bash
dotnet add package Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite
# 或
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite
csharp
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)

csharp
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 });

典型工作流

端到端:WKT 读入 → 有效性修复 → 空间运算 → 写 GeoJSON / 入库。

csharp
using NetTopologySuite;
using NetTopologySuite.Geometries;
using NetTopologySuite.Geometries.Utilities;
using NetTopologySuite.IO;
using NetTopologySuite.IO.Converters;   // NetTopologySuite.IO.GeoJSON4STJ
using System.Text.Json;

// 1. 读入两个输入几何(第二个是自相交的"蝴蝶结",无效)
var services = NtsGeometryServices.Instance;
var reader = new WKTReader(services);
Geometry parcel = reader.Read("POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))");
Geometry zone = reader.Read("POLYGON ((5 5, 15 15, 15 5, 5 15, 5 5))");

// 2. 校验并修复(GeometryFixer 可能把无效面拆成 MultiPolygon)
Console.WriteLine(zone.IsValid);                 // False
if (!zone.IsValid)
    zone = GeometryFixer.Fix(zone);               // 修成 MultiPolygon,IsValid=True

// 3. 空间运算:求交 + 缓冲
Geometry overlap = parcel.Intersection(zone);
Geometry buffered = overlap.Buffer(1.0);
Console.WriteLine(overlap.Area);                  // 12.5(两三角形在方形内的部分)

// 4. 写 GeoJSON(System.Text.Json 转换器,需 GeoJSON4STJ 包)
var opts = new JsonSerializerOptions();
opts.Converters.Add(new GeoJsonConverterFactory());
string geoJson = JsonSerializer.Serialize(buffered, opts);

// 5. 回读校验
Geometry back = JsonSerializer.Deserialize<Geometry>(geoJson, opts);
Console.WriteLine(back.IsValid);                  // True

输出与验收:geoJson 能以 JsonSerializer.Deserialize<Geometry> 读回且 back.IsValid 为 true;overlap.Area 为 12.5(面积只在投影/平面坐标下有实际含义,经纬度下是平面近似值)。

其他常用步骤:

  1. 创建几何工厂:跨方法共享同一个 GeometryFactory 并固定 SRID,避免几何间 SRID 不一致
  2. 空间索引:数据量超过几千条时先建 STRtree,再做批量 Intersects 粗筛
  3. 格式读写:WKTReader/WKTWriter、GeoJsonConverterFactory;Shapefile 走 NetTopologySuite.IO.Esri
  4. EF Core 集成:UseNetTopologySuite() 让 Distance()/Intersects() 翻译为空间 SQL

性能优化

  1. 共享 GeometryFactory,固定 SRID
  2. 大批量空间查询用 STRtree
  3. WKB 比 WKT 更快更紧凑
  4. 多次空间关系判断使用 PreparedGeometry:
csharp
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
找不到 GeoJsonConverterFactory该类属于 NetTopologySuite.IO.GeoJSON4STJ(System.Text.Json),不是 NetTopologySuite.IO.GeoJSON(Newtonsoft)
Buffer 慢减小 quadrantSegments、并行处理
Shapefile 读取写法报错使用 NetTopologySuite.IO.Esri.Shapefile 包与 NetTopologySuite.IO.Esri 命名空间(Shapefile.ReadAllFeatures)
依赖版本不匹配(NTS 2.6 与旧 IO 包)对齐版本:IO.GeoJSON 4.0.0、IO.Esri.Shapefile 1.2.0、ProjNet 2.1.0

AI 使用建议

  • 执行环境:命令在终端 / shell 中执行;先 dotnet --version 确认 SDK 6.0+,dotnet restore 需要访问 NuGet。
  • 先探测版本:dotnet list package 核对 NetTopologySuite 2.6.0、NetTopologySuite.IO.GeoJSON(或 IO.GeoJSON4STJ)4.0.0、NetTopologySuite.IO.Esri.Shapefile 1.2.0、ProjNet 2.1.0;IO 包与主库错配是常见编译/运行期报错源。
  • 验证产物:dotnet build 后跑 dotnet test,或最小控制台做 WKT 往返 + IsValid 断言;GeoJsonConverterFactory 序列化后再反序列化,比对坐标数而不是只打日志。
  • 失败信号:TopologyException 先 GeometryFixer.Fix;程序集加载/TypeInitializationException 多为 IO 包版本不匹配;EF Core 类型冲突是同时引了 Microsoft.SqlServer.Types。
  • 注意事项:NTS 的 SRID 只是元数据、计算在平面进行,跨投影交给 ProjNet;WKBWriter 默认丢 Z/M,需设 HandleOrdinates。
  • 按需读文件:本 SKILL 代码块较多,先按章节标题定位再分段读取,比整篇读更省上下文。

NTS 家族与相关库

包用途
NetTopologySuite.IO.VectorTilesMapbox Vector Tiles(MVT)读写
NetTopologySuite.IO.GeoJSONGeoJSON 读写(Newtonsoft.Json)
NetTopologySuite.IO.GeoJSON4STJGeoJSON 读写(System.Text.Json,提供 GeoJsonConverterFactory)
NetTopologySuite.IO.Esri.ShapefileShapefile 读写(命名空间 NetTopologySuite.IO.Esri)
ProjNet坐标参考系与投影变换(当前主线 2.1.0;旧包 ProjNet4GeoAPI 停在 1.4.1,新项目用 ProjNet)

相关技能

参考资源

Frequently asked questions

What does the Nettopologysuite AI skill do?

Use when doing 2D computational geometry in .NET with NuGet NetTopologySuite 2.6.0 — GeometryFactory with SRID, Contains/Intersects predicates, Intersection/Union/Buffer overlays, STRtree, GeometryFixer, WKT/WKB/GeoJSON I/O, Shapefile via IO.Esri, and EF Core spatial queries on SQL Server/Npgsql.

Why use Nettopologysuite on TypingMind?

Because you install it once and use it with any model. Nettopologysuite is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Nettopologysuite in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/znlgis/opengis-skills/tree/main/gis/nettopologysuite. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Nettopologysuite?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Nettopologysuite?

As many as you like. As long as a model supports skills, you can use Nettopologysuite with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Nettopologysuite AI skill free?

Yes. It is published on GitHub by znlgis under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇