目标:把私有化交付的海图数据(亿海蓝 SQLite 库表文件)发布为瓦片服务,在离线环境中用 Leaflet 加载出与在线平台 ShipxyAPI.Map等效的海图底图,并复刻图源切换、自定义瓦片叠加、常用控件等能力。
| 表名 | 说明 |
|---|---|
| na_b_01 | 1级全球海图 |
| na_b_02 | 2级全球海图 |
| na_b_03 | 3级全球海图 |
| na_b_04 | 4级全球海图 |
| na_b_05 | 5级全球海图 |
| na_b_06 | 6级全球海图 |
| na_b_07 | 7级全球海图 |
| na_b_08 | 8级全球海图 |
| na_f_09 | 9级指定区域海图 |
| na_f_10 | 10级指定区域海图 |
| na_f_11 | 11级指定区域海图 |
| na_f_12 | 12级指定区域海图 |
| na_f_13 | 13级指定区域海图 |
| na_f_14 | 14级指定区域海图 |
| na_f_15 | 15级指定区域海图 |
| na_f_16 | 16级指定区域海图 |
| na_f_17 | 17级指定区域海图 |
| na_f_18 | 18级指定区域海图 |
| sglcolor | 单色图 |
na_b_,9~18 级表名前缀为 na_f_,编号与缩放级别 z 一一对应(z=10 对应 na_f_10)。na_b_,9~18 级表名前缀为 na_f_):| 字段名 | 说明 |
|---|---|
| r | 行 |
| c | 列 |
| version | 图片版本,可忽略 |
| pic | 瓦片图的二进制数据,JFIF(JPEG) 格式,256×256 像素,24 位深,投影模式为 EPSG:3395。注意:当该字段长度为 3 字节时,为单色图 RGB 信息,请按 1.6 节从单色图表中提取图片数据 |
sglcolor):| 字段名 | 说明 |
|---|---|
| color | RGB 色值 |
| pic | 单色图二进制数据 |
| (0,0) | (0,1) |
|---|---|
| (1,0) | (1,1) |
http://服务器IP:端口/tile?x={x}&y={y}&z={z}&l=na&m=qhttp://127.0.0.1:8080/tile?x=513&y=512&z=10&l=na&m=q注意:全球海图在低级别基本全球覆盖,但在高级别时并不是全球无缝覆盖,某些船舶罕至的区域可能无海图,所以在查表时需要处理结果为 null 的情况(服务端与前端均须做缺瓦片兜底,见第 2、3 章)。
colorValue = r*65536 + g*256 + bcolorValue = 255*65536 + 250*256 + 190 = 16775870/tile?x={x}&y={y}&z={z}&l=na&m=qhttp://服务器IP:端口/tile?x={x}&y={y}&z={z}&l=na&m=qx、y、z 分别为列、行、缩放级别(1~18);http://127.0.0.1:8080/tile?x=513&y=512&z=10&l=na&m=q。若交付中已附带接口服务,可直接使用该服务地址,跳过 2.2 的自建实现;自建实现用于自行托管 SQLite 数据的场景。
pic → 3 字节时自动按 1.6 节回退 sglcolor 单色图 → 缺瓦片返回透明占位图。tiles-server/package.json:{
"name": "private-chart-server",
"version": "1.0.0",
"main": "server.js",
"dependencies": {
"better-sqlite3": "^11.0.0"
}
}tiles-server/server.js:http://localhost:8080/tile?x=513&y=512&z=10&l=na&m=q 能看到一张海图瓦片,即服务正常。errorTileUrl;Cache-Control 让浏览器/网关长缓存瓦片;l 参数或不同端口扩展,海图固定 l=na。proj4.js + proj4leaflet 定义自定义 CRS:落地验证建议:CRS 配置完成后,叠加一条已知 WGS84 岸线或几艘 AIS 船位核对——若出现系统性南北偏移,说明该批瓦片实际按球面墨卡托切割,此时把地图 crs配置移除(使用 Leaflet 默认 CRS)即可,其余代码不变。
centerPoint: [32.1, 122.11] 是 [lat, lng],与 Leaflet setView 一致,可直接平移):index.html 运行)#A3CCFF——官方海图海洋区域底色):zoomControlElane/zoomviewControl/scaleCtrl/mousePostionCtrl/measureCtrl/miniMapControl)在 Leaflet 生态全部有对应实现:| 官方控件 | options 默认位置 | Leaflet 私有化实现 |
|---|---|---|
| zoomControlElane 缩放 | topright | L.control.zoom({position:"topright"}) |
| zoomviewControl 级别数字 | topleft | 监听 zoomend 自绘( 下方代码) |
| scaleCtrl 比例尺 | bottomleft | L.control.scale({position:"bottomleft", metric:true}) |
| mousePostionCtrl 鼠标经纬度 | bottomright | 监听 mousemove 自绘(下方代码) |
| measureCtrl 测距 | topleft | L.control.polylineMeasure(leaflet-polylined measure 插件,内网部署) |
| miniMapControl 鹰眼 | 默认关 | L.control.minimap(leaflet-minimap 插件) |
_map.basemapsControl.changeMap("MT_SEA")。私有化环境为每个图源建一个 L.tileLayer,用 L.control.layers 提供切换(也支持代码切换):注意:海图瓦片为 EPSG:3395,若地图/卫星图源为 EPSG:3857,二者不能挂在同一个 CRS 的地图上——需统一投影(重切瓦片或在服务端转投影),或为不同图源分别配置匹配的 CRS。混合图源切换前先用岸线叠加验证。
tileLayer.satellite.url 是按层级分段的(12 级用船讯瓦片、18 级用谷歌卫星),私有化同样可用多个不同 maxZoom 的图层叠加,或用 L.TileLayer.multi(官方月更新海图同款方案)。map.customeTileLayerService.addLayer(options),内部就是把瓦片模板地址挂成一个瓦片图层。私有化直接用 L.tileLayer 叠加:minZoom 必须 ≥1。centerPoint: [32.1, 122.11] 与 Leaflet L.latLng 均为纬度在前,从官方代码平移时无需调换;但调用自建后端接口时注意官方 Getmanyship 等接口是经度在前(lon/lat,且 ×10⁶ 定点),见文档 02。