From 5217082034834b38ff12bf28deb83fb694dc883b Mon Sep 17 00:00:00 2001 From: OpenAI Codex Date: Mon, 21 Sep 2026 21:11:34 +0800 Subject: [PATCH] fix: register S-52 sprite images after style load --- web/kyushu_compare.html | 46 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/web/kyushu_compare.html b/web/kyushu_compare.html index 3784abb..3792a50 100644 --- a/web/kyushu_compare.html +++ b/web/kyushu_compare.html @@ -651,6 +651,43 @@ let referenceStyleTemplate=null; let s52StyleTemplate=null; let activeLeftStyleTemplate=null; let activeRightStyleTemplate=null; +let s52SpriteAtlasPromise=null; + +async function loadS52SpriteAtlas(){ + if(s52SpriteAtlasPromise)return s52SpriteAtlasPromise; + s52SpriteAtlasPromise=(async function(){ + const metaResponse=await fetch('/s52/sprite.json?v=current-release',{cache:'no-store'}); + if(!metaResponse.ok)throw new Error('S-52 sprite JSON HTTP '+metaResponse.status); + const metadata=await metaResponse.json(); + const image=await new Promise(function(resolve,reject){ + const img=new Image(); + img.onload=function(){resolve(img);}; + img.onerror=function(){reject(new Error('S-52 sprite PNG load failed'));}; + img.src='/s52/sprite.png?v=current-release'; + }); + return {metadata:metadata,image:image}; + })(); + return s52SpriteAtlasPromise; +} + +async function ensureS52SpriteImages(map){ + const atlas=await loadS52SpriteAtlas(); + const canvas=document.createElement('canvas'); + const ctx=canvas.getContext('2d',{willReadFrequently:true}); + let added=0; + for(const [name,meta] of Object.entries(atlas.metadata)){ + if(map.hasImage(name))continue; + const width=Number(meta.width)||0, height=Number(meta.height)||0; + if(width<=0||height<=0)continue; + canvas.width=width; canvas.height=height; + ctx.clearRect(0,0,width,height); + ctx.drawImage(atlas.image,Number(meta.x)||0,Number(meta.y)||0,width,height,0,0,width,height); + const pixels=ctx.getImageData(0,0,width,height); + map.addImage(name,pixels,{pixelRatio:Number(meta.pixelRatio)||1}); + added++; + } + return added; +} function sanitizeReferenceStyle(raw){ const style=JSON.parse(JSON.stringify(raw)); @@ -742,15 +779,22 @@ async function loadComparisonStyles(){ } } -leftMap.on("style.load",function(){ +leftMap.on("style.load",async function(){ const sources=Object.keys((leftMap.getStyle() || {}).sources || {}); if(sources.includes("cm95")){ + try{ + await ensureS52SpriteImages(leftMap); + }catch(err){ + console.error(err); + setState(leftState,"S-52 sprite 注册失败:"+(err.message||err),"err"); + } installRuntimePreviewLayers(leftMap); setState(leftState,"当前 Production / S-52 style" + (debugRuntimePreview.checked ? " + runtime preview" : ""),"ok"); }else if(sources.includes("navsea_delivery")){ setState(leftState,"当前 Production / extentfix style","ok"); } applyDebugStyles(); + refreshRuntimeRuleExecutor(); refreshLightArcFeatures(); }); rightMap.on("style.load",applyDebugStyles);