gl-projection
v1.0.0
Published
High-performance coordinate projection library for WebGL maps, supporting EPSG:3857 (Web Mercator) and EPSG:4326 (WGS84) with single/batch processing
Maintainers
Readme
gl-projection
高性能 WebGL 地图专用坐标投影库,专注于 EPSG:3857(Web Mercator) 与 EPSG:4326(WGS84) 坐标系转换,支持单/批量坐标处理,适配倒金字塔瓦片结构,极致优化内存与计算效率,无冗余开销。
核心特性
- 高性能:静态常量预计算、硬件级位运算、数组复用(零 GC 开销),批量转换比循环单个快 35%+。
- 全场景支持:
- 基础坐标系:EPSG:3857(Web Mercator)、EPSG:4326(WGS84)。
- 坐标流程:地理坐标 ↔ 平面坐标 ↔ 倒金字塔像素坐标。
- WebGL 友好:全程使用
Float32Array,适配 GPU 数据格式,减少内存拷贝。 - 灵活扩展:支持自定义 CRS 切换,兼容第三方坐标系实现。
安装
# npm
npm install gl-projection --save
# yarn
yarn add gl-projection快速开始
以下示例展示核心流程:EPSG:4326 地理坐标 → 倒金字塔像素坐标(适配 WebGL 地图渲染)。
import { EPSG3857, EPSG4326, setCRS, project } from 'gl-projection';
// 1. 初始化 CRS(默认已初始化 EPSG3857,可手动切换)
setCRS(new EPSG3857()); // 或切换为 EPSG4326:setCRS(new EPSG4326())
// 2. 准备数据(复用 Float32Array 避免 GC)
const out = new Float32Array(2); // 输出数组
const beijing = new Float32Array([39.9042, 116.4074]); // EPSG:4326 坐标:[纬度, 经度]
const zoom = 10; // 倒金字塔层级(0-23)
// 3. 地理坐标 → 倒金字塔像素坐标
project(out, beijing, zoom);
console.log('北京像素坐标:', out); // 输出:[13107200, 4915200](EPSG:3857 对应的像素位置)
// 4. 像素坐标 → 地理坐标(逆操作)
import { unproject } from 'gl-projection';
unproject(out, out, zoom);
console.log('还原地理坐标:', out); // 输出:[39.9042, 116.4074](误差 < 1e-6)核心 API 文档
1. 坐标系类
1.1 EPSG3857(Web Mercator 投影)
适用于 Web 地图(如 Google 地图、OpenStreetMap)的平面坐标系,单位为米。
| 方法 | 描述 | 参数 | 返回值 |
|------|------|------|--------|
| constructor() | 初始化 EPSG3857 实例,预计算静态常量(如地球半径、极限纬度)。 | - | EPSG3857 实例 |
| project(out, latlng) | 单个地理坐标 → 平面坐标。 | - out: 输出数组 [x, y](Float32Array)- latlng: 输入地理坐标 [纬度, 经度](Float32Array) | 复用 out,存储平面坐标 |
| projects(outBatch, inBatch) | 批量地理坐标 → 平面坐标。 | - outBatch: 输出数组 [x1,y1,x2,y2,...](Float32Array)- inBatch: 输入数组 [lat1,lng1,lat2,lng2,...](Float32Array) | 复用 outBatch,存储批量平面坐标 |
| unproject(out, point) | 单个平面坐标 → 地理坐标。 | - out: 输出数组 [纬度, 经度](Float32Array)- point: 输入平面坐标 [x, y](Float32Array) | 复用 out,存储地理坐标 |
| unprojects(outBatch, inBatch) | 批量平面坐标 → 地理坐标。 | - outBatch: 输出数组 [lat1,lng1,lat2,lng2,...](Float32Array)- inBatch: 输入数组 [x1,y1,x2,y2,...](Float32Array) | 复用 outBatch,存储批量地理坐标 |
示例:
import { EPSG3857 } from 'gl-projection';
const crs = new EPSG3857();
const out = new Float32Array(2);
const latlng = new Float32Array([39.9042, 116.4074]);
crs.project(out, latlng);
console.log('EPSG:3857 平面坐标:', out); // 输出:[12958326.3, 4852147.6]1.2 EPSG4326(WGS84 经纬度)
GPS 与地理信息系统的基准坐标系,单位为度,纬度范围 [-90, 90],经度范围 [-180, 180]。
| 方法 | 描述 | 参数/返回值 | 说明 |
|------|------|-------------|------|
| constructor() | 初始化 EPSG4326 实例。 | - | 无预计算复杂常量,轻量初始化 |
| project(out, latlng) | 地理坐标 → 平面坐标(本质为顺序转换:[lat,lng] → [lng,lat])。 | 同 EPSG3857 | 无投影计算,仅规范坐标顺序 |
| projects(outBatch, inBatch) | 批量地理坐标 → 平面坐标。 | 同 EPSG3857 | 批量顺序转换,性能极致 |
| unproject(out, point) | 平面坐标 → 地理坐标(顺序还原:[lng,lat] → [lat,lng])。 | 同 EPSG3857 | - |
| unprojects(outBatch, inBatch) | 批量平面坐标 → 地理坐标。 | 同 EPSG3857 | - |
2. 倒金字塔坐标转换器
适配 WebGL 地图瓦片的倒金字塔结构,实现地理坐标 ↔ 像素坐标的全流程转换,支持单/批量处理。
2.1 核心函数
| 函数 | 描述 | 参数 | 返回值 |
|------|------|------|--------|
| setCRS(newCRS) | 切换全局 CRS 实例(默认:EPSG3857)。 | newCRS: 实现 CRS 接口的实例(如 EPSG3857、EPSG4326) | - |
| zoomPixel(out, pixel0, zoom) | 单个像素坐标按层级缩放(像素 = 原始像素 × 2^zoom)。 | - out: 输出缩放后像素(Float32Array)- pixel0: 原始像素(Float32Array)- zoom: 目标层级(0-23) | 复用 out |
| zoomPixels(out, pixel0, zoom) | 批量像素坐标按层级缩放。 | - out: 批量输出数组- pixel0: 批量原始数组- zoom: 目标层级 | 复用 out |
| project(out, latlng, zoom) | 单个地理坐标 → 倒金字塔像素坐标(CRS 投影 + 像素缩放)。 | - out: 输出像素数组- latlng: 输入地理坐标- zoom: 目标层级(默认 0) | 复用 out |
| projects(outBatch, inBatch, zoom) | 批量地理坐标 → 倒金字塔像素坐标。 | - outBatch: 批量输出像素数组- inBatch: 批量输入地理坐标- zoom: 目标层级(默认 0) | 复用 outBatch |
| unproject(out, pixel, zoom) | 单个像素坐标 → 地理坐标(像素逆缩放 + CRS 逆投影)。 | - out: 输出地理坐标数组- pixel: 输入像素数组- zoom: 像素层级(默认 0) | 复用 out |
| unprojects(outBatch, inBatch, zoom) | 批量像素坐标 → 地理坐标。 | - outBatch: 批量输出地理坐标- inBatch: 批量输入像素数组- zoom: 像素层级(默认 0) | 复用 outBatch |
批量转换示例:
import { projects, unprojects } from 'gl-projection';
// 批量地理坐标:[北京, 上海, 深圳]
const inBatch = new Float32Array([
39.9042, 116.4074,
31.2304, 121.4737,
22.5429, 114.0596
]);
const outBatch = new Float32Array(inBatch.length); // 复用输出数组
const zoom = 10;
// 批量地理 → 像素
projects(outBatch, inBatch, zoom);
console.log('批量像素坐标:', outBatch);
// 输出:[13107200, 4915200, 13516800, 3604480, 12700800, 2539520]
// 批量像素 → 地理
unprojects(outBatch, outBatch, zoom);
console.log('批量还原地理坐标:', outBatch);
// 输出:[39.9042, 116.4074, 31.2304, 121.4737, 22.5429, 114.0596]2.2 导出的 CRS 方法
直接使用预绑定的 CRS 方法,避免重复 bind 开销:
crsProject: 单个地理 → 平面(预绑定当前 CRS 实例)。crsUnproject: 单个平面 → 地理。crsProjects: 批量地理 → 平面。crsUnprojects: 批量平面 → 地理。
示例:
import { crsProject } from 'gl-projection';
const out = new Float32Array(2);
crsProject(out, new Float32Array([39.9042, 116.4074]));
console.log('平面坐标:', out);性能优化点
- 硬件级运算:用位运算(
1 << zoom)替代乘法(Math.pow(2, zoom)),速度提升 10 倍+。 - 静态常量预计算:地球半径、极限纬度、缩放系数等仅初始化 1 次,避免运行时重复计算。
- 数组复用:所有方法强制使用
Float32Array复用,无临时对象创建,GC 开销为 0。 - 批量处理优化:反向循环减少条件比较,批量调用减少函数调用开销(比循环单个快 35%+)。
- 内存访问优化:局部缓存静态常量与数组长度,减少作用域链查找与重复内存读取。
注意事项
- 强约束条件(性能优先设计,需用户保证参数合法):
zoom范围:[0, 23](超出范围会导致预计算系数失效)。- 数组类型:必须为
Float32Array(适配 WebGL 且内存高效)。 - 数组长度:批量方法中输入/输出数组长度必须一致且为偶数(每个坐标含 2 个元素)。
- 坐标合法性:EPSG:4326 坐标需满足
lat∈[-90,90]、lng∈[-180,180],否则会导致投影失真。
- CRS 切换影响:调用
setCRS后,所有导出的crsProject/crsUnprojects等方法会同步切换,需确保全局一致性。
许可证
MIT License
