인터페이스는 현지화되어 있으며, Skill 소개와 설명 문서는 선택한 언어로 AI가 자동 번역합니다. 코드·명령어·경로·전문 용어는 원문을 유지하며 원작자 문서가 우선합니다.
Skills 둘러보기
생산성 및 협업 · SKILL.md

geometry-api-net

geometry-api-net

Use when working with Esri geometry types (Point, Polyline, Polygon, Envelope) in .NET/C# — spatial operations, JSON/GeoJSON/WKT I/O, geodesic calculations. Esri Geometry API for .NET.

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill 문서

GitHub

name: geometry-api-net description: "Use when working with Esri geometry types (Point, Polyline, Polygon, Envelope) in .NET/C# — spatial operations, JSON/GeoJSON/WKT I/O, geodesic calculations. Esri Geometry API for .NET." tags:

  • dotnet
  • geometry
  • esri
  • spatial
  • wkt
  • wkb
  • geojson
  • geodesic
  • csharp

项目地址: https://github.com/znlgis/geometry-api-net

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

注意: 原 Esri 仓库(github.com/Esri/geometry-api-net)已不再维护(404)。此分支由 znlgis 社区维护,已重命名为 OpenGIS.Esri.Geometry。

许可证: LGPL-2.1

本文件旨在帮助 AI 快速理解并使用 geometry-api-net 库进行空间几何开发。

概述

这是一个 .NET Standard 2.0 的空间几何计算库,提供 6 种几何类型、25+ 空间运算算子和 4 种序列化格式。

  • 核心包: OpenGIS.Esri.Geometry.Core
  • JSON 扩展包: OpenGIS.Esri.Geometry.Json
  • 许可证: LGPL-2.1-only

快速开始

dotnet add package OpenGIS.Esri.Geometry.Core
dotnet add package OpenGIS.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.ConvertersSystem.Text.Json 转换器

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

序列化格式

WKT(Well-Known Text)

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)

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

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

GeoJSON

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

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

Esri JSON

// 导出
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 集成

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(邻近搜索结果)

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

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

常见开发场景

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

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:计算两个经纬度点之间的大地距离(米)

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

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

场景 3:创建缓冲区

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:计算两个区域的交集

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:合并多个几何体

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

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

场景 6:GeoJSON 往返序列化

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 导入几何体并做空间分析

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:获取几何体的凸包

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:计算多边形的质心

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:线的简化与加密

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

AI 使用建议

推荐工作流

  1. 创建几何对象:使用 Point、Polyline、Polygon 等构造函数创建几何
  2. 空间运算:优先使用 GeometryEngine 静态方法(API 最简洁);需要精细控制时使用 Operator.Instance 单例模式
  3. 格式转换:使用 GeometryEngine.GeometryToGeoJson() / GeometryFromWkt() 等方法进行 WKT、WKB、GeoJSON、Esri JSON 互转
  4. 大地测量:对地理坐标的距离/面积计算,使用 GeometryEngine.GeodesicDistance() / GeodesicArea()
  5. 序列化集成:使用 OpenGIS.Esri.Geometry.Json.Converters 命名空间的 System.Text.Json 转换器

关键注意事项

  • Polygon 环必须闭合:首尾点必须相同
  • 返回类型需转换:集合运算返回 Geometry 基类,需根据实际类型做类型转换
  • 大地测量基于 WGS84:GeodesicDistance 使用 Vincenty 公式
  • GeoJSON 导出规则:单路径 Polyline 导出为 LineString,多路径导出为 MultiLineString
  • Operator 使用 Lazy 单例:所有 Operator 类通过 Instance 属性获取单例实例

相关技能

注意事项

  1. Polygon 环必须闭合:首尾点必须相同
  2. 浮点容差:内部使用 GeometryConstants.DefaultTolerance(1e-10)进行浮点比较,该值为内部常量,不可外部配置
  3. 返回类型需转换:集合运算返回 Geometry 基类,需根据实际类型做类型转换
  4. Operator 使用 Lazy 单例:所有 Operator 类通过 Instance 属性获取单例实例
  5. 集合 getter 返回只读视图:GetRing(), GetPath() 等返回 IReadOnlyList<Point>
  6. 大地测量基于 WGS84:GeodesicDistance 使用 Vincenty 公式,GeodesicArea 使用球面超量公式
  7. GeoJSON 导出规则:单路径 Polyline 导出为 LineString,多路径导出为 MultiLineString;Envelope 导出为 Polygon
저장한 Skills