rashdf 0.2.2__tar.gz → 0.3.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rashdf
3
- Version: 0.2.2
3
+ Version: 0.3.0
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,6 +16,7 @@ License-File: LICENSE
16
16
  Requires-Dist: h5py
17
17
  Requires-Dist: geopandas
18
18
  Requires-Dist: pyarrow
19
+ Requires-Dist: xarray
19
20
  Provides-Extra: dev
20
21
  Requires-Dist: pre-commit; extra == "dev"
21
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.2.2"
16
- dependencies = ["h5py", "geopandas", "pyarrow"]
15
+ version = "0.3.0"
16
+ dependencies = ["h5py", "geopandas", "pyarrow", "xarray"]
17
17
 
18
18
  [project.optional-dependencies]
19
19
  dev = ["pre-commit", "ruff", "pytest", "pytest-cov"]
@@ -1,6 +1,6 @@
1
1
  """rashdf CLI."""
2
2
 
3
- from rashdf import RasGeomHdf
3
+ from rashdf import RasGeomHdf, RasPlanHdf
4
4
  from rashdf.utils import df_datetimes_to_str
5
5
 
6
6
  import fiona
@@ -10,6 +10,7 @@ import argparse
10
10
  from ast import literal_eval
11
11
  from pathlib import Path
12
12
  import sys
13
+ import re
13
14
  from typing import List, Optional
14
15
  import warnings
15
16
 
@@ -108,17 +109,22 @@ def export(args: argparse.Namespace) -> Optional[str]:
108
109
  for driver in fiona_supported_drivers():
109
110
  print(driver)
110
111
  return
111
- if "://" in args.hdf_file:
112
- geom_hdf = RasGeomHdf.open_uri(args.hdf_file)
112
+ if re.match(r"^.*\.p\d\d\.hdf$", args.hdf_file):
113
+ ras_hdf_class = RasPlanHdf
113
114
  else:
114
- geom_hdf = RasGeomHdf(args.hdf_file)
115
+ ras_hdf_class = RasGeomHdf
116
+ if re.match(r"^\w+://", args.hdf_file):
117
+ geom_hdf = ras_hdf_class.open_uri(args.hdf_file)
118
+ else:
119
+ geom_hdf = ras_hdf_class(args.hdf_file)
115
120
  func = getattr(geom_hdf, args.func)
116
121
  gdf: GeoDataFrame = func()
117
122
  kwargs = literal_eval(args.kwargs) if args.kwargs else {}
118
123
  if args.to_crs:
119
124
  gdf = gdf.to_crs(args.to_crs)
120
125
  if not args.output_file:
121
- # convert any datetime columns to strings
126
+ # If an output file path isn't provided, write the GeoDataFrame to stdout
127
+ # as GeoJSON. Convert any datetime columns to strings.
122
128
  gdf = df_datetimes_to_str(gdf)
123
129
  with warnings.catch_warnings():
124
130
  # Squash warnings about converting the CRS to OGC URN format.
@@ -143,9 +149,9 @@ def export(args: argparse.Namespace) -> Optional[str]:
143
149
  output_file_path = Path(args.output_file)
144
150
  output_file_ext = output_file_path.suffix
145
151
  if output_file_ext not in [".gpkg"]:
146
- # unless the user specifies a format that supports datetime,
147
- # convert any datetime columns to string
148
- # TODO: besides Geopackage, which of the standard Fiona formats allow datetime?
152
+ # Unless the user specifies a format that supports datetime,
153
+ # convert any datetime columns to string.
154
+ # TODO: besides Geopackage, which of the standard Fiona drivers allow datetime?
149
155
  gdf = df_datetimes_to_str(gdf)
150
156
  gdf.to_file(args.output_file, **kwargs)
151
157
 
@@ -66,12 +66,12 @@ class RasGeomHdf(RasHdf):
66
66
  List[str]
67
67
  A list of the 2D mesh area names (str) within the RAS geometry if 2D areas exist.
