Dev: route the web's map through this stack's tile server; power grid offline

Two reasons an offline dev run's web client had no map:

1. Vite proxied every tile to the public tile host. web_command now sets
   ODIAN_TILE_SERVER_URL=http://127.0.0.1:18081 for the Vite it starts, and
   ODIAN_Engine's _WEB/vite.config.ts sends /basemap, /mvt and /netlayer there:
   the site while it answers, this PC's installed tiles when it does not - the
   same path the .exe already draws from.

2. The power-grid netlayer had no source offline. datasets.json named every
   PostGIS overlay but `powerv2_postgis`, so the tile server answered
   /netlayer/<ds>/powerv2/* with 404 "powerv2_render_sqlite not found" while
   postgis_power_entities / _links / _topology sat in the local snapshot. Added
   to POSTGIS_SOURCES; the tile server resolves it through the same
   ODIAN_TILE_POSTGIS_DSN as the others.

Spot-check: with the site unreachable, /netlayer/<ds>/powerv2/bbox/8/128/86/131/89.json
answers 200 (721064 B, the same body the site serves) and topology.bin 200.
This commit is contained in:
JIMMY_JFEXP
2026-09-29 14:00:28 +02:00
parent d90dda1df5
commit 2d79664dc7
+23 -2
View File
@@ -627,6 +627,10 @@ fn web_command(dir: &Path) -> Command {
.arg("--port") .arg("--port")
.arg(WEB_PORT.to_string()) .arg(WEB_PORT.to_string())
.arg("--strictPort") .arg("--strictPort")
// The map through THIS stack's tile server, as the .exe draws it: the site while it
// answers, this PC's installed tiles when it does not. Without it _WEB's proxy goes
// to the public tile host, and an offline run has no map at all.
.env("ODIAN_TILE_SERVER_URL", format!("http://127.0.0.1:{TILES_PORT}"))
.current_dir(dir); .current_dir(dir);
web web
} }
@@ -805,7 +809,9 @@ const TILES_POSTGIS_DSN_ENV: &str = "ODIAN_TILE_POSTGIS_DSN";
/// launcher sets) leaves the layer with nowhere to read, and it draws nothing at all. That is /// launcher sets) leaves the layer with nowhere to read, and it draws nothing at all. That is
/// what kept oil, gas, aeroways and military bases off an offline map while their tables sat /// what kept oil, gas, aeroways and military bases off an offline map while their tables sat
/// in the database unused - only the four Theatre layers below were ever named here. /// in the database unused - only the four Theatre layers below were ever named here.
const POSTGIS_SOURCES: [&str; 8] = [ /// `powerv2_postgis` (the power grid netlayer) was the last one missing: its tables
/// (`postgis_power_entities` / `_links` / `_topology`) are in the snapshot too.
const POSTGIS_SOURCES: [&str; 9] = [
"aeroway_postgis", "aeroway_postgis",
"datacenter_postgis", "datacenter_postgis",
"gas_postgis", "gas_postgis",
@@ -813,6 +819,7 @@ const POSTGIS_SOURCES: [&str; 8] = [
"military_base_postgis", "military_base_postgis",
"oil_postgis", "oil_postgis",
"place_of_worship_postgis", "place_of_worship_postgis",
"powerv2_postgis",
"school_postgis", "school_postgis",
]; ];
@@ -1407,6 +1414,19 @@ mod tests {
assert_eq!(cmd.get_current_dir(), Some(Path::new(r"E:\dev\ODIAN_Engine\_WEB"))); assert_eq!(cmd.get_current_dir(), Some(Path::new(r"E:\dev\ODIAN_Engine\_WEB")));
} }
#[test]
fn the_web_draws_its_map_from_this_stacks_tile_server() {
// Offline, the public tile host is unreachable; this stack's tile server still has
// the PC's installed tiles. _WEB's vite.config.ts reads this variable.
let cmd = web_command(Path::new(r"E:\dev\ODIAN_Engine\_WEB"));
let tiles = cmd
.get_envs()
.find(|(key, _)| *key == "ODIAN_TILE_SERVER_URL")
.and_then(|(_, value)| value)
.map(|value| value.to_string_lossy().into_owned());
assert_eq!(tiles.as_deref(), Some("http://127.0.0.1:18081"));
}
#[test] #[test]
fn a_query_value_cannot_end_its_own_parameter() { fn a_query_value_cannot_end_its_own_parameter() {
// The address is built here, but the operator name comes from a text field. // The address is built here, but the operator name comes from a text field.
@@ -1547,7 +1567,8 @@ mod tests {
} }
// The ones that were missing, named outright: they are why an offline map had // The ones that were missing, named outright: they are why an offline map had
// hospitals and schools but no oil, gas, aeroways or military bases. // hospitals and schools but no oil, gas, aeroways or military bases.
for key in ["oil_postgis", "gas_postgis", "aeroway_postgis", "military_base_postgis"] { // And the power grid, missing after that: offline, the web's power layer 404'd.
for key in ["oil_postgis", "gas_postgis", "aeroway_postgis", "military_base_postgis", "powerv2_postgis"] {
assert_eq!(doc[dataset][key]["dsn_env"], TILES_POSTGIS_DSN_ENV, "{dataset} {key}"); assert_eq!(doc[dataset][key]["dsn_env"], TILES_POSTGIS_DSN_ENV, "{dataset} {key}");
} }
} }