Files
Harmon 8e0fa11f8f Add an import script for pre-sliced tile trees
DJI Terra already emits standard XYZ z/x/y trees, so a good capture does not
need slicing again. scripts/import-tiles.ps1 validates the source, refuses a
tile-extension mismatch, copies it into the scan root, writes the manifest and
triggers a scan.

The extension check is the point: detectTileFormat picks whichever tile it
happens to see first and the published URL template uses that single extension,
so a layer mixing .png and .webp silently 404s half its tiles.

GUIDE.md gains the mixed workflow: import for the captures that are good as-is,
slice the GeoTIFF when the layer needs to be rebuildable as a mosaic.
2026-10-16 12:03:02 +08:00

10 KiB
Raw Permalink Blame History

使用指南

按任务走的操作手册。接口字段速查见 API.md。

本指南以本机部署为例:

  • 服务地址:http://192.168.1.62:8910(静态 IP,局域网可达)
  • 运维台:http://127.0.0.1:8910/admin/(仅本机)
  • 数据目录:D:\Code\tile-server\data(切片在 tiles\,矢量在 geojson\)

一、五分钟跑通:拿到第一张图

1. 在运维台签发一个令牌

浏览器打开 http://127.0.0.1:8910/admin/ → 访问令牌 → 签发。

  • 底图编码:填已入库的 code,例如 gaode-image
  • 有效时长:留空走默认 30 天
  • 勾不勾"允许提交切片任务",决定这个令牌能不能调切片接口

签完页面顶部会显示明文令牌,形如 bmp_xxxxxxxx。只显示这一次,立刻复制存好。

2. 确认底图已入库

运维台 底图 页能看到 gaode-image / gaode-shp / google-image,并显示级别范围和格式。

取图模板长这样:

http://192.168.1.62:8910/tiles/gaode-image/current/{z}/{x}/{y}.webp

3. 取一张验证

curl.exe -o 0.webp -w "%{http_code} %{content_type}`n" `
  "http://192.168.1.62:8910/tiles/gaode-image/current/0/0/0.webp?token=<令牌>"

返回 200 image/webp 就通了。

4. 放进地图前端

取图模板本身就是前端要的格式,两种用法:

Leaflet

const token = 'bmp_xxxxxxxx';
const urlTemplate = 'http://192.168.1.62:8910/tiles/gaode-image/current/{z}/{x}/{y}.webp';

L.tileLayer(urlTemplate + '?token=' + token, {
  tileSize: 256,
  minZoom: 0,
  maxZoom: 13,          // 用底图详情里的 maxZoom
  attribution: '内部底图'
}).addTo(map);

OpenLayers

new ol.layer.Tile({
  source: new ol.source.XYZ({
    url: 'http://192.168.1.62:8910/tiles/gaode-image/current/{z}/{x}/{y}.webp?token=bmp_xxxxxxxx',
    crossOrigin: 'anonymous'
  })
});

令牌走查询参数(?token=)是给地图客户端设计的——<img> 和瓦片库没法设请求头。 代价是令牌会出现在 URL 里,所以给前端用的令牌要单独签发、单独设短有效期,别和管理令牌混用。

5. 也可以让程序自己去问目录

不要让前端写死 code,让它先查目录:

curl.exe -H "Authorization: Bearer <令牌>" http://192.168.1.62:8910/api/v1/catalog/basemaps

返回里每个底图带 url_template、min_zoom、max_zoom、tile_format, 前端照着渲染即可。目录会按令牌授权自动过滤——没有权限的底图不会出现。


二、无人机影像:一次次的累加

目标:一个图层 uav-2026,飞一次加一次,最终是一张完整的图。

准备

  1. 运维台 访问令牌 签发一个勾了 "允许提交切片任务" 的令牌
  2. 这个令牌不需要任何底图授权——它只用来提交切片,读不到图

第一次飞行

$TOKEN = "bmp_xxxxxxxx"

curl.exe -X POST http://127.0.0.1:8910/api/v1/slice/jobs `
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" `
  -d '{"target_code":"uav-2026","source_paths":["D:\\uav\\flight-a.tif"],"zoom_min":0,"zoom_max":18}'

返回 202 和任务对象,status 是 pending。

几天后又飞了

同一个 target_code,只提交新影像,就是累加:

curl.exe -X POST http://127.0.0.1:8910/api/v1/slice/jobs `
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" `
  -d '{"target_code":"uav-2026","source_paths":["D:\\uav\\flight-b.tif"],"zoom_min":0,"zoom_max":18}'

新影像覆盖到哪算哪,之前飞的地方原样保留(命令里带了 --exclude,空白瓦片不会落盘, 所以不会把旧影像"挖出洞")。

看进度

curl.exe -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8910/api/v1/slice/jobs/<任务id>

status 走 pending → running → succeeded / failed。 失败时 message 有原因,完整输出在 log_path。

什么时候需要"重建"

日常累加是按瓦片覆盖的:如果两次飞行在同一张 256px 瓦片内有重叠, 整块瓦片会来自较新的那次,可能出现瓦片边界的可见接缝。

重叠很小的话不用管。 真觉得有接缝时,做一次镶嵌重建:

运维台 → 影像切片 → 图层源清单 → 点该图层的 「重建为镶嵌」。

