07-数据格式导入导出

第七章:数据格式导入导出

7.1 概述

geometry-api-net 支持多种标准的几何数据格式,使您能够轻松地与其他 GIS 系统、数据库和 Web 服务进行数据交换。

7.1.1 支持的格式

格式 导入 导出 用途
WKT 人类可读的文本格式
WKB 紧凑的二进制格式
GeoJSON Web 应用和 API
Esri JSON ArcGIS 产品集成

7.1.2 格式选择指南

场景 推荐格式 原因
调试和日志 WKT 人类可读
数据库存储 WKB 紧凑高效
Web API GeoJSON 标准通用
ArcGIS 集成 Esri JSON 原生支持
跨平台交换 WKB 或 GeoJSON 广泛支持

7.2 WKT(Well-Known Text)

7.2.1 概念

WKT 是 OGC 定义的文本标记语言,用于表示几何对象。它是人类可读的,便于调试和日志记录。

语法示例

POINT (30 10)
LINESTRING (30 10, 10 30, 40 40)
POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))
MULTIPOINT ((10 40), (40 30), (20 20), (30 10))
MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))
MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5)))

7.2.2 导出 API

public static class WktExportOperator
{
    public static string ExportToWkt(Geometry geometry);
}

7.2.3 导入 API

public static class WktImportOperator
{
    public static Geometry ImportFromWkt(string wkt);
}

7.2.4 使用示例

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

// === 导出为 WKT ===

// 点
var point = new Point(10.5, 20.7);
string pointWkt = WktExportOperator.ExportToWkt(point);
Console.WriteLine(pointWkt);  // POINT (10.5 20.7)

// 三维点
var point3D = new Point(10, 20, 30);
string point3DWkt = WktExportOperator.ExportToWkt(point3D);
Console.WriteLine(point3DWkt);  // POINT Z (10 20 30)

// 折线
var polyline = new Polyline();
polyline.AddPath(new List<Point>
{
    new Point(0, 0),
    new Point(10, 10),
    new Point(20, 0)
});
string lineWkt = WktExportOperator.ExportToWkt(polyline);
Console.WriteLine(lineWkt);  // LINESTRING (0 0, 10 10, 20 0)

// 多路径折线
var multiLine = new Polyline();
multiLine.AddPath(new[] { new Point(0, 0), new Point(10, 10) });
multiLine.AddPath(new[] { new Point(20, 20), new Point(30, 30) });
string multiLineWkt = WktExportOperator.ExportToWkt(multiLine);
Console.WriteLine(multiLineWkt);  // MULTILINESTRING ((0 0, 10 10), (20 20, 30 30))

// 多边形
var polygon = new Polygon();
polygon.AddRing(new List<Point>
{
    new Point(0, 0),
    new Point(10, 0),
    new Point(10, 10),
    new Point(0, 10),
    new Point(0, 0)
});
string polyWkt = WktExportOperator.ExportToWkt(polygon);
Console.WriteLine(polyWkt);  // POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))

// 多点
var multiPoint = new MultiPoint();
multiPoint.Add(new Point(10, 20));
multiPoint.Add(new Point(30, 40));
string mpWkt = WktExportOperator.ExportToWkt(multiPoint);
Console.WriteLine(mpWkt);  // MULTIPOINT (10 20, 30 40)

// 包络矩形(导出为多边形)
var envelope = new Envelope(0, 0, 100, 100);
string envWkt = WktExportOperator.ExportToWkt(envelope);
Console.WriteLine(envWkt);  // POLYGON ((0 0, 100 0, 100 100, 0 100, 0 0))

// 空几何
var emptyPoint = new Point();
string emptyWkt = WktExportOperator.ExportToWkt(emptyPoint);
Console.WriteLine(emptyWkt);  // POINT EMPTY

// === 使用 GeometryEngine ===
string wkt = GeometryEngine.GeometryToWkt(polygon);

7.2.5 从 WKT 导入

// 导入点
var point = WktImportOperator.ImportFromWkt("POINT (10.5 20.7)");
Console.WriteLine($"类型:{point.Type}");  // Point

// 导入三维点
var point3D = WktImportOperator.ImportFromWkt("POINT Z (10 20 30)");
if (point3D is Point p3d)
{
    Console.WriteLine($"Z 值:{p3d.Z}");  // 30
}

// 导入折线
var line = WktImportOperator.ImportFromWkt("LINESTRING (0 0, 10 10, 20 0)");
if (line is Polyline polyline)
{
    Console.WriteLine($"点数:{polyline.GetPath(0).Count}");  // 3
}

