moonbitgeodb

geo
database
gis
spatial
address
moon add JIA2JIA2/moonbitgeodb@0.1.1
Download zip
Author
Version
0.1.1
License
Apache-2.0
Last updated
24 days ago
Downloads
4
README

#moonbitGEODB

一个基于 MoonBit 编写的地理信息数据库,专门用于存储、解析、检索中国地址信息。

#特性

  • 地址解析:支持多格式地址字符串解析,特别是针对中文地址(如"北京市海淀区颐和园路5号")的智能行政区划识别
  • 地理运算:内置 Haversine 距离计算、方位角计算、边界框(BBox)操作
  • 空间索引:基于网格的空间索引,高效进行范围查询和最近邻搜索
  • 名称索引:支持精确匹配、前缀匹配、子串匹配、通配符匹配的名称查找
  • 模糊搜索:基于 Levenshtein 编辑距离的名称模糊匹配
  • 持久化存储
    • 纯二进制格式(大端字节序 + CRC32 校验)
    • 原子写入(先写 .tmp 再重命名),防止数据损坏
    • 自动备份与恢复机制
    • 数据库完整性检查
  • 随机数据生成:内置中国地址生成器,可快速填充测试数据
  • 原生文件 IO:通过 C FFI 实现高性能的文件读写

#高级空间分析

  • DBSCAN 密度聚类:自动识别空间簇和噪声点
  • 多边形操作:面积计算(鞋带公式)和点-in-多边形测试(射线法)
  • Geohash 编码/解码:支持空间索引、前缀查询和邻域查询
  • 坐标转换:WGS84 ↔ GCJ-02(火星坐标)转换
  • 凸包计算:Andrew's monotone chain 算法
  • 路径距离:多点路径距离计算
  • 径向密度分析:同心圆区域分布统计
  • 平均最近邻距离:空间分布分析
  • 分页支持:大数据集的分页查询

#数据导入/导出

  • CSV 导入/导出:支持从 CSV 字符串导入数据
  • GeoJSON 导入/导出:支持 GeoJSON 格式的导入导出
  • 带 BBox 的 GeoJSON:导出包含每个点的边界框信息
  • JSON 导出:支持 JSON 格式导出

#标签与聚合

  • 标签查询:单标签、多标签 AND/OR 逻辑查询
  • 标签管理:添加、删除标签
  • 标签共现分析:标签对分布统计
  • 地理聚合:区县分布、标签计数、省份直方图

#其他功能

  • 反向地理编码:根据坐标查找最近条目
  • 重复数据检测:基于地理距离+名称相似度识别重复条目
  • 空间网格聚类:按网格单元聚合地理数据
  • 距离矩阵:计算多个地点间的两两距离
  • 地址标准化:自动去除行政区划名称后缀
  • 地理围栏查询:边界框内、距离范围内查询
  • 空间范围查询:半径范围内查询

#模块架构

moonbitGEODB/ ├── lib/ │ ├── types/ # 核心类型定义 (GeoPoint, Address, GeoEntry, BBox) │ ├── geo/ # 地理数学运算 (Haversine, Geohash, 坐标转换, 凸包, 多边形) │ ├── parser/ # 地址解析器 (多格式解析, 中文行政区划识别) │ ├── index/ # 空间索引 (网格索引, 名称索引) │ ├── persist/ # 持久化 (二进制编解码, 原子保存, 备份, FFI IO) │ ├── gen/ # 随机中国地址生成器 │ └── db/ # 主数据库 API (GeoDB) └── cmd/ # 命令行接口

#核心模块说明

模块说明
types定义 GeoPoint(地理坐标点)、Address(结构化地址)、GeoEntry(数据库条目)、BBox(边界框)等核心数据类型
geo实现 Haversine 公式、Geohash 编解码、WGS84↔GCJ-02 坐标转换、凸包计算、多边形面积、点-in-多边形、径向密度等地理运算
parser支持逗号分隔、制表符分隔、中文行政区划等多种地址格式的解析
index基于网格的空间索引加速 BBox 查询;基于 HashMap 的名称索引支持多种查找方式
persist二进制编解码(codec.mbt)、GeoEntry 序列化(binary.mbt)、C FFI IO(persist_native.mbt)、原子写入与备份
gen包含 37 个主要中国城市(含真实坐标)、街道名、门牌号的随机地址生成器
db提供完整的数据库操作 API:增删改查、空间查询、标签聚合、持久化、备份恢复、高级分析

