Skip to content

fix(tiles): height must be double precision, not numeric - #74

Merged
yorickdewid merged 1 commit into
mainfrom
fix/tile-height-double-precision
Aug 6, 2026
Merged

fix(tiles): height must be double precision, not numeric#74
yorickdewid merged 1 commit into
mainfrom
fix/tile-height-double-precision

Conversation

@yorickdewid

Copy link
Copy Markdown
Contributor

Follow-up to #73, which was merged before this landed.

ST_AsMVT has no MVT value type for numeric and encodes it as a string. Caught by decoding a dynamic tile against its static counterpart at the same z/x/y:

static : "height": 3.25
dynamic: "height": "3.25"

config/layers/incident.json and the four QuickScan facade configs all feed ["get","height"] straight into fill-extrusion-height, which requires a number. Every one of those layers would have rendered flat once the frontends cut over.

building_tiles has always declared height double precision, which is why the buildings source never hit this.

State

Already applied to prod — both tables were dropped and recreated from the corrected files, then repopulated via f/fundermaps/data/refresh_layer_tiles. This PR lands the same state in git so the two don't drift.

 table_name        | column_name | data_type
-------------------+-------------+------------------
 building_tiles    | height      | double precision
 facade_scan_tiles | height      | double precision
 incident_tiles    | height      | double precision

Verification after the fix

Decoded dynamic vs static at facade_scan/14/8365/5444 — identical property set and identical values:

{"external_id":"NL.IMBAG.PAND.1695100000000374","neighborhood_id":"BU16950001",
 "district_id":"WK169500","municipality_id":"GM1695","height":3.25,
 "skewed_parallel_facade":"big","skewed_perpendicular_facade":"small",
 "facade_type":"mediocre","risk":"e"}

Also swept 60 real static tiles across all five sources and compared feature counts. Per-tile counts differ where data clusters on a tile edge (static carries tippecanoe's wider buffer of features that fall outside the tile). To confirm nothing is actually lost, I compared the set of external_ids across a 4×4 z12 block:

static : 487 distinct
dynamic: 487 distinct
in static but not dynamic: 0
in dynamic but not static: 0

So every feature appears in the tile that contains it; the count gaps are buffer duplication only, and match how building_tiles and building_cluster_tiles have behaved in production since July.

🤖 Generated with Claude Code

ST_AsMVT has no MVT value type for numeric and encodes it as a STRING.
Caught by decoding a dynamic tile against its static counterpart:

  static : "height": 3.25
  dynamic: "height": "3.25"

Both incident.json and the four QuickScan layer configs feed
["get","height"] straight into fill-extrusion-height, which needs a
number — every one of those layers would have rendered flat.

building_tiles has always declared height as double precision, which is
why the buildings source never hit this.

Already applied to prod (the tables were recreated from the corrected
files and repopulated); this lands the same state in git. After the fix
the facade_scan tile is property-for-property and value-for-value
identical to the static one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@yorickdewid
yorickdewid merged commit 3d76339 into main Aug 6, 2026
1 check passed
@yorickdewid
yorickdewid deleted the fix/tile-height-double-precision branch August 6, 2026 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants