test: add STEP-119 RCRR boundary variants and audit
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
tei
2026-10-11 17:42:26 +09:00
parent 46c88b0209
commit 1072816740
7 changed files with 296 additions and 20 deletions

View File

@@ -28,7 +28,8 @@ internal class Step113PbfGateScene(
private val map: MapLibreMap,
private val display: (String) -> Unit
) {
enum class Scenario { PBF63, STATIC_RC, PARTICLE_OFF, PARTIAL_RCRR, SOURCE_CHANGE, STATIC_RC_NO_TIDE }
enum class Scenario { PBF63, STATIC_RC, PARTICLE_OFF, PARTIAL_RCRR, SOURCE_CHANGE, STATIC_RC_NO_TIDE,
RCRR_C_NARROW_NO_TIDE, RCRR_C_WIDE_NO_TIDE, RCRR_R_DYNAMIC_NO_TIDE }
private val handler = Handler(Looper.getMainLooper())
private var generation = 0
@@ -126,7 +127,7 @@ internal class Step113PbfGateScene(
// STEP-118: Keep the original 63-layer PBF baseline unchanged.
// Only the explicitly named user-approved variant excludes one
// orphaned Symbol layer whose tide Source is already absent.
val omitTideLayer = scenario == Scenario.STATIC_RC_NO_TIDE
val omitTideLayer = isNoTideVariant(scenario)
val tideDependent = (0 until base.length()).filter {
base.getJSONObject(it).optString("source") == TIDE_SOURCE
}
@@ -179,7 +180,7 @@ internal class Step113PbfGateScene(
.put("sprite", root.optString("sprite"))
.put("glyphs", root.optString("glyphs")).put("vectorSource", JSONObject(source.toString()))
.put("productionSources", JSONObject(root.getJSONObject("sources").toString()))
.put("internalAnnotationPolicy", "仅STATIC_RC及STATIC_RC_NO_TIDE加载时移除空SDK辅助层;后续添加不再移除")
.put("internalAnnotationPolicy", "STATIC_RC及全部NO_TIDE场景加载时移除空SDK辅助层;后续添加不再移除")
.put("styleAdjustmentScope", if (omitTideLayer)
"TEST-APP-ONLY;原生产Style63层不变;测试副本排除唯一tide-spots→tide孤立Symbol层" else
"NONE;生产Style基础63层原样")
@@ -189,7 +190,7 @@ internal class Step113PbfGateScene(
check(!sources.has(SOURCE)) { "天气 Source ID 冲突" }
sources.put(SOURCE, JSONObject().put("type", "raster-array").put("host-field-submission", true))
val layers = JSONArray()
val prefix = scenario == Scenario.PARTIAL_RCRR
val prefix = isRcrrVariant(scenario)
for (i in 0 until effectiveBase.length()) {
layers.put(effectiveBase.getJSONObject(i))
if (prefix && effectiveBase.getJSONObject(i).getString("id") == "clip-outline") addFields(layers)
@@ -222,16 +223,24 @@ internal class Step113PbfGateScene(
.put("baseParityBasis", if (omitTideLayer)
"同次SDK生产Style63层回读;测试副本仅排除tide-spots,其余62层定义逐项比较;不等同原63层像素验收" else
"同次SDK生产Style回读;完整定义逐层比较,不是设备画面证明")
val plan = planJson(scenario, effectiveIds.last())
parity.put("testPlanSelector", if (scenario == Scenario.PARTIAL_RCRR)
"结构RCRR:sea-area-fill/special-pattern-line-754/最后生产层ID;非现场113边界" else
if (hasField) "当前NavSea源码RC:rn-weather-color" else "基础63层全RETAINED")
val clipIndex = effectiveIds.indexOf("clip-outline")
check(clipIndex >= 0 && clipIndex + 1 < effectiveIds.size) {
"生产Style的clip-outline之后没有基础图层;不可推断RCRR天气位置"
}
val plan = planJson(scenario, effectiveIds.last(), effectiveIds[clipIndex + 1])
parity.put("testPlanSelector", when (scenario) {
Scenario.PARTIAL_RCRR -> "旧RCRR缺源负对照:R0包含缺源tide,C1混合天气与大量静态PBF"
Scenario.RCRR_C_NARROW_NO_TIDE -> "RCRR窄C:仅天气;两段后续静态R"
Scenario.RCRR_C_WIDE_NO_TIDE -> "RCRR宽C:天气及部分PBF;后续静态R"
Scenario.RCRR_R_DYNAMIC_NO_TIDE -> "RCRR错误动态R:天气落R0;验证安全拒绝"
else -> if (hasField) "当前NavSea源码RC:rn-weather-color" else "基础63层全RETAINED"
})
.put("requestedPlan", JSONObject(plan))
commandResults.put("planAccepted", map.setRenderSegmentPlan(plan))
map.setStyle(Style.Builder().fromJson(root.toString())) testStyle@ { style ->
if (!running || epoch != generation) return@testStyle
try {
if (scenario == Scenario.STATIC_RC || scenario == Scenario.STATIC_RC_NO_TIDE) {
if (scenario == Scenario.STATIC_RC || isNoTideVariant(scenario)) {
removeEmptyAnnotationLayer(style, ids)
}
map.cameraPosition = CameraPosition.Builder().target(LatLng(33.45, 129.97))
@@ -494,13 +503,27 @@ internal class Step113PbfGateScene(
private const val ANNOTATION_LAYER = "org.maplibre.annotations.points"
private const val FORECAST_MS = 1786060800000L
private fun planJson(s: Scenario, finalBaseId: String): String {
private fun isRcrrVariant(s: Scenario): Boolean = s == Scenario.PARTIAL_RCRR ||
s == Scenario.RCRR_C_NARROW_NO_TIDE || s == Scenario.RCRR_C_WIDE_NO_TIDE ||
s == Scenario.RCRR_R_DYNAMIC_NO_TIDE
private fun isNoTideVariant(s: Scenario): Boolean = s == Scenario.STATIC_RC_NO_TIDE ||
s == Scenario.RCRR_C_NARROW_NO_TIDE || s == Scenario.RCRR_C_WIDE_NO_TIDE ||
s == Scenario.RCRR_R_DYNAMIC_NO_TIDE
private fun planJson(s: Scenario, finalBaseId: String, firstAfterClipId: String): String {
val segments = JSONArray().put(JSONObject().put("strategy", "RETAINED"))
if (s != Scenario.PBF63) {
segments.put(JSONObject().put("strategy", "CONTINUOUS")
.put("startLayerId", if (s == Scenario.PARTIAL_RCRR) "sea-area-fill" else COLOR))
if (s == Scenario.PARTIAL_RCRR) {
segments.put(JSONObject().put("strategy", "RETAINED").put("startLayerId", "special-pattern-line-754"))
val continuousStart = when (s) {
Scenario.PARTIAL_RCRR, Scenario.RCRR_C_WIDE_NO_TIDE -> "sea-area-fill"
Scenario.RCRR_R_DYNAMIC_NO_TIDE -> firstAfterClipId
else -> COLOR
}
segments.put(JSONObject().put("strategy", "CONTINUOUS").put("startLayerId", continuousStart))
if (isRcrrVariant(s)) {
val upperRetainedStart = if (s == Scenario.RCRR_C_NARROW_NO_TIDE)
firstAfterClipId else "special-pattern-line-754"
segments.put(JSONObject().put("strategy", "RETAINED").put("startLayerId", upperRetainedStart))
segments.put(JSONObject().put("strategy", "RETAINED").put("startLayerId", finalBaseId))
}
}