主题
工具命名空间 Utils
标准版提供 4 个工具命名空间:Measurement(量算)、Analysis(空间分析)、GeomUtils(几何操作)、ProjectionUtils(投影工具)。这些是静态方法集合,无需实例化。
Measurement
量算工具,提供距离、面积、方位角等量算函数。
方法
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
distance(points) | points: Coordinate[] | number | 计算折线总长度(欧氏距离,米) |
geodesicDistance(points) | points: Coordinate[] | number | 计算折线总长度(大地线距离,米) |
area(polygon) | polygon: Coordinate[] | number | 计算多边形面积(平方米) |
geodesicArea(polygon) | polygon: Coordinate[] | number | 计算多边形面积(大地线,平方米) |
height(p1, p2) | p1: Coordinate, p2: Coordinate | number | 计算两点间高度差 |
bearing(from, to) | from: Coordinate, to: Coordinate | number | 计算方位角(度,正北为 0) |
destination(origin, distance, bearing) | origin: Coordinate, distance: number, bearing: number | Point | 根据起点、距离、方位角计算终点 |
midpoint(a, b) | a: Coordinate, b: Coordinate | Point | 计算两点中点 |
along(line, distance) | line: LineString, distance: number | Point | 沿线路指定距离处的点 |
length(line) | line: LineString | number | 计算线路总长度(米) |
formatDistance(meters) | meters: number | string | 格式化距离(自动选择 m/km) |
formatArea(sqMeters) | sqMeters: number | string | 格式化面积(自动选择 m²/km²) |
示例
ts
import { Measurement, LineString, Point } from '@gmap/standard';
// 欧氏距离
const dist = Measurement.distance([[0, 0], [1, 1]]);
console.log(dist); // ~156892 (米)
// 大地线距离(更精确)
const geoDist = Measurement.geodesicDistance([[116.3, 39.9], [116.5, 40.0]]);
console.log(Measurement.formatDistance(geoDist)); // "23.45 km"
// 面积
const area = Measurement.area([
[116.0, 39.0],
[117.0, 39.0],
[117.0, 40.0],
[116.0, 40.0],
]);
console.log(Measurement.formatArea(area)); // "12345.67 km²"
// 方位角
const bearing = Measurement.bearing([116.0, 39.0], [116.0, 40.0]);
console.log(bearing); // 0 (正北)
// 目标点
const dest = Measurement.destination([116.0, 39.0], 50000, 90);
console.log(dest.get()); // [约 116.45, 39.0] (向东 50km)
// 中点
const mid = Measurement.midpoint([116.0, 39.0], [117.0, 40.0]);
console.log(mid.get()); // [116.5, 39.5]
// 沿线路量测
const line = new LineString([[0, 0], [1, 0], [2, 0], [3, 0]]);
const point = Measurement.along(line, 150000); // 150km 处
console.log(point.get());
// 线路总长
const len = Measurement.length(line);
console.log(Measurement.formatDistance(len));
// 格式化
console.log(Measurement.formatDistance(1234)); // "1.23 km"
console.log(Measurement.formatDistance(500)); // "500.0 m"
console.log(Measurement.formatArea(5000000)); // "5.00 km²"
console.log(Measurement.formatArea(500)); // "500.0 m²"Analysis
空间分析工具,提供缓冲区、叠加、插值等分析函数。
方法
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
buffer(geom, distance) | geom: Geometry, distance: number | Geometry | 缓冲区分析 |
overlay(a, b, mode) | a: Geometry, b: Geometry, mode: string | Geometry | 叠加分析 |
clip(geom, extent) | geom: Geometry, extent: Extent | Geometry | 裁剪 |
spatialJoin(a, b, mode) | a: FeatureCollection, b: FeatureCollection, mode: string | FeatureCollection | 空间连接 |
nearest(points, target, k) | points: Coordinate[], target: Coordinate, k: number | Point[] | 最近邻查询 |
viewshed(terrain, observer, radius) | terrain: unknown, observer: Coordinate, radius: number | object | 视域分析 |
lineOfSight(terrain, from, to) | terrain: unknown, from: Coordinate, to: Coordinate | object | 通视分析 |
profile(line, terrain) | line: LineString, terrain: unknown | object | 剖面分析 |
slope(terrain, point) | terrain: unknown, point: Coordinate | number | 坡度计算 |
aspect(terrain, point) | terrain: unknown, point: Coordinate | number | 坡向计算 |
contour(terrain, interval) | terrain: unknown, interval: number | LineString[] | 等值线生成 |
hotspot(points, method) | points: FeatureCollection, method: string | FeatureCollection | 热点分析 |
voronoi(points, extent) | points: Coordinate[], extent: Extent | Polygon[] | 泰森多边形 |
shortestPath(from, to) | from: Coordinate, to: Coordinate | LineString | 最短路径 |
serviceArea(center, breaks) | center: Coordinate, breaks: number[] | Polygon[] | 服务区分析 |
cluster(points, options) | points: Coordinate[], options: object | { centroids, groups } | 聚类分析 |
density(points, options) | points: FeatureCollection, options: object | FeatureCollection | 密度分析 |
interpolate(points, method) | points: unknown, method: string | object | 插值分析 |
示例
ts
import { Analysis, Point, Polygon, LineString, BoundingBox } from '@gmap/standard';
// 缓冲区
const point = new Point([116.397, 39.908]);
const buffer = Analysis.buffer(point, 5000); // 5km 缓冲区
// 裁剪
const bbox = new BoundingBox([116, 39, 117, 40]);
const clipped = Analysis.clip(polygon, bbox.toArray());
// 最近邻
const nearest = Analysis.nearest(
[[116.1, 39.1], [116.2, 39.2], [116.3, 39.3]],
[116.25, 39.25],
2, // 返回最近的 2 个
);
// 泰森多边形
const voronoi = Analysis.voronoi(
[[116.1, 39.1], [116.2, 39.2], [116.3, 39.3]],
[115.5, 38.5, 117.5, 40.5],
);
// 热点分析
const hotspot = Analysis.hotspot(censusData, 'Getis-Ord');
// 聚类
const { centroids, groups } = Analysis.cluster(
[[116.1, 39.1], [116.12, 39.12], [116.5, 39.5]],
{ radius: 5000 },
);
// 坡度
const slopeVal = Analysis.slope(terrainData, [116.397, 39.908]);
// 等值线
const contours = Analysis.contour(terrainData, 50); // 50m 间距GeomUtils
几何操作工具,提供几何运算和转换函数。
方法
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
union(a, b) | a: Geometry, b: Geometry | Geometry | 并集 |
intersection(a, b) | a: Geometry, b: Geometry | Geometry | 交集 |
difference(a, b) | a: Geometry, b: Geometry | Geometry | 差集(A - B) |
symDifference(a, b) | a: Geometry, b: Geometry | Geometry | 对称差集 |
convexHull(points) | points: Coordinate[] | Polygon | 凸包 |
concaveHull(points) | points: Coordinate[] | Polygon | 凹包 |
boundingBox(geometries) | geometries: Geometry[] | BoundingBox | 合并包围盒 |
simplify(geometry, tolerance) | geometry: Geometry, tolerance: number | Geometry | 简化 |
smooth(geometry, iterations?) | geometry: Geometry, iterations?: number | Geometry | 平滑 |
split(line, splitter) | line: LineString, splitter: Geometry | LineString[] | 分割线 |
snap(geometry, target, tolerance) | geometry: Geometry, target: Geometry, tolerance: number | Geometry | 捕捉/对齐 |
validate(geometry) | geometry: Geometry | { valid: boolean; errors?: string[] } | 验证几何有效性 |
repair(geometry) | geometry: Geometry | Geometry | 修复无效几何 |
toDegrees(rad) | rad: number | number | 弧度转角度 |
toRadians(deg) | deg: number | number | 角度转弧度 |
wrapLng(lng) | lng: number | number | 经度规范化(-180 ~ 180) |
示例
ts
import { GeomUtils, Point, LineString, Polygon } from '@gmap/standard';
// 凸包
const hull = GeomUtils.convexHull([
[116.1, 39.1],
[116.2, 39.2],
[116.3, 39.1],
[116.25, 39.05],
]);
// 简化
const line = new LineString([[0, 0], [1, 0.1], [2, 0], [3, 0.1], [4, 0]]);
const simplified = GeomUtils.simplify(line, 0.01);
// 验证
const result = GeomUtils.validate(polygon);
if (!result.valid) {
console.error('几何无效:', result.errors);
}
// 修复
const repaired = GeomUtils.repair(invalidPolygon);
// 角度/弧度转换
console.log(GeomUtils.toDegrees(Math.PI)); // 180
console.log(GeomUtils.toRadians(180)); // 3.14159...
console.log(GeomUtils.wrapLng(200)); // -160
console.log(GeomUtils.wrapLng(-200)); // 160
// 平滑
const smoothLine = GeomUtils.smooth(line, 3);
// 捕捉
const snapped = GeomUtils.snap(point, targetLine, 0.001);ProjectionUtils
投影工具,提供投影注册、查询和坐标转换功能。
方法
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
get(id) | id: string | Projection | undefined | 获取已注册投影 |
register(id, projection) | id: string, projection: Projection | void | 注册投影 |
transform(coords, fromCRS, toCRS) | coords: Coordinate | Coordinate[], fromCRS: string, toCRS: string | Coordinate | Coordinate[] | 坐标转换 |
isSupported(id) | id: string | boolean | 检查投影是否已注册 |
list() | — | string[] | 列出所有已注册投影 |
示例
ts
import { ProjectionUtils, Projection } from '@gmap/standard';
// 注册自定义投影
ProjectionUtils.register('EPSG:4547', new Projection(
'EPSG:4547',
'+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +datum=CGCS2000 +units=m'
));
// 查询投影
const proj = ProjectionUtils.get('EPSG:4547');
console.log(proj?.id); // 'EPSG:4547'
// 坐标转换
const coord = ProjectionUtils.transform(
[39500000, 4400000],
'EPSG:4547',
'EPSG:4326',
);
console.log(coord); // [约 117.0, 约 39.76]
// 批量转换
const coords = ProjectionUtils.transform(
[[39500000, 4400000], [39600000, 4500000]],
'EPSG:4547',
'EPSG:4326',
);
console.log(coords); // 2 个 WGS84 坐标
// 检查是否支持
console.log(ProjectionUtils.isSupported('EPSG:4547')); // true
console.log(ProjectionUtils.isSupported('EPSG:9999')); // false
// 列出所有投影
const all = ProjectionUtils.list();
console.log(all); // ['EPSG:4547', ...]综合示例
ts
import {
Measurement, Analysis, GeomUtils, ProjectionUtils,
Point, LineString, Polygon, BoundingBox, Projection,
} from '@gmap/standard';
// 1. 注册自定义投影
ProjectionUtils.register('EPSG:4547', new Projection(
'EPSG:4547',
'+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +datum=CGCS2000 +units=m'
));
// 2. 从工程坐标转为 WGS84
const wgs84Coord = ProjectionUtils.transform(
[39512345, 4412345],
'EPSG:4547',
'EPSG:4326',
);
// 3. 计算距离
const dist = Measurement.geodesicDistance([wgs84Coord, [117.5, 40.0]]);
console.log(`距离: ${Measurement.formatDistance(dist)}`);
// 4. 创建缓冲区
const buffer = Analysis.buffer(new Point(wgs84Coord), 1000);
// 5. 验证几何
const validation = GeomUtils.validate(buffer);
if (validation.valid) {
console.log('缓冲区几何有效');
}
// 6. 凸包
const points = [
[116.1, 39.1],
[116.2, 39.3],
[116.4, 39.2],
[116.3, 39.0],
];
const hull = GeomUtils.convexHull(points);
console.log(`凸包面积: ${Measurement.formatArea(hull.getArea())}`);