diff --git a/web/kyushu_compare.html b/web/kyushu_compare.html
index 0b19c1d..1b15bfc 100644
--- a/web/kyushu_compare.html
+++ b/web/kyushu_compare.html
@@ -44,7 +44,7 @@
九州 S-52 PBF 对比
-
左:Production v4 / 0.4.12 本地 PBF 右:extentfix 原始数据源
+
左:当前 Production 本地 PBF 右:extentfix 原始数据源
@@ -63,7 +63,7 @@
- 左:九州 Production v4 / 0.4.12等待参考 style…
+ 左:九州当前 Production等待参考 style…
点击任一侧海图,对比同一位置的 Feature。
LOCAL
@@ -656,8 +656,8 @@ function cloneReferenceForLocal(referenceStyle){
source.minzoom=5;
source.maxzoom=12;
source.bounds=[128.0,29.5,132.5,34.8];
- source.attribution="CM95 九州 S-52 Production 0.4.12 OpenCPN coverage";
- style.name=(style.name || "NavSea") + " / Kyushu Production v4 / 0.4.12";
+ source.attribution="CM95 九州当前 S-52 Production";
+ style.name=(style.name || "NavSea") + " / Kyushu current Production";
return style;
}
@@ -670,7 +670,7 @@ function prepareS52Style(raw){
source.minzoom=5;
source.maxzoom=12;
source.bounds=[128.0,29.5,132.5,34.8];
- source.attribution="CM95 九州 S-52 Production 0.4.12 OpenCPN coverage";
+ source.attribution="CM95 九州当前 S-52 Production";
style.sprite=location.origin + "/s52/sprite";
if(referenceStyleTemplate && referenceStyleTemplate.glyphs){
style.glyphs=referenceStyleTemplate.glyphs;
@@ -728,9 +728,9 @@ leftMap.on("style.load",function(){
const sources=Object.keys((leftMap.getStyle() || {}).sources || {});
if(sources.includes("cm95")){
installRuntimePreviewLayers(leftMap);
- setState(leftState,"Production v4 / 0.4.12 / S-52 style" + (debugRuntimePreview.checked ? " + runtime preview" : ""),"ok");
+ setState(leftState,"当前 Production / S-52 style" + (debugRuntimePreview.checked ? " + runtime preview" : ""),"ok");
}else if(sources.includes("navsea_delivery")){
- setState(leftState,"Production v4 / 0.4.12 / extentfix style","ok");
+ setState(leftState,"当前 Production / extentfix style","ok");
}
applyDebugStyles();
refreshLightArcFeatures();
@@ -791,7 +791,7 @@ debugLeftS52.addEventListener("change",function(){
debugRuntimePreview.addEventListener("change",function(){
if(leftMap.getSource("cm95")){
installRuntimePreviewLayers(leftMap);
- setState(leftState,"Production v4 / 0.4.12 / S-52 style" + (debugRuntimePreview.checked ? " + runtime preview" : ""),"ok");
+ setState(leftState,"当前 Production / S-52 style" + (debugRuntimePreview.checked ? " + runtime preview" : ""),"ok");
applyDebugStyles();
}
});
diff --git a/web/kyushu_compare_server.py b/web/kyushu_compare_server.py
index 1b0c114..6a0b9b0 100644
--- a/web/kyushu_compare_server.py
+++ b/web/kyushu_compare_server.py
@@ -29,7 +29,10 @@ def main():
html_path = web_root / "kyushu_compare.html"
runtime_executor_path = web_root / "s52_runtime_executor.js"
assets_root = project_root / "build" / "fukuoka_s52_web" / "site" / "assets"
- s52_style_path = project_root / "build" / "s52_style_compiler_release_57e72826db1d" / "style.s52.json"
+ release_suffix = args.release_id.rsplit("-", 1)[-1]
+ s52_style_path = (
+ project_root / "build" / f"s52_style_compiler_release_{release_suffix}" / "style.s52.json"
+ )
s52_sprite_root = project_root / "build" / "s52_resources_v2" / "final"
s52_symbol_metadata_path = (
project_root / "build" / "s52_resources_v2" / "base" / "s52_symbol_metadata.json"
diff --git a/web/s52_runtime_executor.js b/web/s52_runtime_executor.js
index aa378c7..e7d4dd3 100644
--- a/web/s52_runtime_executor.js
+++ b/web/s52_runtime_executor.js
@@ -2,7 +2,7 @@
"use strict";
const DEFAULTS=Object.freeze({shallowContourM:2,safetyContourM:3,safetyDepthM:3,deepContourM:6,twoShades:false,depthUnit:"metres",heightUnit:"metres",symbolizedBoundaries:false});
-const COLORS=Object.freeze({CHBLK:"#070707",CHBRN:"#b19139",CHGRF:"#6d7473",CHMGD:"#c545c3",CSTLN:"#6d7473",DEPCN:"#7d898c",DEPSC:"#525a5c",DEPIT:"#83b295",DEPVS:"#73b6ef",DEPMS:"#98c5f2",DEPMD:"#bad5e1",DEPDW:"#d4eaee",LITRD:"#f15469",LITGN:"#68e456",LITYW:"#f4da48",OUTLW:"#070707"});
+const COLORS=Object.freeze({"NODTA":"#a3b4b7","CURSR":"#eb7d36","CHBLK":"#070707","CHGRD":"#7d898c","CHGRF":"#a3b4b7","CHRED":"#f15469","CHGRN":"#68e456","CHYLW":"#f4da48","CHMGD":"#c545c3","CHMGF":"#d3a6e9","CHBRN":"#b19139","CHWHT":"#d4eaee","SCLBR":"#eb7d36","CHCOR":"#eb7d36","LITRD":"#f15469","LITGN":"#68e456","LITYW":"#f4da48","ISDNG":"#c545c3","DNGHL":"#f15469","TRFCD":"#c545c3","TRFCF":"#d3a6e9","LANDA":"#c9b97a","LANDF":"#8b661f","CSTLN":"#525a5c","SNDG1":"#7d898c","SNDG2":"#070707","DEPSC":"#525a5c","DEPCN":"#7d898c","DEPDW":"#d4eaee","DEPMD":"#bad5e1","DEPMS":"#98c5f2","DEPVS":"#73b6ef","DEPIT":"#83b295","RADHI":"#68e456","RADLO":"#3f8a34","ARPAT":"#3fa56f","NINFO":"#eb7d36","RESBL":"#3a78f0","ADINF":"#b29f34","RESGR":"#7d898c","SHIPS":"#070707","PSTRK":"#070707","SYTRK":"#7d898c","PLRTE":"#dc4025","APLRT":"#eb7d36","UINFD":"#070707","UINFF":"#7d898c","UIBCK":"#d4eaee","UIAFD":"#73b6ef","UINFR":"#f15469","UINFG":"#68e456","UINFO":"#eb7d36","UINFB":"#3a78f0","UINFM":"#c545c3","UIBDR":"#7d898c","UIAFF":"#c9b97a","OUTLW":"#070707","OUTLL":"#c9b97a","RES01":"#a3b4b7","RES02":"#a3b4b7","RES03":"#a3b4b7","BKAJ1":"#070707","BKAJ2":"#232728"});
function jsonValue(value,fallback){if(value===undefined||value===null||value==="")return fallback;if(typeof value!=="string")return value;try{return JSON.parse(value);}catch(_err){return fallback;}}
function numberValue(props,key,fallback=null){const value=Number(props&&props[key]);return Number.isFinite(value)?value:fallback;}
@@ -101,7 +101,7 @@ function operationFeatures(feature,settings,context,resourceExists){
const effects=Object.assign({},...chain.filter(x=>x.opcode==="SE").map(x=>x.side_effects||{}));
chain.forEach(item=>{const opcode=String(item.opcode||""),args=item.args||[];if(opcode==="OP")return;if(opcode==="SE"){output.push({type:"Feature",id:String(feature.id==null?"":feature.id)+":"+item.sequence,geometry:geometry,properties:Object.assign({runtime_opcode:"SE",runtime_sequence:item.sequence},effects)});return;}if(["AC","AP"].includes(opcode)&&!["Polygon","MultiPolygon"].includes(geomType))return;if(["LS","LC"].includes(opcode)&&!["LineString","MultiLineString","Polygon","MultiPolygon"].includes(geomType))return;if(["SY","SOUNDG","AP","LC"].includes(opcode)&&args[0]&&resourceExists&&!resourceExists(String(args[0]))){missing.push(String(args[0]));return;}
let textOverride=null;if(opcode==="TX"&&item.procedure==="LIGHTS05"&&context.lightLabelState){const text=String((item.text&&item.text.value)||args[0]||""),decision=context.lightLabelState.accept(geometry.coordinates,text);if(!decision.emit)return;textOverride=decision.yoff;}
- const draw=Object.assign({runtime_opcode:opcode,runtime_sequence:item.sequence,runtime_resource:String(args[0]||""),runtime_procedure:String(item.procedure||""),runtime_args_json:JSON.stringify(args),runtime_missing_resources:missing.join(",")},effects);if(opcode==="AC")draw.runtime_color=COLORS[args[0]]||COLORS.CHMGD;if(opcode==="LS"){draw.runtime_line_style=String(args[0]||"SOLD");draw.runtime_line_width=Number(args[1]||1);draw.runtime_color=COLORS[args[2]]||COLORS.CHBLK;}if(opcode==="TX"){draw.runtime_text=String((item.text&&item.text.value)||args[0]||"");draw.runtime_color=COLORS[(item.text&&item.text.color)||"CHBLK"]||COLORS.CHBLK;draw.runtime_text_xoff=Number((item.text&&item.text.xoff)||0);draw.runtime_text_yoff=textOverride===null?Number((item.text&&item.text.yoff)||0):textOverride;}if(opcode==="SOUNDG"){draw.runtime_opcode="SOUNDG";draw.runtime_soundg_index=output.filter(x=>x.properties.runtime_opcode==="SOUNDG").length;}const metadata=(context.symbolMetadata||{})[String(args[0]||"")]||{};if(Array.isArray(metadata.maplibre_icon_offset))draw.runtime_icon_offset=metadata.maplibre_icon_offset;output.push({type:"Feature",id:String(feature.id==null?"":feature.id)+":"+item.sequence,geometry:geometry,properties:draw});
+ const draw=Object.assign({runtime_opcode:opcode,runtime_sequence:item.sequence,runtime_resource:String(args[0]||""),runtime_procedure:String(item.procedure||""),runtime_args_json:JSON.stringify(args),runtime_missing_resources:missing.join(",")},effects);if(opcode==="AC")draw.runtime_color=COLORS[args[0]]||COLORS.NODTA;if(opcode==="LS"){draw.runtime_line_style=String(args[0]||"SOLD");draw.runtime_line_width=Number(args[1]||1);draw.runtime_color=COLORS[args[2]]||COLORS.NODTA;}if(opcode==="TX"){draw.runtime_text=String((item.text&&item.text.value)||args[0]||"");draw.runtime_color=COLORS[(item.text&&item.text.color)||"CHBLK"]||COLORS.CHBLK;draw.runtime_text_xoff=Number((item.text&&item.text.xoff)||0);draw.runtime_text_yoff=textOverride===null?Number((item.text&&item.text.yoff)||0):textOverride;}if(opcode==="SOUNDG"){draw.runtime_opcode="SOUNDG";draw.runtime_soundg_index=output.filter(x=>x.properties.runtime_opcode==="SOUNDG").length;}const metadata=(context.symbolMetadata||{})[String(args[0]||"")]||{};if(Array.isArray(metadata.maplibre_icon_offset))draw.runtime_icon_offset=metadata.maplibre_icon_offset;output.push({type:"Feature",id:String(feature.id==null?"":feature.id)+":"+item.sequence,geometry:geometry,properties:draw});
});output.missingResources=missing;output.sideEffects=chain.filter(x=>x.opcode==="SE").map(x=>x.side_effects||{});return output;
}
class RuntimeExecutor{