npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

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

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. 硬件级运算:用位运算(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