feat: add production-like particle field feed

This commit is contained in:
OpenAI Codex
2026-09-04 14:51:42 +08:00
parent 885e7aebef
commit 7c679f09ac
23 changed files with 545 additions and 26 deletions

View File

@@ -0,0 +1,4 @@
{
"schema": "maplibre-particle-field/v1", "fieldId": "production-wind-t00", "fieldType": "WIND", "displayDomain": "GLOBAL", "generation": 1, "validTime": 202609040000, "dataVersion": 1,
"bounds": {"west": -180.0, "south": -85.0, "east": 180.0, "north": 85.0}, "grid": {"width": 16, "height": 16}, "vector": {"layout": "interleaved-uv", "encoding": "float32-le", "noData": -9999.0}, "payload": {"byteLength": 2048}
}

View File

@@ -0,0 +1,4 @@
{
"schema": "maplibre-particle-field/v1", "fieldId": "production-wind-t01", "fieldType": "WIND", "displayDomain": "GLOBAL", "generation": 2, "validTime": 202609040100, "dataVersion": 2,
"bounds": {"west": -180.0, "south": -85.0, "east": 180.0, "north": 85.0}, "grid": {"width": 16, "height": 16}, "vector": {"layout": "interleaved-uv", "encoding": "float32-le", "noData": -9999.0}, "payload": {"byteLength": 2048}
}

View File

@@ -0,0 +1,4 @@
{
"schema": "maplibre-particle-field/v1", "fieldId": "production-wind-t02", "fieldType": "WIND", "displayDomain": "GLOBAL", "generation": 3, "validTime": 202609040200, "dataVersion": 3,
"bounds": {"west": -180.0, "south": -85.0, "east": 180.0, "north": 85.0}, "grid": {"width": 16, "height": 16}, "vector": {"layout": "interleaved-uv", "encoding": "float32-le", "noData": -9999.0}, "payload": {"byteLength": 2048}
}

View File

@@ -0,0 +1,4 @@
{
"schema": "maplibre-particle-field/v1", "fieldId": "production-wind-t03", "fieldType": "WIND", "displayDomain": "GLOBAL", "generation": 4, "validTime": 202609040300, "dataVersion": 4,
"bounds": {"west": -180.0, "south": -85.0, "east": 180.0, "north": 85.0}, "grid": {"width": 16, "height": 16}, "vector": {"layout": "interleaved-uv", "encoding": "float32-le", "noData": -9999.0}, "payload": {"byteLength": 2048}
}

View File

@@ -32,6 +32,7 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
private var trailFade = DEFAULT_TRAIL_FADE
private var speedColorEnabled = true
private var timeWindowMode = false
private var productionFeedMode = false
private var styleLoadEpoch = 0L
private var styleReady = false
// Display mirror only; Core remains the playback state authority.
@@ -97,21 +98,25 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
}
findViewById<Button>(R.id.validationUniformEast).setOnClickListener {
timeWindowMode = false
productionFeedMode = false
fixtureMode = FIXTURE_UNIFORM_EAST
if (this::maplibreMap.isInitialized) loadValidationStyle(active, enabled, "UNIFORM_EAST")
}
findViewById<Button>(R.id.validationUniformNorth).setOnClickListener {
timeWindowMode = false
productionFeedMode = false
fixtureMode = FIXTURE_UNIFORM_NORTH
if (this::maplibreMap.isInitialized) loadValidationStyle(active, enabled, "UNIFORM_NORTH")
}
findViewById<Button>(R.id.validationVortex).setOnClickListener {
timeWindowMode = false
productionFeedMode = false
fixtureMode = FIXTURE_VORTEX
if (this::maplibreMap.isInitialized) loadValidationStyle(active, enabled, "VORTEX")
}
findViewById<Button>(R.id.validationTimeWindow).setOnClickListener {
timeWindowMode = true
productionFeedMode = true
fixtureMode = FIXTURE_UNIFORM_EAST
timeMix = 0.0f
timelineState = "NOT READY"
@@ -381,7 +386,7 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
} else {
"EAST"
}
val playback = if (timeWindowMode) " · TL $timelineState · $timelineSpeed" else ""
val playback = if (timeWindowMode) " · ${if (productionFeedMode) "PRODUCTION" else "FIXTURE"} · TL $timelineState · $timelineSpeed" else ""
return "$mask · $runtime · $fields$playback · MIX ${(timeMix * 100).toInt()}% · $particleCount · W ${"%.1f".format(lineWidth)} L ${"%.3f".format(particleLength)} O ${(particleOpacity * 100).toInt()} T ${(trailOpacity * 100).toInt()} F ${(trailFade * 100).toInt()} C ${if (speedColorEnabled) "ON" else "OFF"}"
}
@@ -402,30 +407,33 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
} else {
""
}
val source = if (productionFeedMode) {
"""{"type":"raster-array","production-fields":[
{"metadata":"asset://integration/particle-production/field-00.json","field":"asset://integration/particle-fixtures/uniform-east/field.f32"},
{"metadata":"asset://integration/particle-production/field-01.json","field":"asset://integration/particle-fixtures/uniform-north/field.f32"},
{"metadata":"asset://integration/particle-production/field-02.json","field":"asset://integration/particle-fixtures/vortex/field.f32"},
{"metadata":"asset://integration/particle-production/field-03.json","field":"asset://integration/particle-fixtures/uniform-east/field.f32"}
]}"""
} else {
"""{"type":"raster-array","fixture":"$fixtureId",
"metadata":"asset://integration/particle-fixtures/$fixtureId/metadata.json",
"field":"asset://integration/particle-fixtures/$fixtureId/field.f32",
"next-fixture":"$nextFixtureId",
"next-metadata":"asset://integration/particle-fixtures/$nextFixtureId/metadata.json",
"next-field":"asset://integration/particle-fixtures/$nextFixtureId/field.f32",
"runtime-fields":[
{"fixture":"vortex","metadata":"asset://integration/particle-fixtures/vortex/metadata.json","field":"asset://integration/particle-fixtures/vortex/field.f32"},
{"fixture":"nodata","metadata":"asset://integration/particle-fixtures/nodata/metadata.json","field":"asset://integration/particle-fixtures/nodata/field.f32"},
{"fixture":"uniform-east","metadata":"asset://integration/particle-fixtures/uniform-east/metadata.json","field":"asset://integration/particle-fixtures/uniform-east/field.f32"},
{"fixture":"uniform-north","metadata":"asset://integration/particle-fixtures/uniform-north/metadata.json","field":"asset://integration/particle-fixtures/uniform-north/field.f32"}
]}"""
}
return """
{
"version": 8,
"name": "Particle Core Layer Validation",
"sources": {
"particle-fixture": {
"type": "raster-array",
"fixture": "$fixtureId",
"metadata": "asset://integration/particle-fixtures/$fixtureId/metadata.json",
"field": "asset://integration/particle-fixtures/$fixtureId/field.f32",
"next-fixture": "$nextFixtureId",
"next-metadata": "asset://integration/particle-fixtures/$nextFixtureId/metadata.json",
"next-field": "asset://integration/particle-fixtures/$nextFixtureId/field.f32",
"runtime-fields": [
{"fixture":"vortex","metadata":"asset://integration/particle-fixtures/vortex/metadata.json",
"field":"asset://integration/particle-fixtures/vortex/field.f32"},
{"fixture":"nodata","metadata":"asset://integration/particle-fixtures/nodata/metadata.json",
"field":"asset://integration/particle-fixtures/nodata/field.f32"},
{"fixture":"uniform-east","metadata":"asset://integration/particle-fixtures/uniform-east/metadata.json",
"field":"asset://integration/particle-fixtures/uniform-east/field.f32"},
{"fixture":"uniform-north","metadata":"asset://integration/particle-fixtures/uniform-north/metadata.json",
"field":"asset://integration/particle-fixtures/uniform-north/field.f32"}
]
},
"particle-fixture": $source,
"validation-point": {
"type": "geojson",
"data": {"type":"Feature","geometry":{"type":"Point","coordinates":[0,0]}}