Commit graph

626 commits

Author SHA1 Message Date
Admin
7f3f568933 map: opacity-aware AA fringes, single-level translucent rings; macos: skip foreign windows in scroll path
- Opaque faces get boundary-straddling AA skirts (coverage 50% at the
  edge, legacy convention); translucent faces ramp outward only and their
  straddling rings pick one level part — premultiplied translucent color
  must never paint over itself (double-blend darkened plaza boundaries).
- macos event loop: a foreign window class in the scroll-wheel path (the
  screen-capture overlay's TUINSWindow) has no macos_window_ptr ivar —
  skip instead of panicking. This was the random studio death whenever a
  system screenshot overlay was active.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 10:42:24 +02:00
Admin
2a30f55305 map: kill tiler runaway (chunked dissolve), i_overlay 7, AA fringe v1, forensics harness
Runaway root cause, captured via self-sampling memory watchdog + boolean
input dumps: simplify_shape on 17-20k-ring soups (dense tiers at high
overzoom) spins in contour extraction for minutes while allocating
unboundedly (both i_overlay 4 and 7). Chunked dissolve (3000-ring chunks,
union of clean outlines) turns the captured hangs into 91/140 ms; the
full pan/tilt torture that blasted to 100 GB now holds 5-6 GB flat.

- i_overlay 4.5 -> 7.0.3 (API-compatible, booleans ~1.7x faster).
- Boolean input hygiene: 1/64-unit snap + degenerate ring drop.
- DzField: guard degenerate terminal-segment cap extension, clamp grid
  walks (a NaN/huge coord can no longer explode cell insertion).
- AA fringe v1: miter skirts along boolean output rings, u 0.5->0 over
  1px, emitted after each face at its ladder slot.
- Level-straddling rings join both grounded+lifted parts (transition
  seams overlap instead of sharing an epsilon-fragile edge).
- Oneway arrows foreshorten with tilt (ground-plane glyphs).
- Debug: in-app memory watchdog (14 GB: sample own stacks -> abort),
  MP_TILE_PROFILE via /tmp/mp_tile_profile, boolean repro test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 10:42:24 +02:00
Admin
82566e94b0 map: 3D bake LOD — adaptive tree canopies, no roof AA fringe, wall ring LOD
Dense tiles carried 30-70 MB of fill buffer: thousands of park trees at
16x8 ball tessellation for ~14 px canopies, an AA fringe doubling roof
verts across every building (a lifted roof edge meets its own wall, not
the background), and sub-pixel footprint edges as wall quads. Screen-
adaptive canopy segments + aa=0 roofs + 1.2px wall edge collapse:
67.8 -> 26.0 MB worst measured tile. Also: DzField cap extension so
lifted way ends hold deck height through their round caps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 10:42:24 +02:00
Admin
4043031b1a map: level-split disjoint cascade, dissolve-first booleans, memory caps, perf harness
- Two-cover cascade: grounded content subtracts grounded cover, lifted
  subtracts lifted — a deck cuts its own casing (no more cap outlines
  bleeding through on bridges) but never the road running underneath;
  ramp feet still cut streets. Group parts dissolve to clean outlines
  (simplify_shape) before any cross-group op.
- Depth ladder by slot (per face, per stroke rank) instead of per event:
  coarser, safer separation between coplanar overlaps.
- DzField sampling gated by active-area bbox per face; corridor bbox
  prefilter for interleaved strokes.
- Byte-budget tile cache eviction (1.2 GB) + pending-upload queue cap
  (384 MB): 3D building bakes run 30-70 MB of fill buffer per tile and a
  count-capped cache alone reached tens of GB.
- MP_TILE_PROFILE stage clock + headless union_perf_probe test with the
  live theme mirrored (probe_compiled_theme): rz17 tile build 1.4s -> 0.9-1.0s.
- Revert baker lateral clearance: the constraint cascaded through solver
  rounds and lifted the whole network; needs a bounded formulation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 10:42:24 +02:00
Admin
103ec8f5d3 map: rank-interleaved paint ladder, per-tier dz fields, lifted decks keep under-roads
- Union faces and legacy strokes merge into one rank-ordered paint sequence
  (plazas, casings, centers) — cycle lanes and park paths draw above the
  surfaces they ride, higher tiers still cover both; flat = buffer order,
  tilt = same order via the param5 ladder.
- Joint coverage: bevel wedges at gentle bends, discs at corners/ends;
  union ways get the same chaikin smoothing as legacy strokes (dz-aware).
- Per-tier DzField (nearest-way-wins, grounded ways at 0) + crack-free
  midpoint face subdivision replace the narrow runtime corridors: decks
  lift edge-to-edge, casings stay attached, no tents or shards.
- Lifted rings no longer subtract from lower groups: roads continue
  underneath decks (paint order hides them flat, real depth when tilted).
- Lift-aware tilt depth: deck depth margin scales with lift so water and
  ground at the display position can't depth-win over a bridge.
- Baker: tapered lateral clearance for elevated ways running beside
  lower-layer roads (ribbon widths overlap without centerline crossings);
  connected ways exempt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 10:42:24 +02:00
Admin
fff629bb3f map: bridge dz solver+AHN bake, base_dz transcode, road overlay unifier
Bridge elevation (bridge.md M1+M2): tools/map_tiles bridge-bake solves
per-vertex road/rail dz over the OSM graph (crossing clearance, grade
ramps, deck holds, junction consensus) with AHN DSM-DTM measured deck
profiles (BigTIFF reader in geodata, WGS84->RD), baked as bridge_dz +
per-base-tile base_dz (L/F/P join to exact renderer geometry). Renderer
joins dz through parse into TileWay.dz; strokes/arrows/fills lift off
their own profiles; tunnels never deck.

Road overlay unifier: painter's algorithm as geometry — per-way segment
rects + vertex discs, i_overlay top-down subtraction cascade into
DISJOINT faces (overlay_paint_groups), triangulated once; flat render is
pixel-equal to paint order (proven 0-diff on the abstract unit case) and
tilt cannot reorder it. Legacy strokes interleave by rank; plazas join
the cascade at true alpha. @roads 0/1 A/B toggle, @abtest headless
CPU-raster diff harness (1.50% vs 2D reference on the Raampoort tile),
@cam debug camera, bridge_eval.sh aerial-vs-render loop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 10:42:24 +02:00
Admin
85515cea35 map: 3D terrain displacement, Europe-wide DEM, landcover drape, wind layer
Terrain gets real z in tilt mode: a displaced 288x216 surface mesh plus
per-vertex ground lift for all tile geometry (roads/fills/buildings/icons)
via vertex-stage sample_lod of a terrarium-packed elevation texture, with
labels riding the same ground through a lift-aware camera delta. Depth
domains rescale per frame to stay inside the -24 budget; road passes get
a relief-scaled clearance over the surface so cities keep correct
street-vs-building order. Regional zooms (<z14) drape landcover colors
into the hillshade (full-res MVT rasterization, treeline fade) instead of
lifting km-scale polygons that cannot follow relief.

Terrain build now covers EV-trip Europe (lat 43..58, lon -5..17, 8.8 GB
GLO-30 z6-12) with sign-safe Copernicus stems, transparent no-data, and
an Alpine rock/snow ramp. Terrain requests render 4096x3072 over ~3
viewports and only re-render on real movement.

Also: NOMADS GFS wind particle layer synced to the weather clock with 3D
altitude, rain cloud deck lift, stuck-tile fixes (expiring missing set,
decode-failure backoff, restyle placeholder purge), 78-degree tilt
ceiling, and park fill z-fight fix via widened micro-depth ranks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 10:42:24 +02:00
Kevin Boos
1de784dd0e PortalList: allow setting layout flow at runtime; AdaptiveView fixes (#1144)
* PortalList: add `set_flow(cx, flow)` to switch a list between vertical and
  horizontal layout flow at runtime. Much faster than using `script_apply_eval`,
  and always fully correct because it updates the `vec_index` axis.
  It also avoids a full ScriptReapply sequence, which is potentially expensive
  across all of an app's widgets.
* AdaptiveView: add `active_variant()` getter so that widgets using AdaptiveView   do not have to separately track which variant it should be in.   Removes all ambiguity and possibility of divergence... finally!
  * Also fixes long-standing TODO item in AdaptiveView about properly handling
    weird window geom events, e.g., on macOS sometimes it spits out a 0-width
    window update which is total b.s.
* DisplayContext: add `is_desktop_width()` helper.
* Window: ignore spurious zero-size window geom events.
2026-07-28 19:31:42 +02:00
Admin
c0aeb25b0a map: rain radar overlay, flying 3D markers, Europe routing, geodata crate
- rain radar layer: pure-Rust KNMI HDF5 reader (superblock v0 walk,
  single-chunk deflate datasets, byte-exact vs h5py), ellipsoidal polar
  stereographic reprojection (20 m vs product corners), bilinear value
  sampling -> smooth banded isolines, textured quad overlay through the
  overlay camera, 25-frame nowcast animation; RadarSync polls at most
  once per 4 min through a disk-persisted gate and caches frames on disk
- makepad-geodata + makepad-tesla crates join the workspace (overlay
  builders, radar sync, NL open-data layers; transit routes now z7-14)
- Europe major-roads routing graph: nav-build --major-roads does a
  ways-first scan (5.7M ways / 46M nodes / 194 s / 971 MB) and the app
  falls back to it when a route leaves the regional graph — Amsterdam to
  Paris routes offline (501.8 km)
- 3D flying markers: chargers/POIs/stops ride thin stalks with DYNAMIC
  height (each pin clears its own building +8 m); labels, kW text,
  brand and tap zones all consume the baked per-marker lift; stalks and
  buildings grow together on the 2D->3D transition (per-tile flat->3D
  fade heights, no replay on zoom regens)
- markers depth-honest (small bias, buildings occlude them); phong-lit
  canopy/light spheres matching the buildings' NW sun; buildings tint by
  BAG age in 3D; district area tints (rank 60, alpha .32); transit line
  labels + stop names; follow-mode is an explicit attach/detach toggle;
  rotation release schedules the label re-place (no stuck upside-down
  labels after a fast spin)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 18:00:27 +02:00
Admin
16a5f507bb map: transit lines/labels, districts, 3D signals+trees, label flip invariant
- transit routes draw as per-line colored strokes (stable ref-hash
  palette) on white casings, labeled "Tram 7"/"Metro 52"; stops get
  name labels (stations z13+, local z15+)
- districts layer: tiered admin boundaries (gemeente/wijk/buurt) and
  centroid name labels staged by zoom, muted admin purple
- upside-down labels fixed structurally: post-placement invariant
  re-places any glyph run that reads net-leftward (hairpin ramps fooled
  every pre-placement chord heuristic); vertical dead band ±4°
- overlay charger pins hold collision priority over base charging_station
  icons, which are suppressed while a charger overlay is active; pins
  reserve their bubble box so POI text places beside them
- per-icon zoom floors: overlay pins use kW tier floors (8/10/12) —
  micro floor 16.5 no longer hides them; 0.6 zoom grace; fail-open when
  the icon_zoom uniform is unset; oneway arrows from z15
- rail z-fighting: stroke merge drops duplicate quantized segments from
  forked ways (switches drew shared segments twice, shimmering in tilt)
- 3D mode: stoplights (pole + red/amber/green lights) and taller
  ellipsoid trees; live_reload names its override files

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 16:57:07 +02:00
Admin
1b0decc6c9 map: charger pin redesign, upright/billboard labels, 3D trees, exits
- Tesla-style droplet pins anchored at the tail tip (rotate around the
  exact site point in tilted views); red exclusively Tesla, amber DC,
  blue AC; Tesla pins show stall count, others peak kW
- in-pin text through the normal text renderer: billboard-anchored
  glyphs (anchor scales with the map, glyph size constant), exempt from
  label collision/repeat culling, no halo
- upright camera-delta labels: straightened labels (place names, POIs,
  brands, pin text) translate with the rotation gesture but stay
  horizontal — no more rotate-then-snap on regen
- per-icon zoom floors baked in vertex param4 + live icon_zoom uniform:
  stale deeper-bucket tiles never flash markers on zoom-out (param4 is
  lift-height only for non-icon shapes — icons stay on the ground)
- motorway exit labels (street_labels_points): carto-red name + ref
- 2D/3D mode: tilt gesture syncs app state (TiltChanged action), tilt
  release near-flat settles to exact 0, mode flip re-bakes tiles
  (extrusions appear/disappear without a zoom nudge)
- Simple 3D Buildings: building:part volumes with min_height bases;
  outlines containing parts flatten to footprints; famous buildings
  with tourism=attraction extrude instead of dying as attraction fills
- little 3D trees in tilt mode: crossed trunk quads + sphere-slice
  ball canopy (architecture-model proportions)
- searchdb/mbtiles support work: reach-based distance ranking, direct
  tile lookup + writer ordering

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 16:02:44 +02:00
Admin
1b1d908d2a map: exact camera-delta matrix — labels land where the regen lands
The snap: tilt does not commute with rotation. The placement maps world
points rotate-then-y-compress, so the true delta between the cached
camera (r0,t0) and now (r1,t1) is S(t1)*R(d)*S(1/t0) — a general 2x2
matrix, not the rotate+scale previously approximated. The shader takes
the full matrix; the pan shift pre-inverts through it so pans during
rotation land correctly. Between-frame tracking now converges on the
exact re-place result — no more rotate-snap in 2.5D.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 14:13:58 +02:00
Admin
f8273f52d1 map: GPU camera-delta for labels; brand text draws over the pins
- DrawRotatedText gains cam_cs/cam_sn/cam_tilt/cam_pivot uniforms: while
  the camera rotates or tilts between re-places, ALL placed glyphs spin
  and squash about the view pivot on the GPU — whole-quad transform, so
  orientation follows position for free; the CPU per-frame rotated copy
  is gone and the async re-place trues up with identity uniforms
- label plans carry a post-icon flag: in-pin digits' phase now also
  hosts the charger brand text, which was drawn before the symbol pass
  and hid BEHIND its own pin

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 14:10:03 +02:00
Admin
43ce32da7d map: tappable charger pins with info card; stale POI carpet hidden
- every baked charger pin records its normalized position + known
  attributes (name, operator, city, max_kw, evses, connectors) as a
  PinHit in the tile; taps hit-test a billboard rect through the same
  overlay camera markers use (rotation/tilt correct), emitting
  MapViewAction::PinTapped ahead of the generic tap
- examples/map: bottom-left info card — operator title, "250 kW max",
  bays/connectors, site name, city; hides on plain map tap. (The
  search-engine enrichment of this card is deferred by request)
- zooming out from icon level no longer splatters the stale POI carpet:
  a tile baked at z16+ hides its symbol pass below icon zoom while
  low-bucket pins keep drawing

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 14:05:10 +02:00
Admin
b497800d73 map: cached labels track the camera every frame — rotate first, regen after
Spinning in 2.5D detached labels from the map: the cached-plan reuse
was capped at 15 degrees and required equal tilt, so most rotation
frames drew stale untransformed placements until the next re-place.
Now ANY rotation/tilt delta (at equal zoom) redraws the cached glyphs
rigidly rotated about the pivot and y-compressed by the tilt ratio —
labels follow the camera best-effort and the async 120ms full re-place
trues them up, exactly the stale-tile philosophy of the dash shader.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:59:40 +02:00
Admin
c6c24cfbff map: charger pins are one icon composite — badge, bolt, kW digits
Rethink after the pin felt shaky: the kW text went through the label
placement machinery (map-space offsets, per-bucket relayout, rotation
rigid-redraw) while the badge was a zoom-constant billboard — parts
drifted, doubled and jumped. Now the whole pin is ONE composite in the
icon pass at a single anchor: tier-colored badge, white bolt with its
in-pin offset baked into the mesh, and the kW number as seven-segment
vector digit meshes composed at fixed screen-px offsets. Everything
billboards together; the label system is out of the loop (brand text
below the pin remains a normal label).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:54:21 +02:00
Admin
0fe26153b0 map: markers never clip the tilted ground, pin text stays upright rotating
- POI/pin symbols get tilt depth 90 (was 0.04): a marker is UI-like and
  must win against the ground plane and buildings under 3D — the pin
  was slicing into the map surface. Oneway arrows stay ground-hugging
- during rotation gestures the cached-label rigid-rotate now exempts
  pin-class glyph ranges: their billboard pins stay screen-aligned, so
  spinning the kW text with the map read as doubled, garbled digits

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:49:26 +02:00
Admin
478b711ce5 voice: pure-rust silero v5 vad + learned speech gate in window voice input
Ports the silero v5 16k branch to pure rust (minimal onnx-protobuf weight
extraction, hardcoded graph: stft-conv, 4x conv+relu, lstm cell, sigmoid
head), 512-sample chunks with 64-sample carried context. Validated against
onnxruntime to 2.3e-6 max diff (fixtures committed), ~425us/chunk release.
Model loads from repo-root silero_vad.onnx or MAKEPAD_VAD_MODEL. vad-test
bin for wav files. window_voice_input now gates packets on vad probability
(0.5 enter / 0.35 exit) and falls back to the rms gate when the model file
is missing — the log line says which gate is active.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:47:05 +02:00
Admin
f4147b4a45 map: kW inside the pin bubble, brand labels, pins above street names
The Tesla-pin refinement round:
- fast sites render the wide badge with the white bolt LEFT and the kW
  number INSIDE the bubble (white pin-class text); street AC gets the
  small badge; operator brand ("Tesla", "Fastned"…) reads under the
  pin from z13, tier-colored
- overlay paths accept ?fast / ?slow charger-power filters and the
  Layers panel splits EV chargers into fast and slow toggles
- draw order restructured: fills/casings/strokes → labels → icon pass →
  pin-class text, so pins sit OVER street names while their own kW text
  sits over the pins
- point labels for chargers/places/micro POIs straighten under
  rotation/3D like addresses do — pins are billboards, their text now
  matches

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:45:33 +02:00
Admin
21bdc6fd92 map: icon draw pass no longer hidden below z16
The pass-3 gate hid ALL baked symbols below ICON_MIN_ZOOM — charger
pins were in the buffers from z9 but never drawn. Floor now tracks the
lowest icon class (z8.75). Stale high-bucket tiles may briefly splash
their POI carpet on deep zoom-out until the rebuild lands — acceptable
against pins missing entirely.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:39:26 +02:00
Admin
675d4f1901 map: Tesla-style charger pins — big badges, white bolt, never collided
- charger sites render as 24px tier-colored pin badges (red/amber/blue)
  with a white bolt centered in the body; sized-mesh support added so
  one icon can break the 14px grid
- chargers take top icon-collision priority and their kW labels rank 8
  (above street names) at font 1.0 — a site stays trackable from z9
  road-trip zoom all the way in without popping out
- label extraction for chargers: >=50 kW label their power, Tesla
  operators label "Supercharger {kW}"

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:36:59 +02:00
Admin
14405e17fa map: kW-tiered EV chargers — Superchargers visible from road-trip zoom
Tesla-GPS framing: charging power is first-class map data.
- icon zoom floors by max_kw: ultra-fast (>=150 kW) from z9, fast DC
  (>=50) from z11, street AC posts z13 — the collision pass keeps
  density sane
- icon color by tier: red ultra-fast, amber fast, blue AC
- labels from z13: "Supercharger 250 kW" for Tesla operators (red),
  "{kw} kW" for other fast DC (amber); street AC stays unlabeled
- app layer toggles read app-tracked state (reading .active in the
  changed() pass raced widget state — same class as the panel bug),
  plus an overlays log line for future diagnosis

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:32:36 +02:00
Admin
bf14d772f9 map: capitals are cities, place text scales with population
- Amsterdam vanished zoomed out: shortbread tags it kind=capital
  (Haarlem state_capital) which fell into the everything-else z13.5+
  bucket. Kinds normalize now (capital/state_capital -> city)
- population rides along in the label key: city text steps 1.2/1.4/1.65
  at 150k/500k inhabitants so Amsterdam reads bigger than Purmerend,
  and a log-population score tiebreak places big cities first
- global label pass no longer gated at z13 (committed logic; the gate
  removal is what turned zoomed-out labels on at all)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 13:20:29 +02:00
Admin
d3a3591b37 map: settlement name labels — cities/towns/suburbs at zoomed-out scales
The shortbread place_labels layer was never admitted, so zooming out
lost ALL labels (streets are the only other source and they fade with
length). Now: place points classify by kind and follow osm-carto's
placenames.mss gates (city z4-15.5 at 1.55x text, town z7+, village/
suburb z11.5+, quarter/hamlet/neighbourhood z13.5+), outranking every
other label source. Nature-reserve area labels also escape the z15
area-label gate — their tiles exist from z6 and the reserves are huge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 12:39:20 +02:00
Admin
d6a933ea5c map: nature labels + building-age and population choropleths
- natura2000/wetlands areas label their Dutch source names (naam_n2k /
  naam) in green at their centroids
- Building age: BAG bouwjaar choropleth over the building fills (rust =
  pre-1800 through blue = 2010s, gray = unknown), z13-14
- Population: CBS vierkant cells (vk500/vk100) yellow-to-deep-blue by
  aantal_inwoners at 45% opacity; empty cells stay transparent
- two more checkboxes in the Layers panel

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 12:28:37 +02:00
Admin
ea201e40ad widgets: set_visible on a never-drawn view escalates to full redraw
A visible:false view that has never drawn has an empty area, so its own
redraw was a no-op — set_visible(true) only took effect on the next
unrelated full repaint, the classic "appears after hot reload" bug (hit
by the map app's layers panel; same class as the elevation graph fix).
Also: overlay_chargers_probe ignored-test builds a real Amsterdam tile
with the chargers overlay (450 icons verified).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 12:25:23 +02:00
Admin
9ca167c8b0 map: geodata overlay layers render — chargers, transit, nature, districts
Phase 1 of the layers.md track:
- MapView grows overlay_mbtiles_paths (semicolon list) + set_overlay_paths
  (stale-keeping rebuild). The loader opens each overlay mbtiles, clamps
  to its metadata zoom range, and fetches ancestor tiles with a
  quadrant transform when the overlay's maxzoom is below the requested
  tile (fills/strokes ride the existing clippers; points bounds-filter)
- overlay MVT layers merge into the normal tile build, styled by layer
  name: chargers = blue bolt icons from z12, transit stops dots z13 +
  route shapes above the road net, natura2000/wetlands translucent
  green tint (fill alpha now flows through fill groups) + outline,
  gemeente/wijk/buurt purple dashed boundaries by admin level
- examples/map: Layers button + checkbox panel (EV chargers, Transit,
  Nature areas, Districts; raster + rain marked as next phase)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 12:12:27 +02:00
Admin
a2e1f77326 map: footbridge deck uses pedestrian surface color; tracks join gray paths
bridge_area_fill is the gray bridge-structure color — the deck between
the rims needs the pedestrian street surface (white light / dark slab
dark). Track dots drop carto brown for the light-gray path family.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 10:45:47 +02:00
Admin
8605804807 map: footbridge rim/deck in correct passes, theme-derived edge colors
- the renderer paints all casings before all centers; the bridge rim
  was a center-pass line and covered the deck (dark-filled bridges).
  Rim is now the casing, the light deck the center, and the faint dots
  ride a companion style one sort-rank above
- outline colors (bridge rim, platform edge, pedestrian-area edge) now
  derive from theme fills via contrast_edge() — dark fills get a
  lighter rim, light fills a darker one — so dark mode flips them
  automatically instead of baking light-theme grays

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 10:42:00 +02:00
Admin
47bad601f7 map: footbridge three-pass rendering — dark rim, white deck, dots on top
The dotted centerline continues across the span (it does on osm.org,
just faint); the rim is a companion stroke job keyed off the deck color
so the two-pass StrokeStyle stays untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 10:34:35 +02:00
Admin
236e4de5d1 map: footbridges draw as white deck with dark rim, dots stop on the span
Matches osm.org's little outlined bridge box: dark gray casing, near-
white solid deck, no dotted centerline across the water.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 10:33:15 +02:00
Admin
caeb26f4b4 map: pedestrian-area edge line, slimmer footbridge decks
- road-polygon fills (pedestrian squares, wide walking-path areas) get
  carto's thin gray constant-px edge from z15
- footbridge deck narrowed (2.4x the dot width, was 3.4x) — the rope
  bridge at Artis read twice as fat as osm.org

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 10:30:44 +02:00
Admin
1a0cda9b11 map: zoo animal labels from attraction nodes, gray paths, footbridge decks
- the animal enclosure WAYS turned out absent from the detail archive
  (converter mystery, ids fine, no filter — parked), but every animal
  also exists as an attraction=animal NODE: those now flow through the
  micro_pois point path as label-only features (culture brown, no icon).
  Verified live at Artis: Zwarte slingeraap, Roze pelikaan, Rode vari,
  Goudwanggibbon, Aziatische olifant all place like osm.org
- walking paths are light gray dotted everywhere (user preference over
  carto salmon); restricted-access stays gray too
- footway bridges draw a small white deck under the dots — the little
  outline box carto shows at water crossings
- diagnostic probes for the Artis tiles kept as ignored tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 10:25:11 +02:00
Admin
2f114d5f9d map: area labels can finally compete — zoo animal names place now
- root cause found by driving a real Artis tile through the full build
  in a test: admission, extraction and compaction were all fine (42/42
  enclosures labeled in the tile buffers) — the labels died at placement
  scoring. Point-anchored area labels have a ~zero-length path, and the
  score formula's path-length term let every street name outscore them
  in dense viewports. They now get a 420px length credit and green_area
  ranks 4 (above pois, below streets)
- pedestrian streets/paths render carto-style: near-white core with a
  gray casing (both palettes) instead of falling through to defaults
- trees 2x: canopy disc 5.4 with a 1.7 dark core, matching osm.org
  proportions

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 09:53:32 +02:00
Admin
17ae14b723 map: OSM layer-tag collision fix, barriers, two-tone trees, zoo polish
- CRITICAL: OSM's own layer=-1/1 stacking tag collided with our "layer"
  source-layer key (or_insert kept the OSM value) — any layer-tagged
  feature was unrecognizable downstream: the Artis tourism=zoo way
  (layer=-1) never got its boundary, and detail admission missed such
  features entirely. Source-layer name now owns the key; OSM's value
  moves to "osm_layer"
- barrier lines from the detail archive: walls/retaining walls dark
  thin, fences lighter, hedges green (the Artis perimeter wall)
- trees are now carto's light canopy disc with a dark center dot
- attraction rings force-close (tile clipping opened them — Aziatische
  olifant label was dropped)
- restricted-access paths (private/no/customers) gray out instead of
  public salmon inside zoos and private grounds
- micro street furniture (trees, benches, bins, dots) collides at ~45%
  radius so a tree row no longer knocks out its benches

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 09:44:50 +02:00
Admin
f3087e1fec map: pattern fills anchored to the map, staggered stipple + tree circles
- pattern coords now come from the vertex stage in tile-local space
  scaled to view px (v_world was post-camera SCREEN space — the pattern
  sat still while the map panned under it)
- courtyard gardens: smaller dots on an odd/even staggered grid;
  playgrounds keep the hatch; woods/forests/cemeteries get staggered
  OPEN circles (tree rings) instead of sharing the garden dots

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 09:38:56 +02:00
Admin
89595fcb3c map: procedural pattern fills — garden/cemetery stipple, playground hatch
carto textures its fills; ours were flat. Fill groups now carry a
pattern shape (30 = dot stipple for leisure=garden and landuse=cemetery,
31 = diagonal hatch for playgrounds) and the map shader darkens the
fill color procedurally in screen-stable world space — no textures,
pans/rotates with the map.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 09:34:50 +02:00
Admin
c5dccb78e5 map: Artis zoo pass — enclosure labels, sand fills, zoo boundary, cemetery green
- named zoo enclosures/attractions (attraction=animal etc.) from the
  detail archive label at their centroid in carto's culture brown; area
  labels no longer require a fill color, so a named enclosure on plain
  grass still gets its name
- natural=sand/beach/shingle fill carto's pale tan (theme rule both
  palettes); sand-floored enclosures rank above the zoo's grass
- tourism=zoo/theme_park perimeter draws a muted purple constant-px
  boundary line
- landuse=cemetery gets its proper green (was generic gray — Joodse
  begraafplaats Zeeburg)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 09:32:38 +02:00
Admin
d7704ea424 map: angle-gated overzoom smoothing, no dark casing on footpath bridges
- Chaikin corner-cutting now requires a GENTLE turn (< ~30 degrees) in
  addition to short adjacent segments: densely sampled canal-belt quay
  roads still carry sharp corners at bridge junctions between short
  segments, and cutting those curved the road through the corner
  buildings and off the bridges
- the "black dashed fragments" at every canal crossing were the dark
  bridge casing applied to thin footway/steps bridges (a sub-px 0x4a4a4a
  edge under 0.9px salmon dots); carto only cases real roads — thin
  uncased paths keep their plain dotted style on bridges
- tile.rs: keep an ignored bridge_probe diagnostic test (dumps line
  features near a point in a real tile with tags)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 09:28:07 +02:00
Admin
c7a739aacd map: adaptive Chaikin (fix roads curving through buildings), square force-close
- overzoom smoothing regression: uniform Chaikin also cut real 90-degree
  street corners, rounding roads through building blocks and detaching
  them from their bridges. Now only vertices with BOTH adjacent segments
  under ~10 screen px get cut (dense tile-quantized curves); sparse
  vertices are genuine corners and stay sharp
- pedestrian squares: area=yes semantically means polygon — close the
  ring unconditionally (tile clipping can leave LineString rings open)
- examples/map: headless UI smoke test (makepad_test) + local data
  symlink so the in-process hub run finds local/maps

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 09:24:03 +02:00
Admin
0c47be94ef map: implicit ring closure for osm_lines areas, icon collision priority
- Hella Haasseplein root cause: pedestrian squares in osm_lines arrive
  as LineStrings, so `closed` was never set and the area admission
  skipped them — detect implicit closure (first==last) and mark the
  ring closed for the fill pass
- icon collision: doors and generic dots now yield to real symbols
  (the recycling icon was losing to the building entrance beside it);
  entrances gate at z18 like carto
- tools: tagprobe <pbf> <name> — dump every OSM element matching a
  name, for answering "how is this actually tagged" without overpass

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 23:44:12 +02:00
Admin
d52731c769 map: polygon-anchored POIs, pedestrian squares, top-to-bottom vertical labels
- polygon POIs (parking lots, garages, shops/offices mapped on their
  building) now icon at the ring centroid like carto — this is what
  makes the parking P's appear; underground garages skip the centroid
  (carto shows their entrance instead: amenity=parking_entrance now
  draws the P) and named parkings get a blue name label
- pedestrian squares (Hella Haasseplein): admitted from the detail
  archive into the street-area fill pipeline — including closed
  highway=pedestrian area=yes ways that live in osm_lines, since
  highway ways don't classify as polygons at conversion — and named
  squares/greens both label at their centroid
- vertical street labels read TOP-TO-BOTTOM (osm.org convention, user
  preference), never bottom-to-top; upside-down protection stays via
  the text-span chord

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 23:40:25 +02:00
Admin
e4054b72be map: station parity batch — platforms, POI icons, label robustness
- platform polygons (railway/public_transport=platform from the detail
  archive) as gray slabs with a constant-px edge, 2D and 3D, z15.5+
- new icons: traffic signals, parking P, EV charger, plus a generic
  colored dot for named POIs with no dedicated symbol (offices like
  TomTom get dot + name label from the detail layer); per-icon zoom
  gates (entrances z17.5, signals/chargers/dots z16.5, parking z15.5)
- rail: sidings/yards (service=*) fade lighter and thinner like carto's
  dead-end tracks; railway landuse gets carto's pale purple tint
- small green patches (verges, lawns, scrub) restored at street zoom
  from the detail archive — z14 base generalization drops them
- overzoom Chaikin smoothing on stroke geometry: ovals and tram loops
  stop reading as polygons at 8-16x magnification; roundabout/circular
  junctions get oneway arrows without an explicit oneway tag
- labels: reading direction decided by the chord across the whole text
  span (mid-point tangent flipped labels 180 on zigzag segments), and
  small rotation deltas reuse the cached placement rigidly rotated
  about the pivot — no more per-frame wiggle during heading-up nav

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 23:30:35 +02:00
Admin
0ce4f3c669 map: entrance/information icons, rail stripe proportions, flat-city elevation
- entrance door icons (entrance=*, railway=subway_entrance) from the
  all-tag detail layer at door-level zoom (z17.5+); tourism=information
  (i) icon in both the shortbread poi and detail micro-poi paths
- rail sleeper retune vs OSM reference: thinner band (casing 2.4, core
  1.2) with longer airy stripes dash(8,8); sleeper look starts z15 so
  zoomed-out station corridors stay a calm thin line; trams only darken
  toward near-black at z16+
- elevation: median spike removal + ~220m smoothing + 2.5m climb
  hysteresis — SRTM rooftop noise no longer fakes 50m of ascent across
  pancake-flat Amsterdam (test asserts single-digit climb)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 23:17:24 +02:00
Admin
e66b64ddeb map: Europe searchdb, route elevation profile, rail/tram/water-label styling
- libs/map_nav searchdb: disk-backed all-of-Europe search index (120M docs,
  8GB, ~30ms cold queries via pread; external-sort builder, cell-sharded
  postings, rank heads, digit-token address filtering with street fallback);
  nav-build --searchdb two-pass pbf streaming; nav-probe dbsearch; app
  worker prefers local/maps/europe.searchdb over the places index
- examples/map elevation: dem.rs fetches AWS skadi SRTM tiles on demand
  (cached local/maps/dem/, offline after), median+220m smoothing and 2.5m
  climb hysteresis so radar rooftop noise doesn't fake ascent in flat
  cities; elev_graph.rs DrawVector profile panel above the route bar
- rail styling: heavy rail draws carto sleeper look (theme casing + white
  stripe dash) z14+; trams/metro stay a solid near-black line (shortbread
  tags trams rail=true — kind decides now); platform/station/dead railway
  values no longer draw as track linework
- water name labels: water_polygons_labels/water_lines_labels admitted
  through extraction, source ranks, and LABEL_CLASS_WATER colors; label
  layers excluded from stroke styling (double-drew as rivers)
- label fix: near-vertical reading-direction tie-break was inverted;
  vertical street names read bottom-to-top under any camera rotation
- cleanness: oneway arrows lighter+sparser, tree discs smaller

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 23:13:47 +02:00
Admin
9f067b5623 map: continent-wide place search with Google-style tiered ranking
score_search_hit: settlements are near-immune to distance ("brussels"
from Amsterdam means Bruxelles, not the closest Brusselsestraat),
POIs/streets keep strong local bias, and a number token signals
address intent. nav-build --places-only scans a pbf for settlement
nodes into a compact index (Europe: 1.31M places, 67MB, 60s); the app
merges it with the regional full index, deduping same-name near hits.

Route overlay decimation now measures against the last drawn point,
bounding the error at ~1.5px — pairwise skipping compounded and
visibly reshaped the route when zoomed out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 22:16:44 +02:00
Admin
cda49d8c9f map: readable search results, second-search fix, double-click routing
Search results render as two-line cards (name, then category · address
· distance) instead of one cramped line. Picking a result clears the
input — the next query no longer appends to the old text, which broke
every follow-up search. The nav worker restarts on demand if a script
hot-reload wiped the channel state.

Long-press never synthesizes from a held mouse button on desktop, so
double-click now triggers the same action (set position, then route
here); hints updated accordingly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 22:09:57 +02:00
Admin
ff309a5f1b map: true 2D/3D toggle — tiles rebake when tilt crosses zero
Flat mode returns to the classic building style (base fills +
outlines) instead of a top-down view of the extruded roofs: crossing
between flat and tilted bumps the style epoch and sentinels every
resident tile's bucket, so the normal stale-bucket restyle path
rebuilds them while the previous geometry stays visible and
cross-fades.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 21:57:32 +02:00
Admin
ed90441a5f map: tilt-mode hardware depth, camera drag gesture, z-fight fixes
Tilted rendering now resolves occlusion in the depth buffer: map
geometry lives in a negative depth domain (UI/labels/overlay drawn
later always win by call order), view-ground y dominates so walls and
roofs occlude anything behind them under any rotation, and a baked
sort-rank micro-depth in param5 (4 depth quanta per rank step) orders
overlapping layers at equal ground without quantization flicker.
Bridges bias their micro-depth like their sort rank, the dark bridge
edge sits one step under the road fill (exact ties noise-win — black
bridges), and nested greens get distinct sub-ranks (park < garden <
grass < pitch) so parks stop shimmering. Flat mode stays on the
classic call-order path, byte-identical.

Camera ergonomics: right-mouse-drag (or Option-drag) rotates the
camera horizontally and tilts vertically, emitting ViewportChanged on
release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 21:51:02 +02:00
Admin
adbdbeaa2d map: 2.5D mode — tilt camera and extruded shaded buildings
Axonometric tilt as camera uniforms: screen y compresses about the
view center and building vertices carry their height in meters in
param4, lifted toward screen-top by height * px_per_m * sin(tilt) —
tilt animates freely with zero tile rebuilds. All CPU projections
(gestures, zoom anchor, screen<->lonlat, tile-selection AABB, label
placement + cache, overlay) undo the tilt alongside the rotation.

In 3D mode building footprints come from the all-tag detail archive
(real height / building:levels tags, 8m default) replacing the base
building fills: per-edge flat-shaded wall quads (NW light) painted
north-first as the painter's occlusion approximation, then the lifted
roof. The example app gets a 3D toggle with an eased tilt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 21:25:21 +02:00