facett-geomap/tests/osm_zorder.rs
//! **Z-band paint-order proof** for the 2D OSM viewer (`OsmView`).
//!
//! The documented order (see `osm2d::PaintBand`) is, bottom→top:
//! Background → Fill (land/water) → Line (roads) → Point → Overlay → Label → Pin.
//! This renders a scene where a big **water fill** covers the pane, a bright **road**
//! crosses it, and a **pin** sits on top, then asserts through the real pixels that
//! the road is visible OVER the water (fills paint under roads) and the pin marker
//! is visible OVER everything (pins on top). It is the always-headless-runnable
//! guard for the CPU reference lane; the GPU-lane fix (emitting the line callback
//! AFTER the fills, so the two lanes agree) is structural — the GPU lane cannot
//! render on the headless harness.
//!
//! Run: `cargo test -p facett-geomap --test osm_zorder`
use egui_kittest::Harness;
use facett_core::Facet;
use facett_geomap::Way;
use facett_geomap::osm2d::{OsmView, Pin};
/// A closed square ring in (lon, lat).
fn square(x0: f64, y0: f64, x1: f64, y1: f64) -> Vec<(f64, f64)> {
vec![(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)]
}
/// Count pixels whose colour is close to `(r,g,b)` (within a per-channel band).
fn count_near(img: &image::RgbaImage, r: u8, g: u8, b: u8, tol: i32) -> usize {
img.pixels()
.filter(|p| {
(p.0[0] as i32 - r as i32).abs() <= tol
&& (p.0[1] as i32 - g as i32).abs() <= tol
&& (p.0[2] as i32 - b as i32).abs() <= tol
})
.count()
}
#[test]
fn fills_paint_under_roads_under_pins() {
// A pure-BLUE water polygon over the whole data bbox, a pure-GREEN road across
// its middle, and a pin at the centre. Distinct primaries make the bands
// unambiguous in the rendered pixels.
let water = Way::filled(
1,
"water",
square(0.0, 0.0, 10.0, 10.0),
egui::Color32::from_rgb(0, 0, 255), // fill: blue
egui::Color32::from_rgb(0, 0, 200), // outline: blue-ish
1.0,
);
let road = Way::line(
2,
"road",
vec![(0.5, 5.0), (9.5, 5.0)],
egui::Color32::from_rgb(0, 255, 0), // road: green
6.0,
);
let pin = Pin::new(5.0, 5.0, "");
let mut view = OsmView::from_geometry("z-order", Vec::new(), vec![water, road]).with_pins(vec![pin]);
let mut harness = Harness::builder().with_size(egui::vec2(400.0, 400.0)).build_ui(move |ui| {
view.ui(ui);
});
harness.run_steps(3);
let img = harness.render().expect("wgpu render produced an image");
let blue = count_near(&img, 0, 0, 255, 40);
let green = count_near(&img, 0, 255, 0, 60);
let red = count_near(&img, 230, 90, 90, 60); // the pin marker head
eprintln!("[z-order] blue(water)={blue} green(road)={green} red(pin)={red}");
// Water fills a large area (the background band).
assert!(blue > 5_000, "the water fill covers a healthy area of the pane (got {blue})");
// The GREEN road is visible ON TOP of the water: if fills painted over roads,
// the green line would be covered by blue and vanish. Red-when-broken for the
// fills-under-roads invariant.
assert!(green > 300, "the road must be visible over the water fill (got {green} green px)");
// The RED pin marker sits on top of everything.
assert!(red > 40, "the pin marker must be visible on top (got {red} red px)");
// testmatrix cell — OSM 2D z-band paint order holds (fills < roads < pins);
// surfaces in the dwarves testmatrix (`--features testmatrix`), no-op otherwise.
facett_core::testmatrix::emit(
"facett-geomap/osm2d",
"fills_paint_under_roads_under_pins",
blue > 5_000 && green > 300 && red > 40,
&format!("z-order pixels: water(blue)={blue}, road(green over water)={green}, pin(red on top)={red}"),
);
}