#构建与运行

#环境要求

  • MoonBit 编译器
  • GCC 编译器(用于 C FFI 链接)
  • Linux/Unix 环境(用于文件系统操作)

#构建

# 设置链接器路径(解决 pthread 和 libc 找不到的问题) export LIBRARY_PATH=/usr/lib64 # 强制使用 GCC 而非 tcc(推荐) export MOON_CC=gcc # 构建项目 moon build # 运行测试 moon test

#CLI 命令参考

moon run cmd <address> 解析并存储地址 moon run cmd search <keyword> 按名称关键词搜索 moon run cmd fuzzy <kw> [max_dist] 模糊搜索(Levenshtein 距离) moon run cmd nearby <lat> <lng> [km] 附近查找 moon run cmd within <lat> <lng> <km> 地理围栏查询 moon run cmd tag <tag> 按标签查找 moon run cmd tags 列出所有标签 moon run cmd tag-all <t1> [t2 ...] 多标签 AND 查询 moon run cmd tag-any <t1> [t2 ...] 多标签 OR 查询 moon run cmd province <province> 按省份查找 moon run cmd city <city> 按城市查找 moon run cmd district <district> 按区县查找 moon run cmd stats 地理统计 moon run cmd export [path] 导出 CSV moon run cmd to-json [path] 导出 JSON moon run cmd to-geojson [path] 导出 GeoJSON moon run cmd add-tag <id> <tag> 添加标签 moon run cmd remove-tag <id> <tag> 删除标签 moon run cmd rename <id> <name> 重命名 moon run cmd update-coords <id> <lat> <lng> 更新坐标 moon run cmd seed [n] 生成随机地址(默认 100 条) moon run cmd save <path> 保存数据库 moon run cmd load <path> 加载数据库 moon run cmd backup <path> 创建备份 moon run cmd check <path> 完整性检查 moon run cmd info <path> 查看数据库信息 moon run cmd pattern <pattern> 通配符搜索 moon run cmd distance <id1> <id2> 两点距离 moon run cmd neighbors <id> [k] k 个最近邻 moon run cmd nearest-pairs [k] k 对最近点 moon run cmd districts [province] 区县分布 moon run cmd tag-count <tag> 标签计数 moon run cmd tag-pairs 标签共现对 moon run cmd centroid <tag> 加权质心 moon run cmd import-csv <csv_str> CSV 导入 moon run cmd import-geojson <gj_str> GeoJSON 导入 moon run cmd duplicates [dist] [edit] 重复检测 moon run cmd cluster [cell_size_km] 网格聚类 moon run cmd matrix <id1> [id2 ...] 距离矩阵 moon run cmd reverse-geocode <lat> <lng> 反向地理编码 moon run cmd dbscan <eps_km> <min_points> DBSCAN 聚类 moon run cmd polygon <lat1>,<lng1> <lat2>,<lng2> ... 多边形操作 moon run cmd geohash-neighbors <hash> [precision] Geohash 邻域 moon run cmd radial-density <lat> <lng> <km> <rings> 径向密度 moon run cmd to-geojson-bbox [path] 带 BBox 的 GeoJSON moon run cmd clear 清空所有条目 moon run cmd help 显示帮助

#CLI 使用示例

# 运行默认演示 moon run cmd # 解析并存储地址 moon run cmd "北京市海淀区颐和园路5号" # 搜索关键字 moon run cmd search "颐和园" # 模糊搜索(最多 2 次编辑距离) moon run cmd fuzzy "Yuan" 2 # 附近查找 moon run cmd nearby 39.9 116.4 5 # 地理围栏查询 moon run cmd within 39.9 116.4 10 # 多标签 AND 查询 moon run cmd tag-all "poi" "attraction" # 按省份查找 moon run cmd province "北京市" # 生成 500 条随机地址 moon run cmd seed 500 # DBSCAN 聚类(1km 半径,最少 2 点成簇) moon run cmd dbscan 1.0 2 # 多边形查询 moon run cmd polygon 0,0 0,1 1,1 1,0 # Geohash 邻域查询 moon run cmd geohash-neighbors wx4g0d 6 # 径向密度分析 moon run cmd radial-density 39.9 116.4 1.0 10 # 保存/加载数据库 moon run cmd save geo.db moon run cmd load geo.db # 完整性检查 moon run cmd check geo.db # 数据导出 moon run cmd export output.csv moon run cmd to-geojson output.json

