Skip to content

Repository files navigation

udbx4ts

npm version Node.js Version TypeScript License

TypeScript UDBX runtime — 在 Web 浏览器和 Electron 中读写 UDBX 空间数据库。

English | 中文


目录


简介

UDBX(Universal Spatial Database Extension)是基于 SQLite 的空间数据库格式,兼容 SpatiaLite 的 GAIA 二进制几何编码。udbx4ts 提供纯 TypeScript 实现,支持在浏览器和 Electron 环境中高效处理空间数据。

核心特点:

  • 🌐 双平台支持 — 浏览器(SQLite WASM + OPFS)和 Electron(better-sqlite3)
  • 📦 零依赖核心 — 核心层无外部依赖,最小化打包体积
  • 🔧 类型安全 — 完整的 TypeScript 类型定义
  • 🚀 流式处理 — 支持 AsyncIterable 流式读取大数据集
  • 📝 兼容规范 — 严格遵循 udbx4spec 跨语言规范

功能特性

特性 浏览器 Electron
打开/创建 UDBX 文件 ✅ OPFS / 内存 ✅ 本地文件
点数据集 (Point/PointZ) ✅ 读/写 ✅ 读/写
线数据集 (Line/LineZ) ✅ 读/写 ✅ 读/写
面数据集 (Region/RegionZ) ✅ 读/写 ✅ 读/写
纯属性表 (Tabular) ✅ 读/写 ✅ 读/写
Text 数据集 ✅ 最小 GeoText 读/写 ✅ 最小 GeoText 读/写
CAD 数据集 ✅ 最小 GeoHeader GeoPoint / GeoLine / GeoRegion 读/写 ✅ 最小 GeoHeader GeoPoint / GeoLine / GeoRegion 读/写
流式读取 (AsyncIterable) ✅ 分页代理 ✅ 原生流式
批量写入 ✅ 事务优化 ✅ 事务优化
视口空间查询(RTree / 包络缓存) ✅ Point/Line/Region/Z/Text/CAD ✅ Point/Line/Region/Z/Text/CAD

安装

npm install udbx4ts

浏览器环境

浏览器运行时需要 @sqlite.org/sqlite-wasm,已通过 peerDependency 声明:

npm install @sqlite.org/sqlite-wasm

Electron 环境

Electron 运行时需要 better-sqlite3

npm install better-sqlite3

快速开始

浏览器环境

  1. 创建 Web Workerworker.ts):
import { installSqliteWasmWorkerRuntime } from "udbx4ts/web";

installSqliteWasmWorkerRuntime(self, {
  openTarget: {
    opfsPath: "udbx/workspace.udbx",
    memoryName: "udbx-fallback"
  }
});
  1. 在主线程中使用main.ts):
import { createBrowserUdbx } from "udbx4ts/web";

// 创建 Worker
const worker = new Worker(
  new URL("./worker.ts", import.meta.url),
  { type: "module" }
);

// 初始化数据源
const ds = await createBrowserUdbx(worker, { kind: "memory" });

// 创建点数据集
const points = await ds.createPointDataset("cities", 4326, [
  { name: "name", fieldType: "text", nullable: false },
  { name: "population", fieldType: "int32", nullable: true }
]);

// 插入要素
await points.insert({
  id: 1,
  geometry: { type: "Point", coordinates: [116.4, 39.9], srid: 4326 },
  attributes: { name: "Beijing", population: 21540000 }
});

// 流式查询
for await (const feature of points.iterate()) {
  console.log(feature.id, feature.geometry.coordinates, feature.attributes);
}

// 关闭连接
await ds.close();

Electron 环境

// main process
import { createElectronUdbx } from "udbx4ts/electron";

// 打开已有文件
const ds = await createElectronUdbx({ path: "/path/to/file.udbx" });

// 或创建新文件
const ds = await createElectronUdbx({ path: "/path/to/new.udbx" });

// 创建面数据集
const regions = await ds.createRegionDataset("parcels", 4326, [
  { name: "area", fieldType: "double", nullable: true },
  { name: "owner", fieldType: "text", nullable: false }
]);

