# 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 ` - `X-Access-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 - 在线切片 - 栅格处理任务 - 结果资产管理流水线