- 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>
- 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>
- 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>
LlamaSession gains append_image_embeddings: precomputed vision embeddings
prefill through a second Embeddings-input graph spec sharing the same
cache tensors (SessionGraphParams grows an embeddings_input discriminant).
HybridDecodeBatchLayout gains an optional pre-expanded rope_positions
override, threaded to encode_rope_positions — cache indices and attention
masks stay linear while image tokens get qwen-vl 2D positions
[pos0, pos0+y, pos0+x, 0] and the span advances rope position by
max(w, h). Text after an image continues from the shifted position; pure
text paths are byte-identical to before (verified via llama-generate).
vlm-probe runs the whole thing: ppm -> vision tower -> chatml with
vision_start/end -> greedy. Output is token-for-token identical to
llama-mtmd-cli --temp 0 on both test images (radar scene description and
'A red circle.'). 229-token mixed prefill 0.98s, generation 27.9 tok/s
on the 9B UD-Q4_K_XL.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New vision module: mmproj GGUF load (reuses the arch-agnostic loader),
exact-port preprocessing (calc_size_preserved_ratio, f64 bilinear resize to
match the reference binary's double promotion, block-major patch unfold),
and the 27-block ViT graph: patchify as two matmuls vs the flattened conv
weights, interpolated learned pos-embd (gpu bilinear+antialias, gathered to
block order), 2D vision rope, full bidirectional flash attention (f16 k/v,
f32 prec), layernorm composed as norm-mul-add, and the qwen3vl_merger
2-layer MLP into the LLM's 4096-dim space.
vlm-vision-probe validates against clip.cpp dumps: preproc bit-exact on
aligned images (1e-7), embeddings rms 3e-4..9e-4 / cosine 0.99999+ on all
three test images — inside the oracle's own flash-vs-composed spread
(rms 8.9e-4). 64-token encode 38ms, 192-token 103ms after graph compile.
Also fixes a stale DeltaNetRecurrentBlockSpec test initializer that broke
cargo test compilation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
- 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>
- 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>
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>
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>
- 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>
New makepad-converse crate: SpeechOutput/Playback moved out of gamemaker
(mix_into for custom audio callbacks, install_audio_output convenience);
TranscriptFilter trait + PassthroughFilter + FilterWorker thread (filters
built on the worker via factory since LlamaSession is not Send);
ConversePipeline wiring filter -> makepad_ai agent backend -> speech with a
ConverseAction stream, llm leg pluggable (claude-code / acp /
openai-compatible base_url for local servers). QwenFilter behind the
local-llm feature: chatml prompt, non-thinking prefill, greedy, SEND:/SKIP:
line protocol, fail-open parse; filter-repl bin for interactive testing.
Gamemaker's speech leg now uses the crate; its agent plumbing stays local.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
Grid width for the non-flat unary path was ne01 while the kernel decomposes
tgpig.x into (ne0-chunk, row) — rows past ntg were silently dropped, masked
below the 32768-element flat-path threshold; silu on [8192, n] crossed it at
prefill batch 4 and corrupted qwen35 batched prefill. Grid is now
ne01 * ceil(ne0/nth). Adds metal unary/gated-delta-net/ssm_conv regression
tests, the llama-batch-probe bisect harness, prefill batch default 32, and
keeps the graph cache until a reserve-retry actually needs eviction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
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>
- 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>
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>
- 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>
Relations reference ways randomly across the extract; the 128-group
WayStore LRU crawled Europe's pass 4 at ~260 relations/s (5+ hours).
Now: FlatWayStore decodes the whole relation-member way store into RAM
next to FlatNodeStore, assembler workers resolve and prepare features
(new prepare_point completes the set), a single writer owns the spool,
and the ordered consumer only parses members/tags. NH pass 4 3.9s ->
1.3s, per-layer feature counts identical.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
- 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>
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>
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>
Projected grid values are <= 2^26 at zoom 14, so i32 is exact; decode
hard-errors on out-of-range rather than ever truncating (no swimming
roads). NH output identical feature counts.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Europe's ways arrive in creation order, i.e. spatially random: any node
cache that fits in a fraction of the store loses. The store is only
13.8GB compressed, so FlatNodeStore decodes ALL of it once (parallel,
~a minute for Europe) and resolver workers share it lock-free via Arc —
no cache, no eviction, no zlib on the hot path. NH pass 3: 5.6s -> 3.5s;
feature counts unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- NodeStore eviction was a min_by_key scan of the whole cache per miss;
with the Europe-sized cache that scan became the bottleneck (1.2k
ways/s). FIFO queue eviction is O(1) amortized
- way resolution now fans out over a resolver worker pool (each with
its own NodeStore handle and cache slice); geometry is localized on
the workers via prepare_lines/prepare_polygons and a single writer
thread owns the spool, so the on-disk format is untouched. The
id-ordered relation-way store stays on the ordered consumer thread
- Noord-Holland: pass 3 32.6s -> 5.6s, full conversion 25.7s; per-layer
feature counts identical (byte diff is record interleave order only)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
- 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>
Two fixes to the detail converter that spent 10+ hours on Europe:
- visit_pbf: ordered parallel decode — blob reads stay serial, the
zlib+protobuf decode fans out over a worker pool, and the callback
runs in exact file order on the calling thread, so id-ordered store
builders need no changes
- NodeStore group cache: 256 groups (128MB) thrashed on Europe-scale
way resolution (~115us/way of cache-miss zlib re-decode, ~8.6k
ways/s); now MAKEPAD_NODE_CACHE_MIB (default 8GB), way resolution
~370k/s
Noord-Holland: 61s end-to-end, output byte-identical to the slow
converter (7547 tiles, same bytes).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
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>
- 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>
- 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>
- 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>
- 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>
- 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>
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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>