// 批量插入
await regions.insertMany([
  {
    id: 1,
    geometry: {
      type: "MultiPolygon",
      coordinates: [[[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]],
      srid: 4326
    },
    attributes: { area: 1000.5, owner: "Alice" }
  },
  // ... 更多要素
]);

// 查询统计
const count = await regions.count();
console.log(`Total parcels: ${count}`);

await ds.close();

API 概览

UdbxDataSource

数据源入口,管理数据集的创建、打开和列举。

interface UdbxDataSource {
  // 数据集管理
  listDatasets(): Promise<readonly DatasetInfo[]>;
  getDataset(name: string): Promise<UdbxDataset>;
  querySpatial(
    datasetName: string,
    options: SpatialQueryOptions
  ): Promise<SpatialQueryResult>;

  // 创建数据集
  createPointDataset(name: string, srid: number, fields?: FieldInfo[]): Promise<PointDataset>;
  createLineDataset(name: string, srid: number, fields?: FieldInfo[]): Promise<LineDataset>;
  createRegionDataset(name: string, srid: number, fields?: FieldInfo[]): Promise<RegionDataset>;
  createPointZDataset(name: string, srid: number, fields?: FieldInfo[]): Promise<PointZDataset>;
  createLineZDataset(name: string, srid: number, fields?: FieldInfo[]): Promise<LineZDataset>;
  createRegionZDataset(name: string, srid: number, fields?: FieldInfo[]): Promise<RegionZDataset>;
  createTextDataset(name: string, srid: number, fields?: FieldInfo[]): Promise<TextDataset>;
  createCadDataset(name: string, fields?: FieldInfo[]): Promise<CadDataset>;
  createTabularDataset(name: string, fields?: FieldInfo[]): Promise<TabularDataset>;

  // 连接管理
  close(): Promise<void>;
}

数据集操作

已完整实现的 Point、Line、Region、PointZ、LineZ、RegionZ、Tabular、Text 最小 GeoText 和 CAD 最小 GeoHeader 数据集支持以下操作。

interface ReadableDataset<TFeature> {
  // 查询
  getById(id: number): Promise<TFeature>;
  list(options?: QueryOptions): Promise<TFeature[]>;
  iterate(options?: QueryOptions): AsyncIterable<TFeature>;

  // 元数据
  getFields(): Promise<FieldInfo[]>;
  count(): Promise<number>;
  getInfo(): DatasetInfo;
}

interface WritableDataset<TFeature> extends ReadableDataset<TFeature> {
  // 写入
  insert(feature: TFeature): Promise<void>;
  insertMany(features: Iterable<TFeature> | AsyncIterable<TFeature>): Promise<void>;
  update(id: number, changes: Partial<TFeature>): Promise<void>;
  delete(id: number): Promise<void>;
}

公开 API 稳定语义

udbx4ts 的公开 API 遵循 udbx4spec/docs/08-api-stable-surface.md。TypeScript 侧统一使用异步接口,浏览器、Node.js 和 Electron 运行时不得改变核心语义。

语义 TypeScript API 稳定行为
打开/创建数据源 UdbxDataSource.open / UdbxDataSource.create / 运行时工厂 打开或创建 UDBX;运行时差异不得泄漏到核心语义
列出数据集 listDatasets() 返回 DatasetInfo 列表
按名称获取数据集 getDataset(name) 不存在时 reject UdbxNotFoundError
按 ID 获取对象 getById(id) 不存在时 reject UdbxNotFoundError,不 resolve null
列表读取 list(options?) / iterate(options?) 默认按 SmID 升序返回
计数 count() 读取物理表真实行数,不以 SmRegister.SmObjectCount 缓存为准
写入 insert(...) / insertMany(...) 写入对象并同步对象数
更新 update(id, changes) 目标不存在时 reject UdbxNotFoundError;未知字段返回 not found 或约束类错误
删除 delete(id) 目标不存在时 reject UdbxNotFoundError;成功后同步对象数

错误处理示例:

import { UdbxNotFoundError } from "udbx4ts";

try {
  const feature = await points.getById(42);
  console.log(feature);
} catch (error) {
  if (error instanceof UdbxNotFoundError) {
    // 数据集、字段、记录或要素不存在
  } else {
    throw error;
  }
}

字段类型

支持 14 种标准字段类型:

type FieldType =
  | "boolean"   // 布尔值
  | "byte"      // 8位整数
  | "int16"     // 16位整数
  | "int32"     // 32位整数
  | "int64"     // 64位整数
  | "single"    // 单精度浮点
  | "double"    // 双精度浮点
  | "date"      // 日期
  | "time"      // 时间
  | "binary"    // 二进制数据
  | "text"      // 文本
  | "ntext"     // 长文本
  | "char"      // 定长字符
  | "geometry"; // 几何数据

架构

src/
├── core/                    # 核心层(平台无关)
│   ├── dataset/             # 数据集实现
│   ├── datasource/          # 数据源入口
│   ├── geometry/            # 几何编解码
│   │   ├── gaia/            # GAIA 二进制编解码
│   │   └── jsts/            # JSTS 适配器
│   ├── schema/              # UDBX 元数据表
│   ├── sql/                 # SQL 驱动抽象
│   └── types/               # 类型定义
├── shared-runtime/          # 共享运行时协议
├── runtime-browser/         # 浏览器运行时
│   ├── client/              # 主线程客户端
│   ├── worker/              # Worker 运行时
│   ├── sqlite/              # SQLite WASM 适配
│   └── fs/                  # OPFS 文件操作
└── runtime-electron/        # Electron 运行时
    └── BetterSqlite3Driver.ts

关键设计原则:

  • 核心层与运行时解耦src/core/ 不依赖任何平台特定 API
  • 异步接口统一:所有公共 API 均为异步,屏蔽平台差异
  • Worker 隔离:浏览器端数据库操作全部在 Web Worker 中执行
  • 事务批量写入insertMany 使用事务和预处理语句优化性能

示例


开发

# 安装依赖
npm install

# 类型检查
npm run typecheck

# 运行测试
npm test

# 浏览器端测试
npm run test:browser

# 构建
npm run build

# 启动浏览器示例
npm run dev:browser

相关项目

  • udbx4j — Java 实现,功能完善的参考实现
  • udbx4spec — 跨语言 API 规范定义

许可证

MIT

About

TypeScript UDBX runtime for Web browsers and Electron. Spatial database with GAIA geometry encoding.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages