Geometry Api Net logo

Geometry Api Net

Community
znlgis
geometry-api-net

Use when working with Esri geometry types (Point, Polyline, Polygon, Envelope) in .NET/C# — GeometryEngine, NuGet OpenGIS.Esri.Geometry.Core 1.0.9, WKT/EWKT, WKB, GeoJSON and Esri JSON I/O, System.Text.Json converters, geodesic distance; also for unclosed polygon rings, Geometry base-class casts after overlay, or the retired Esri/geometry-api-net repo. Esri Geometry API for .NET.

Overview

Publisherznlgis
Repositoryopengis-skills
Skill namegeometry-api-net
Stars
76
Forks
12
Bundled files
1
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.

  • 1 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

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

Installation

Install the Geometry Api Net 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/geometry-api-net
  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/geometry-api-net .claude/skills/geometry-api-net
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Geometry Api Net 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 Geometry Api Net 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 Geometry Api Net 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/znlgis/geometry-api-net

官方文档: https://github.com/znlgis/geometry-api-net/wiki

NuGet: OpenGIS.Esri.Geometry.Core(最新 1.0.9,截至 2026-10)

许可证: LGPL-2.1

注意: 原 Esri 仓库(github.com/Esri/geometry-api-net)已停止维护(404);此分支由 znlgis 社区维护,包名与命名空间已改为 OpenGIS.Esri.Geometry。

概述

这是一个 .NET Standard 2.0 的空间几何计算库,提供 6 种几何类型(Point、MultiPoint、Line、Polyline、Polygon、Envelope)、35 个算子类(Operators 命名空间 27 个几何算子 + IO 命名空间 8 个读写算子,含 8 个 DE-9IM 谓词:Contains/Crosses/Disjoint/Equals/Intersects/Overlaps/Touches/Within)和 4 种序列化格式(WKT/EWKT、WKB/EWKB、GeoJSON、Esri JSON)。

  • 核心包:OpenGIS.Esri.Geometry.Core(GeometryEngine 提供 39 个静态便捷方法)
  • JSON 扩展包:OpenGIS.Esri.Geometry.Json(System.Text.Json 转换器)
  • 许可证:LGPL-2.1-only
  • 能力边界:不提供 MakeValid,Simplify 只做抽稀、不修复自相交环;需要几何修复请在上游(GEOS/PostGIS/JTS)完成后再导入。

快速开始

bash
dotnet add package OpenGIS.Esri.Geometry.Core
dotnet add package OpenGIS.Esri.Geometry.Json    # 可选,System.Text.Json 支持

核心 API 与命名空间

命名空间用途
OpenGIS.Esri.Geometry.Core核心入口,GeometryEngine 便捷 API
OpenGIS.Esri.Geometry.Core.Geometries几何类型(Point, Polygon 等)
OpenGIS.Esri.Geometry.Core.Operators空间运算算子
OpenGIS.Esri.Geometry.Core.SpatialReference空间参考 / 坐标系统
OpenGIS.Esri.Geometry.Core.IO序列化(WKT, WKB, GeoJSON, EsriJson)
OpenGIS.Esri.Geometry.Json.ConvertersSystem.Text.Json 转换器

几何类型体系与两种 API 风格的完整说明见 reference/geometry-types.md

序列化格式

WKT(Well-Known Text)

csharp
using OpenGIS.Esri.Geometry.Core.IO;

// 导出
string wkt = WktExportOperator.ExportToWkt(geometry);
// "POINT (10.5 20.7)"
// "POINT Z (10.5 20.7 30.1)"
// "LINESTRING (0 0, 10 0, 10 10)"
// "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))"
// "MULTIPOINT ((1 2), (3 4))"

// 导入
Geometry geometry = WktImportOperator.ImportFromWkt("POINT (10.5 20.7)");

WKB(Well-Known Binary)

csharp
// 导出(默认小端序)
byte[] wkb = WkbExportOperator.ExportToWkb(geometry);
byte[] wkbBigEndian = WkbExportOperator.ExportToWkb(geometry, bigEndian: true);

// 导入(自动检测字节序)
Geometry geometry = WkbImportOperator.ImportFromWkb(wkbBytes);

GeoJSON

csharp
// 导出
string geoJson = GeoJsonExportOperator.ExportToGeoJson(geometry);
// {"type":"Point","coordinates":[10.5,20.7]}

