rashdf 0.8.0__tar.gz → 0.8.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rashdf-0.8.0 → rashdf-0.8.1}/PKG-INFO +2 -2
- {rashdf-0.8.0 → rashdf-0.8.1}/pyproject.toml +2 -2
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf/geom.py +50 -25
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf.egg-info/PKG-INFO +2 -2
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf.egg-info/requires.txt +1 -1
- {rashdf-0.8.0 → rashdf-0.8.1}/tests/test_geom.py +54 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/LICENSE +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/README.md +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/setup.cfg +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/src/cli.py +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf/__init__.py +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf/base.py +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf/plan.py +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf/utils.py +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf.egg-info/SOURCES.txt +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf.egg-info/dependency_links.txt +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf.egg-info/entry_points.txt +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/src/rashdf.egg-info/top_level.txt +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/tests/test_base.py +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/tests/test_cli.py +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/tests/test_plan.py +0 -0
- {rashdf-0.8.0 → rashdf-0.8.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rashdf
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: Read data from HEC-RAS HDF files.
|
|
5
5
|
Project-URL: repository, https://github.com/fema-ffrd/rashdf
|
|
6
6
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -16,7 +16,7 @@ License-File: LICENSE
|
|
|
16
16
|
Requires-Dist: h5py
|
|
17
17
|
Requires-Dist: geopandas<2.0,>=1.0
|
|
18
18
|
Requires-Dist: pyarrow
|
|
19
|
-
Requires-Dist: xarray
|
|
19
|
+
Requires-Dist: xarray<=2025.4.0
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
Requires-Dist: pre-commit; extra == "dev"
|
|
22
22
|
Requires-Dist: ruff; extra == "dev"
|
|
@@ -12,8 +12,8 @@ classifiers = [
|
|
|
12
12
|
"Programming Language :: Python :: 3.11",
|
|
13
13
|
"Programming Language :: Python :: 3.12",
|
|
14
14
|
]
|
|
15
|
-
version = "0.8.
|
|
16
|
-
dependencies = ["h5py", "geopandas>=1.0,<2.0", "pyarrow", "xarray"]
|
|
15
|
+
version = "0.8.1"
|
|
16
|
+
dependencies = ["h5py", "geopandas>=1.0,<2.0", "pyarrow", "xarray<=2025.4.0"]
|
|
17
17
|
|
|
18
18
|
[project.optional-dependencies]
|
|
19
19
|
dev = [
|
|
@@ -17,6 +17,8 @@ from shapely import (
|
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
from typing import Dict, List, Optional, Union
|
|
20
|
+
from warnings import warn
|
|
21
|
+
from pathlib import Path
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
from .base import RasHdf
|
|
@@ -29,7 +31,7 @@ from .utils import (
|
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
class RasGeomHdfError(Exception):
|
|
32
|
-
"""HEC-RAS
|
|
34
|
+
"""HEC-RAS Geometry HDF error class."""
|
|
33
35
|
|
|
34
36
|
pass
|
|
35
37
|
|
|
@@ -43,6 +45,7 @@ class RasGeomHdf(RasHdf):
|
|
|
43
45
|
BC_LINES_PATH = f"{GEOM_PATH}/Boundary Condition Lines"
|
|
44
46
|
IC_POINTS_PATH = f"{GEOM_PATH}/IC Points"
|
|
45
47
|
BREAKLINES_PATH = f"{GEOM_PATH}/2D Flow Area Break Lines"
|
|
48
|
+
REFINEMENT_REGIONS_PATH = f"{GEOM_PATH}/2D Flow Area Refinement Regions"
|
|
46
49
|
REFERENCE_LINES_PATH = f"{GEOM_PATH}/Reference Lines"
|
|
47
50
|
REFERENCE_POINTS_PATH = f"{GEOM_PATH}/Reference Points"
|
|
48
51
|
CROSS_SECTIONS = f"{GEOM_PATH}/Cross Sections"
|
|
@@ -295,19 +298,28 @@ class RasGeomHdf(RasHdf):
|
|
|
295
298
|
polyline_points = self[polyline_points_path][()]
|
|
296
299
|
|
|
297
300
|
geoms = []
|
|
298
|
-
for pnt_start, pnt_cnt, part_start, part_cnt in polyline_info:
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
301
|
+
for i, (pnt_start, pnt_cnt, part_start, part_cnt) in enumerate(polyline_info):
|
|
302
|
+
try:
|
|
303
|
+
points = polyline_points[pnt_start : pnt_start + pnt_cnt]
|
|
304
|
+
if part_cnt == 1:
|
|
305
|
+
geoms.append(LineString(points))
|
|
306
|
+
else: # pragma: no cover | TODO: add test coverage for this
|
|
307
|
+
parts = polyline_parts[part_start : part_start + part_cnt]
|
|
308
|
+
geoms.append(
|
|
309
|
+
MultiLineString(
|
|
310
|
+
list(
|
|
311
|
+
points[part_pnt_start : part_pnt_start + part_pnt_cnt]
|
|
312
|
+
for part_pnt_start, part_pnt_cnt in parts
|
|
313
|
+
)
|
|
309
314
|
)
|
|
310
315
|
)
|
|
316
|
+
except (
|
|
317
|
+
Exception
|
|
318
|
+
) as e: # pragma: no cover | TODO: add test coverage for this
|
|
319
|
+
geoms.append(None)
|
|
320
|
+
warn(
|
|
321
|
+
f"Feature ID {i} within '{Path(path).name}' layer set to null due to invalid geometry. {e}",
|
|
322
|
+
UserWarning,
|
|
311
323
|
)
|
|
312
324
|
return geoms
|
|
313
325
|
|
|
@@ -370,25 +382,38 @@ class RasGeomHdf(RasHdf):
|
|
|
370
382
|
GeoDataFrame
|
|
371
383
|
A GeoDataFrame containing the 2D mesh area refinement regions if they exist.
|
|
372
384
|
"""
|
|
373
|
-
if
|
|
385
|
+
if self.REFINEMENT_REGIONS_PATH not in self:
|
|
374
386
|
return GeoDataFrame()
|
|
375
|
-
rr_data = self[
|
|
387
|
+
rr_data = self[self.REFINEMENT_REGIONS_PATH]
|
|
376
388
|
rr_ids = range(rr_data["Attributes"][()].shape[0])
|
|
377
389
|
names = np.vectorize(convert_ras_hdf_string)(rr_data["Attributes"][()]["Name"])
|
|
378
390
|
geoms = list()
|
|
379
|
-
for pnt_start, pnt_cnt, part_start, part_cnt in
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
391
|
+
for i, (pnt_start, pnt_cnt, part_start, part_cnt) in enumerate(
|
|
392
|
+
rr_data["Polygon Info"][()]
|
|
393
|
+
):
|
|
394
|
+
try:
|
|
395
|
+
points = rr_data["Polygon Points"][()][pnt_start : pnt_start + pnt_cnt]
|
|
396
|
+
if part_cnt == 1:
|
|
397
|
+
geoms.append(Polygon(points))
|
|
398
|
+
else: # pragma: no cover | TODO: add test coverage for this
|
|
399
|
+
parts = rr_data["Polygon Parts"][()][
|
|
400
|
+
part_start : part_start + part_cnt
|
|
401
|
+
]
|
|
402
|
+
geoms.append(
|
|
403
|
+
MultiPolygon(
|
|
404
|
+
list(
|
|
405
|
+
points[part_pnt_start : part_pnt_start + part_pnt_cnt]
|
|
406
|
+
for part_pnt_start, part_pnt_cnt in parts
|
|
407
|
+
)
|
|
390
408
|
)
|
|
391
409
|
)
|
|
410
|
+
except (
|
|
411
|
+
Exception
|
|
412
|
+
) as e: # pragma: no cover | TODO: add test coverage for this
|
|
413
|
+
geoms.append(None)
|
|
414
|
+
warn(
|
|
415
|
+
f"Feature ID {i} within '{Path(self.REFINEMENT_REGIONS_PATH).name}' layer set to null due to invalid geometry. {e}",
|
|
416
|
+
UserWarning,
|
|
392
417
|
)
|
|
393
418
|
return GeoDataFrame(
|
|
394
419
|
{"rr_id": rr_ids, "name": names, "geometry": geoms},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rashdf
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.1
|
|
4
4
|
Summary: Read data from HEC-RAS HDF files.
|
|
5
5
|
Project-URL: repository, https://github.com/fema-ffrd/rashdf
|
|
6
6
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -16,7 +16,7 @@ License-File: LICENSE
|
|
|
16
16
|
Requires-Dist: h5py
|
|
17
17
|
Requires-Dist: geopandas<2.0,>=1.0
|
|
18
18
|
Requires-Dist: pyarrow
|
|
19
|
-
Requires-Dist: xarray
|
|
19
|
+
Requires-Dist: xarray<=2025.4.0
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
Requires-Dist: pre-commit; extra == "dev"
|
|
22
22
|
Requires-Dist: ruff; extra == "dev"
|
|
@@ -4,6 +4,7 @@ import h5py
|
|
|
4
4
|
from pyproj import CRS
|
|
5
5
|
from src.rashdf import RasGeomHdf
|
|
6
6
|
from pandas.testing import assert_frame_equal
|
|
7
|
+
import pytest
|
|
7
8
|
|
|
8
9
|
from . import _create_hdf_with_group_attrs, _gdf_matches_json, _gdf_matches_json_alt
|
|
9
10
|
|
|
@@ -35,30 +36,71 @@ def test_mesh_area_names():
|
|
|
35
36
|
assert ghdf.mesh_area_names() == ["2D Interior Area", "Perimeter_NW"]
|
|
36
37
|
|
|
37
38
|
|
|
39
|
+
def test_invalid_mesh_area_names(tmp_path):
|
|
40
|
+
test_hdf = tmp_path / "test.hdf"
|
|
41
|
+
_create_hdf_with_group_attrs(test_hdf, RasGeomHdf.GEOM_PATH, TEST_ATTRS)
|
|
42
|
+
# Test the empty Mesh Area names
|
|
43
|
+
with RasGeomHdf(test_hdf) as ghdf:
|
|
44
|
+
assert ghdf.mesh_area_names() == []
|
|
45
|
+
|
|
46
|
+
|
|
38
47
|
def test_mesh_areas():
|
|
39
48
|
mesh_areas_json = TEST_JSON / "mesh_areas.json"
|
|
40
49
|
with RasGeomHdf(MUNCIE_G05) as ghdf:
|
|
41
50
|
assert _gdf_matches_json(ghdf.mesh_areas(), mesh_areas_json)
|
|
42
51
|
|
|
43
52
|
|
|
53
|
+
def test_invalid_mesh_areas(tmp_path):
|
|
54
|
+
test_hdf = tmp_path / "test.hdf"
|
|
55
|
+
_create_hdf_with_group_attrs(test_hdf, RasGeomHdf.GEOM_PATH, TEST_ATTRS)
|
|
56
|
+
# Test the empty Mesh Areas
|
|
57
|
+
with RasGeomHdf(test_hdf) as ghdf:
|
|
58
|
+
assert ghdf.mesh_areas().empty
|
|
59
|
+
|
|
60
|
+
|
|
44
61
|
def test_mesh_cell_faces():
|
|
45
62
|
mesh_cell_faces_json = TEST_JSON / "mesh_cell_faces.json"
|
|
46
63
|
with RasGeomHdf(MUNCIE_G05) as ghdf:
|
|
47
64
|
assert _gdf_matches_json(ghdf.mesh_cell_faces(), mesh_cell_faces_json)
|
|
48
65
|
|
|
49
66
|
|
|
67
|
+
def test_invalid_mesh_faces(tmp_path):
|
|
68
|
+
test_hdf = tmp_path / "test.hdf"
|
|
69
|
+
_create_hdf_with_group_attrs(test_hdf, RasGeomHdf.GEOM_PATH, TEST_ATTRS)
|
|
70
|
+
# Test the empty Mesh Faces
|
|
71
|
+
with RasGeomHdf(test_hdf) as ghdf:
|
|
72
|
+
assert ghdf.mesh_cell_faces().empty
|
|
73
|
+
|
|
74
|
+
|
|
50
75
|
def test_mesh_cell_points():
|
|
51
76
|
mesh_cell_points_json = TEST_JSON / "mesh_cell_points.json"
|
|
52
77
|
with RasGeomHdf(MUNCIE_G05) as ghdf:
|
|
53
78
|
assert _gdf_matches_json(ghdf.mesh_cell_points(), mesh_cell_points_json)
|
|
54
79
|
|
|
55
80
|
|
|
81
|
+
def test_invalid_mesh_cell_points(tmp_path):
|
|
82
|
+
test_hdf = tmp_path / "test.hdf"
|
|
83
|
+
_create_hdf_with_group_attrs(test_hdf, RasGeomHdf.GEOM_PATH, TEST_ATTRS)
|
|
84
|
+
# Test the empty Mesh Cell Points
|
|
85
|
+
with RasGeomHdf(test_hdf) as ghdf:
|
|
86
|
+
assert ghdf.mesh_cell_points().empty
|
|
87
|
+
|
|
88
|
+
|
|
56
89
|
def test_mesh_cell_polygons():
|
|
57
90
|
mesh_cell_polygons_json = TEST_JSON / "mesh_cell_polygons.json"
|
|
58
91
|
with RasGeomHdf(MUNCIE_G05) as ghdf:
|
|
59
92
|
assert _gdf_matches_json(ghdf.mesh_cell_polygons(), mesh_cell_polygons_json)
|
|
60
93
|
|
|
61
94
|
|
|
95
|
+
def test_invalid_mesh_cell_polygons(tmp_path):
|
|
96
|
+
# Create a dummy HDF file
|
|
97
|
+
test_hdf = tmp_path / "test.hdf"
|
|
98
|
+
_create_hdf_with_group_attrs(test_hdf, RasGeomHdf.GEOM_PATH, TEST_ATTRS)
|
|
99
|
+
# Test the empty Mesh Cell Polygons
|
|
100
|
+
with RasGeomHdf(test_hdf) as ghdf:
|
|
101
|
+
assert ghdf.mesh_cell_polygons().empty
|
|
102
|
+
|
|
103
|
+
|
|
62
104
|
def test_mesh_cell_polygons_coal():
|
|
63
105
|
"""Test with the mesh from the Coal River model.
|
|
64
106
|
|
|
@@ -118,6 +160,18 @@ def test_get_geom_2d_flow_area_attrs(tmp_path):
|
|
|
118
160
|
assert ras_hdf.get_geom_2d_flow_area_attrs() == TEST_ATTRS
|
|
119
161
|
|
|
120
162
|
|
|
163
|
+
def test_invalid_get_geom_2d_flow_area_attrs(tmp_path):
|
|
164
|
+
test_hdf = tmp_path / "test.hdf"
|
|
165
|
+
_create_hdf_with_group_attrs(test_hdf, RasGeomHdf.GEOM_PATH, TEST_ATTRS)
|
|
166
|
+
ras_hdf = RasGeomHdf(test_hdf)
|
|
167
|
+
|
|
168
|
+
with pytest.raises(
|
|
169
|
+
AttributeError,
|
|
170
|
+
match=f"Unable to get 2D Flow Area; {RasGeomHdf.FLOW_AREA_2D_PATH} group not found in HDF5 file.",
|
|
171
|
+
):
|
|
172
|
+
ras_hdf.get_geom_2d_flow_area_attrs()
|
|
173
|
+
|
|
174
|
+
|
|
121
175
|
def test_structs():
|
|
122
176
|
structs_json = TEST_JSON / "structures.json"
|
|
123
177
|
with RasGeomHdf(MUNCIE_G05) as ghdf:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|