@luothink/three-gis-kit
v1.0.3
Published
A utility library for three.js GIS, including CSG operations, coordinate transformation, geometry calculations and pipe modeling.
Maintainers
Readme
@luothink/three-gis-kit
A utility library for three.js GIS calculations.
Installation
npm install @luothink/three-gis-kitUsage
import { CSGUtils, GeometryUtils, GeoCoordUtils, GISUtils, ENUProjection, PhoneBearingUtils } from '@luothink/three-gis-kit';API
CSGUtils
提供 CSG (three-bvh-csg) 布尔运算功能。
performCSG(THREE, CSG, meshA, meshB, operation)
执行 CSG 布尔运算。
| 参数 | 类型 | 说明 | |------|------|------| | THREE | Object | THREE.js 库对象 | | CSG | Object | CSG 库对象 (three-bvh-csg) | | meshA | Mesh | 待运算的 Mesh 对象 A | | meshB | Mesh | 待运算的 Mesh 对象 B | | operation | String | 运算操作 |
operation 可选值:
union- 并集 (A ∪ B)subtract- 差集 (A - B)intersect- 交集 (A ∩ B)difference- 对称差集 (A ⊕ B)reverse_subtraction- 反向差集 (B - A)hollow_subtraction- 空心差集hollow_intersection- 空心交集
import { CSGUtils } from '@luothink/three-gis-kit';
import * as THREE from 'three';
import * as CSG from 'three-bvh-csg';
const resultMesh = CSGUtils.performCSG(THREE, CSG, meshA, meshB, 'subtract');注意:CSGUtils.performCSG 会从你传入的 CSG 对象中解构 ADDITION/SUBTRACTION/INTERSECTION/DIFFERENCE/REVERSE_SUBTRACTION/HOLLOW_INTERSECTION/HOLLOW_SUBTRACTION 等常量。如果你没有直接传入 import * as CSG from 'three-bvh-csg',而是自己组装 CSG 对象,请确保把这些常量也一并传入,否则会在运行时报错或得到错误结果。
GeoCoordUtils
提供 GIS 坐标转换功能,包括经纬度、墨卡托、世界坐标的转换。
lonLatToMercator(lng, lat, alt?)
将经纬度转换为墨卡托投影坐标。
import { GeoCoordUtils } from '@luothink/three-gis-kit';
const mercator = GeoCoordUtils.lonLatToMercator(121.543793, 29.868336);
// { x: 13528332.56, y: 3503547.56, z: 0 }mercatorToLonLat(x, y, z?)
将墨卡托投影坐标转换为经纬度。
const lnglat = GeoCoordUtils.mercatorToLonLat(13528332.56, 3503547.56);
// { x: 121.543793, y: 29.868336, z: 0 }lonLatToWorld(lng, lat, alt?)
将经纬度转换为世界坐标 (Three.js 坐标系)。
const world = GeoCoordUtils.lonLatToWorld(121.543793, 29.868336, 100);
// { x: 13528332.56, y: 100, z: -3503547.56 }worldToLonLat(x, y, z)
将世界坐标转换为经纬度。
const lnglat = GeoCoordUtils.worldToLonLat(13528332.56, 100, -3503547.56);
// { x: 121.543793, y: 29.868336, z: 100 }mercatorToWorld(x, y, alt?)
将墨卡托投影坐标转换为世界坐标。
worldToMercator(x, y, z)
将世界坐标转换为墨卡托投影坐标。
lonLatToWorldENU(lng, lat, alt, originLng, originLat, originAlt?)
将经纬度/高程转换为以指定原点为参考的本地坐标(单位:米),输出为 Three.js 友好的坐标:
x = eastz = -northy = alt - originAlt
该方法会对输入做鲁棒性处理:
- 自动纠正经纬度顺序反了的情况(典型:纬度绝对值 > 90 且经度绝对值 ≤ 90 时交换)
- 高程疑似为毫米时自动换算为米(绝对值在 1000 到 1e7 之间按 mm 处理)
import { GeoCoordUtils } from '@luothink/three-gis-kit';
const origin = { lng: 121.543793, lat: 29.868336, alt: 0 };
const p = { lng: 121.544793, lat: 29.868336, alt: 100 };
const enuWorld = GeoCoordUtils.lonLatToWorldENU(p.lng, p.lat, p.alt, origin.lng, origin.lat, origin.alt);
// { x: east, y: up, z: -north }ENUProjection
提供局部 ENU (East-North-Up) 坐标投影功能,可用于将指定原点附近的经纬度/高程转换为本地平面坐标(单位:米)。
new ENUProjection(originLng, originLat, originAlt?)
创建投影实例并设置局部原点。
setOrigin(lng, lat, alt?)
重置局部原点。
project(lng, lat)
将经纬度投影为局部 EN 坐标,返回 [east, north](单位:米)。
project3(lng, lat, alt?)
将经纬度/高程投影为局部 ENU 坐标,返回 [east, north, up](单位:米)。alt 默认为 0。
import { ENUProjection } from '@luothink/three-gis-kit';
const projection = new ENUProjection(121.543793, 29.868336, 0);
const [east, north] = projection.project(121.544793, 29.868336);
// east/north: 相对原点的水平位移(米)
const [e, n, u] = projection.project3(121.543793, 29.868336, 100);
// u: 相对原点的高度差(米)GISUtils
提供 GIS 相关的实用工具函数。
calcDistance(start, end, ignoreAltitude?)
计算两点之间的距离(考虑海拔高度)。
| 参数 | 类型 | 说明 | |------|------|------| | start | {x, y, z} | 起点坐标 | | end | {x, y, z} | 终点坐标 | | ignoreAltitude | Boolean | 是否忽略海拔,默认 false |
import { GISUtils } from '@luothink/three-gis-kit';
const start = { x: 121.543793, y: 29.868336, z: 0 };
const end = { x: 121.553793, y: 29.878336, z: 50 };
const distance = GISUtils.calcDistance(start, end);
// 返回距离(米)calcPipeLength_ar(start, end, THREE)
计算 3D 管长(圆柱体高度)。
const length = GISUtils.calcPipeLength_ar(start, end, THREE);degreesToDMS(degrees, isLongitude?)
将十进制度数转换为度分秒 (DMS) 格式。
const result = GISUtils.degreesToDMS(121.543793, true);
console.log(result.toString()); // "121°32'37.6548\"E"toRadian(degrees)
角度转弧度。
toDegree(radians)
弧度转角度。
GeometryUtils
提供几何计算功能。
lineToCylinder(THREE, startingPoint, endPoint, radiusStart, radiusEnd, material, radiusIncrement?, pipeLength_ar)
将两点之间的线段转换为圆柱体(管道)模型。
import { GeometryUtils } from '@luothink/three-gis-kit';
import * as THREE from 'three';
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const start = { x: 0, y: 0, z: 0 };
const end = { x: 10, y: 10, z: 10 };
const pipeLength = 17.32;
const cylinder = GeometryUtils.lineToCylinder(
THREE, start, end, 0.5, 0.5, material, 0, pipeLength
);adjustLineLength(startPoint, endPoint, pipeLength, newLength, fixedPoint?)
调整管道长度(保持方向不变)。
| 参数 | 类型 | 说明 | |------|------|------| | startPoint | {x, y, z} | 起点坐标 | | endPoint | {x, y, z} | 终点坐标 | | pipeLength | Number | 当前管道长度 | | newLength | Number | 目标长度 | | fixedPoint | String | 固定点: "start" 或 "end" |
const result = GeometryUtils.adjustLineLength(
{ x: 0, y: 0, z: 0 },
{ x: 10, y: 0, z: 0 },
10,
20,
'start'
);
// { start: {x:0, y:0, z:0}, end: {x:20, y:0, z:0} }PhoneBearingUtils
提供手机朝向(指南针方位角)获取功能,统一处理不同操作系统/浏览器下的差异,并支持数据平滑与防抖。
PhoneBearingUtils.getInstance(options?)
获取 PhoneBearingUtils 单例。
| 参数 | 类型 | 说明 |
|------|------|------|
| options.smoothingFactor | Number | 平滑系数 (0~1),越接近1越平滑,默认 0.85 |
| options.minDeltaDeg | Number | 最小变化阈值(度),小于该值不下发,默认 1.5 |
| options.maxUpdateHz | Number | 最大下发频率(Hz),默认 15 |
async start()
启动设备方向事件监听。 注意:在 iOS 13+ 中,必须在用户手势(如点击按钮)的回调中调用此方法以申请权限,且仅在 HTTPS 环境下有效。
subscribe(callback)
订阅朝向变化,返回一个用于取消订阅的函数。回调参数 bearingDeg 为 0~360 的度数,0 表示正北,顺时针递增。
stop()
主动停止设备方向事件监听(当最后一个订阅被取消时,也会自动停止)。
import { PhoneBearingUtils } from '@luothink/three-gis-kit';
// 获取单例
const bearing = PhoneBearingUtils.getInstance({
smoothingFactor: 0.85,
minDeltaDeg: 1.5,
maxUpdateHz: 15
});
async function enableFollow() {
// 必须在用户交互事件中调用
const ok = await bearing.start();
if (!ok) return;
// 订阅方位角变化
const unsubscribe = bearing.subscribe((deg) => {
console.log('当前手机朝向(度):', deg);
// map.setBearing(deg);
});
// 需要停止时调用
// unsubscribe();
}Development
npm testLicense
ISC