// 导入多边形
var polygon = WktImportOperator.ImportFromWkt(
    "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))");
if (polygon is Polygon poly)
{
    Console.WriteLine($"面积:{poly.Area}");  // 100
}

// 导入带孔洞的多边形
var polyWithHole = WktImportOperator.ImportFromWkt(
    "POLYGON ((0 0, 100 0, 100 100, 0 100, 0 0), (25 25, 75 25, 75 75, 25 75, 25 25))");
if (polyWithHole is Polygon pwh)
{
    Console.WriteLine($"环数:{pwh.RingCount}");  // 2
}

// 导入多点
var multiPoint = WktImportOperator.ImportFromWkt("MULTIPOINT (10 20, 30 40)");

// 导入多折线
var multiLine = WktImportOperator.ImportFromWkt(
    "MULTILINESTRING ((0 0, 10 10), (20 20, 30 30))");

// 使用 GeometryEngine
var geom = GeometryEngine.GeometryFromWkt("POINT (5 5)");

7.2.6 WKT 格式规范

// 点
POINT (x y)
POINT Z (x y z)
POINT M (x y m)
POINT ZM (x y z m)
POINT EMPTY

// 多点
MULTIPOINT ((x1 y1), (x2 y2), ...)
MULTIPOINT (x1 y1, x2 y2, ...)  // 简化语法

// 线串
LINESTRING (x1 y1, x2 y2, ...)
LINESTRING EMPTY

// 多线串
MULTILINESTRING ((x1 y1, x2 y2), (x3 y3, x4 y4))

// 多边形
POLYGON ((外环), (孔洞1), (孔洞2), ...)

// 多多边形
MULTIPOLYGON (((外环1)), ((外环2), (孔洞)))

7.3 WKB(Well-Known Binary)

7.3.1 概念

WKB 是 WKT 的二进制表示形式,更紧凑,适合数据库存储和网络传输。

二进制结构

字节序 (1 字节): 0 = 大端, 1 = 小端
几何类型 (4 字节): 1=Point, 2=LineString, 3=Polygon, 4=MultiPoint, 5=MultiLineString, 6=MultiPolygon
坐标数据 (8 字节每个双精度值)

7.3.2 导出 API

public static class WkbExportOperator
{
    public static byte[] ExportToWkb(Geometry geometry, bool bigEndian = false);
}

7.3.3 导入 API

public static class WkbImportOperator
{
    public static Geometry ImportFromWkb(byte[] wkb);
}

7.3.4 使用示例

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

// === 导出为 WKB ===

var point = new Point(10.5, 20.7);

// 默认小端字节序
byte[] wkb = WkbExportOperator.ExportToWkb(point);
Console.WriteLine($"WKB 长度:{wkb.Length} 字节");  // 21 字节

// 大端字节序(用于某些系统)
byte[] wkbBigEndian = WkbExportOperator.ExportToWkb(point, bigEndian: true);

// 使用 GeometryEngine
byte[] wkb2 = GeometryEngine.GeometryToWkb(point);

// 导出多边形
var polygon = new Polygon();
polygon.AddRing(new List<Point>
{
    new Point(0, 0),
    new Point(10, 0),
    new Point(10, 10),
    new Point(0, 10),
    new Point(0, 0)
});
byte[] polyWkb = WkbExportOperator.ExportToWkb(polygon);
Console.WriteLine($"多边形 WKB 长度:{polyWkb.Length} 字节");

// === 从 WKB 导入 ===

var imported = WkbImportOperator.ImportFromWkb(wkb);
if (imported is Point p)
{
    Console.WriteLine($"导入的点:({p.X}, {p.Y})");  // (10.5, 20.7)
}

// 使用 GeometryEngine
var geom = GeometryEngine.GeometryFromWkb(polyWkb);
Console.WriteLine($"导入类型:{geom.Type}");  // Polygon

// 往返测试
var original = new Point(123.456, 789.012);
byte[] exported = WkbExportOperator.ExportToWkb(original);
var roundTripped = WkbImportOperator.ImportFromWkb(exported);
Console.WriteLine($"往返成功:{GeometryEngine.Equals(original, roundTripped)}");  // true

7.3.5 WKB 字节结构

// Point WKB 结构 (21 字节)
// [0]     字节序: 0x01 (小端) 或 0x00 (大端)
// [1-4]   类型: 0x01000000 (Point)
// [5-12]  X 坐标 (double)
// [13-20] Y 坐标 (double)

// Polygon WKB 结构
// [0]     字节序
// [1-4]   类型: 0x03000000 (Polygon)
// [5-8]   环数量
// 对于每个环:
//   [n-n+3]   点数量
//   [...]     点坐标 (每个点 16 字节: X + Y)

7.3.6 WKB 与数据库

// 存储到数据库
byte[] wkb = GeometryEngine.GeometryToWkb(geometry);
// INSERT INTO spatial_table (geom) VALUES (@wkb)

// 从数据库读取
// byte[] wkb = reader["geom"] as byte[];
var geometry = GeometryEngine.GeometryFromWkb(wkb);

// PostGIS 示例 SQL
// INSERT INTO my_table (geom) VALUES (ST_GeomFromWKB(@wkb, 4326))
// SELECT ST_AsBinary(geom) FROM my_table

7.4 GeoJSON

7.4.1 概念

GeoJSON 是基于 JSON 的地理数据格式,广泛用于 Web GIS 应用。它是 IETF RFC 7946 标准。

结构示例

{
  "type": "Point",
  "coordinates": [102.0, 0.5]
}

{
  "type": "Polygon",
  "coordinates": [
    [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]
  ]
}

7.4.2 导出 API

public class GeoJsonExportOperator : IGeometryOperator<string>
{
    public static GeoJsonExportOperator Instance { get; }
    
    public static string ExportToGeoJson(Geometry geometry);
}

7.4.3 导入 API

public static class GeoJsonImportOperator
{
    public static Geometry ImportFromGeoJson(string geoJson);
}

7.4.4 使用示例

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

// === 导出为 GeoJSON ===

// 点
var point = new Point(10.5, 20.3, 30.7);
string pointJson = GeoJsonExportOperator.ExportToGeoJson(point);
Console.WriteLine(pointJson);
// {"type":"Point","coordinates":[10.5,20.3,30.7]}

// 多点
var multiPoint = new MultiPoint();
multiPoint.Add(new Point(10, 20));
multiPoint.Add(new Point(30, 40));
string mpJson = GeoJsonExportOperator.ExportToGeoJson(multiPoint);
Console.WriteLine(mpJson);
// {"type":"MultiPoint","coordinates":[[10,20],[30,40]]}

// 折线(单路径 = LineString)
var line = new Polyline();
line.AddPath(new[] { new Point(0, 0), new Point(10, 10) });
string lineJson = GeoJsonExportOperator.ExportToGeoJson(line);
Console.WriteLine(lineJson);
// {"type":"LineString","coordinates":[[0,0],[10,10]]}

// 折线(多路径 = MultiLineString)
var multiLine = new Polyline();
multiLine.AddPath(new[] { new Point(0, 0), new Point(10, 10) });
multiLine.AddPath(new[] { new Point(20, 20), new Point(30, 30) });
string multiLineJson = GeoJsonExportOperator.ExportToGeoJson(multiLine);
Console.WriteLine(multiLineJson);
// {"type":"MultiLineString","coordinates":[[[0,0],[10,10]],[[20,20],[30,30]]]}

// 多边形
var polygon = new Polygon();
polygon.AddRing(new List<Point>
{
    new Point(0, 0),
    new Point(10, 0),
    new Point(10, 10),
    new Point(0, 10),
    new Point(0, 0)
});
string polyJson = GeoJsonExportOperator.ExportToGeoJson(polygon);
Console.WriteLine(polyJson);
// {"type":"Polygon","coordinates":[[[0,0],[10,0],[10,10],[0,10],[0,0]]]}

// 包络矩形(作为多边形导出)
var envelope = new Envelope(0, 0, 100, 100);
string envJson = GeoJsonExportOperator.ExportToGeoJson(envelope);

// 使用 GeometryEngine
string json = GeometryEngine.GeometryToGeoJson(polygon);

// === 从 GeoJSON 导入 ===

// 导入点
var point2 = GeoJsonImportOperator.ImportFromGeoJson(
    "{\"type\":\"Point\",\"coordinates\":[10.5,20.3]}");
if (point2 is Point p)
{
    Console.WriteLine($"导入的点:({p.X}, {p.Y})");
}

// 导入多边形
var poly2 = GeoJsonImportOperator.ImportFromGeoJson(
    "{\"type\":\"Polygon\",\"coordinates\":[[[0,0],[10,0],[10,10],[0,10],[0,0]]]}");
if (poly2 is Polygon polygon2)
{
    Console.WriteLine($"导入的多边形面积:{polygon2.Area}");
}

// 使用 GeometryEngine
var geom = GeometryEngine.GeometryFromGeoJson("{\"type\":\"Point\",\"coordinates\":[5,5]}");

7.4.5 GeoJSON 格式规范

// Point
{"type": "Point", "coordinates": [x, y]}
{"type": "Point", "coordinates": [x, y, z]}

// MultiPoint
{"type": "MultiPoint", "coordinates": [[x1, y1], [x2, y2]]}

// LineString
{"type": "LineString", "coordinates": [[x1, y1], [x2, y2], [x3, y3]]}

// MultiLineString
{"type": "MultiLineString", "coordinates": [[[x1, y1], [x2, y2]], [[x3, y3], [x4, y4]]]}

// Polygon (外环逆时针,孔洞顺时针)
{"type": "Polygon", "coordinates": [[[x1, y1], [x2, y2], [x3, y3], [x1, y1]]]}

// Polygon with hole
{"type": "Polygon", "coordinates": [
  [[外环坐标]],
  [[孔洞坐标]]
]}

// MultiPolygon
{"type": "MultiPolygon", "coordinates": [[[[多边形1坐标]]], [[[多边形2坐标]]]]}

// GeometryCollection
{"type": "GeometryCollection", "geometries": [
  {"type": "Point", "coordinates": [x, y]},
  {"type": "LineString", "coordinates": [[x1, y1], [x2, y2]]}
]}

// Feature (带属性的几何)
{
  "type": "Feature",
  "geometry": {"type": "Point", "coordinates": [x, y]},
  "properties": {"name": "示例点", "value": 123}
}

// FeatureCollection
{
  "type": "FeatureCollection",
  "features": [
    {"type": "Feature", "geometry": {...}, "properties": {...}},
    {"type": "Feature", "geometry": {...}, "properties": {...}}
  ]
}

7.4.6 Web 应用集成

// 在 ASP.NET Core 控制器中使用
[HttpGet("geometry/{id}")]
public IActionResult GetGeometry(int id)
{
    var geometry = _repository.GetById(id);
    string geoJson = GeometryEngine.GeometryToGeoJson(geometry);
    
    return Content(geoJson, "application/geo+json");
}

[HttpPost("geometry")]
public IActionResult CreateGeometry([FromBody] string geoJson)
{
    var geometry = GeometryEngine.GeometryFromGeoJson(geoJson);
    _repository.Add(geometry);
    
    return Ok();
}

7.5 Esri JSON

7.5.1 概念

Esri JSON 是 Esri 定义的专有 JSON 格式,用于 ArcGIS 产品系列。与 GeoJSON 相比,它包含更多 Esri 特有的属性。

结构示例

// Point
{"x": 10.5, "y": 20.3}
{"x": 10.5, "y": 20.3, "z": 30.7}

// Polyline
{
  "paths": [[[0, 0], [10, 10], [20, 0]]]
}

// Polygon
{
  "rings": [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]]]
}

// 带空间参考
{
  "x": 10.5,
  "y": 20.3,
  "spatialReference": {"wkid": 4326}
}

7.5.2 导出 API

public class EsriJsonExportOperator : IGeometryOperator<string>
{
    public static EsriJsonExportOperator Instance { get; }
    
    public string Execute(Geometry geometry, 
                         SpatialReference? spatialReference = null);
}

7.5.3 导入 API

public static class EsriJsonImportOperator
{
    public static Geometry ImportFromEsriJson(string esriJson);
}

7.5.4 使用示例

using Esri.Geometry.Core;
using Esri.Geometry.Core.Geometries;
using Esri.Geometry.Core.IO;
using Esri.Geometry.Core.SpatialReference;

// === 导出为 Esri JSON ===

// 点
var point = new Point(10.5, 20.3);
string pointJson = EsriJsonExportOperator.Instance.Execute(point);
Console.WriteLine(pointJson);
// {"x":10.5,"y":20.3}

// 三维点
var point3D = new Point(10.5, 20.3, 30.7);
string point3DJson = EsriJsonExportOperator.Instance.Execute(point3D);
Console.WriteLine(point3DJson);
// {"x":10.5,"y":20.3,"z":30.7}

// 带空间参考
var sr = SpatialReference.Wgs84();
string pointWithSR = EsriJsonExportOperator.Instance.Execute(point, sr);
Console.WriteLine(pointWithSR);
// {"x":10.5,"y":20.3,"spatialReference":{"wkid":4326}}

// 折线
var polyline = new Polyline();
polyline.AddPath(new[] { new Point(0, 0), new Point(10, 10), new Point(20, 0) });
string lineJson = EsriJsonExportOperator.Instance.Execute(polyline);
Console.WriteLine(lineJson);
// {"paths":[[[0,0],[10,10],[20,0]]]}

// 多边形
var polygon = new Polygon();
polygon.AddRing(new List<Point>
{
    new Point(0, 0),
    new Point(10, 0),
    new Point(10, 10),
    new Point(0, 10),
    new Point(0, 0)
});
string polyJson = EsriJsonExportOperator.Instance.Execute(polygon);
Console.WriteLine(polyJson);
// {"rings":[[[0,0],[10,0],[10,10],[0,10],[0,0]]]}

// 包络矩形
var envelope = new Envelope(0, 0, 100, 100);
string envJson = EsriJsonExportOperator.Instance.Execute(envelope);
Console.WriteLine(envJson);
// {"xmin":0,"ymin":0,"xmax":100,"ymax":100}

// 使用 GeometryEngine
string json = GeometryEngine.GeometryToEsriJson(polygon);

// === 从 Esri JSON 导入 ===

// 导入点
var point2 = EsriJsonImportOperator.ImportFromEsriJson("{\"x\":10.5,\"y\":20.3}");

// 导入折线
var line = EsriJsonImportOperator.ImportFromEsriJson(
    "{\"paths\":[[[0,0],[10,10],[20,0]]]}");

// 导入多边形
var poly = EsriJsonImportOperator.ImportFromEsriJson(
    "{\"rings\":[[[0,0],[10,0],[10,10],[0,10],[0,0]]]}");

// 导入包络矩形
var env = EsriJsonImportOperator.ImportFromEsriJson(
    "{\"xmin\":0,\"ymin\":0,\"xmax\":100,\"ymax\":100}");

// 使用 GeometryEngine
var geom = GeometryEngine.GeometryFromEsriJson("{\"x\":5,\"y\":5}");

7.5.5 Esri JSON 格式规范

// Point
{"x": number, "y": number}
{"x": number, "y": number, "z": number}
{"x": number, "y": number, "m": number}
{"x": number, "y": number, "z": number, "m": number}

// Multipoint
{
  "points": [[x1, y1], [x2, y2], ...]
}

// Polyline
{
  "paths": [
    [[x1, y1], [x2, y2], ...],  // 路径 1
    [[x3, y3], [x4, y4], ...]   // 路径 2
  ]
}

// Polygon
{
  "rings": [
    [[x1, y1], [x2, y2], ...],  // 外环
    [[x3, y3], [x4, y4], ...]   // 孔洞
  ]
}

// Envelope
{
  "xmin": number,
  "ymin": number,
  "xmax": number,
  "ymax": number
}

// 带空间参考
{
  "x": number,
  "y": number,
  "spatialReference": {
    "wkid": 4326
  }
}

7.5.6 与 ArcGIS 服务集成

// 发送到 ArcGIS REST 服务
async Task<string> QueryFeatureService(Polygon queryGeometry)
{
    string esriJson = GeometryEngine.GeometryToEsriJson(queryGeometry);
    
    using var client = new HttpClient();
    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("geometry", esriJson),
        new KeyValuePair<string, string>("geometryType", "esriGeometryPolygon"),
        new KeyValuePair<string, string>("inSR", "4326"),
        new KeyValuePair<string, string>("f", "json")
    });
    
    var response = await client.PostAsync(
        "https://services.arcgis.com/.../query",
        content);
    
    return await response.Content.ReadAsStringAsync();
}

7.6 格式转换

7.6.1 格式间转换

using Esri.Geometry.Core;
using Esri.Geometry.Core.IO;

// WKT → GeoJSON
string wkt = "POINT (10 20)";
var geometry = WktImportOperator.ImportFromWkt(wkt);
string geoJson = GeoJsonExportOperator.ExportToGeoJson(geometry);

// GeoJSON → WKB
string json = "{\"type\":\"Point\",\"coordinates\":[10,20]}";
var geom = GeoJsonImportOperator.ImportFromGeoJson(json);
byte[] wkb = WkbExportOperator.ExportToWkb(geom);

