Initial import of map-asset-gateway

This commit is contained in:
2026-04-14 13:10:10 +08:00
commit 1893ad3857
30 changed files with 6676 additions and 0 deletions
+399
View File
@@ -0,0 +1,399 @@
# map-asset-gateway
`map-asset-gateway` 是一个面向现有底图瓦片和矢量文件的目录管理与分发服务。
它不负责生成瓦片,不负责 GIS 生产流程,也不负责旧版遥感结果处理流水线。它只做这几件事:
- 扫描已有的底图瓦片目录
- 扫描已有的 GeoJSON / Shapefile 文件
- 将元数据写入 SQLite
- 为底图和矢量资源签发访问 token
- 按 token 提供 catalog、瓦片访问和矢量下载
- 将底图或矢量描述推送给下游系统
## 技术栈
- Go
- SQLite
- Go 标准库 `net/http`
## 适用场景
适合已经有离线瓦片目录、GeoJSON、SHP 数据,希望补一层统一管理、授权和分发接口的场景。
不适合下面这些需求:
- 在线切片或重建瓦片
- 栅格处理、预览图生成、图例生成
- PostgreSQL / PostGIS 任务流水线
- Python worker 驱动的结果管理系统
## 运行架构
服务启动时会按下面的顺序运行:
1. 读取 `config/service.env` 或环境变量
2. 打开 SQLite 并自动建表
3. 注册默认扫描源
4. 如果 `AUTO_SCAN_ON_START=true`,自动扫描底图和矢量目录
5. 启动 HTTP API 和管理页
这是一个单进程服务,没有额外 worker,没有外部数据库依赖。
## 目录结构
```text
.
├─ services/api-go/ Go 服务源码
├─ config/ 环境变量配置
├─ scripts/ 启动脚本
├─ docs/ 接入文档
├─ data/ 本地数据目录,不建议提交到 Git
├─ logs/ 本地运行日志,不建议提交到 Git
└─ temp/ 本地临时文件,不建议提交到 Git
```
说明:
- `services/api-go` 是当前项目主体。
- 历史遗留 demo 已从仓库中移除,避免和当前服务边界混淆。
- `data/``logs/``temp/``.gocache/``.gomodcache/``.gotmp/``.gopath/` 都属于本地运行或构建产物。
## 快速启动
### 前置条件
- Go 1.26 或兼容版本
- 可写的本地目录用于放 SQLite、扫描根目录和 Go 缓存
- Windows 环境下可直接使用仓库自带批处理脚本
### 配置
复制示例配置:
```text
config/service.env.example -> config/service.env
```
关键配置项:
| 变量 | 说明 |
| --- | --- |
| `API_HOST` | 监听地址 |
| `API_PORT` | 监听端口 |
| `API_BASE_URL` | API 对外基地址 |
| `TILE_PUBLIC_BASE_URL` | 底图下载地址前缀 |
| `VECTOR_PUBLIC_BASE_URL` | 矢量下载地址前缀 |
| `SQLITE_PATH` | SQLite 文件路径 |
| `BASEMAP_SCAN_ROOT` | 底图扫描根目录 |
| `VECTOR_SCAN_ROOT` | 矢量扫描根目录 |
| `AUTO_SCAN_ON_START` | 启动时是否自动扫描 |
默认示例见 [config/service.env.example](./config/service.env.example)。
### 启动
Windows 下推荐:
```powershell
.\start-all.bat
```
或者直接运行 API
```powershell
.\scripts\run-api.bat
```
停止:
```powershell
.\stop-all.bat
```
启动后可访问:
- 管理页: `http://127.0.0.1:8910/admin/`
- 健康检查: `http://127.0.0.1:8910/health`
- 就绪检查: `http://127.0.0.1:8910/ready`
## 数据组织与扫描规则
### 底图目录
服务支持两种底图目录形式。
### 1. 带 `manifest.json` 的目录
```text
data/tiles/gaode-image/
manifest.json
tiles/
0/0/0.png
1/0/0.png
```
示例 `manifest.json`
```json
{
"code": "gaode-image",
"name": "Gaode Image",
"type": "xyz",
"version": "2026-04",
"status": "ready",
"tile_format": "png",
"tile_scheme": "xyz",
"min_zoom": 0,
"max_zoom": 18,
"root_path": "tiles",
"is_default": true
}
```
### 2. 直接是 `z/x/y.ext` 的裸目录
```text
data/tiles/google-image/
0/0/0.webp
1/0/0.webp
```
这类目录会自动导入为:
- `code = 目录名归一化后的值`
- `version = current`
- `type = xyz`
说明:
- `google-image``google_image``google.image` 最终都会被归一化成类似 `google-image` 的内部 code。
- 默认版本路由 `/tiles/{code}/{z}/{x}/{y}.ext` 会解析到该底图当前默认版本。
### 矢量目录
`VECTOR_SCAN_ROOT` 会被递归扫描。
示例:
```text
data/geojson/admin-boundary.geojson
data/geojson/roads.zip
data/geojson/landuse/parcel.shp
data/geojson/landuse/parcel.dbf
data/geojson/landuse/parcel.shx
```
扫描规则:
- `.geojson``.json` 会被识别为 `geojson`
- `.zip` 会被识别为 `shpzip`
- `.shp` 会被识别为 `shapefile`
- `shapefile` 下载时会按同名 sidecar 文件动态打包成 zip
## 访问控制
服务使用 token 做资源访问控制。
一个 token 可以授权:
- 一个或多个底图
- 一个或多个矢量资源
支持的 token 传递方式:
- `Authorization: Bearer <token>`
- `X-Access-Token: <token>`
- 查询参数 `token=`
- 查询参数 `access_token=`
## 典型使用流程
### 1. 启动服务并扫描目录
如果开启了 `AUTO_SCAN_ON_START=true`,服务会在启动时自动扫描。
也可以通过管理接口手动触发:
- `POST /api/v1/admin/scan-sources/{code}/run`
- `POST /api/v1/admin/vectors/rescan`
### 2. 创建 token
示例:
```json
POST /api/v1/admin/tokens
{
"name": "insar-v2",
"basemap_codes": ["google-image"],
"vector_codes": ["全国行政区.geojson", "landuse/parcel.shp"]
}
```
### 3. 访问 catalog 或资源
```text
GET /api/v1/catalog/basemaps?token=bmp_xxx
GET /api/v1/catalog/vectors?token=bmp_xxx
GET /tiles/google-image/10/843/388.webp?token=bmp_xxx
GET /tiles/google-image/current/10/843/388.webp?token=bmp_xxx
GET /geojson/全国行政区.geojson?token=bmp_xxx
GET /shp/landuse/parcel.shp?token=bmp_xxx
GET /vectors/landuse-parcel/download?token=bmp_xxx
```
说明:
- `/tiles/{code}/{z}/{x}/{y}.ext` 走默认版本兼容路由
- `/tiles/{code}/{version}/{z}/{x}/{y}.ext` 显式指定版本
- `/geojson/{...}` 支持按原始相对路径、文件名或内部 code 解析
- `/shp/{...}` 会把 `.shp + .dbf + .shx ...` 打成 zip 返回
### 4. 推送给下游系统
先注册目标系统:
- `GET /api/v1/admin/targets`
- `POST /api/v1/admin/targets`
再触发推送:
- `POST /api/v1/admin/pushes`
- `POST /api/v1/admin/vector-pushes`
推送内容是底图版本或矢量资源的描述信息,不是资源文件本体上传。
## API 概览
### 系统接口
- `GET /health`
- `GET /ready`
- `GET /api/v1/system`
### 管理接口
- `GET /admin/`
- `GET /api/v1/admin/dashboard`
- `GET /api/v1/admin/basemaps`
- `GET /api/v1/admin/vectors`
- `GET /api/v1/admin/scan-sources`
- `POST /api/v1/admin/scan-sources`
- `POST /api/v1/admin/scan-sources/{code}/run`
- `POST /api/v1/admin/vectors/rescan`
- `POST /api/v1/admin/basemaps/{code}/default-version`
- `GET /api/v1/admin/targets`
- `POST /api/v1/admin/targets`
- `GET /api/v1/admin/tokens`
- `POST /api/v1/admin/tokens`
- `POST /api/v1/admin/tokens/{id}/disable`
- `GET /api/v1/admin/push-records`
- `POST /api/v1/admin/pushes`
- `GET /api/v1/admin/vector-push-records`
- `POST /api/v1/admin/vector-pushes`
### Catalog 与下载接口
- `GET /api/v1/catalog/basemaps`
- `GET /api/v1/catalog/basemaps/{code}`
- `GET /api/v1/catalog/vectors`
- `GET /api/v1/catalog/vectors/{code}`
- `GET /tiles/{code}/{z}/{x}/{y}.ext`
- `GET /tiles/{code}/{version}/{z}/{x}/{y}.ext`
- `GET /geojson/{relative/path/to/file.geojson}`
- `GET /shp/{relative/path/to/file.shp}`
- `GET /vectors/{code}/download`
## 数据库表
- `basemaps`
- `basemap_versions`
- `scan_sources`
- `scan_runs`
- `target_systems`
- `service_tokens`
- `token_grants`
- `push_records`
- `vector_assets`
- `vector_token_grants`
- `vector_push_records`
## 提交到 Git 前的约定
这个仓库里有很多目录本质上是本地运行数据或缓存,不建议提交到版本库。
默认不建议提交:
- `data/`
- `logs/`
- `temp/`
- `.tmp/`
- `.gocache/`
- `.gomodcache/`
- `.gotmp/`
- `.gopath/`
- `config/service.env`
原因:
- `data/` 里通常是真实底图、真实 GeoJSON/SHP、以及本地 SQLite 数据库
- `logs/``temp/` 是运行期产物
- `.gocache/``.gomodcache/``.gotmp/``.gopath/` 是本地 Go 构建缓存
- `config/service.env` 往往包含机器本地路径
如果需要给新同事一个可运行的仓库,建议提交:
- 源码
- `config/service.env.example`
- 文档
- 一个最小化的目录约定说明
而不是直接提交大体积瓦片、数据库和本地缓存。
## 开发与测试
在仓库内使用本地 Go 缓存目录跑测试:
```powershell
$env:GOCACHE='C:\path\to\map-asset-gateway\.gocache'
$env:GOMODCACHE='C:\path\to\map-asset-gateway\.gomodcache'
$env:GOTMPDIR='C:\path\to\map-asset-gateway\.gotmp'
$env:GOPATH='C:\path\to\map-asset-gateway\.gopath'
$env:GOPROXY='https://goproxy.cn,direct'
$env:GOSUMDB='off'
go test ./...
```
当前测试主要覆盖:
- 底图扫描
- 矢量扫描
- token 鉴权
- 默认版本瓦片路由
- GeoJSON / SHP 兼容访问路径
## 相关文档
- [config/service.env.example](./config/service.env.example)
- [docs/INSAR_MANAGEMENT_SYSTEM_V2.md](./docs/INSAR_MANAGEMENT_SYSTEM_V2.md)
## 项目边界
再次强调,这个项目当前的边界是:
- 扫描
- 建目录
- 发 token
- 鉴权
- 下载
- 推送资源描述
不包括:
- Python worker
- PostgreSQL
- PostGIS
- 在线切片
- 栅格处理任务
- 结果资产管理流水线