#快速开始

#编程 API 使用

// 创建内存数据库
let db = @db.GeoDB::in_memory()

// 插入条目(自动解析地址字符串)
let entry = db.insert_raw(
"yhy001",
"颐和园",
39.9999,
116.2755,
"北京市海淀区颐和园路5号"
)

// 按 ID 查找
match db.get("yhy001") {
Some(e) => println(e.name)
None => println("not found")
}

// 按名称查找
let results = db.find_by_name("颐和园")

// 按关键字模糊搜索
let results = db.find_name_contains("海淀")

// 附近查找(5 公里内)
let nearby = db.find_nearby(
@types.GeoPoint::make(39.9999, 116.2755),
radius_km=5.0,
limit=10
)

// DBSCAN 密度聚类
let clusters = db.cluster_dbscan(1.0, 2)

// Geohash 前缀查询
let results = db.find_by_geohash_prefix("wx4g0d", precision=6)

// 路径距离计算
let d = db.path_distance(["id1", "id2", "id3"])

// 分页查询
let page = db.page_all(limit=10, offset=0)

// 地址标准化
let ok = db.normalize_address("yhy001")

// 保存到文件
ignore(db.save_to("geo.db"))

// 从文件加载
let loaded = @db.GeoDB::open("geo.db")

#高级 API 使用

// Geohash 编码/解码
let gh = @geo.geohash_encode(39.9087, 116.3975, 6)
let pt = @geo.geohash_decode(gh)

// Geohash 邻域(3×3 网格)
let neighbors = @geo.geohash_neighbors(gh)

// 坐标转换(WGS84 → GCJ-02)
let (gcj_lng, gcj_lat) = @geo.wgs84_to_gcj02(116.4, 39.9)

// 凸包计算
let hull = @geo.convex_hull(points)

// 多边形面积(km²)
let area = @geo.polygon_area(polygon_points)

// 点在多边形内测试
let inside = @geo.point_in_polygon(point, polygon)

// 平均最近邻距离
let avg_nn = @geo.average_nn_distance(points)

// 重复数据检测
let groups = db.find_duplicates(max_distance_km=0.1, max_edit_dist=2)

// 空间网格聚类
let clusters = db.cluster_by_grid(cell_size_km=1.0)

// 距离矩阵
let matrix = db.distance_matrix(["id1", "id2", "id3"])

// 径向密度分析
let rings = db.radial_density(center, ring_width_km=1.0, num_rings=10)

// 反向地理编码
match db.reverse_geocode(39.9, 116.4) {
Some((entry, dist)) => println("Nearest: " + entry.name)
None => println("Not found")
}

#随机数据生成

// 生成 100 条随机中国地址
let entries = @gen.gen_batch(100)

// 预填充数据库
let db = @gen.gen_db(500)

// 也可以通过 CLI 生成并持久化
// moon run cmd seed 500 # 自动保存到 geo_seeded.db

#持久化设计

#二进制文件格式

数据库采用纯二进制格式存储,由以下部分组成:

+------------------+ | File Header | 魔数 ("GEO1") + 版本号 + 条目数 + 创建/更新时间戳 +------------------+ | Entry Block 0 | 条目长度 + CRC32 + 序列化数据 | Entry Block 1 | ... +------------------+ | ... | +------------------+

#测试

# 运行所有测试 moon test

测试覆盖:
  • 类型构造与序列化
  • 地理距离与 BBox 运算
  • Geohash 编解码与邻域查询
  • WGS84 ↔ GCJ-02 坐标转换
  • 凸包计算与多边形面积
  • DBSCAN 密度聚类
  • 径向密度分析
  • 地址解析(中文、英文、多格式)
  • 空间索引与名称索引
  • 数据库 CRUD 操作
  • 标签查询与聚合
  • 地理统计与分布
  • 持久化与恢复
  • 随机地址生成器

#许可证

Apache-2.0