124 lines
4.8 KiB
HTML
124 lines
4.8 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||
<title>CM95 派生等深线独立 PBF 测试</title>
|
||
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css" />
|
||
<style>
|
||
html,body,#map{margin:0;width:100%;height:100%;overflow:hidden}
|
||
body{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}
|
||
.panel{position:absolute;z-index:10;top:10px;left:10px;max-width:370px;padding:10px 12px;
|
||
background:rgba(20,22,26,.92);color:#eef1f5;border:1px solid #555;border-radius:8px;
|
||
font-size:12px;line-height:1.45;box-shadow:0 3px 12px rgba(0,0,0,.35)}
|
||
.panel h1{font-size:14px;margin:0 0 7px}.panel label{display:flex;gap:7px;align-items:center;margin:6px 0}
|
||
.note{color:#b8c1cd}.stats{margin-top:8px;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;
|
||
white-space:pre-wrap;color:#d7dde6}.legend{display:flex;gap:8px;flex-wrap:wrap;margin-top:7px}
|
||
.legend span{padding:2px 5px;border:1px solid #666;border-radius:4px}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="map"></div>
|
||
<div class="panel">
|
||
<h1>独立 bathymetry PBF</h1>
|
||
<label><input id="toggle" type="checkbox" checked />显示派生等深线</label>
|
||
<label>透明度 <input id="opacity" type="range" min="0.15" max="1" step="0.05" value="0.8" /></label>
|
||
<div class="note">单独 vector source:<code>bathymetry</code>;source-layer:<code>bathymetry_contour</code>。</div>
|
||
<div class="note">底图仅用 GSI raster 便于检查,不依赖现有 CM95 大 build。</div>
|
||
<div class="note">等深线由 SOUNDG 测深点经 TIN 插值、水域裁剪生成,仅作低可靠性参考。</div>
|
||
<div class="legend"><span>2m</span><span>5m</span><span>10m</span><span>20m</span><span>30m</span><span>50m</span></div>
|
||
<div id="stats" class="stats">加载 build manifest…</div>
|
||
</div>
|
||
<script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
|
||
<script>
|
||
const SOURCE_ID="bathymetry";
|
||
const LAYER_ID="bathymetry-contours";
|
||
const LABEL_ID="bathymetry-labels";
|
||
const START={center:[130.05,33.45],zoom:9.4,bearing:0,pitch:0};
|
||
const style={
|
||
version:8,
|
||
sources:{
|
||
gsi:{
|
||
type:"raster",
|
||
tiles:["https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png"],
|
||
tileSize:256,
|
||
maxzoom:18
|
||
},
|
||
bathymetry:{
|
||
type:"vector",
|
||
minzoom:8,
|
||
maxzoom:12,
|
||
tiles:[location.origin+"/bathymetry/{z}/{x}/{y}.pbf"]
|
||
}
|
||
},
|
||
layers:[
|
||
{id:"background",type:"background",paint:{"background-color":"#f4f4f1"}},
|
||
{id:"gsi",type:"raster",source:"gsi",paint:{"raster-opacity":0.82}},
|
||
{
|
||
id:LAYER_ID,type:"line",source:SOURCE_ID,"source-layer":"bathymetry_contour",
|
||
paint:{
|
||
"line-color":[
|
||
"match",["to-number",["get","depth_m"]],
|
||
2,"#425f88",5,"#4e6f99",10,"#5b7dab",
|
||
20,"#6c8db4",30,"#7b9cc0",50,"#8ba9c8","#6f8da8"
|
||
],
|
||
"line-width":["case",[">=",["to-number",["get","depth_m"]],20],1.35,1.0],
|
||
"line-opacity":0.8
|
||
}
|
||
},
|
||
{
|
||
id:LABEL_ID,type:"symbol",source:SOURCE_ID,"source-layer":"bathymetry_contour",minzoom:10,
|
||
layout:{
|
||
"symbol-placement":"line","symbol-spacing":260,
|
||
"text-field":["concat",["to-string",["get","depth_m"]]," m"],
|
||
"text-size":10,"text-allow-overlap":false
|
||
},
|
||
paint:{
|
||
"text-color":"#40566d",
|
||
"text-halo-color":"rgba(255,255,255,.88)",
|
||
"text-halo-width":1
|
||
}
|
||
}
|
||
]
|
||
};
|
||
const map=new maplibregl.Map({
|
||
container:"map",style,center:START.center,zoom:START.zoom,bearing:0,pitch:0,
|
||
attributionControl:false
|
||
});
|
||
map.addControl(new maplibregl.NavigationControl(),"top-right");
|
||
|
||
function setVisible(visible){
|
||
const value=visible?"visible":"none";
|
||
if(map.getLayer(LAYER_ID))map.setLayoutProperty(LAYER_ID,"visibility",value);
|
||
if(map.getLayer(LABEL_ID))map.setLayoutProperty(LABEL_ID,"visibility",value);
|
||
}
|
||
|
||
document.getElementById("toggle").addEventListener("change",function(e){
|
||
setVisible(e.target.checked);
|
||
});
|
||
document.getElementById("opacity").addEventListener("input",function(e){
|
||
if(map.getLayer(LAYER_ID))map.setPaintProperty(LAYER_ID,"line-opacity",Number(e.target.value));
|
||
});
|
||
|
||
fetch("/bathymetry-manifest.json",{cache:"no-store"})
|
||
.then(r=>r.json())
|
||
.then(m=>{
|
||
const t=m.tile_stats||{},s=m.sounding_stats||{};
|
||
document.getElementById("stats").textContent=[
|
||
"build="+m.build_id,
|
||
"bbox="+JSON.stringify(m.bbox_wgs84),
|
||
"soundings="+(s.unique_sounding_points??"?"),
|
||
"levels="+(m.contour_levels_m||[]).join(",")+" m",
|
||
"tiles="+(t.pbf_tiles??"?"),
|
||
"features="+(t.tile_feature_instances??"?"),
|
||
"encoder_drop="+(t.encoder_dropped_features??"?"),
|
||
"bytes="+(t.pbf_bytes??"?")
|
||
].join("\n");
|
||
})
|
||
.catch(err=>{
|
||
document.getElementById("stats").textContent="manifest load failed: "+String(err);
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|