# parseshp **Repository Path**: nodets/parseshp ## Basic Information - **Project Name**: parseshp - **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-09 - **Last Updated**: 2025-10-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # parseshp 高性能、生产级的 Shapefile 解析库,基于 TypeScript 开发,**同时支持 ESM 和 CommonJS 模块系统**,适配 Node.js 环境。专注于**速度、稳定性和类型安全**,可解析点、线、面、多点等 Shapefile 几何类型,输出标准 GeoJSON,提供流式处理、几何简化、多线程加速等高级功能,适用于 GIS 数据处理、空间分析等场景。 ## 特性 - ✅ **双模块支持**:原生兼容 ESM(`import`)和 CommonJS(`require`),无需额外配置 - ✅ **类型安全**:完整 TypeScript 类型定义,IDE 自动补全+类型校验,减少 runtime 错误 - ✅ **高性能**:对象池复用、坐标缓存、多线程加速,处理 1000 万+ 要素内存稳定 - ✅ **流式处理**:大文件分块解析,避免内存溢出(支持 10GB+ 超大型 Shapefile) - ✅ **全面兼容**:支持 UTF-8/GBK/ISO-8859 等编码,兼容所有标准 Shapefile 几何类型 - ✅ **生产级稳定**:完善的错误处理、资源自动释放,无内存泄漏 - ✅ **跨平台**:支持 Windows/macOS/Linux,Node.js 14.13+ 均可运行 ## 安装 ```bash # npm npm install parseshp # yarn yarn add parseshp # pnpm pnpm add parseshp ``` **依赖要求**:Node.js 14.13.0+(ESM 支持需 Node.js 14.13+,CommonJS 支持 Node.js 12+,推荐 16+ 稳定版) ## 快速开始 根据项目使用的模块系统,选择对应的引入方式: ### 1. ESM 模块(推荐,`import` 语法) 适用于 `package.json` 中配置 `"type": "module"` 的项目,或使用 `.mjs` 后缀的文件。 #### 1.1 基础解析(全量读取) ```typescript // ESM 基础解析示例 import parseshp, { createShapefileStream } from 'parseshp'; async function esmBasicParse() { try { // 解析 Shapefile(传入基础路径,无需扩展名) const result = await parseshp('./data/cities', { encoding: 'utf-8', // 处理中文属性(如 GBK 编码需指定 'gbk') simplify: 0.001, // 几何简化精度(0-1,值越大简化越明显) logLevel: 'info', // 日志级别:silent/error/warn/info/debug enableCache: true // 启用坐标缓存,减少重复坐标内存占用 }); // 输出结果(标准 GeoJSON FeatureCollection) console.log(`解析完成:共 ${result.features.length} 个要素`); console.log('数据边界框:', result.bbox); console.log('第一个要素属性:', result.features[0].properties); } catch (err) { // 精细化错误处理 if (err.name === 'MissingFileError') { console.error('错误:缺少 .shp/.shx/.dbf 必要文件', err.message); } else if (err.name === 'EncodingError') { console.error('错误:编码不匹配,尝试添加 encoding: "gbk" 配置', err.message); } else { console.error('解析失败:', err.message); } } } esmBasicParse(); ``` #### 1.2 流式解析(大文件处理) ```typescript // ESM 流式解析示例(处理 100 万+ 要素) import { createShapefileStream } from 'parseshp'; async function esmStreamParse() { const stream = createShapefileStream('./data/national-roads', { highWaterMark: 256 * 1024, // 缓冲区大小(256KB,大文件建议增大) workerCount: 4, // 多线程数量(默认 CPU 核心数/2,最大不超过 8) filter: (feature) => { // 过滤:仅保留长度 > 1000m 的道路 return feature.properties.length > 1000; } }); let processedCount = 0; // 逐要素处理(for await...of 适配流式迭代) for await (const feature of stream) { processedCount++; // 业务逻辑:如写入数据库、转换为其他格式等 console.log(`处理道路 ${processedCount}:${feature.properties.name}`); } console.log(`流式解析完成:共处理 ${processedCount} 条道路数据`); } esmStreamParse().catch(console.error); ``` ### 2. CommonJS 模块(`require` 语法) 适用于传统 Node.js 项目(`package.json` 无 `"type": "module"`,或使用 `.cjs` 后缀的文件)。 #### 2.1 基础解析(全量读取) ```javascript // CommonJS 基础解析示例 const parseshp = require('parseshp'); async function cjsBasicParse() { try { const result = await parseshp('./data/cities', { encoding: 'gbk', // 处理 GBK 编码的中文属性 simplify: 0.005, // 中等简化精度,平衡精度和性能 logLevel: 'warn' // 仅输出警告和错误日志 }); console.log(`解析完成:${result.features.length} 个城市`); } catch (err) { console.error('CommonJS 解析错误:', err.message); } } cjsBasicParse(); ``` #### 2.2 流式解析(大文件处理) ```javascript // CommonJS 流式解析示例 const { createShapefileStream } = require('parseshp'); function cjsStreamParse() { const stream = createShapefileStream('./data/large-polygons', { workerCount: 2, highWaterMark: 128 * 1024 }); let count = 0; // 监听 data 事件处理要素 stream.on('data', (feature) => { count++; console.log(`处理要素 ${count}:${feature.properties.id}`); }); // 监听结束事件 stream.on('end', () => { console.log(`CommonJS 流式解析完成:共 ${count} 个要素`); }); // 监听错误事件 stream.on('error', (err) => { console.error('流式解析错误:', err.message); }); } cjsStreamParse(); ``` ## 模块支持说明 `parseshp` 通过以下配置实现双模块兼容,确保 ESM 和 CommonJS 项目均可无缝使用: ### 1. 底层配置(`package.json`) ```json { "type": "module", // 优先 ESM "main": "./dist/cjs/index.js", // CommonJS 入口 "module": "./dist/esm/index.js", // ESM 入口 "types": "./dist/types/index.d.ts", // 类型定义入口(双模块共享) "exports": { ".": { "import": "./dist/esm/index.js", // ESM 引入路径 "require": "./dist/cjs/index.js", // CommonJS 引入路径 "types": "./dist/types/index.d.ts" // 类型定义 } } } ``` ### 2. 兼容性注意事项 - **ESM 要求**:Node.js 14.13.0+(建议 16+),项目需配置 `"type": "module"` 或使用 `.mjs` 文件 - **CommonJS 要求**:Node.js 12.0.0+,无需额外配置,直接用 `require` 引入 - **TypeScript 项目**:无论使用 ESM 还是 CommonJS,只需确保 `tsconfig.json` 中 `module` 配置与项目一致(如 `ESNext` 对应 ESM,`CommonJS` 对应 CommonJS) ## API 文档 ### 1. 核心函数 #### `parseshp(path: string, options?: ParseOptions): Promise>` 全量解析 Shapefile,返回完整的 `FeatureCollection`(标准 GeoJSON)。 | 参数 | 类型 | 说明 | |------------|-------------------------------|----------------------------------------------------------------------| | `path` | `string` | Shapefile 基础路径(如 `./data/cities`,需存在 `cities.shp`/`cities.shx`/`cities.dbf`) | | `options` | `ParseOptions` | 解析配置(见下文) | | **返回值** | `Promise>`| 包含所有要素、边界框的 GeoJSON 对象 | #### `createShapefileStream(path: string, options?: ParseOptions): Readable` 创建流式解析器,返回 Node.js 可读流(`objectMode: true`),逐要素输出 `Feature`。 | 参数 | 类型 | 说明 | |------------|-------------------------------|----------------------------------------------------------------------| | `path` | `string` | 同 `parseshp` 函数 | | `options` | `ParseOptions` | 同 `parseshp` 函数 | | **返回值** | `Readable` | 可读流,支持 `for await...of` 或 `on('data')` 处理要素 | ### 2. 解析配置(`ParseOptions`) | 选项名 | 类型 | 默认值 | 说明 | |-----------------|-------------------------------|---------------------------------|----------------------------------------------------------------------| | `encoding` | `string` | `'utf-8'` | DBF 属性编码(支持 `utf-8`/`gbk`/`gb2312`/`ISO-8859-1`/`CP1252` 等) | | `simplify` | `number` | `0` | 几何简化精度(0 = 不简化,建议范围 `0.0001 ~ 0.1`,值越大顶点越少) | | `filter` | `(feature: Feature) => boolean` | `() => true` | 要素过滤函数(返回 `true` 保留,`false` 过滤) | | `workerCount` | `number` | `Math.max(1, CPU核心数 / 2)` | 多线程数量(用于几何简化,最大值建议 ≤ 8,避免线程调度开销) | | `highWaterMark` | `number` | `64 * 1024`(64KB) | 读取缓冲区大小(大文件建议设为 `128*1024` 或 `256*1024`) | | `enableCache` | `boolean` | `false` | 启用坐标缓存(重复坐标多的数据集(如建筑轮廓)可减少 40%-60% 内存) | | `logLevel` | `'silent'/'error'/'warn'/'info'/'debug'` | `'info'` | 日志级别(`silent` 关闭所有日志,`debug` 输出解析细节) | ### 3. 错误类型 解析过程中抛出的错误可通过 `err.name` 区分,便于精细化处理: | 错误名称 | 场景说明 | 解决方案 | |------------------------|-------------------------------------------|-------------------------------------------| | `MissingFileError` | 缺少 .shp/.shx/.dbf 任一必要文件 | 检查文件路径和完整性,确保三文件齐全 | | `InvalidFormatError` | Shapefile 格式损坏(文件头错误、数据截断) | 验证文件有效性(可通过 QGIS 打开测试) | | `EncodingError` | DBF 编码转换失败(中文乱码、特殊字符报错) | 指定正确编码(如 `encoding: 'gbk'`) | | `ResourceReleaseError` | 资源释放失败(文件句柄关闭异常) | 避免解析中强制终止程序,检查系统权限 | | `ShapefileError` | 其他通用错误 | 查看错误详情,提交 GitHub Issue 反馈 | ## 高级功能示例 ### 1. 几何简化(平衡精度与性能) ```typescript // ESM 示例:简化高精度面数据(如省级行政边界) import parseshp from 'parseshp'; async function simplifyExample() { const result = await parseshp('./data/provinces', { simplify: 0.002, // 保留核心轮廓,减少 70% 顶点数量 enableCache: true }); console.log(`简化前顶点数:${result.features[0].geometry.coordinates[0].length}`); console.log(`简化后顶点数:${result.features[0].geometry.coordinates[0].length}`); } ``` ### 2. 多线程加速(复杂几何处理) ```typescript // CommonJS 示例:4 线程处理 500 万线要素 const { createShapefileStream } = require('parseshp'); async function multiThreadExample() { const stream = createShapefileStream('./data/railways', { workerCount: 4, // 4 线程并行简化 simplify: 0.001, // 线要素简化 highWaterMark: 256 * 1024 }); let count = 0; for await (const feature of stream) { count++; } console.log(`多线程处理完成:${count} 条铁路数据`); } ``` ## 测试与调试 ### 1. 本地测试 ```bash # 安装开发依赖 npm install -D # 运行单元测试(覆盖双模块引入逻辑) npm test # 运行集成测试(解析真实 Shapefile 数据) npm run test:integrate # 查看测试覆盖率 npm run test:coverage ``` ### 2. 调试建议 - **ESM 项目**:使用 `node --inspect index.mjs` 启动调试 - **CommonJS 项目**:使用 `node --inspect index.js` 启动调试 - **日志调试**:将 `logLevel` 设为 `'debug'`,查看解析过程中的详细日志(如文件读取进度、要素数量) ## 许可证 [MIT License](https://opensource.org/licenses/MIT)