Files
2026-04-14 13:28:08 +08:00

399 lines
9.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
## 项目边界
再次强调,这个项目当前的边界是:
- 扫描
- 建目录
- 发 token
- 鉴权
- 下载
- 推送资源描述
不包括:
- Python worker
- PostgreSQL
- PostGIS
- 在线切片
- 栅格处理任务
- 结果资产管理流水线