بنقرة واحدة
geometry-api-net
geometry-api-net 是一个 .NET Standard 2.0 的空间几何计算库,提供对二维和三维几何对象的创建、解析、序列化以及空间关系运算能力。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
geometry-api-net 是一个 .NET Standard 2.0 的空间几何计算库,提供对二维和三维几何对象的创建、解析、序列化以及空间关系运算能力。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
面向 AI 编程助手的开源 GIS、CAD、C#、AI、IoT、3D 技能集合。覆盖 65 个开源项目,提供一站式技能索引、标签搜索、按需加载指南,让 AI 助手在 GIS/CAD/C#/AI/3D 领域获得更准确的代码生成与问题排查能力。
DocuTranslate(xunbu/docutranslate)是基于大语言模型的轻量级本地文件翻译工具,支持 PDF/Word/Excel/Markdown/EPUB/字幕/JSON 等多格式翻译,内置 MinerU PDF 解析、术语表自动生成、Web UI、REST API、Client SDK 与 MCP 接入。
AI/LLM 技能分类索引,覆盖 LLM 应用开发平台、自学习智能体、个人 AI 助手 Gateway、终端编码代理、多模型编排插件、文件翻译工具、AI 编程方法论等领域共 8 个开源项目,按需加载即可获得 Dify、Hermes Agent、OpenClaw、OpenCode、DocuTranslate 等工具的精准 AI 辅助。
GIS(地理信息系统)技能分类索引,覆盖空间数据处理、地图服务、几何运算、Web 可视化等领域共 23 个开源工具,按需加载即可获得 GDAL、QGIS、GeoServer、PostGIS、JTS 等工具的精准 AI 辅助。
robotgo-flow(znlgis/robotgo-flow)是基于 go-vgo/robotgo 构建的 Windows 桌面 RPA 自动化框架,通过声明式 YAML 定义工作流,利用图像模板匹配定位屏幕 UI 元素,自动执行鼠标/键盘/浏览器操作,内置人类行为模拟、交互式录制器与 .NET 10 WPF 托盘应用。
Others(其它)技能分类索引,覆盖 Go 语言核心语法与工程实践、RobotGo 跨平台桌面自动化(RPA)库、robotgo-flow 基于 YAML 的 Windows RPA 框架、自托管邮件营销平台 BillionMail、Java 微服务后台脚手架 RuoYi-Cloud 与 SSL 证书自动化客户端 acme.sh,按需加载即可获得邮件系统搭建、Spring Cloud 微服务开发、SSL/TLS 证书自动签发续期、Go 语言后端开发、GUI 自动化等通用工具的精准 AI 辅助。
| name | geometry-api-net |
| description | geometry-api-net 是一个 .NET Standard 2.0 的空间几何计算库,提供对二维和三维几何对象的创建、解析、序列化以及空间关系运算能力。 |
| tags | ["dotnet","geometry","esri","spatial","wkt","wkb","geojson","geodesic","csharp"] |
项目地址: https://github.com/znlgis/geometry-api-net
本文件旨在帮助 AI 快速理解并使用 geometry-api-net 库进行空间几何开发。
这是一个 .NET Standard 2.0 的空间几何计算库,提供 6 种几何类型、25+ 空间运算算子和 4 种序列化格式。
Esri.Geometry.CoreEsri.Geometry.Jsondotnet add package Esri.Geometry.Core
dotnet add package Esri.Geometry.Json # 可选,System.Text.Json 支持
| 命名空间 | 用途 |
|---|---|
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.Converters | System.Text.Json 转换器 |
public enum GeometryType
{
Unknown = 0,
Point = 1,
Line = 2,
Envelope = 3,
MultiPoint = 4,
Polyline = 5,
Polygon = 6
}
所有几何类型继承自 Geometry,共有属性和方法:
// 属性
geometry.Type // GeometryType 枚举
geometry.IsEmpty // 是否为空
geometry.Dimension // 维度(Point=0, Line/Polyline=1, Polygon/Envelope=2)
geometry.IsPoint // 是否为点类型
geometry.IsLinear // 是否为线类型
geometry.IsArea // 是否为面类型
// 方法
geometry.GetEnvelope() // 获取外包矩形
geometry.CalculateArea2D() // 计算面积
geometry.CalculateLength2D() // 计算长度
geometry.Copy() // 深拷贝
geometry.IsValid() // 是否有效
var p = new Point(); // 空点 (NaN)
var p = new Point(10, 20); // 2D 点
var p = new Point(10, 20, 30); // 3D 点 (带 Z)
p.X // double, X 坐标
p.Y // double, Y 坐标
p.Z // double?, Z 坐标(可空)
p.M // double?, M 值(可空)
p.Distance(otherPoint) // 计算两点距离
p.Equals(otherPoint, tolerance) // 容差比较
var line = new Line(); // 空线段
var line = new Line(new Point(0, 0), new Point(10, 10));
line.Start // Point, 起点
line.End // Point, 终点
line.Length // double, 长度
var env = new Envelope(); // 空包围盒
var env = new Envelope(0, 0, 100, 100); // xMin, yMin, xMax, yMax
env.XMin, env.YMin, env.XMax, env.YMax // 边界坐标
env.Width // 宽度
env.Height // 高度
env.Center // Point, 中心点
env.Area // 面积
env.Contains(point) // 是否包含点
env.Intersects(otherEnv) // 是否与另一个包围盒相交
env.Merge(point) // 合并点到包围盒
env.Merge(otherEnv) // 合并另一个包围盒
var mp = new MultiPoint();
var mp = new MultiPoint(new[] { new Point(1, 2), new Point(3, 4) });
mp.Add(new Point(5, 6)); // 添加点
mp.Count // 点数量
mp.GetPoint(0) // 获取指定索引的点
mp.GetPoints() // 获取所有点 (IEnumerable<Point>)
var polyline = new Polyline();
// 添加路径(path),每条路径是一组连续的点
polyline.AddPath(new[] {
new Point(0, 0), new Point(10, 0), new Point(10, 10)
});
polyline.PathCount // 路径数量
polyline.Length // 总长度
polyline.GetPath(0) // 获取指定索引的路径 (IReadOnlyList<Point>)
polyline.GetPaths() // 获取所有路径
var polygon = new Polygon();
// 添加环(ring),首尾点必须闭合
polygon.AddRing(new[] {
new Point(0, 0), new Point(10, 0), new Point(10, 10),
new Point(0, 10), new Point(0, 0) // ← 首尾闭合
});
polygon.RingCount // 环数量
polygon.Area // 面积(Shoelace 公式)
polygon.GetRing(0) // 获取指定索引的环 (IReadOnlyList<Point>)
polygon.GetRings() // 获取所有环
GeometryEngine 提供所有操作的便捷静态方法入口,是最简洁的使用方式:
using OpenGIS.Esri.Geometry.Core;
// 空间关系判断
bool result = GeometryEngine.Contains(geometry1, geometry2);
bool result = GeometryEngine.Intersects(geometry1, geometry2);
bool result = GeometryEngine.Within(geometry1, geometry2);
bool result = GeometryEngine.Disjoint(geometry1, geometry2);
bool result = GeometryEngine.Crosses(geometry1, geometry2);
bool result = GeometryEngine.Touches(geometry1, geometry2);
bool result = GeometryEngine.Overlaps(geometry1, geometry2);
bool result = GeometryEngine.Equals(geometry1, geometry2);
double dist = GeometryEngine.Distance(geometry1, geometry2);
// 集合运算
Geometry result = GeometryEngine.Union(geometry1, geometry2);
Geometry result = GeometryEngine.Intersection(geometry1, geometry2);
Geometry result = GeometryEngine.Difference(geometry1, geometry2);
Geometry result = GeometryEngine.SymmetricDifference(geometry1, geometry2);
// 几何运算
Geometry buffer = GeometryEngine.Buffer(geometry, distance);
Geometry hull = GeometryEngine.ConvexHull(geometry);
Geometry simple = GeometryEngine.Simplify(geometry, tolerance);
Geometry simpleOGC = GeometryEngine.SimplifyOGC(geometry, spatialRef);
bool isSimple = GeometryEngine.IsSimpleOGC(geometry, spatialRef);
Geometry general = GeometryEngine.Generalize(geometry, maxDeviation);
Geometry dense = GeometryEngine.Densify(geometry, maxSegmentLength);
Geometry clipped = GeometryEngine.Clip(geometry, clipEnvelope);
Geometry offset = GeometryEngine.Offset(geometry, distance);
Point center = GeometryEngine.Centroid(geometry);
Geometry boundary = GeometryEngine.Boundary(geometry);
double area = GeometryEngine.Area(geometry);
double length = GeometryEngine.Length(geometry);
// 大地测量
double geodesicDist = GeometryEngine.GeodesicDistance(point1, point2);
double geodesicArea = GeometryEngine.GeodesicArea(polygon);
// 邻近搜索
Proximity2DResult nearest = GeometryEngine.GetNearestCoordinate(geometry, point, testPolygonInterior);
Proximity2DResult nearest = GeometryEngine.GetNearestVertex(geometry, point);
Proximity2DResult[] results = GeometryEngine.GetNearestVertices(geometry, point, searchRadius, maxVertexCount);
// 序列化 / 反序列化
string wkt = GeometryEngine.GeometryToWkt(geometry);
Geometry fromWkt = GeometryEngine.GeometryFromWkt(wktString);
byte[] wkb = GeometryEngine.GeometryToWkb(geometry, bigEndian);
Geometry fromWkb = GeometryEngine.GeometryFromWkb(wkbBytes);
string json = GeometryEngine.GeometryToGeoJson(geometry);
Geometry fromJson = GeometryEngine.GeometryFromGeoJson(geoJsonString);
string esri = GeometryEngine.GeometryToEsriJson(geometry);
Geometry fromEsri = GeometryEngine.GeometryFromEsriJson(esriJsonString);
每个算子都通过 Instance 单例属性获取(Lazy 初始化),适合需要更精细控制的场景:
using OpenGIS.Esri.Geometry.Core.Operators;
// 空间关系
bool contains = ContainsOperator.Instance.Execute(geom1, geom2);
bool intersects = IntersectsOperator.Instance.Execute(geom1, geom2);
double distance = DistanceOperator.Instance.Execute(geom1, geom2);
bool equals = EqualsOperator.Instance.Execute(geom1, geom2);
bool disjoint = DisjointOperator.Instance.Execute(geom1, geom2);
bool within = WithinOperator.Instance.Execute(geom1, geom2);
bool crosses = CrossesOperator.Instance.Execute(geom1, geom2);
bool touches = TouchesOperator.Instance.Execute(geom1, geom2);
bool overlaps = OverlapsOperator.Instance.Execute(geom1, geom2);
// 集合运算
Geometry union = UnionOperator.Instance.Execute(geom1, geom2);
Geometry intersection = IntersectionOperator.Instance.Execute(geom1, geom2);
Geometry difference = DifferenceOperator.Instance.Execute(geom1, geom2);
Geometry symDiff = SymmetricDifferenceOperator.Instance.Execute(geom1, geom2);
// 一元运算
Geometry buffer = BufferOperator.Instance.Execute(geometry, distance);
Geometry convexHull = ConvexHullOperator.Instance.Execute(geometry);
Geometry simplified = SimplifyOperator.Instance.Execute(geometry, tolerance);
Point centroid = CentroidOperator.Instance.Execute(geometry);
Geometry boundary = BoundaryOperator.Instance.Execute(geometry);
double area = AreaOperator.Instance.Execute(geometry);
double length = LengthOperator.Instance.Execute(geometry);
Geometry offset = OffsetOperator.Instance.Execute(geometry, distance);
// 大地测量
double geodesicDist = GeodesicDistanceOperator.Instance.Execute(point1, point2);
double geodesicArea = GeodesicAreaOperator.Instance.Execute(polygon);
// 邻近搜索
Proximity2DResult result = Proximity2DOperator.Instance.GetNearestCoordinate(geometry, point, testPolygonInterior);
Proximity2DResult result = Proximity2DOperator.Instance.GetNearestVertex(geometry, point);
Proximity2DResult[] results = Proximity2DOperator.Instance.GetNearestVertices(geometry, point, searchRadius, maxVertexCount);
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)");
// 导出(默认小端序)
byte[] wkb = WkbExportOperator.ExportToWkb(geometry);
byte[] wkb = WkbExportOperator.ExportToWkb(geometry, bigEndian: true);
// 导入(自动检测字节序)
Geometry geometry = WkbImportOperator.ImportFromWkb(wkbBytes);
// 导出
string geoJson = GeoJsonExportOperator.ExportToGeoJson(geometry);
// {"type":"Point","coordinates":[10.5,20.7]}
// 导入
Geometry geometry = GeoJsonImportOperator.ImportFromGeoJson(geoJsonString);
// 导出
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);
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);
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 result = GeometryEngine.GetNearestCoordinate(geometry, point);
result.IsEmpty // bool, 结果是否为空
result.Coordinate // Point, 最近坐标点
result.VertexIndex // int, 最近顶点索引
result.Distance // double, 距离
result.IsRightSide // bool, 是否在多路径几何的右侧
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
var beijing = new Point(116.4074, 39.9042);
var shanghai = new Point(121.4737, 31.2304);
double meters = GeometryEngine.GeodesicDistance(beijing, shanghai);
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
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)
var p1 = new Point(0, 0);
var p2 = new Point(10, 10);
Geometry merged = GeometryEngine.Union(p1, p2);
// 结果为 MultiPoint,包含两个点
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);
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
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);
// 结果为包围所有点的最小凸多边形
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
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);
# 构建
dotnet build
# 运行测试(xUnit)
dotnet test
# 运行示例
dotnet run --project samples/OpenGIS.Esri.Geometry.Samples
Point、Polyline、Polygon 等构造函数创建几何GeometryEngine 静态方法(API 最简洁);需要精细控制时使用 Operator.Instance 单例模式GeometryEngine.GeometryToGeoJson() / GeometryFromWkt() 等方法进行 WKT、WKB、GeoJSON、Esri JSON 互转GeometryEngine.GeodesicDistance() / GeodesicArea()OpenGIS.Esri.Geometry.Json.Converters 命名空间的 System.Text.Json 转换器Geometry 基类,需根据实际类型做类型转换GeodesicDistance 使用 Vincenty 公式LineString,多路径导出为 MultiLineStringInstance 属性获取单例实例GeometryConstants.DefaultTolerance(1e-10)进行浮点比较,该值为内部常量,不可外部配置Geometry 基类,需根据实际类型做类型转换Instance 属性获取单例实例GetRing(), GetPath() 等返回 IReadOnlyList<Point>GeodesicDistance 使用 Vincenty 公式,GeodesicArea 使用球面超量公式LineString,多路径导出为 MultiLineString;Envelope 导出为 Polygon