fix: restore LIGHTS runtime symbol without duplicate base
This commit is contained in:
@@ -76,7 +76,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/assets/maplibre-gl.js"></script>
|
<script src="/assets/maplibre-gl.js"></script>
|
||||||
<script src="/s52_runtime_executor.js?v=dynamic-only-v1"></script>
|
<script src="/s52_runtime_executor.js?v=lights-symbol-runtime-v1"></script>
|
||||||
<script>
|
<script>
|
||||||
const REFERENCE_STYLE =
|
const REFERENCE_STYLE =
|
||||||
"https://pbf.jpcn.ccwu.cc/style/style.navsea-delivery-full-semantic-extentfix.json";
|
"https://pbf.jpcn.ccwu.cc/style/style.navsea-delivery-full-semantic-extentfix.json";
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ function representativePointGeometry(geometry){
|
|||||||
function operationFeatures(feature,settings,context,resourceExists){
|
function operationFeatures(feature,settings,context,resourceExists){
|
||||||
const props=feature.properties||{},geometry=feature.geometry||{},geomType=String(geometry.type||""),chain=expandRuleChain(props,settings,context),missing=[],output=[];
|
const props=feature.properties||{},geometry=feature.geometry||{},geomType=String(geometry.type||""),chain=expandRuleChain(props,settings,context),missing=[],output=[];
|
||||||
const effects=Object.assign({},...chain.filter(x=>x.opcode==="SE").map(x=>x.side_effects||{}));
|
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;}
|
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"].includes(opcode)&&args[0]&&resourceExists&&resourceExists(String(args[0]))===false){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;}
|
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.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;const drawGeometry=["SY","SOUNDG","TX"].includes(opcode)?representativePointGeometry(geometry):geometry;output.push({type:"Feature",id:String(feature.id==null?"":feature.id)+":"+item.sequence,geometry:drawGeometry,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;const drawGeometry=["SY","SOUNDG","TX"].includes(opcode)?representativePointGeometry(geometry):geometry;output.push({type:"Feature",id:String(feature.id==null?"":feature.id)+":"+item.sequence,geometry:drawGeometry,properties:draw});
|
||||||
});output.missingResources=missing;output.sideEffects=chain.filter(x=>x.opcode==="SE").map(x=>x.side_effects||{});return output;
|
});output.missingResources=missing;output.sideEffects=chain.filter(x=>x.opcode==="SE").map(x=>x.side_effects||{});return output;
|
||||||
@@ -131,7 +131,7 @@ class RuntimeExecutor{
|
|||||||
addSequence(seq){const base={source:this.sourceId};this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-ac`,type:"fill",filter:this.filter(seq,"AC"),paint:{"fill-color":["get","runtime_color"],"fill-opacity":0.92}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-ap`,type:"fill",filter:this.filter(seq,"AP"),paint:{"fill-pattern":["get","runtime_resource"],"fill-opacity":0.85}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-ls`,type:"line",filter:this.filter(seq,"LS"),layout:{"line-cap":"round"},paint:{"line-color":["get","runtime_color"],"line-width":["get","runtime_line_width"],"line-dasharray":["match",["get","runtime_line_style"],"DASH",["literal",[4,2]],"DOTT",["literal",[1,2]],["literal",[1,0]]]}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-lc`,type:"line",filter:this.filter(seq,"LC"),paint:{"line-pattern":["get","runtime_resource"],"line-width":5}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-sy`,type:"symbol",filter:this.filter(seq,"SY"),layout:{"icon-image":["get","runtime_resource"],"icon-offset":["coalesce",["get","runtime_icon_offset"],["literal",[0,0]]],"icon-allow-overlap":true,"icon-ignore-placement":true}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-soundg`,type:"symbol",filter:this.filter(seq,"SOUNDG"),layout:{"icon-image":["get","runtime_resource"],"icon-offset":["coalesce",["get","runtime_icon_offset"],["literal",[0,0]]],"icon-allow-overlap":true,"icon-ignore-placement":true}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-tx`,type:"symbol",filter:this.filter(seq,"TX"),layout:{"text-field":["get","runtime_text"],"text-size":10,"text-offset":["literal",[0,0]],"text-allow-overlap":false,"text-optional":true},paint:{"text-color":["get","runtime_color"],"text-halo-color":"rgba(255,255,255,.65)","text-halo-width":0.5}}));}
|
addSequence(seq){const base={source:this.sourceId};this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-ac`,type:"fill",filter:this.filter(seq,"AC"),paint:{"fill-color":["get","runtime_color"],"fill-opacity":0.92}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-ap`,type:"fill",filter:this.filter(seq,"AP"),paint:{"fill-pattern":["get","runtime_resource"],"fill-opacity":0.85}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-ls`,type:"line",filter:this.filter(seq,"LS"),layout:{"line-cap":"round"},paint:{"line-color":["get","runtime_color"],"line-width":["get","runtime_line_width"],"line-dasharray":["match",["get","runtime_line_style"],"DASH",["literal",[4,2]],"DOTT",["literal",[1,2]],["literal",[1,0]]]}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-lc`,type:"line",filter:this.filter(seq,"LC"),paint:{"line-pattern":["get","runtime_resource"],"line-width":5}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-sy`,type:"symbol",filter:this.filter(seq,"SY"),layout:{"icon-image":["get","runtime_resource"],"icon-offset":["coalesce",["get","runtime_icon_offset"],["literal",[0,0]]],"icon-allow-overlap":true,"icon-ignore-placement":true}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-soundg`,type:"symbol",filter:this.filter(seq,"SOUNDG"),layout:{"icon-image":["get","runtime_resource"],"icon-offset":["coalesce",["get","runtime_icon_offset"],["literal",[0,0]]],"icon-allow-overlap":true,"icon-ignore-placement":true}}));this.addLayer(Object.assign({},base,{id:`runtime-rule-${seq}-tx`,type:"symbol",filter:this.filter(seq,"TX"),layout:{"text-field":["get","runtime_text"],"text-size":10,"text-offset":["literal",[0,0]],"text-allow-overlap":false,"text-optional":true},paint:{"text-color":["get","runtime_color"],"text-halo-color":"rgba(255,255,255,.65)","text-halo-width":0.5}}));}
|
||||||
sourceLayers(){const set=new Set();((this.map.getStyle()||{}).layers||[]).forEach(layer=>{if(layer.source==="cm95"&&layer["source-layer"])set.add(layer["source-layer"]);});return Array.from(set);}
|
sourceLayers(){const set=new Set();((this.map.getStyle()||{}).layers||[]).forEach(layer=>{if(layer.source==="cm95"&&layer["source-layer"])set.add(layer["source-layer"]);});return Array.from(set);}
|
||||||
updateSafety(){const values=[];try{(this.map.querySourceFeatures("cm95",{sourceLayer:"depth_contour"})||[]).forEach(f=>{const v=numberValue(f.properties,"contour_depth_m",null);if(v!==null&&v>=this.settings.safetyContourM)values.push(v);});}catch(_err){}this.effectiveSafetyContourM=values.length?Math.min.apply(null,values):null;}
|
updateSafety(){const values=[];try{(this.map.querySourceFeatures("cm95",{sourceLayer:"depth_contour"})||[]).forEach(f=>{const v=numberValue(f.properties,"contour_depth_m",null);if(v!==null&&v>=this.settings.safetyContourM)values.push(v);});}catch(_err){}this.effectiveSafetyContourM=values.length?Math.min.apply(null,values):null;}
|
||||||
refresh(){if(!this.map.getSource("cm95")||!this.map.isSourceLoaded("cm95"))return;this.updateSafety();this.lightLabelState.reset();const seen=new Set(),features=[],context={effectiveSafetyContourM:this.effectiveSafetyContourM,lightLabelState:this.lightLabelState,symbolMetadata:this.symbolMetadata};this.sourceLayers().forEach(layer=>{let rows=[];try{rows=this.map.querySourceFeatures("cm95",{sourceLayer:layer})||[];}catch(_err){return;}rows.forEach(feature=>{if(!feature.properties)return;const presentations=jsonValue(feature.properties.s52_light_presentations,[]),variants=[],topDynamic=hasDynamicCsRule(feature.properties.s52_rule_chain),topProcedure=String(feature.properties.s52_runtime_csp||feature.properties.s52_csp_resolved||feature.properties.s52_csp||"");if(topDynamic)variants.push(feature);if(feature.properties.s52_lights_metres_rule_chain&&!(topDynamic&&topProcedure==="LIGHTS05")){variants.push(Object.assign({},feature,{type:"Feature",id:String(feature.id==null?"":feature.id)+":light:metres",geometry:feature.geometry,properties:Object.assign({},feature.properties,{s52_rule_chain:feature.properties.s52_lights_metres_rule_chain})}));}if(Array.isArray(presentations))presentations.forEach((presentation,index)=>variants.push(Object.assign({},feature,{type:"Feature",id:String(feature.id==null?"":feature.id)+":light:"+index,geometry:feature.geometry,properties:Object.assign({},feature.properties,presentation)})));variants.forEach(variant=>{if(!variant.properties.s52_rule_chain)return;const key=[layer,variant.id,JSON.stringify(variant.geometry),variant.properties.s52_rule_chain].join("|");if(seen.has(key))return;seen.add(key);operationFeatures(variant,this.settings,context,name=>this.map.hasImage(name)).forEach(item=>features.push(item));});});});const caSeen=new Set();this.caFeatures=features.filter(item=>{if(item.properties.runtime_opcode!=="CA")return false;const key=JSON.stringify([item.geometry&&item.geometry.coordinates,item.properties.runtime_args_json]);if(caSeen.has(key))return false;caSeen.add(key);return true;});const visibleOps=new Set(["AC","AP","LS","LC","SY","SOUNDG","TX"]),mapFeatures=features.filter(item=>visibleOps.has(item.properties.runtime_opcode)&&!(item.properties.runtime_opcode==="SY"&&item.properties.runtime_procedure==="LIGHTS05"));const source=this.map.getSource(this.sourceId);if(source&&source.setData)source.setData({type:"FeatureCollection",features:mapFeatures});}
|
refresh(){if(!this.map.getSource("cm95")||!this.map.isSourceLoaded("cm95"))return;this.updateSafety();this.lightLabelState.reset();const seen=new Set(),features=[],context={effectiveSafetyContourM:this.effectiveSafetyContourM,lightLabelState:this.lightLabelState,symbolMetadata:this.symbolMetadata};this.sourceLayers().forEach(layer=>{let rows=[];try{rows=this.map.querySourceFeatures("cm95",{sourceLayer:layer})||[];}catch(_err){return;}rows.forEach(feature=>{if(!feature.properties)return;const presentations=jsonValue(feature.properties.s52_light_presentations,[]),variants=[],topDynamic=hasDynamicCsRule(feature.properties.s52_rule_chain),topProcedure=String(feature.properties.s52_runtime_csp||feature.properties.s52_csp_resolved||feature.properties.s52_csp||"");if(topDynamic)variants.push(feature);if(feature.properties.s52_lights_metres_rule_chain&&!(topDynamic&&topProcedure==="LIGHTS05")){variants.push(Object.assign({},feature,{type:"Feature",id:String(feature.id==null?"":feature.id)+":light:metres",geometry:feature.geometry,properties:Object.assign({},feature.properties,{s52_rule_chain:feature.properties.s52_lights_metres_rule_chain})}));}if(Array.isArray(presentations))presentations.forEach((presentation,index)=>variants.push(Object.assign({},feature,{type:"Feature",id:String(feature.id==null?"":feature.id)+":light:"+index,geometry:feature.geometry,properties:Object.assign({},feature.properties,presentation)})));variants.forEach(variant=>{if(!variant.properties.s52_rule_chain)return;const key=[layer,variant.id,JSON.stringify(variant.geometry),variant.properties.s52_rule_chain].join("|");if(seen.has(key))return;seen.add(key);operationFeatures(variant,this.settings,context,name=>{if(!this.symbolMetadata||!Object.keys(this.symbolMetadata).length)return true;return Object.prototype.hasOwnProperty.call(this.symbolMetadata,name);}).forEach(item=>features.push(item));});});});const caSeen=new Set();this.caFeatures=features.filter(item=>{if(item.properties.runtime_opcode!=="CA")return false;const key=JSON.stringify([item.geometry&&item.geometry.coordinates,item.properties.runtime_args_json]);if(caSeen.has(key))return false;caSeen.add(key);return true;});const visibleOps=new Set(["AC","AP","LS","LC","SY","SOUNDG","TX"]),mapFeatures=features.filter(item=>visibleOps.has(item.properties.runtime_opcode));const source=this.map.getSource(this.sourceId);if(source&&source.setData)source.setData({type:"FeatureCollection",features:mapFeatures});}
|
||||||
}
|
}
|
||||||
const api={DEFAULTS:DEFAULTS,COLORS:COLORS,jsonValue:jsonValue,soundingRules:soundingRules,hazardRules:hazardRules,dynamicRules:dynamicRules,expandRuleChain:expandRuleChain,operationFeatures:operationFeatures,caScaleMetrics:caScaleMetrics,LightLabelState:LightLabelState,RuntimeExecutor:RuntimeExecutor};root.CM95S52Runtime=api;if(typeof module!=="undefined"&&module.exports)module.exports=api;
|
const api={DEFAULTS:DEFAULTS,COLORS:COLORS,jsonValue:jsonValue,soundingRules:soundingRules,hazardRules:hazardRules,dynamicRules:dynamicRules,expandRuleChain:expandRuleChain,operationFeatures:operationFeatures,caScaleMetrics:caScaleMetrics,LightLabelState:LightLabelState,RuntimeExecutor:RuntimeExecutor};root.CM95S52Runtime=api;if(typeof module!=="undefined"&&module.exports)module.exports=api;
|
||||||
})(typeof globalThis!=="undefined"?globalThis:this);
|
})(typeof globalThis!=="undefined"?globalThis:this);
|
||||||
|
|||||||
Reference in New Issue
Block a user