Add Kyushu profile to shared compare page

This commit is contained in:
OpenAI Codex
2026-03-31 22:07:34 +08:00
parent 7a98544382
commit 4524268d40
3 changed files with 2352 additions and 35 deletions

View File

@@ -252,10 +252,17 @@
<body>
<div class="toolbar">
<div>
<div class="title">唐津 20 海里对比页</div>
<div class="subtitle">左侧是原始版 <code>style.json</code>,右侧是当前交付线使用的 delivery 样式 + 唐津 20 海里 delivery PBF。两边联动同步点击任一对象可查看属性适合直接肉眼排差异。</div>
<div id="page-title" class="title">唐津 20 海里对比页</div>
<div id="page-subtitle" class="subtitle">左侧是原始版 <code>style.json</code>,右侧是当前交付线使用的 delivery 样式 + 唐津 20 海里 delivery PBF。两边联动同步点击任一对象可查看属性适合直接肉眼排差异。</div>
</div>
<div class="toolbar-actions">
<div class="version-chip">
区域:
<select id="profile-select" style="margin-left:8px;border:none;background:transparent;font:inherit;font-weight:700;color:inherit;outline:none;">
<option value="karatsu20">唐津 20 海里</option>
<option value="kyushu">九州</option>
</select>
</div>
<div id="version-chip" class="version-chip">版本: 加载中</div>
<button id="reload-btn" type="button">重新加载</button>
<button id="home-btn" type="button">回到唐津</button>
@@ -273,7 +280,7 @@
<section class="pane">
<div class="pane-tag">
<strong style="color: var(--right);">右侧 · Delivery</strong>
<span>正式 delivery style + 唐津 20 海里 PBF</span>
<span id="delivery-pane-label">正式 delivery style + 唐津 20 海里 PBF</span>
</div>
<div id="map-delivery" class="map"></div>
</section>
@@ -305,20 +312,50 @@
<script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
<script>
const COMPARE_VERSION = "20nm-r7-20260331-2044";
const COMPARE_VERSION = "20nm-r8-20260331-2208";
const ORIGINAL_STYLE_URL = "./style.json";
const DELIVERY_STYLE_URL = "./domain/style.navsea-delivery-karatsu-10nm.json";
const ORIGINAL_TILE_URL = "http://192.168.200.184/newpec/exported_auto/tile.mapple-on.jp__newpec-mvt-20260106__z___x___y_.pbf/tiles/{z}/{x}/{y}.pbf";
const DELIVERY_TILE_URL = "http://192.168.200.184/pbf-delivery-karatsu-20nm/{z}/{x}/{y}.pbf";
const INITIAL_VIEW = {
center: [129.9697, 33.4425],
zoom: 11,
bearing: 0,
pitch: 0
const PROFILES = {
karatsu20: {
label: "唐津 20 海里",
pageTitle: "唐津 20 海里对比页",
subtitle: "左侧是原始版 <code>style.json</code>,右侧是当前交付线使用的 delivery 样式 + 唐津 20 海里 delivery PBF。两边联动同步点击任一对象可查看属性适合直接肉眼排差异。",
deliveryPaneLabel: "正式 delivery style + 唐津 20 海里 PBF",
deliveryStyleUrl: "./domain/style.navsea-delivery-karatsu-10nm.json",
deliveryTileUrl: "http://192.168.200.184/pbf-delivery-karatsu-20nm/{z}/{x}/{y}.pbf",
initialView: {
center: [129.9697, 33.4425],
zoom: 11,
bearing: 0,
pitch: 0
},
homeLabel: "回到唐津"
},
kyushu: {
label: "九州",
pageTitle: "九州对比页",
subtitle: "左侧是原始版 <code>style.json</code>,右侧是当前交付线使用的 delivery 样式 + 九州 delivery PBF。两边联动同步点击任一对象可查看属性适合直接肉眼排差异。",
deliveryPaneLabel: "正式 delivery style + 九州 PBF",
deliveryStyleUrl: "./domain/style.navsea-delivery-kyushu.json",
deliveryTileUrl: "http://192.168.200.184/pbf-delivery-kyushu-reencoded/{z}/{x}/{y}.pbf",
initialView: {
center: [130.7, 32.2],
zoom: 8,
bearing: 0,
pitch: 0
},
homeLabel: "回到九州"
}
};
const searchParams = new URLSearchParams(window.location.search);
const requestedProfile = searchParams.get("profile");
const reloadBtn = document.getElementById("reload-btn");
const homeBtn = document.getElementById("home-btn");
const profileSelect = document.getElementById("profile-select");
const pageTitleEl = document.getElementById("page-title");
const pageSubtitleEl = document.getElementById("page-subtitle");
const deliveryPaneLabelEl = document.getElementById("delivery-pane-label");
const versionChip = document.getElementById("version-chip");
const statusEl = document.getElementById("status");
const inspectHintEl = document.getElementById("inspect-hint");
@@ -334,8 +371,23 @@
let deliveryMap;
let syncLock = false;
let styleVersion = `${COMPARE_VERSION}-${Date.now()}`;
let currentProfileKey = PROFILES[requestedProfile] ? requestedProfile : "karatsu20";
versionChip.textContent = `版本: ${COMPARE_VERSION}`;
profileSelect.value = currentProfileKey;
function getCurrentProfile() {
return PROFILES[currentProfileKey];
}
function applyProfileUi() {
const profile = getCurrentProfile();
pageTitleEl.textContent = profile.pageTitle;
pageSubtitleEl.innerHTML = profile.subtitle;
deliveryPaneLabelEl.textContent = profile.deliveryPaneLabel;
homeBtn.textContent = profile.homeLabel;
document.title = `NavSea Compare · ${profile.label}`;
}
function setStatus(text) {
statusEl.textContent = text;
@@ -377,9 +429,10 @@
}
function buildDeliveryStyle(style) {
const profile = getCurrentProfile();
const next = structuredClone(style);
if (next.sources?.navsea_delivery) {
next.sources.navsea_delivery.tiles = [withCacheBuster(DELIVERY_TILE_URL, styleVersion)];
next.sources.navsea_delivery.tiles = [withCacheBuster(profile.deliveryTileUrl, styleVersion)];
}
return touchStyleAssets(next);
}
@@ -436,15 +489,17 @@
}
async function loadMaps() {
const profile = getCurrentProfile();
styleVersion = `${COMPARE_VERSION}-${Date.now()}`;
reloadBtn.disabled = true;
homeBtn.disabled = true;
setStatus(`正在加载原始版和 delivery 版样式… 当前版本 ${COMPARE_VERSION}`);
profileSelect.disabled = true;
setStatus(`正在加载${profile.label}的原始版和 delivery 版样式… 当前版本 ${COMPARE_VERSION}`);
try {
const [originalStyleRaw, deliveryStyleRaw] = await Promise.all([
fetchStyle(ORIGINAL_STYLE_URL),
fetchStyle(DELIVERY_STYLE_URL)
fetchStyle(profile.deliveryStyleUrl)
]);
const originalStyle = buildOriginalStyle(originalStyleRaw);
const deliveryStyle = buildDeliveryStyle(deliveryStyleRaw);
@@ -453,18 +508,18 @@
originalMap = new maplibregl.Map({
container: "map-original",
style: originalStyle,
center: INITIAL_VIEW.center,
zoom: INITIAL_VIEW.zoom,
bearing: INITIAL_VIEW.bearing,
pitch: INITIAL_VIEW.pitch
center: profile.initialView.center,
zoom: profile.initialView.zoom,
bearing: profile.initialView.bearing,
pitch: profile.initialView.pitch
});
deliveryMap = new maplibregl.Map({
container: "map-delivery",
style: deliveryStyle,
center: INITIAL_VIEW.center,
zoom: INITIAL_VIEW.zoom,
bearing: INITIAL_VIEW.bearing,
pitch: INITIAL_VIEW.pitch
center: profile.initialView.center,
zoom: profile.initialView.zoom,
bearing: profile.initialView.bearing,
pitch: profile.initialView.pitch
});
originalMap.addControl(new maplibregl.NavigationControl(), "top-right");
@@ -478,25 +533,20 @@
function markLoaded() {
loaded += 1;
if (loaded >= 2) {
setStatus(`双屏已加载,可直接拖动、缩放、点击对比。当前版本 ${COMPARE_VERSION}`);
setStatus(`${profile.label}双屏已加载,可直接拖动、缩放、点击对比。当前版本 ${COMPARE_VERSION}`);
}
}
originalMap.on("load", markLoaded);
deliveryMap.on("load", markLoaded);
} else {
const camera = {
center: originalMap.getCenter(),
zoom: originalMap.getZoom(),
bearing: originalMap.getBearing(),
pitch: originalMap.getPitch()
};
const camera = profile.initialView;
let loaded = 0;
function markLoaded() {
loaded += 1;
if (loaded >= 2) {
originalMap.jumpTo(camera);
deliveryMap.jumpTo(camera);
setStatus(`双屏样式已重新加载。当前版本 ${COMPARE_VERSION}`);
setStatus(`${profile.label}双屏样式已重新加载。当前版本 ${COMPARE_VERSION}`);
}
}
originalMap.once("style.load", markLoaded);
@@ -510,23 +560,33 @@
} finally {
reloadBtn.disabled = false;
homeBtn.disabled = false;
profileSelect.disabled = false;
}
}
reloadBtn.addEventListener("click", loadMaps);
profileSelect.addEventListener("change", () => {
currentProfileKey = profileSelect.value;
searchParams.set("profile", currentProfileKey);
window.history.replaceState({}, "", `${window.location.pathname}?${searchParams.toString()}`);
applyProfileUi();
loadMaps();
});
homeBtn.addEventListener("click", () => {
if (!originalMap || !deliveryMap) return;
const profile = getCurrentProfile();
const camera = {
center: INITIAL_VIEW.center,
zoom: INITIAL_VIEW.zoom,
bearing: INITIAL_VIEW.bearing,
pitch: INITIAL_VIEW.pitch
center: profile.initialView.center,
zoom: profile.initialView.zoom,
bearing: profile.initialView.bearing,
pitch: profile.initialView.pitch
};
originalMap.jumpTo(camera);
deliveryMap.jumpTo(camera);
setStatus("已回到唐津 20 海里初始视角。");
setStatus(`已回到${profile.label}初始视角。`);
});
applyProfileUi();
resetInspectPanel("点击左右任一地图对象,查看当前命中的 source、source-layer、render layer 和属性。");
loadMaps();
</script>

File diff suppressed because it is too large Load Diff