Code repo: GSA/datagov-harvester
Problem
Zero-area WKT geometries are silently dropped, so the record's translated_spatial is NULL and it disappears from spatial search.
translate_wkt_to_geojson() (general_utils.py:1142) parses the WKT fine, then validate_geojson() (:968) rejects it with less_three_unique_nodes / exterior_not_ccw.
This hits 83 of 802 datasets (10.3%) in the live OpenTopography feed (https://portal.opentopography.org/csw/catalog30.json). That source rounds coordinates to 2 decimal places, which collapses small-extent surveys into degenerate polygons:
POLYGON((-115.63 32.49, -115.63 32.49, -115.63 32.49, -115.63 32.49, -115.63 32.49))
POLYGON((-87.88 43.34, -87.88 43.35, -87.88 43.35, -87.88 43.34, -87.88 43.34))
Why it's a bug, not bad data
munge_spatial() (:1161) already handles exactly this for v1.1 comma-separated bboxes — duplicate corners collapse to a Point, 3-unique-corner boxes to a LineString. The WKT path skips that logic entirely:
| Same geometry, different notation |
Result |
-115.63,32.49,-115.63,32.49 (v1.1 bbox) |
✅ Point |
-87.88,43.34,-87.88,43.35 (v1.1 bbox) |
✅ LineString |
POINT(-115.63 32.49) (WKT) |
✅ Point |
POLYGON((-115.63 32.49, …×5)) (WKT) |
❌ NULL |
Suggested fix
In translate_wkt_to_geojson, after shapely.wkt.loads + force_2d, reduce degenerate geometries before returning: dedupe the ring and emit Point for 1 unique vertex, LineString for 2. shapely already exposes geom.is_empty, geom.area, and geom.exterior.coords.
Acceptance criteria
Context
Found in #6038 (SPIKE-3). Blocks #6197.
Code repo: GSA/datagov-harvester
Problem
Zero-area WKT geometries are silently dropped, so the record's
translated_spatialisNULLand it disappears from spatial search.translate_wkt_to_geojson()(general_utils.py:1142) parses the WKT fine, thenvalidate_geojson()(:968) rejects it withless_three_unique_nodes/exterior_not_ccw.This hits 83 of 802 datasets (10.3%) in the live OpenTopography feed (
https://portal.opentopography.org/csw/catalog30.json). That source rounds coordinates to 2 decimal places, which collapses small-extent surveys into degenerate polygons:Why it's a bug, not bad data
munge_spatial()(:1161) already handles exactly this for v1.1 comma-separated bboxes — duplicate corners collapse to aPoint, 3-unique-corner boxes to aLineString. The WKT path skips that logic entirely:-115.63,32.49,-115.63,32.49(v1.1 bbox)Point-87.88,43.34,-87.88,43.35(v1.1 bbox)LineStringPOINT(-115.63 32.49)(WKT)PointPOLYGON((-115.63 32.49, …×5))(WKT)NULLSuggested fix
In
translate_wkt_to_geojson, aftershapely.wkt.loads+force_2d, reduce degenerate geometries before returning: dedupe the ring and emitPointfor 1 unique vertex,LineStringfor 2.shapelyalready exposesgeom.is_empty,geom.area, andgeom.exterior.coords.Acceptance criteria
POLYGONwith 1 unique vertex translates to a GeoJSONPointPOLYGONwith 2 unique vertices translates to a GeoJSONLineStringPOINT EMPTY/ malformed WKT still returns""(existing tests keep passing)translated_spatialContext
Found in #6038 (SPIKE-3). Blocks #6197.