HMS to Cloud Native GIS — CLI for exporting HEC-HMS results to GeoParquet, PMTiles, DuckDB, and PostGIS
Project description
hms2cng — HMS to Cloud Native GIS
CLI tool for exporting HEC-HMS results to GeoParquet, querying with DuckDB, and generating PMTiles for web visualization.
Built on top of hms-commander.
Installation
# Base installation (GeoParquet export only)
pip install hms2cng
# With DuckDB support
pip install "hms2cng[duckdb]"
# With PostGIS sync
pip install "hms2cng[postgis]"
# All features
pip install "hms2cng[all]"
PMTiles Generation
PMTiles generation requires external CLI tools:
- tippecanoe — Install via conda-forge:
conda install -c conda-forge tippecanoe - pmtiles — Install from protomaps:
go install github.com/protomaps/go-pmtiles/pmtiles@latest
On Windows, these are easiest to install via WSL or conda-forge.
Quick Start
Export Geometry
# From basin model file (exports subbasins by default)
hms2cng geometry model.basin subbasins.parquet
# Specific layer (subbasins, reaches, junctions, watershed)
hms2cng geometry model.basin reaches.parquet --layer reaches
# With explicit CRS (recommended for reprojection to WGS84)
hms2cng geometry model.basin subbasins.parquet --crs EPSG:2278 --out-crs EPSG:4326
Export Results
# Export peak outflow statistics from HMS results folder
hms2cng results ./results/ subbasin_flow.parquet \
--type subbasin \
--var "Flow Out"
# All element types
hms2cng results ./results/ all_results.parquet --type all
# Stage instead of flow
hms2cng results ./results/ stage.parquet --type reach --var Stage
Query with DuckDB
# Filter by peak flow threshold
hms2cng query subbasin_flow.parquet \
"SELECT * FROM _ WHERE max_value > 1000 ORDER BY max_value DESC"
# Time of peak analysis
hms2cng query subbasin_flow.parquet \
"SELECT name, max_value, time_of_max, units FROM _ WHERE max_value > 500"
# Save results to file
hms2cng query subbasin_flow.parquet \
"SELECT * FROM _ WHERE max_value > 1000" \
--output high_flow_subbasins.parquet
Generate PMTiles
# From GeoParquet (requires tippecanoe + pmtiles CLI)
hms2cng pmtiles subbasins.parquet subbasins.pmtiles \
--layer subbasins \
--min-zoom 8 \
--max-zoom 14
Sync to PostGIS
# Upload to PostGIS
hms2cng sync subbasins.parquet \
"postgresql://user:pass@192.168.3.30:5432/gis_data" \
hms_subbasins \
--schema uberclaw
Python API
from hms2cng import (
export_basin_geometry,
export_hms_results,
DuckSession,
generate_pmtiles_from_input,
sync_to_postgres
)
# Export geometry
export_basin_geometry("model.basin", "subbasins.parquet", layer="subbasins")
# Export results (parses RUN_*.results XML for summary statistics)
export_hms_results(
"./results/",
"subbasin_flow.parquet",
element_type="subbasin",
variable="Outflow"
)
# Query with DuckDB
session = DuckSession()
session.register_parquet("subbasin_flow.parquet")
df = session.query("SELECT * FROM _ WHERE max_value > 1000")
session.close()
# Generate PMTiles (requires tippecanoe + pmtiles CLI)
generate_pmtiles_from_input("subbasins.parquet", "subbasins.pmtiles")
# Sync to PostGIS
sync_to_postgres(
"subbasins.parquet",
"postgresql://user:pass@host:5432/db",
"hms_subbasins",
schema="uberclaw"
)
Tifton Example
The Tifton HMS example project demonstrates the complete workflow:
# Set paths
set TIFTON=C:\GH\hms-commander\hms_example_projects\tifton
# Export subbasin geometry
hms2cng geometry %TIFTON%\Tifton.basin tifton_subbasins.parquet --layer subbasins
# Export peak outflow results
hms2cng results %TIFTON%\results tifton_outflow.parquet --type subbasin --var Outflow
# Query for high flows
hms2cng query tifton_outflow.parquet "SELECT name, max_value, time_of_max FROM _ WHERE max_value > 500"
# Sync to PostGIS
hms2cng sync tifton_subbasins.parquet "postgresql://uberclaw:pass@192.168.3.30:5432/gis_data" tifton_subbasins --schema uberclaw
Architecture
HEC-HMS Model (.basin, results/RUN_*.results)
↓
hms-commander (geometry + XML parsing)
↓
GeoParquet (.parquet)
↓
┌───────┴────────┐
↓ ↓
DuckDB PostGIS
(query) (multi-user)
↓ ↓
└───────┬────────┘
↓
PMTiles (.pmtiles)
↓
MapLibre GL
Notes
CRS Handling
- If your HMS project has a
.prjfile or CRS is detected automatically, geometry will be reprojected to WGS84 (EPSG:4326) by default. - Use
--crs EPSG:XXXXto specify the input CRS manually if auto-detection fails. - Use
--out-crs EPSG:XXXXto control output CRS.
Results Export
- Results are extracted from the
RUN_*.resultsXML files generated by HEC-HMS. - This provides summary statistics (peak, min, mean, time of peak) without requiring DSS file access.
- For full time-series export,
pyjnius+ HEC-DSS libraries are required (currently not bundled).
PMTiles on Windows
- Install tippecanoe and pmtiles via conda-forge or WSL.
- The CLI will produce a clear error if the tools are not found.
Development
# Clone and install in dev mode
git clone https://github.com/gpt-cmdr/hms2cng
cd hms2cng
uv pip install -e ".[all]"
# Run tests
uv run pytest tests/
# Build package
uv run python -m build
License
MIT - See LICENSE file
Author
William M. Katzenmeyer, P.E., C.F.M. CLB Engineering Corporation
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hms2cng-0.1.0.tar.gz.
File metadata
- Download URL: hms2cng-0.1.0.tar.gz
- Upload date:
- Size: 27.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6cb7a3bd3f5852ba119863180bfdf69e085b7be71b59c1c632eae9d546f9706
|
|
| MD5 |
5c342a0896bd9f75d11ab343690406c1
|
|
| BLAKE2b-256 |
7b34f78706d444d1b82a2963d2689f0e344482a48e56306d954362e7ce8d972a
|
File details
Details for the file hms2cng-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hms2cng-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0eef41f238ebc0a077bd1e981b9badb8856cd591da5fd6b3c14752604c7012ed
|
|
| MD5 |
aa0f8ef50368601aa84b4a603d52c484
|
|
| BLAKE2b-256 |
150b4321a840f07f03d56dbbe0d2216b23d3a29335f7b0b7e2983f01fbabb4ce
|