68
68
  """
69
- if "/Geometry/2D Flow Areas" not in self:
69
+ if self.FLOW_AREA_2D_PATH not in self:
70
70
  return list()
71
71
  return list(
72
72
  [
73
73
  convert_ras_hdf_string(n)
74
- for n in self["/Geometry/2D Flow Areas/Attributes"][()]["Name"]
74
+ for n in self[f"{self.FLOW_AREA_2D_PATH}/Attributes"][()]["Name"]
75
75
  ]
76
76
  )
77
77
 
@@ -87,7 +87,7 @@ class RasGeomHdf(RasHdf):
87
87
  if not mesh_area_names:
88
88
  return GeoDataFrame()
89
89
  mesh_area_polygons = [
90
- Polygon(self[f"/Geometry/2D Flow Areas/{n}/Perimeter"][()])
90
+ Polygon(self[f"{self.FLOW_AREA_2D_PATH}/{n}/Perimeter"][()])
91
91
  for n in mesh_area_names
92
92
  ]
93
93
  return GeoDataFrame(
@@ -112,13 +112,13 @@ class RasGeomHdf(RasHdf):
112
112
 
113
113
  cell_dict = {"mesh_name": [], "cell_id": [], "geometry": []}
114
114
  for i, mesh_name in enumerate(mesh_area_names):
115
- cell_cnt = self["/Geometry/2D Flow Areas/Cell Info"][()][i][1]
115
+ cell_cnt = self[f"{self.FLOW_AREA_2D_PATH}/Cell Info"][()][i][1]
116
116
  cell_ids = list(range(cell_cnt))
117
117
  cell_face_info = self[
118
- f"/Geometry/2D Flow Areas/{mesh_name}/Cells Face and Orientation Info"
118
+ f"{self.FLOW_AREA_2D_PATH}/{mesh_name}/Cells Face and Orientation Info"
119
119
  ][()]
120
120
  cell_face_values = self[
121
- f"/Geometry/2D Flow Areas/{mesh_name}/Cells Face and Orientation Values"
121
+ f"{self.FLOW_AREA_2D_PATH}/{mesh_name}/Cells Face and Orientation Values"
122
122
  ][()][:, 0]
123
123
  face_id_lists = list(
124
124
  np.vectorize(
@@ -169,8 +169,8 @@ class RasGeomHdf(RasHdf):
169
169
  return GeoDataFrame()
170
170
  pnt_dict = {"mesh_name": [], "cell_id": [], "geometry": []}
171
171
  for i, mesh_name in enumerate(mesh_area_names):
172
- starting_row, count = self["/Geometry/2D Flow Areas/Cell Info"][()][i]
173
- cell_pnt_coords = self["/Geometry/2D Flow Areas/Cell Points"][()][
172
+ starting_row, count = self[f"{self.FLOW_AREA_2D_PATH}/Cell Info"][()][i]
173
+ cell_pnt_coords = self[f"{self.FLOW_AREA_2D_PATH}/Cell Points"][()][
174
174
  starting_row : starting_row + count
175
175
  ]
176
176
  pnt_dict["mesh_name"] += [mesh_name] * cell_pnt_coords.shape[0]
@@ -196,16 +196,16 @@ class RasGeomHdf(RasHdf):
196
196
  face_dict = {"mesh_name": [], "face_id": [], "geometry": []}
197
197
  for mesh_name in mesh_area_names:
198
198
  facepoints_index = self[
199
- f"/Geometry/2D Flow Areas/{mesh_name}/Faces FacePoint Indexes"
199
+ f"{self.FLOW_AREA_2D_PATH}/{mesh_name}/Faces FacePoint Indexes"
200
200
  ][()]
201
201
  facepoints_coordinates = self[
202
- f"/Geometry/2D Flow Areas/{mesh_name}/FacePoints Coordinate"
202
+ f"{self.FLOW_AREA_2D_PATH}/{mesh_name}/FacePoints Coordinate"
203
203
  ][()]
204
204
  faces_perimeter_info = self[
205
- f"/Geometry/2D Flow Areas/{mesh_name}/Faces Perimeter Info"
205
+ f"{self.FLOW_AREA_2D_PATH}/{mesh_name}/Faces Perimeter Info"
206
206
  ][()]
207
207
  faces_perimeter_values = self[
208
- f"/Geometry/2D Flow Areas/{mesh_name}/Faces Perimeter Values"
208
+ f"{self.FLOW_AREA_2D_PATH}/{mesh_name}/Faces Perimeter Values"
209
209
  ][()]
210
210
  face_id = -1
211
211
  for pnt_a_index, pnt_b_index in facepoints_index: