WKT互转GEOJSON
本示例展示如何使用 Terraformer WKT 库在 Well-Known Text (WKT) 格式和 GeoJSON 格式之间进行相互转换。WKT 是一种文本标记语言,用于表示矢量几何对象,而 GeoJSON 是一种基于 JSON 的地理空间数据交换格式,两者在 GIS 应用中都被广泛使用。
loading StackBlitz editor
核心功能
WKT 和 GeoJSON 基础概念
WKT (Well-Known Text):
- 一种文本标记语言,用于表示矢量几何对象
- 格式简洁,易于人类阅读和编写
- 示例:
POINT(30 10)、POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))
GeoJSON:
- 基于 JSON 的地理空间数据交换格式
- 易于 Web 应用解析和处理
- 示例:
{"type": "Point", "coordinates": [30, 10]}
@terraformer/wkt 库
Terraformer 是一个用于处理地理空间数据的开源工具库,提供了便捷的 WKT 与 GeoJSON 转换功能:
import { wktToGeoJSON, geojsonToWKT } from "@terraformer/wkt";
// WKT 转 GeoJSON
const geojson = wktToGeoJSON("POINT(30 10)");
// 结果: {"type": "Point", "coordinates": [30, 10]}
// GeoJSON 转 WKT
const wkt = geojsonToWKT({
type: "Point",
coordinates: [30, 10]
});
// 结果: "POINT(30 10)"
关键代码
安装依赖
npm install @terraformer/wkt
WKT 转 GeoJSON
import { wktToGeoJSON } from "@terraformer/wkt";
// 点
const point = wktToGeoJSON("POINT(30 10)");
// {"type": "Point", "coordinates": [30, 10]}
// 线
const lineString = wktToGeoJSON("LINESTRING(30 10, 10 30, 40 40)");
// {"type": "LineString", "coordinates": [[30, 10], [10, 30], [40, 40]]}
// 多边形
const polygon = wktToGeoJSON(
"POLYGON((35 10, 45 45, 15 40, 10 20, 35 10))"
);
// {"type": "Polygon", "coordinates": [[[35, 10], [45, 45], [15, 40], [10, 20], [35, 10]]]}
GeoJSON 转 WKT
import { geojsonToWKT } from "@terraformer/wkt";
// 点
const pointWKT = geojsonToWKT({
type: "Point",
coordinates: [30, 10]
});
// "POINT(30 10)"
// 线
const lineWKT = geojsonToWKT({
type: "LineString",
coordinates: [[30, 10], [10, 30], [40, 40]]
});
// "LINESTRING(30 10, 10 30, 40 40)"
// 多边形(带孔)
const polygonWKT = geojsonToWKT({
type: "Polygon",
coordinates: [
// 外环
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],
// 内环(孔)
[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]
]
});
// "POLYGON((100 0, 101 0, 101 1, 100 1, 100 0), (100.2 0.2, 100.8 0.2, 100.8 0.8, 100.2 0.8, 100.2 0.2))"
错误处理
try {
const result = wktToGeoJSON(wktString);
console.log(result);
} catch (error) {
console.error("WKT 格式无效:", error.message);
}
应用场景
- 数据格式转换:在不同 GIS 系统之间迁移数据时进行格式转换
- 数据库集成:将 PostGIS 等空间数据库的 WKT 格式数据转换为 Web 友好的 GeoJSON
- 地图可视化:将 WKT 格式的几何数据转换为 GeoJSON 用于地图库(如 Leaflet、Mapbox、Cesium)渲染
- API 数据交互:处理不同 API 返回的不同格式的地理空间数据
- 空间分析:在前端进行空间几何运算前的数据格式统一
- 数据导入导出:支持用户以不同格式导入导出地理数据
支持的几何类型
| WKT 类型 | GeoJSON 类型 | 示例 |
|---|---|---|
| POINT | Point | POINT(30 10) |
| LINESTRING | LineString | LINESTRING(30 10, 10 30, 40 40) |
| POLYGON | Polygon | POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)) |
| MULTIPOINT | MultiPoint | MULTIPOINT((10 40), (40 30)) |
| MULTILINESTRING | MultiLineString | MULTILINESTRING((10 10, 20 20), (15 15, 30 15)) |
| MULTIPOLYGON | MultiPolygon | MULTIPOLYGON(((30 20, 45 40, 10 40, 30 20))) |
| GEOMETRYCOLLECTION | GeometryCollection | GEOMETRYCOLLECTION(POINT(4 6), LINESTRING(4 6, 7 10)) |
常见问题
坐标顺序问题
WKT 和 GeoJSON 的坐标顺序可能导致混淆:
- WKT:通常使用
X Y格式(即经度 纬度) - GeoJSON:规范要求使用
[经度, 纬度]格式
好在 @terraformer/wkt 库会自动处理这种转换,但在手动处理时需要注意。
多边形孔洞(Holes)
带有内环(孔洞)的多边形在 WKT 和 GeoJSON 中都支持:
// GeoJSON 格式
{
"type": "Polygon",
"coordinates": [
[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]], // 外环
[[2, 2], [8, 2], [8, 8], [2, 8], [2, 2]] // 内环(孔)
]
}
// 对应的 WKT 格式
// POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 8 2, 8 8, 2 8, 2 2))
精度损失
在进行多次转换时可能会出现浮点数精度损失,建议:
- 减少不必要的往返转换
- 在关键应用中考虑使用固定精度的坐标值
- 转换后验证关键坐标点的精度
注意事项
- 格式验证:转换前确保输入数据格式正确,建议添加 try-catch 错误处理
- 坐标有效性:验证坐标值是否在合理范围内(经度 -180
180,纬度 -9090) - 多边形闭合:多边形的首尾坐标必须相同,形成闭合环
- 右手法则:多边形外环应按逆时针方向定义,内环(孔)按顺时针方向定义
- 坐标顺序一致性:确保整个应用中坐标顺序使用一致(避免经纬度混淆)
- 大数据量处理:处理大量几何对象时注意性能,考虑分批处理
- Z 坐标支持:该库支持带高程的 3D 坐标,如
POINT(30 10 5)
在 Cesium 中使用
将 GeoJSON 数据加载到 Cesium:
import { Viewer, GeoJsonDataSource } from "cesium";
import { wktToGeoJSON } from "@terraformer/wkt";
const viewer = new Viewer("cesiumContainer");
// 将 WKT 转换为 GeoJSON
const wkt = "POLYGON((120 30, 120 40, 130 40, 130 30, 120 30))";
const geojson = wktToGeoJSON(wkt);
// 加载到 Cesium
const dataSource = await GeoJsonDataSource.load(geojson);
viewer.dataSources.add(dataSource);
// 视图飞到数据位置
viewer.flyTo(dataSource);