# gl-projection **Repository Path**: proj4js/gl-projection ## Basic Information - **Project Name**: gl-projection - **Description**: 高性能 WebGL 地图专用坐标投影库,专注于 **EPSG:3857(Web Mercator)** 与 **EPSG:4326(WGS84)** 坐标系转换,支持单/批量坐标处理,适配倒金字塔瓦片结构,极致优化内存与计算效率,无冗余开销。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-02 - **Last Updated**: 2025-10-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # gl-projection 高性能 WebGL 地图专用坐标投影库,专注于 **EPSG:3857(Web Mercator)** 与 **EPSG:4326(WGS84)** 坐标系转换,支持单/批量坐标处理,适配倒金字塔瓦片结构,极致优化内存与计算效率,无冗余开销。 ## 核心特性 - **高性能**:静态常量预计算、硬件级位运算、数组复用(零 GC 开销),批量转换比循环单个快 35%+。 - **全场景支持**: - 基础坐标系:EPSG:3857(Web Mercator)、EPSG:4326(WGS84)。 - 坐标流程:地理坐标 ↔ 平面坐标 ↔ 倒金字塔像素坐标。 - **WebGL 友好**:全程使用 `Float32Array`,适配 GPU 数据格式,减少内存拷贝。 - **灵活扩展**:支持自定义 CRS 切换,兼容第三方坐标系实现。 ## 安装 ```bash # npm npm install gl-projection --save # yarn yarn add gl-projection ``` ## 快速开始 以下示例展示核心流程:**EPSG:4326 地理坐标 → 倒金字塔像素坐标**(适配 WebGL 地图渲染)。 ```typescript 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`,存储批量地理坐标 | **示例**: ```typescript 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` | **批量转换示例**: ```typescript 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`: 批量平面 → 地理。 **示例**: ```typescript import { crsProject } from 'gl-projection'; const out = new Float32Array(2); crsProject(out, new Float32Array([39.9042, 116.4074])); console.log('平面坐标:', out); ``` ## 性能优化点 1. **硬件级运算**:用位运算(`1 << zoom`)替代乘法(`Math.pow(2, zoom)`),速度提升 10 倍+。 2. **静态常量预计算**:地球半径、极限纬度、缩放系数等仅初始化 1 次,避免运行时重复计算。 3. **数组复用**:所有方法强制使用 `Float32Array` 复用,无临时对象创建,GC 开销为 0。 4. **批量处理优化**:反向循环减少条件比较,批量调用减少函数调用开销(比循环单个快 35%+)。 5. **内存访问优化**:局部缓存静态常量与数组长度,减少作用域链查找与重复内存读取。 ## 注意事项 1. **强约束条件**(性能优先设计,需用户保证参数合法): - `zoom` 范围:`[0, 23]`(超出范围会导致预计算系数失效)。 - 数组类型:必须为 `Float32Array`(适配 WebGL 且内存高效)。 - 数组长度:批量方法中输入/输出数组长度必须一致且为偶数(每个坐标含 2 个元素)。 - 坐标合法性:EPSG:4326 坐标需满足 `lat∈[-90,90]`、`lng∈[-180,180]`,否则会导致投影失真。 2. **CRS 切换影响**:调用 `setCRS` 后,所有导出的 `crsProject`/`crsUnprojects` 等方法会同步切换,需确保全局一致性。 ## 许可证 MIT License