// WKB → Esri JSON
byte[] data = { /* WKB 数据 */ };
var geometry2 = WkbImportOperator.ImportFromWkb(data);
string esriJson = EsriJsonExportOperator.Instance.Execute(geometry2);

// 批量转换
List<string> wktList = new() { "POINT (1 1)", "POINT (2 2)", "POINT (3 3)" };
List<string> jsonList = wktList
    .Select(wkt => WktImportOperator.ImportFromWkt(wkt))
    .Select(geom => GeoJsonExportOperator.ExportToGeoJson(geom))
    .ToList();

7.6.2 通用转换器

public static class GeometryFormatConverter
{
    public enum Format { WKT, WKB, GeoJSON, EsriJSON }
    
    public static string Convert(string input, Format from, Format to)
    {
        // 解析输入
        Geometry geometry = from switch
        {
            Format.WKT => WktImportOperator.ImportFromWkt(input),
            Format.GeoJSON => GeoJsonImportOperator.ImportFromGeoJson(input),
            Format.EsriJSON => EsriJsonImportOperator.ImportFromEsriJson(input),
            _ => throw new ArgumentException("Unsupported input format")
        };
        
        // 生成输出
        return to switch
        {
            Format.WKT => WktExportOperator.ExportToWkt(geometry),
            Format.GeoJSON => GeoJsonExportOperator.ExportToGeoJson(geometry),
            Format.EsriJSON => EsriJsonExportOperator.Instance.Execute(geometry),
            _ => throw new ArgumentException("Unsupported output format")
        };
    }
    
    public static byte[] ConvertToWkb(string input, Format from)
    {
        Geometry geometry = from switch
        {
            Format.WKT => WktImportOperator.ImportFromWkt(input),
            Format.GeoJSON => GeoJsonImportOperator.ImportFromGeoJson(input),
            Format.EsriJSON => EsriJsonImportOperator.ImportFromEsriJson(input),
            _ => throw new ArgumentException("Unsupported format")
        };
        
        return WkbExportOperator.ExportToWkb(geometry);
    }
}

// 使用
string result = GeometryFormatConverter.Convert(
    "POINT (10 20)", 
    GeometryFormatConverter.Format.WKT, 
    GeometryFormatConverter.Format.GeoJSON
);

7.7 最佳实践

7.7.1 格式选择

// 调试时使用 WKT
Console.WriteLine($"几何对象:{GeometryEngine.GeometryToWkt(geometry)}");

// 存储到数据库使用 WKB
byte[] data = GeometryEngine.GeometryToWkb(geometry);

// Web API 返回 GeoJSON
return Ok(GeometryEngine.GeometryToGeoJson(geometry));

// 与 ArcGIS 交互使用 Esri JSON
string esriJson = GeometryEngine.GeometryToEsriJson(geometry);

7.7.2 错误处理

try
{
    var geometry = WktImportOperator.ImportFromWkt(wkt);
}
catch (FormatException ex)
{
    Console.WriteLine($"WKT 格式错误:{ex.Message}");
}
catch (ArgumentException ex)
{
    Console.WriteLine($"参数错误:{ex.Message}");
}

// 安全解析
public static Geometry? TryParseWkt(string wkt)
{
    try
    {
        return WktImportOperator.ImportFromWkt(wkt);
    }
    catch
    {
        return null;
    }
}

7.7.3 性能优化

// 批量处理时使用 WKB(更紧凑)
var geometries = new List<Geometry>();
var wkbData = geometries
    .Select(g => WkbExportOperator.ExportToWkb(g))
    .ToList();

// 避免频繁序列化/反序列化
// ❌ 不好
foreach (var item in items)
{
    string json = GeometryEngine.GeometryToGeoJson(geometry);
    ProcessJson(json);
}

// ✅ 好
string json = GeometryEngine.GeometryToGeoJson(geometry);
foreach (var item in items)
{
    ProcessWithGeometry(geometry);
}

7.8 小结

本章详细介绍了 geometry-api-net 支持的四种数据格式:

  1. WKT:人类可读的文本格式,适合调试和日志
  2. WKB:紧凑的二进制格式,适合数据库存储
  3. GeoJSON:JSON 格式,适合 Web 应用
  4. Esri JSON:Esri 专有格式,适合 ArcGIS 集成

每种格式都有其最佳使用场景,选择合适的格式可以提高开发效率和系统性能。

在下一章中,我们将学习空间参考系统,了解如何处理不同坐标系之间的转换。

posted @ 2025-12-03 16:29  我才是银古  阅读(9)  评论(0)    收藏  举报