// 导入
Geometry geometry = GeoJsonImportOperator.ImportFromGeoJson(geoJsonString);

Esri JSON

csharp
// 导出
string esriJson = EsriJsonExportOperator.Instance.Execute(geometry);
// Point:      {"x":10.5,"y":20.7}
// MultiPoint: {"points":[[1,2],[3,4]]}
// Polyline:   {"paths":[[[0,0],[10,0],[10,10]]]}
// Polygon:    {"rings":[[[0,0],[10,0],[10,10],[0,10],[0,0]]]}
// Envelope:   {"xmin":0,"ymin":0,"xmax":10,"ymax":10}

// 导入
Geometry geometry = EsriJsonImportOperator.ImportFromEsriJson(esriJsonString);

System.Text.Json 集成

csharp
using OpenGIS.Esri.Geometry.Json.Converters;

var options = new JsonSerializerOptions();
options.Converters.Add(new PointJsonConverter());

string json = JsonSerializer.Serialize(point, options);
Point point = JsonSerializer.Deserialize<Point>(json, options);

空间参考

csharp
using OpenGIS.Esri.Geometry.Core.SpatialReference;

// 预定义空间参考
var wgs84 = SpatialReference.Wgs84();          // EPSG:4326 (经纬度)
var webMercator = SpatialReference.WebMercator(); // EPSG:3857 (Web 墨卡托)

// 自定义 WKID
var sr = new SpatialReference(4490);            // CGCS2000

// 属性
sr.Wkid         // int?, WKID 编号
sr.LatestWkid   // int?, 最新 WKID
sr.Wkt          // string?, WKT 表示

// 组合几何与空间参考
var mapGeom = new MapGeometry(geometry, SpatialReference.Wgs84());
mapGeom.Geometry         // Geometry 对象
mapGeom.SpatialReference // SpatialReference 对象

Proximity2DResult(邻近搜索结果)

csharp
Proximity2DResult result = GeometryEngine.GetNearestCoordinate(geometry, point);

result.IsEmpty       // bool, 结果是否为空
result.Coordinate    // Point, 最近坐标点
result.VertexIndex   // int, 最近顶点索引
result.Distance      // double, 距离
result.IsRightSide   // bool, 是否在多路径几何的右侧

典型工作流

端到端:WKT 读入 → 有效性校验 → 叠加分析 → 输出 GeoJSON 与 Esri JSON。

csharp
using OpenGIS.Esri.Geometry.Core;
using OpenGIS.Esri.Geometry.Core.Geometries;
using OpenGIS.Esri.Geometry.Core.IO;

// 1. 从 WKT 读入输入几何(环由库自动闭合)
Geometry parcel = GeometryEngine.GeometryFromWkt(
    "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))");
Geometry zone = GeometryEngine.GeometryFromWkt(
    "POLYGON ((5 5, 15 5, 15 15, 5 15, 5 5))");

// 2. 校验:先确认几何本身可用,不要拿 0 容差去"修复"
if (!parcel.IsValid() || !zone.IsValid())
    throw new InvalidOperationException("输入几何无效,请先修正数据");

// 3. 叠加:求交集(5×5 的方形重叠区)
Geometry overlapArea = GeometryEngine.Intersection(parcel, zone);
bool intersects = GeometryEngine.Intersects(parcel, zone);   // true
double area = GeometryEngine.Area(overlapArea);              // 约 25(内部容差带来 1e-6 级误差)

// 4. 输出两种格式
string geoJson = GeometryEngine.GeometryToGeoJson(overlapArea);
string esriJson = EsriJsonExportOperator.Instance.Execute(overlapArea);

// 5. 回读校验:序列化再反序列化,几何应一致
Geometry roundTrip = GeometryEngine.GeometryFromGeoJson(geoJson);
bool same = GeometryEngine.Equals(overlapArea, roundTrip);

