explore(ogc): aggregate raw feature pages before shaping - #377
explore(ogc): aggregate raw feature pages before shaping#377thodson-usgs wants to merge 5 commits into
Conversation
Every OGC getter returned a ``GeoDataFrame`` when its filter matched at least one row and a plain ``DataFrame`` when it matched none. ``_empty_feature_frame`` exists to guarantee an empty page keeps the concrete class -- its docstring calls itself "the single home for this empty-page contract", because a later ``pd.concat([empty, geo_page])`` would otherwise strip geometry and CRS. But ``_deal_with_empty`` runs last, on every getter, 160 lines away in the same file, and built a fresh ``pd.DataFrame(columns=...)`` -- discarding the guarantee it was handed. So ``.geometry``, ``.to_crs()``, ``.plot()`` and ``pd.concat`` across a loop of per-site calls broke only on the empty result: the case least likely to be covered by a caller's tests, and invisible from ``df.columns`` because the ``geometry`` column is still listed. Reindexing the frame we were given applies the schema's columns while keeping the class -- and the ``geometry`` dtype with it. The plain-pandas path is unchanged: ``pd.DataFrame().reindex(columns=[...])`` is still a ``pd.DataFrame``. The regression test uses a ``DataFrame`` subclass rather than real geopandas, so the invariant is checked even where geopandas is absent (it is not in the ``[test]`` extra). Verified to fail against the old line and pass against the new one. 788 passed, mypy --strict clean, all hooks pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BTaSm7HmVb94RSJiKW4WAS
|
Follow-up simplification is now in LOC / complexity resultCompared with pinned
The refactor removes the dead OGC compatibility paginator, collapses two overloads plus an Wily's bottom-15 package MI remains improved versus main ( Revalidation
Benchmark still performs 10 -> 1 frame conversions per 10-page chunk:
All informational guardrails pass. The required warning still applies: Experimental alternative to #373; do not merge until comparison is complete. |
Status
Experimental alternative to #373; do not merge until comparison is complete.
Explores #376. This leaves #373 and its
fix/empty-result-frame-typebranch unchanged. The final diff is an alternative implementation of the same empty-frame contracts; this branch carries the narrow fix commits as setup and then moves OGC page aggregation to raw features.What changes
max_rowsto raw features, and convert once per completed chunk.(DataFrame or GeoDataFrame, metadata)contracts, WGS84 geometry, empty schemas, CQL2 POST replay, metadata, progress, ordering, and deduplication.Comparison
_get_resp_data(response, ...)_feature_frame(features, ...)plus_combine_feature_pagescombine_pages; DataFrame default retainedThe benchmark is reproducible with:
Timing thresholds are informational, not CI assertions.
Structural health
Compared with
upstream/main(61428b5e) usingpyscn 1.29.0andwily 1.25.0:ogc/shaping.pyloses 33 production lines and improves MI 44.84 → 54.47; validation/interface complexity moves intoogc.engineandtransport.pagination.This is a modest net maintainability gain rather than an unequivocal simplification, so the behavioral and performance evidence should drive the decision.
Validation
The pre-commit run includes Xenon, complexipy, Import Linter, mypy, Ruff, and nbstripout.
Review notes
A two-axis review against #376 found no Standards violations. Spec findings around progress counts, terminal empty pages, serial-versus-parallel equality/request counts, live rating retrieval, Water Use fan-out, and benchmark clarity were addressed before this branch was published.