Skip to content

fix: avoid division by zero for flat faces on PostgreSQL 18 - #212

Merged
jravani merged 3 commits into
mainfrom
fix/surface-dimensions-pg18
Oct 22, 2026
Merged

jravani merged 3 commits into
mainfrom
fix/surface-dimensions-pg18

Conversation

@jravani

@jravani jravani commented Oct 22, 2026

Copy link
Copy Markdown
Member

On PostgreSQL 18, feature extraction fails for every batch with division by zero in script 03, so no building is extracted. PostgreSQL 16 and 17 are not affected; environment/http/docker-compose.yml runs PostGIS 16.

Cause

surface_dimensions divides the face normal by h = sqrt(nx^2 + ny^2) and drops near-horizontal faces with WHERE ABS(nz) <= 0.985. PostgreSQL 16 and 17 apply the filter first. PostgreSQL 18 computes the axes of a flat face (h = 0) anyway and raises the error. Every batch holds a flat roof or ground surface.

Change

  • h is NULLIF(sqrt(nx * nx + ny * ny), 0). Flat faces still get NULL in both extents; every other face is unchanged.
  • CHANGELOG.md: Fixes entry. A database created earlier gets the fixed function on its next -reset-city2tabula, since functions are installed by the setup step.

Tests

  • surface_dimensions on a flat 1 x 1 m face and a vertical 2 x 3 m wall:

    PostgreSQL before after
    16.4 (postgis/postgis:16-3.4) (,) (2,3) (,) (2,3)
    17.0 (postgis/postgis:17-3.4) (,) (2,3) (,) (2,3)
    18.6 (PostGIS 3.6.4) ERROR: division by zero (,) (2,3)
  • On PostgreSQL 18.6, -extract-features on 27,420 Bavarian and NRW buildings failed in all 28 batches before and extracts all of them after.

  • go test -tags integration ./internal/process/ passes. The integration container is PostgreSQL 17, so no automated test fails before this change.

surface_dimensions divides the face normal by h = sqrt(nx^2 + ny^2) to
build its in-plane axes, and filters out near-horizontal faces with
WHERE ABS(nz) <= 0.985. PostgreSQL 16 and 17 apply that filter first.
PostgreSQL 18 computes the axes of a flat face (h = 0) anyway and
raises division by zero, which fails script 03 for every batch that
holds a flat roof or ground surface, so no building is extracted.

h is now NULLIF(..., 0). Flat faces still get NULL in both extents and
every other face is unchanged: a flat face gives (,) and a 2 x 3 m wall
(2,3) on PostgreSQL 16.4, 17.0 and 18.6 alike.
@codecov

codecov Bot commented Oct 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@jravani
jravani merged commit 52b48a1 into main Oct 22, 2026
7 checks passed
@jravani
jravani deleted the fix/surface-dimensions-pg18 branch October 22, 2026 16:20
@jravani jravani mentioned this pull request Oct 23, 2026
@jravani jravani added this to the v0.12.0 milestone Oct 23, 2026
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.

1 participant