From 484dfbd1e0da7e31fc7a5dcc5e1d8d7952e1ab23 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 20 May 2026 16:34:14 +0000 Subject: [PATCH] landclass: filter antimeridian-wrapping PAD-US records 47 PAD-US units (Aleutian/Bering-Sea BOEM marine features, all is_valid=False) are stored as antimeridian-wrapping polygons whose bbox spans ~360 deg of longitude. Their invalid planar geometry forms latitude bands that ST_Intersects false-matches for non-US points (e.g. London/Germany at ~51N matched "Rat Islands" ogc_fid 3974). Fix: add `AND (ST_XMax(geom) - ST_XMin(geom)) < 60` to the lookup_landclass SELECT. No DB writes; two cheap ST_XMax/XMin evals on the already spatial-index-filtered result set. Verified live: total 651088 rows, filtered 651041 (exactly 47 excluded); Yosemite/Grand Canyon retained, London/Germany now empty. Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/landclass.py | 3 +++ lib/landclass_test.py | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 lib/landclass_test.py diff --git a/lib/landclass.py b/lib/landclass.py index f581994..7760cce 100644 --- a/lib/landclass.py +++ b/lib/landclass.py @@ -214,6 +214,9 @@ def lookup_landclass(lat, lon): des_tp, gap_sts, pub_access, category, gis_acres, state_nm FROM pad_units WHERE ST_Intersects(geom, ST_SetSRID(ST_MakePoint(%s, %s), 4326)) + -- exclude antimeridian-wrapping polygons: 47 BOEM marine artifacts + -- span ~360 deg longitude and false-match non-US points at their lat band + AND (ST_XMax(geom) - ST_XMin(geom)) < 60 ORDER BY gis_acres ASC LIMIT 10""", (lon, lat) diff --git a/lib/landclass_test.py b/lib/landclass_test.py new file mode 100644 index 0000000..cba8ca7 --- /dev/null +++ b/lib/landclass_test.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +"""Tests for lib.landclass PAD-US lookups. + +Live-PostgreSQL regression test using the skip-if-not-available pattern +(matching test_real_timezone_db in reverse_bundle_test.py). Plain asserts + +a __main__ runner, matching the rest of lib/*_test.py. + +Note: lookup_landclass swallows DB errors and returns [] (it never raises), +so PG availability is probed via a known US point (Boise) rather than by +catching an exception. +""" + +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from lib import landclass + + +def test_landclass_no_antimeridian_false_match(): + # Yosemite doubles as the liveness probe: a point on real US public land. + # (lookup_landclass returns [] when PG is unreachable AND when the point is + # off public land, so the probe must be a known-public-land point — e.g. + # downtown Boise is private and would yield [] even with PG up.) + yosemite = landclass.lookup_landclass(37.85, -119.55) + if not yosemite: + print(" SKIP: live PG not available (Yosemite returned no rows)") + return + # Filter must NOT drop legitimate (non-wrapping) US units. + assert len(yosemite) >= 1, f"Yosemite should match >=1 PAD-US unit, got {len(yosemite)}" + + # London (51.5074 N) previously false-matched the antimeridian-wrapping + # 'Rat Islands' record (ogc_fid 3974, ~360 deg lon span). The < 60 deg + # filter must now drop it -> empty result. + london = landclass.lookup_landclass(51.5074, -0.1278) + assert london == [], f"London should match no PAD-US unit, got {[r.get('unit_name') for r in london]}" + print(" PASS: antimeridian filter drops London false-match, keeps Yosemite coverage") + + +if __name__ == '__main__': + print("Running landclass tests...") + test_landclass_no_antimeridian_false_match() + print("All tests passed.")