它会自动读出这个图层记录的全部源影像、沿用当前已发布的级别范围, 先 gdalbuildvrt 拼成一张虚拟栅格再切,重叠区逐像素合成,没有接缝。

图层现在由哪些影像构成

curl.exe -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8910/api/v1/slice/layers/uav-2026/sources

运维台同一页也有这张清单。

两个注意点

  • target_code 必须是英文数字(如 uav-2026)。中文会被归一化掉导致报错。 想显示"2026无人机影像",由你的前端自己映射 code → 中文名。
  • 切片是单并发的,按提交顺序执行。一次提交多个图层要排队,但不会阻塞接口。

另一种做法:直接导入大疆智图的切片

大疆智图自己就会输出切片(terra_dom\tile\ 下是标准的 z/x/y.png, 坐标方案是 XYZ,和本服务一致)。如果你在智图里看过、效果满意、 不需要重做镶嵌,那就没必要再切一遍——直接把它的切片并进来。

用 scripts\import-tiles.ps1:

.\scripts\import-tiles.ps1 `
  -Source "D:\Nie_WorkSpace\煤矿拍摄区域\lidars\terra_dom\tile" `
  -Code "coal-mine-dom" `
  -Name "煤矿拍摄区域 DOM"

脚本做四件事:校验源目录 → 检查扩展名冲突 → 拷贝进扫描根 → 写好 manifest 并扫描。

累加:同一个 -Code 再来一次就是累加,和切片输出落在一起:

.\scripts\import-tiles.ps1 -Source "D:\...\第二个项目\terra_dom\tile" `
  -Code "uav-2026" -Name "2026无人机影像"

为什么要用脚本而不是手拷:服务发布取图 URL 时,瓦片扩展名是取"随便找到的第一个文件"。 同一个图层里如果混了 .png 和 .webp,模板只会发布其中一种,另一种全部 404 且不报错。 脚本会在拷贝前拦住这种情况。级别范围不一致没关系(自动取并集),扩展名必须统一。

两种做法怎么选

情况 做法
智图里看着满意,不需要重做 导入切片(本节),快
要累加、要能"一键重建为镶嵌" 切片 dom.tif(上一节),有源清单
同一次数据既想快又要可重建 导入切片发布 + 把 dom.tif 也提交一次切片登记为源

导入的切片是"成品",layer_sources 里不会记录它的原图, 所以这类图层用不了控制台的"重建为镶嵌"。想要那个能力就得走切片。

三、给下游系统对接

方式一:下游主动拉(推荐)

下游拿一个令牌,调目录 → 拿 url_template → 自己取图。

curl.exe -H "Authorization: Bearer <令牌>" http://192.168.1.62:8910/api/v1/catalog/basemaps

好处:地址由服务方维护,换 IP / 加图层下游不用改代码。

方式二:服务方推送描述

在运维台 推送 页配好目标系统(回调地址 + 可选请求头), 资源更新时把描述推给下游,下游收到后再自己来拉。

  • 推送是异步的,提交后先返回 pending
  • 失败自动重试(30s、60s),状态在推送记录里看
  • 失败记录可以点 重推

切片完成回调

提交切片任务时带上 callback_url:

{"target_code":"uav-2026","source_paths":["D:\\uav\\b.tif"],"callback_url":"http://portal-a/api/tile-jobs/done"}

任务结束时服务会 POST:

{"event":"tile.job.finished","job":{ ...任务对象... }}

失败同样自动退避重试。


四、常见问题速查

现象 原因 怎么办
401 invalid token 令牌错、过期或被停用 运维台令牌页看状态;重新签发
403 token has no access 令牌有效但没授权这个底图 用有该底图授权的令牌,或重新签发
403 admin endpoints are loopback-only 从别的机器调了管理接口 管理接口只能在本机调;远程请用业务令牌走 /api/v1/catalog、/tiles
403 ... slice scope 令牌没勾"允许提交切片任务" 重新签发并勾上
404 取图 该 z/x/y 没切出来,或资源已下线 运维台 底图 页看该版本的"在位/文件缺失"标记
取图地址里是 127.0.0.1 改过 base URL 但没重扫 运维台点 立即扫描,模板是扫描时生成的
切片任务 failed 源影像路径不对、不是栅格、GDAL 报错 看任务的 message 和 log_path
页面打不开 在别的机器访问了 /admin/ 管理台仅本机;远程只能调业务接口
别的网段访问不通 路由器没有两个网段之间的路由 找网络管理员加路由

五、日常运维

运维台各页对应的动作:

页面 用途
总览 待处理事项(失败的扫描/推送、缺失的资源)+ 实时指标
底图 台账、默认版本、取图模板、就地验真(粘贴令牌试拉一张)
矢量 矢量资源与下载地址,同样可验真
令牌 签发 / 停用,查看授权范围与最近使用时间
推送 目标系统、推送记录、失败重推
扫描 扫描源、立即扫描、扫描历史
影像切片 提交切片、任务列表、图层源清单与重建
服务 版本、对外地址、探针与指标入口

故障排查第一站是日志:

Get-Content D:\Code\tile-server\bin\logs\basemap-pusher.log -Tail 50

访问日志每行形如 GET /tiles/xxx/... 200 320B 2ms,令牌已脱敏成 ***。

服务管理(install/uninstall/start/stop 需管理员):

scripts\service.bat status
scripts\service.bat restart