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:增删改查、空间查询、标签聚合、持久化、备份恢复、高级分析 |
# 设置链接器路径(解决 pthread 和 libc 找不到的问题)
export LIBRARY_PATH=/usr/lib64
# 强制使用 GCC 而非 tcc(推荐)
export MOON_CC=gcc
# 构建项目
moon build
# 运行测试
moon testmoon 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 显示帮助# 运行默认演示
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// 创建内存数据库
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")// 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