Skip to content

Commit d8b3f71

Browse files
authored
Merge pull request #590 from DataIntegrationGroup/water-elevation-layer
feat: fix water elevation units to feet in materialized view and update related tests
2 parents 661f2cf + e3e4fde commit d8b3f71

2 files changed

Lines changed: 124 additions & 1 deletion

File tree

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
"""fix water elevation units to feet
2+
3+
Revision ID: n7a8b9c0d1e2
4+
Revises: m6f7a8b9c0d1
5+
Create Date: 2026-03-10 11:10:00.000000
6+
"""
7+
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
from sqlalchemy import inspect, text
12+
13+
# revision identifiers, used by Alembic.
14+
revision: str = "n7a8b9c0d1e2"
15+
down_revision: Union[str, Sequence[str], None] = "m6f7a8b9c0d1"
16+
branch_labels: Union[str, Sequence[str], None] = None
17+
depends_on: Union[str, Sequence[str], None] = None
18+
19+
METERS_TO_FEET = 3.28084
20+
21+
LATEST_LOCATION_CTE = """
22+
SELECT DISTINCT ON (lta.thing_id)
23+
lta.thing_id,
24+
lta.location_id,
25+
lta.effective_start
26+
FROM location_thing_association AS lta
27+
WHERE lta.effective_end IS NULL
28+
ORDER BY lta.thing_id, lta.effective_start DESC
29+
""".strip()
30+
31+
32+
def _create_water_elevation_view() -> str:
33+
return f"""
34+
CREATE MATERIALIZED VIEW ogc_water_elevation_wells AS
35+
WITH latest_location AS (
36+
{LATEST_LOCATION_CTE}
37+
),
38+
ranked_obs AS (
39+
SELECT
40+
fe.thing_id,
41+
o.id AS observation_id,
42+
o.observation_datetime,
43+
(o.value - COALESCE(o.measuring_point_height, 0))
44+
AS depth_to_water_below_ground_surface
45+
FROM observation AS o
46+
JOIN sample AS s ON s.id = o.sample_id
47+
JOIN field_activity AS fa ON fa.id = s.field_activity_id
48+
JOIN field_event AS fe ON fe.id = fa.field_event_id
49+
JOIN thing AS t ON t.id = fe.thing_id
50+
WHERE
51+
t.thing_type = 'water well'
52+
AND fa.activity_type = 'groundwater level'
53+
AND o.value IS NOT NULL
54+
AND o.observation_datetime IS NOT NULL
55+
),
56+
latest_obs AS (
57+
SELECT
58+
ro.*,
59+
ROW_NUMBER() OVER (
60+
PARTITION BY ro.thing_id
61+
ORDER BY ro.observation_datetime DESC, ro.observation_id DESC
62+
) AS rn
63+
FROM ranked_obs AS ro
64+
)
65+
SELECT
66+
t.id AS id,
67+
t.name,
68+
t.thing_type,
69+
lo.observation_id,
70+
lo.observation_datetime,
71+
l.elevation,
72+
lo.depth_to_water_below_ground_surface,
73+
((l.elevation * {METERS_TO_FEET}) - lo.depth_to_water_below_ground_surface)
74+
AS water_elevation,
75+
l.point
76+
FROM latest_obs AS lo
77+
JOIN thing AS t ON t.id = lo.thing_id
78+
JOIN latest_location AS ll ON ll.thing_id = t.id
79+
JOIN location AS l ON l.id = ll.location_id
80+
WHERE lo.rn = 1
81+
"""
82+
83+
84+
def upgrade() -> None:
85+
bind = op.get_bind()
86+
inspector = inspect(bind)
87+
existing_tables = set(inspector.get_table_names(schema="public"))
88+
required_tables = {
89+
"thing",
90+
"location",
91+
"location_thing_association",
92+
"observation",
93+
"sample",
94+
"field_activity",
95+
"field_event",
96+
}
97+
98+
if not required_tables.issubset(existing_tables):
99+
missing = sorted(t for t in required_tables if t not in existing_tables)
100+
raise RuntimeError(
101+
"Cannot create ogc_water_elevation_wells. Missing required tables: "
102+
+ ", ".join(missing)
103+
)
104+
105+
op.execute(text("DROP MATERIALIZED VIEW IF EXISTS ogc_water_elevation_wells"))
106+
op.execute(text(_create_water_elevation_view()))
107+
op.execute(
108+
text(
109+
"COMMENT ON MATERIALIZED VIEW ogc_water_elevation_wells IS "
110+
"'Latest water elevation per well in feet; computed as (elevation_m * 3.28084) - depth_to_water_below_ground_surface_ft.'"
111+
)
112+
)
113+
op.execute(
114+
text(
115+
"CREATE UNIQUE INDEX ux_ogc_water_elevation_wells_id "
116+
"ON ogc_water_elevation_wells (id)"
117+
)
118+
)
119+
120+
121+
def downgrade() -> None:
122+
op.execute(text("DROP MATERIALIZED VIEW IF EXISTS ogc_water_elevation_wells"))

tests/test_ogc.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,8 @@ def test_ogc_water_elevation_wells_computes_elevation_minus_depth_to_water(
344344

345345
assert float(row.depth_to_water_below_ground_surface) == 5.0
346346
assert float(row.elevation) == 2464.9
347-
assert abs(float(row.water_elevation) - 2459.9) < 1e-9
347+
expected_water_elevation_ft = (2464.9 * 3.28084) - 5.0
348+
assert abs(float(row.water_elevation) - expected_water_elevation_ft) < 1e-9
348349

349350

350351
def test_ogc_collections():

0 commit comments

Comments
 (0)