输出与验收:

  • overlapArea 是 (5,5)-(10,10) 的矩形,GeometryEngine.Area() 实测约 24.999998(默认容差 1e-10 下的浮点结果,不要断言严格等于 25)。
  • geoJson 形如 {"type":"Polygon","coordinates":[[[10,5],...]]};esriJson 形如 {"rings":[[[10,5],...]]}。
  • same 必须为 true;若为 false,先检查环是否闭合、坐标顺序是否一致。
  • GeometryEngine.Simplify(geometry, tolerance) 的 tolerance 必须为正,传 0.0 会抛 ArgumentException: Tolerance must be positive;且 Simplify 只做抽稀,不保证把自相交环修成有效面,需修复无效数据请在上游处理。

注意:集合运算返回 Geometry 基类,需要面积/环等具体成员时按实际类型(Polygon/Polyline)转型后再用。


常见开发场景

场景 1:判断点是否在多边形内

csharp
var polygon = new Polygon();
polygon.AddRing(new[] {
    new Point(0, 0), new Point(10, 0), new Point(10, 10),
    new Point(0, 10), new Point(0, 0)
});
var point = new Point(5, 5);

bool inside = GeometryEngine.Contains(polygon, point);  // true

场景 2:计算两个经纬度点之间的大地距离(米)

csharp
var beijing = new Point(116.4074, 39.9042);
var shanghai = new Point(121.4737, 31.2304);

double meters = GeometryEngine.GeodesicDistance(beijing, shanghai);

场景 3:创建缓冲区

csharp
var point = new Point(10, 20);
Geometry buffer = GeometryEngine.Buffer(point, 5.0);  // 半径为 5 的缓冲区

var envelope = buffer.GetEnvelope();
// XMin=5, YMin=15, XMax=15, YMax=25

场景 4:计算两个区域的交集

csharp
var env1 = new Envelope(0, 0, 10, 10);
var env2 = new Envelope(5, 5, 15, 15);

Geometry result = GeometryEngine.Intersection(env1, env2);
// 交集区域: (5,5) 到 (10,10)

场景 5:合并多个几何体

csharp
var p1 = new Point(0, 0);
var p2 = new Point(10, 10);

Geometry merged = GeometryEngine.Union(p1, p2);
// 结果为 MultiPoint,包含两个点

场景 6:GeoJSON 往返序列化

csharp
var polygon = new Polygon();
polygon.AddRing(new[] {
    new Point(0, 0), new Point(1, 0), new Point(1, 1),
    new Point(0, 1), new Point(0, 0)
});

string geoJson = GeometryEngine.GeometryToGeoJson(polygon);
Geometry restored = GeometryEngine.GeometryFromGeoJson(geoJson);

场景 7:从 WKT 导入几何体并做空间分析

csharp
var geom1 = GeometryEngine.GeometryFromWkt("POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))");
var geom2 = GeometryEngine.GeometryFromWkt("POINT (5 5)");

bool contains = GeometryEngine.Contains(geom1, geom2);  // true
double distance = GeometryEngine.Distance(geom1, geom2); // 0

场景 8:获取几何体的凸包

csharp
var multiPoint = new MultiPoint(new[] {
    new Point(0, 0), new Point(10, 0), new Point(5, 10),
    new Point(3, 3), new Point(7, 2)
});

Geometry hull = GeometryEngine.ConvexHull(multiPoint);
// 结果为包围所有点的最小凸多边形

场景 9:计算多边形的质心

csharp
var polygon = new Polygon();
polygon.AddRing(new[] {
    new Point(0, 0), new Point(10, 0), new Point(10, 10),
    new Point(0, 10), new Point(0, 0)
});

Point centroid = GeometryEngine.Centroid(polygon);
// centroid.X = 5, centroid.Y = 5

场景 10:线的简化与加密

csharp
var polyline = new Polyline();
polyline.AddPath(new[] {
    new Point(0, 0), new Point(5, 0.1), new Point(10, 0),
    new Point(10, 5), new Point(10, 10)
});

// 简化:移除偏差小于 tolerance 的顶点
Geometry simplified = GeometryEngine.Simplify(polyline, 0.5);

// 加密:确保每段不超过 maxSegmentLength
Geometry densified = GeometryEngine.Densify(polyline, 2.0);

// 泛化:保持形状前提下减少顶点
Geometry generalized = GeometryEngine.Generalize(polyline, 1.0);

构建与测试

bash
# 构建
dotnet build

# 运行测试(xUnit)
dotnet test

# 运行示例
dotnet run --project samples/OpenGIS.Esri.Geometry.Samples

常见问题

