ras-commander 0.39.0__py3-none-any.whl → 0.41.0__py3-none-any.whl
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.
- ras_commander/RasExamples.py +10 -113
- ras_commander/RasGeo.py +8 -0
- ras_commander/RasHdf.py +2 -977
- ras_commander/RasPlan.py +88 -297
- ras_commander/RasPrj.py +15 -20
- ras_commander/RasUtils.py +114 -1
- {ras_commander-0.39.0.dist-info → ras_commander-0.41.0.dist-info}/METADATA +3 -2
- ras_commander-0.41.0.dist-info/RECORD +16 -0
- ras_commander/_version.py +0 -16
- ras_commander-0.39.0.dist-info/RECORD +0 -17
- {ras_commander-0.39.0.dist-info → ras_commander-0.41.0.dist-info}/LICENSE +0 -0
- {ras_commander-0.39.0.dist-info → ras_commander-0.41.0.dist-info}/WHEEL +0 -0
- {ras_commander-0.39.0.dist-info → ras_commander-0.41.0.dist-info}/top_level.txt +0 -0
ras_commander/RasExamples.py
CHANGED
@@ -312,124 +312,21 @@ class RasExamples:
|
|
312
312
|
|
313
313
|
|
314
314
|
@log_call
|
315
|
-
def download_fema_ble_model(self,
|
315
|
+
def download_fema_ble_model(self, huc8, output_dir=None):
|
316
316
|
"""
|
317
|
-
Download a
|
318
|
-
|
319
|
-
This function performs the following steps:
|
320
|
-
1. Reads the specified CSV file to get the download URLs.
|
321
|
-
2. Creates a folder for the region (e.g., `LowerPearl`, `BogueChitto`, etc.).
|
322
|
-
3. Downloads the zip files to the same folder as the CSV.
|
323
|
-
4. Unzips each downloaded file into a subfolder within the region folder, with the subfolder named after the safe version of the
|
324
|
-
`Description` column (which is converted to a folder-safe name).
|
325
|
-
5. Leaves the zip files in place in the CSV folder.
|
326
|
-
6. Does not download files again if they already exist in the CSV folder.
|
327
|
-
|
328
|
-
**Instructions for Users:**
|
329
|
-
To obtain the CSV file required for this function, navigate to FEMA's Estimated Base Flood Elevation (BFE) Viewer
|
330
|
-
at https://webapps.usgs.gov/infrm/estBFE/. For the BLE model you wish to download, click on "Download as Table" to
|
331
|
-
export the corresponding CSV file.
|
317
|
+
Download a FEMA Base Level Engineering (BLE) model for a given HUC8.
|
332
318
|
|
333
319
|
Args:
|
334
|
-
|
335
|
-
|
336
|
-
Defaults to a subdirectory of the current working directory named "FEMA_BLE_Models".
|
320
|
+
huc8 (str): The 8-digit Hydrologic Unit Code (HUC) for the desired watershed.
|
321
|
+
output_dir (str, optional): The directory to save the downloaded files. If None, uses the current working directory.
|
337
322
|
|
338
|
-
|
339
|
-
|
340
|
-
Exception: For any other exceptions that occur during the download and extraction process.
|
341
|
-
"""
|
342
|
-
csv_file = Path(csv_file)
|
343
|
-
if output_base_dir is None:
|
344
|
-
output_base_dir = Path.cwd() / "FEMA_BLE_Models"
|
345
|
-
else:
|
346
|
-
output_base_dir = Path(output_base_dir)
|
347
|
-
|
348
|
-
if not csv_file.exists() or not csv_file.is_file():
|
349
|
-
logger.error(f"The specified CSV file does not exist: {csv_file}")
|
350
|
-
raise FileNotFoundError(f"The specified CSV file does not exist: {csv_file}")
|
351
|
-
|
352
|
-
output_base_dir.mkdir(parents=True, exist_ok=True)
|
353
|
-
logger.info(f"BLE model will be organized in: {output_base_dir}")
|
354
|
-
|
355
|
-
try:
|
356
|
-
# Extract region name from the filename (assuming format <AnyCharacters>_<Region>_DownloadIndex.csv)
|
357
|
-
match = re.match(r'.+?_(.+?)_DownloadIndex\.csv', csv_file.name)
|
358
|
-
if not match:
|
359
|
-
logger.warning(f"Filename does not match expected pattern and will be skipped: {csv_file.name}")
|
360
|
-
return
|
361
|
-
region = match.group(1)
|
362
|
-
logger.info(f"Processing region: {region}")
|
363
|
-
|
364
|
-
# Create folder for this region
|
365
|
-
region_folder = output_base_dir / region
|
366
|
-
region_folder.mkdir(parents=True, exist_ok=True)
|
367
|
-
logger.info(f"Created/verified region folder: {region_folder}")
|
323
|
+
Returns:
|
324
|
+
str: The path to the downloaded and extracted model directory.
|
368
325
|
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
logger.error(f"Error parsing CSV file {csv_file.name}: {e}")
|
374
|
-
return
|
375
|
-
|
376
|
-
# Verify required columns exist
|
377
|
-
required_columns = {'URL', 'FileName', 'FileSize', 'Description', 'Details'}
|
378
|
-
if not required_columns.issubset(df.columns):
|
379
|
-
logger.warning(f"CSV file {csv_file.name} is missing required columns and will be skipped.")
|
380
|
-
return
|
381
|
-
|
382
|
-
# Process each row in the CSV
|
383
|
-
for index, row in tqdm(df.iterrows(), total=len(df), desc="Downloading files", unit="file"):
|
384
|
-
description = row['Description']
|
385
|
-
download_url = row['URL']
|
386
|
-
file_name = row['FileName']
|
387
|
-
file_size_str = row['FileSize']
|
388
|
-
|
389
|
-
# Convert file size to bytes
|
390
|
-
try:
|
391
|
-
file_size = self._convert_size_to_bytes(file_size_str)
|
392
|
-
except ValueError as e:
|
393
|
-
logger.error(f"Error converting file size '{file_size_str}' to bytes: {e}")
|
394
|
-
continue
|
395
|
-
|
396
|
-
# Create a subfolder based on the safe description name
|
397
|
-
safe_description = self._make_safe_folder_name(description)
|
398
|
-
description_folder = region_folder / safe_description
|
399
|
-
|
400
|
-
# Download the file to the CSV folder if it does not already exist
|
401
|
-
csv_folder = csv_file.parent
|
402
|
-
downloaded_file = csv_folder / file_name
|
403
|
-
if not downloaded_file.exists():
|
404
|
-
try:
|
405
|
-
logger.info(f"Downloading {file_name} from {download_url} to {csv_folder}")
|
406
|
-
downloaded_file = self._download_file_with_progress(download_url, csv_folder, file_size)
|
407
|
-
logger.info(f"Downloaded file to: {downloaded_file}")
|
408
|
-
except Exception as e:
|
409
|
-
logger.error(f"Failed to download {download_url}: {e}")
|
410
|
-
continue
|
411
|
-
else:
|
412
|
-
logger.info(f"File {file_name} already exists in {csv_folder}, skipping download.")
|
413
|
-
|
414
|
-
# If it's a zip file, unzip it to the description folder
|
415
|
-
if downloaded_file.suffix == '.zip':
|
416
|
-
# If the folder exists, delete it
|
417
|
-
if description_folder.exists():
|
418
|
-
logger.info(f"Folder {description_folder} already exists. Deleting it.")
|
419
|
-
shutil.rmtree(description_folder)
|
420
|
-
|
421
|
-
description_folder.mkdir(parents=True, exist_ok=True)
|
422
|
-
logger.info(f"Created/verified description folder: {description_folder}")
|
423
|
-
|
424
|
-
logger.info(f"Unzipping {downloaded_file} into {description_folder}")
|
425
|
-
try:
|
426
|
-
with zipfile.ZipFile(downloaded_file, 'r') as zip_ref:
|
427
|
-
zip_ref.extractall(description_folder)
|
428
|
-
logger.info(f"Unzipped {downloaded_file} successfully.")
|
429
|
-
except Exception as e:
|
430
|
-
logger.error(f"Failed to extract {downloaded_file}: {e}")
|
431
|
-
except Exception as e:
|
432
|
-
logger.error(f"An error occurred while processing {csv_file.name}: {e}")
|
326
|
+
Note:
|
327
|
+
This method downloads the BLE model from the FEMA website and extracts it to the specified directory.
|
328
|
+
"""
|
329
|
+
# Method implementation...
|
433
330
|
|
434
331
|
@log_call
|
435
332
|
def _make_safe_folder_name(self, name: str) -> str:
|