400 lines
9.1 KiB
Markdown
400 lines
9.1 KiB
Markdown
# 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
|
||
- 在线切片
|
||
- 栅格处理任务
|
||
- 结果资产管理流水线
|