# tilehash **Repository Path**: proj4js/tilehash ## Basic Information - **Project Name**: tilehash - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-04 - **Last Updated**: 2025-10-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # tilehash 专为地图瓦片设计的高性能哈希编码库——**解决GIS/地图开发者面临的ZXY坐标存储冗余、空间计算复杂等核心痛点**。 - 用紧凑哈希(如 `"k8q8y"`)替代冗长的ZXY坐标(`z=10, x=345, y=678`) - 支持8+种空间计算(邻近查询、距离估算、区域覆盖等) - 无缝运行于Node.js/浏览器环境,提供完整TypeScript类型安全 - 核心方法每秒可处理百万级编码/解码操作 ## 🌟 核心优势 ### 1. 专为地图瓦片设计,比通用编码工具更专业 普通哈希工具(如MD5)或地理编码(如Geohash)无法适配地图瓦片的ZXY体系,而tilehash深度优化瓦片场景: | 工具 | 目标场景 | 瓦片专属特性 | 空间计算能力 | |---------------------|------------------|-------------------------------|-----------------------------| | tilehash | 地图瓦片(ZXY) | ✅ 缩放级别前缀、边界循环处理 | 8+种(邻近、距离、包含等) | | Geohash | 地理坐标(经纬度)| ❌ 无瓦片适配能力 | 仅2种(邻近、包含) | | 普通哈希(如MD5) | 通用数据 | ❌ 无空间关联性 | 0种(仅哈希,无计算能力) | ### 2. 紧凑高效,大幅降低存储与传输成本 针对地图瓦片的ZXY分布特性优化哈希长度,兼顾压缩率与可读性: - **动态长度**:根据缩放级别自动调整(z=10时约5个字符,z=25时约8个字符) - **存储节省**:相比原始ZXY字符串(如 `"z=10,x=345,y=678"`),存储体积减少60%+ - **传输优化**:更小的哈希体积可加快API请求速度,尤其适合地图瓦片预加载、缓存同步等场景 ### 3. 性能强劲,支撑高并发场景 基于位运算与预计算查表优化,核心方法性能达到工业级标准: #### 性能测试数据(Node.js v18.16.0,Intel i7-12700H,10万次迭代) | 方法 | 平均耗时(微秒/次) | 吞吐量(次/秒) | 开发者价值 | |---------------------|---------------------|------------------------|-----------------------------| | `isValid`(验证) | 0.21 – 0.28 | 350万 – 480万 | 每秒验证480万哈希,无卡顿 | | `encode`(编码) | 0.62 – 1.85 | 54万 – 160万 | 高并发场景下每秒编码160万瓦片 | | `decode`(解码) | 0.87 – 2.63 | 38万 – 115万 | 快速解析哈希,加速瓦片加载 | | `getNeighbors`(邻近查询) | 8.76 – 23.74 | 4.2万 – 11.4万 | 每秒预加载10万+邻近瓦片 | > 📌 核心优化手段:位运算批量处理二进制数据 + 预计算幂值/掩码表,避免重复计算 ### 4. 易用性拉满,降低开发成本 无需复杂配置,3行代码即可上手,同时提供完善的开发者友好特性: - **TypeScript原生支持**:完整类型定义,VS Code等IDE自动补全,减少类型错误 - **友好错误提示**:参数非法时返回明确信息(如 `"z必须在0-30之间"`,而非模糊的“参数错误”) - **零依赖**:无额外第三方依赖,包体积<5KB(gzip后),不增加项目负担 ### 5. 跨环境兼容,覆盖全场景需求 无需担心环境差异,一套代码可运行于所有主流开发场景: | 运行环境 | 支持版本 | 依赖要求 | |---------------------|--------------------|---------------------------| | Node.js | ✅ v14.0.0+ | 无(原生支持) | | 浏览器 | ✅ Chrome/Firefox/Safari 13+ | 支持ES5+语法 | | 前端框架 | ✅ React/Vue/Angular | 无框架锁定,直接导入使用 | ## 🚀 典型使用场景 ### 1. 地图瓦片缓存优化 - **问题**:将ZXY坐标(如 `"z10x345y678"`)存入localStorage或后端缓存时,字符串冗长、占用空间大。 - **解决方案**:用tilehash编码为短字符串,减少60%+缓存体积。 ```javascript // 编码后存入缓存 const hash = TileHash.encode(10, 345, 678); // "k8q8y" localStorage.setItem('cached_tile', hash); // 从缓存解码 const cachedHash = localStorage.getItem('cached_tile'); const { z, x, y } = TileHash.decode(cachedHash); // 恢复为z=10, x=345, y=678 ``` ### 2. 瓦片预加载(用户地图拖拽场景) - **问题**:用户拖拽地图时,需提前加载周边8个瓦片以避免空白,手动计算ZXY邻近值繁琐易出错。 - **解决方案**:1行代码获取所有邻近瓦片哈希,直接用于预加载。 ```javascript // 获取当前瓦片的8个邻近瓦片 const currentHash = "k8q8y"; const neighborHashes = TileHash.getNeighbors(currentHash); // 结果:["k8q8x", "k8q8z", "k8q90", ...](8个邻近瓦片) // 批量预加载邻近瓦片 neighborHashes.forEach(hash => { const { z, x, y } = TileHash.decode(hash); loadTile(z, x, y); // 调用瓦片加载函数 }); ``` ### 3. LBS应用空间搜索 - **问题**:需查询“某瓦片1公里范围内的POI”,直接用经纬度范围计算效率低。 - **解决方案**:结合距离估算与区域覆盖,快速锁定目标瓦片,缩小查询范围。 ```javascript // 1. 估算1公里对应的瓦片范围(假设当前瓦片哈希为"k8q8y") const centerHash = "k8q8y"; const { z } = TileHash.decode(centerHash); // 2. 获取1公里范围对应的经纬度边界(需结合业务逻辑微调) const bounds = { minLng: 116.3, maxLng: 116.4, minLat: 39.9, maxLat: 40.0 }; // 3. 获取边界内所有瓦片,仅查询这些瓦片的POI const targetHashes = TileHash.getHashesInBounds( bounds.minLng, bounds.maxLng, bounds.minLat, bounds.maxLat, z ); // 4. 按瓦片哈希批量查询POI(效率远高于全局经纬度查询) const pois = await queryPoisByTileHashes(targetHashes); ``` ## 🔧 快速开始 ### 1. 安装 通过npm或yarn安装: ```bash # npm npm install tilehash --save # yarn yarn add tilehash ``` ### 2. 基础使用示例 #### Node.js/CommonJS ```javascript const { TileHash } = require('tilehash'); // 1. 编码:ZXY → 哈希 const z = 10; // 缩放级别(0-30) const x = 345; // 瓦片列号(0 ≤ x ≤ 2^z - 1) const y = 678; // 瓦片行号(0 ≤ y ≤ 2^z - 1) const hash = TileHash.encode(z, x, y); console.log('编码结果:', hash); // 输出示例:"k8q8y" // 2. 解码:哈希 → ZXY const decoded = TileHash.decode(hash); console.log('解码结果:', decoded); // 输出:{ z: 10, x: 345, y: 678 } // 3. 验证哈希合法性 const isValid = TileHash.isValid(hash); console.log('是否合法:', isValid); // 输出:true ``` #### TypeScript/ES Modules ```typescript import { TileHash, TileCoordinates } from 'tilehash'; // 编码(类型自动推导) const hash: string = TileHash.encode(10, 345, 678); // 解码(类型安全,返回TileCoordinates接口) const coords: TileCoordinates = TileHash.decode(hash); console.log(coords.z, coords.x, coords.y); // 输出:10 345 678 ``` ## 📚 完整API文档 所有方法均通过`TileHash`类静态调用,以下是核心API说明: ### 1. 核心编码/解码 #### `TileHash.encode(z: number, x: number, y: number): string` 将ZXY瓦片坐标编码为哈希字符串。 - **参数**: - `z`:缩放级别(0-30,超出范围会抛出错误) - `x`:瓦片列号(需满足 `0 ≤ x ≤ 2^z - 1`) - `y`:瓦片行号(需满足 `0 ≤ y ≤ 2^z - 1`) - **返回**:紧凑的瓦片哈希字符串 - **抛出错误**:参数超出有效范围时(如`z=31`或`x=-1`) #### `TileHash.decode(hash: string): TileCoordinates` 将哈希字符串解码为ZXY坐标。 - **参数**: - `hash`:合法的tilehash字符串(长度≥2) - **返回**:`TileCoordinates`对象(包含`z`/`x`/`y`属性) - **抛出错误**:哈希非法(如字符无效、长度不匹配缩放级别) #### `TileHash.isValid(hash: string): boolean` 验证哈希字符串是否合法(避免解码时抛出错误)。 - **参数**:`hash`:待验证的字符串 - **返回**:`true`(合法)/ `false`(非法) ### 2. 空间计算方法 #### `TileHash.getNeighbors(hash: string, wrapEdges?: boolean): string[]` 获取指定瓦片的8个邻近瓦片哈希。 - **参数**: - `hash`:目标瓦片的哈希 - `wrapEdges`:是否启用地图边界循环(默认`true`,适合全球地图,如左边界邻接右边界) - **返回**:8个邻近瓦片的哈希数组(顺序:上左→上→上右→左→右→下左→下→下右) - **说明**:`wrapEdges=false`时,边界外瓦片返回空字符串 #### `TileHash.contains(parentHash: string, childHash: string): boolean` 判断父瓦片(低缩放级别)是否包含子瓦片(高缩放级别)。 - **参数**: - `parentHash`:父瓦片哈希(低缩放级别,如z=5) - `childHash`:子瓦片哈希(高缩放级别,如z=10) - **返回**:`true`(包含)/ `false`(不包含) - **逻辑**:父瓦片哈希是子瓦片哈希的前缀(如z=5的哈希是其所有z=10子瓦片的前缀) #### `TileHash.estimateDistance(hash1: string, hash2: string): number` 估算两个瓦片中心点之间的直线距离(单位:米)。 - **参数**: - `hash1`:第一个瓦片的哈希 - `hash2`:第二个瓦片的哈希 - **返回**:距离(米,基于地球赤道周长近似计算) - **说明**:自动将两个瓦片缩放至同一级别(取较高的缩放级别)以保证精度 #### `TileHash.getHashesInBounds(minLng: number, maxLng: number, minLat: number, maxLat: number, z: number): string[]` 获取覆盖指定经纬度范围的所有瓦片哈希。 - **参数**: - `minLng`/`maxLng`:最小/最大经度(-180 ≤ 经度 ≤ 180) - `minLat`/`maxLat`:最小/最大纬度(-85.05 ≤ 纬度 ≤ 85.05,地球瓦片有效范围) - `z`:目标缩放级别 - **返回**:范围内所有瓦片的哈希数组 - **优化**:z>20时自动限制范围为1°×1°,避免生成百万级瓦片导致内存溢出 #### `TileHash.scaleToLevel(hash: string, targetZ: number): string` 将瓦片哈希缩放至指定缩放级别(放大/缩小)。 - **参数**: - `hash`:原始瓦片哈希 - `targetZ`:目标缩放级别(0-30) - **返回**:目标级别的瓦片哈希 - **逻辑**: - 放大(`targetZ > 原z`):坐标 × 2^(目标z-原z)(1个瓦片拆分为4个) - 缩小(`targetZ < 原z`):坐标 ÷ 2^(原z-目标z)(4个瓦片合并为1个) ## 📄 许可证 本项目基于**MIT许可证**开源,可自由用于商业和非商业项目。详见[LICENSE](LICENSE)文件。