问题解决
NuGet 安装后找不到命名空间同时安装 OpenGIS.Esri.Geometry.Core 与(可选)OpenGIS.Esri.Geometry.Json;命名空间为 OpenGIS.Esri.Geometry.Core.*
Polygon 面积 / 包含判断异常环必须闭合(首尾点相同);注意 IsValid() 对自相交环较宽松,可能返回 true
Simplify 抛 ArgumentException: Tolerance must be positive容差必须为正,不能传 0.0;Simplify 只抽稀,不修复自相交
浮点坐标比较误差内部容差 GeometryConstants.DefaultTolerance(1e-10),为内部常量、不可外部配置;面积等断言用近似比较
集合运算返回值类型不符预期返回 Geometry 基类,需按实际类型做类型转换后使用
无法 new 算子实例所有 Operator 类通过 Instance 属性获取 Lazy 单例
修改 GetRing() / GetPath() 结果报错返回 IReadOnlyList<Point> 只读视图,需要复制后修改
GeodesicDistance 结果异常基于 WGS84(Vincenty 公式),输入必须是经纬度坐标;GeodesicArea 使用球面超量公式
GeoJSON 导出类型与预期不符单路径 Polyline 导出为 LineString,多路径导出为 MultiLineString;Envelope 导出为 Polygon

AI 使用建议

  • 本技能的组织:主文件给高频用法,完整参数表与高级示例在 reference/geometry-types.md,需要时再展开;示例工程与生成的数据写到工作目录,不要改动技能目录本身。
  • 执行环境:先 dotnet --version(库目标 netstandard2.0,可被 net6/net8/net9/net10 引用);Windows 上用 PowerShell 执行 dotnet 命令,dotnet new console -o demo && cd demo 建最小工程。
  • 依赖坐标:dotnet add package OpenGIS.Esri.Geometry.Core --version 1.0.9(NuGet 最新 1.0.9,2026-09-21),需要 System.Text.Json 转换器时再装 OpenGIS.Esri.Geometry.Json;还原失败报 NU1101 说明源或版本不可用,报告“依赖不可下载”,不要自己编版本号。
  • 验证产物:最小控制台程序断言三件事——GeometryEngine.GeometryFromWkt → GeometryToWkt 往返、GeometryEngine.Contains(polygon, point) 返回 true、GeometryEngine.Buffer(point, 5.0).GetEnvelope() 为 (XMin=5,YMin=15,XMax=15,YMax=25),再 dotnet run 看实际输出;dotnet build 成功不代表几何结果正确。
  • 构建与测试:dotnet build 编译、dotnet test 跑 xUnit、dotnet run --project samples/OpenGIS.Esri.Geometry.Samples 跑示例(需在仓库 checkout 内,且该路径存在);输出在 bin/、obj/,不要提交。
  • 编译期陷阱:Polygon.AddRing 必须闭合(首尾点相同)否则面积/包含判断异常;集合运算返回 Geometry 基类,要按 Point/Polygon 转型后再用;容差 GeometryConstants.DefaultTolerance(1e-10)是内部常量,无法外部调整。
  • 大地测量前提:GeodesicDistance/GeodesicArea 基于 WGS84(Vincenty),输入必须是经纬度;对投影坐标(如 EPSG:3857 米制)调用会得到无意义结果。
  • 安全与权限:dotnet restore 需访问 NuGet 源,离线时先确认本地缓存;修改全局 NuGet.config、安装 SDK 或写入系统目录前先征得用户同意,命令输出里不要回显私有源凭据。

相关技能

参考资源

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Geometry Api Net AI skill do?

Use when working with Esri geometry types (Point, Polyline, Polygon, Envelope) in .NET/C# — GeometryEngine, NuGet OpenGIS.Esri.Geometry.Core 1.0.9, WKT/EWKT, WKB, GeoJSON and Esri JSON I/O, System.Text.Json converters, geodesic distance; also for unclosed polygon rings, Geometry base-class casts after overlay, or the retired Esri/geometry-api-net repo. Esri Geometry API for .NET.

Why use Geometry Api Net on TypingMind?

Because you install it once and use it with any model. Geometry Api Net 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 Geometry Api Net in TypingMind?

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

Which AI models can use Geometry Api Net?

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 Geometry Api Net?

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

Is the Geometry Api Net 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 👇