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

readshp

v0.0.2

Published

High-performance Shapefile reader for Node.js, supporting ESM/CommonJS, GeoJSON output, stream processing, and geometry simplification

Downloads

14

Readme

readshp

高性能、生产级的 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+ 均可运行

安装

# npm
npm install readshp

# yarn
yarn add readshp

# pnpm
pnpm add readshp

依赖要求: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 基础解析(全量读取)

// ESM 基础解析示例
import readshp, { createShapefileStream } from 'readshp';

async function esmBasicParse() {
  try {
    // 解析 Shapefile(传入基础路径,无需扩展名)
    const result = await readshp('./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 流式解析(大文件处理)

// ESM 流式解析示例(处理 100 万+ 要素)
import { createShapefileStream } from 'readshp';

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 基础解析(全量读取)

// CommonJS 基础解析示例
const readshp = require('readshp');

async function cjsBasicParse() {
  try {
    const result = await readshp('./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 流式解析(大文件处理)

// CommonJS 流式解析示例
const { createShapefileStream } = require('readshp');

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();

模块支持说明

readshp 通过以下配置实现双模块兼容,确保 ESM 和 CommonJS 项目均可无缝使用:

1. 底层配置(package.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.jsonmodule 配置与项目一致(如 ESNext 对应 ESM,CommonJS 对应 CommonJS)

API 文档

1. 核心函数

readshp<T>(path: string, options?: ParseOptions<T>): Promise<FeatureCollection<T>>

全量解析 Shapefile,返回完整的 FeatureCollection(标准 GeoJSON)。

| 参数 | 类型 | 说明 | |------------|-------------------------------|----------------------------------------------------------------------| | path | string | Shapefile 基础路径(如 ./data/cities,需存在 cities.shp/cities.shx/cities.dbf) | | options | ParseOptions<T> | 解析配置(见下文) | | 返回值 | Promise<FeatureCollection<T>>| 包含所有要素、边界框的 GeoJSON 对象 |

createShapefileStream<T>(path: string, options?: ParseOptions<T>): Readable

创建流式解析器,返回 Node.js 可读流(objectMode: true),逐要素输出 Feature<T>

| 参数 | 类型 | 说明 | |------------|-------------------------------|----------------------------------------------------------------------| | path | string | 同 readshp 函数 | | options | ParseOptions<T> | 同 readshp 函数 | | 返回值 | Readable | 可读流,支持 for await...ofon('data') 处理要素 |

2. 解析配置(ParseOptions<T>

| 选项名 | 类型 | 默认值 | 说明 | |-----------------|-------------------------------|---------------------------------|----------------------------------------------------------------------| | encoding | string | 'utf-8' | DBF 属性编码(支持 utf-8/gbk/gb2312/ISO-8859-1/CP1252 等) | | simplify | number | 0 | 几何简化精度(0 = 不简化,建议范围 0.0001 ~ 0.1,值越大顶点越少) | | filter | (feature: Feature<T>) => boolean | () => true | 要素过滤函数(返回 true 保留,false 过滤) | | workerCount | number | Math.max(1, CPU核心数 / 2) | 多线程数量(用于几何简化,最大值建议 ≤ 8,避免线程调度开销) | | highWaterMark | number | 64 * 1024(64KB) | 读取缓冲区大小(大文件建议设为 128*1024256*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. 几何简化(平衡精度与性能)

// ESM 示例:简化高精度面数据(如省级行政边界)
import readshp from 'readshp';

async function simplifyExample() {
  const result = await readshp('./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. 多线程加速(复杂几何处理)

// CommonJS 示例:4 线程处理 500 万线要素
const { createShapefileStream } = require('readshp');

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. 本地测试

# 安装开发依赖
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