Skip to content

Commit

Permalink
stormwater updates
Browse files Browse the repository at this point in the history
  • Loading branch information
kaklise committed Oct 17, 2023
1 parent 4e13a04 commit 7e621f0
Show file tree
Hide file tree
Showing 14 changed files with 591 additions and 289 deletions.
8 changes: 8 additions & 0 deletions documentation/apidoc/wntr.stormwater.gis.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
wntr.stormwater.gis module
=====================================

.. automodule:: wntr.stormwater.gis
:members:
:inherited-members:
:no-undoc-members:
:show-inheritance:
8 changes: 8 additions & 0 deletions documentation/apidoc/wntr.stormwater.graphics.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
wntr.stormwater.graphics module
=====================================

.. automodule:: wntr.stormwater.graphics
:members:
:inherited-members:
:no-undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions documentation/apidoc/wntr.stormwater.io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ wntr.stormwater.io module

.. automodule:: wntr.stormwater.io
:members:
:inherited-members:
:no-undoc-members:
:show-inheritance:
8 changes: 8 additions & 0 deletions documentation/apidoc/wntr.stormwater.metrics.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
wntr.stormwater.metrics module
=====================================

.. automodule:: wntr.stormwater.metrics
:members:
:inherited-members:
:no-undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions documentation/apidoc/wntr.stormwater.network.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ wntr.stormwater.network module

.. automodule:: wntr.stormwater.network
:members:
:inherited-members:
:no-undoc-members:
:show-inheritance:
8 changes: 8 additions & 0 deletions documentation/apidoc/wntr.stormwater.scenario.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
wntr.stormwater.scenario module
=====================================

.. automodule:: wntr.stormwater.scenario
:members:
:inherited-members:
:no-undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions documentation/apidoc/wntr.stormwater.sim.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ wntr.stormwater.sim module

.. automodule:: wntr.stormwater.sim
:members:
:inherited-members:
:no-undoc-members:
:show-inheritance:
10 changes: 5 additions & 5 deletions wntr/stormwater/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
The wntr.stormwater package contains storm water resilience functionality
through integration of WNTR with SWMM, pyswmm, and swmmio
"""
from wntr.stormwater.network import *
from wntr.stormwater.sim import *
from wntr.stormwater.gis import *
from wntr.stormwater.fragility import *
from wntr.stormwater.metrics import *
from wntr.stormwater.graphics import *
from wntr.stormwater.io import *
from wntr.stormwater.io import *
from wntr.stormwater.metrics import *
from wntr.stormwater.network import *
from wntr.stormwater.sim import *
from wntr.stormwater.scenario import *
222 changes: 222 additions & 0 deletions wntr/stormwater/gis.py
Original file line number Diff line number Diff line change
@@ -1 +1,223 @@
from wntr.gis import snap, intersect

import swmmio

import pandas as pd
import numpy as np

try:
from shapely.geometry import LineString, Point
has_shapely = True
except ModuleNotFoundError:
has_shapely = False

try:
import geopandas as gpd
has_geopandas = True
except ModuleNotFoundError:
has_geopandas = False

import wntr.network.elements

class StormWaterNetworkGIS:
"""
Storm Water network GIS class
Contains methods to create GeoDataFrames from StormWaterNetworkModel.
The ability to a create StormWaterNetworkModel from GeoDataFrames is
not implemented.
Parameters
----------
gis_data : dict, optional
Dictionary of GeoDataFrames containing data to populate an instance
of StormWaterNetworkGIS. Valid dictionary keys are
'junctions', 'outfalls','storage',
'conduits', 'weirs', 'orifices', and 'pumps'
Raises
------
ModuleNotFoundError
if missing either shapely or geopandas
"""

def __init__(self, gis_data=None) -> None:

if not has_shapely or not has_geopandas:
raise ModuleNotFoundError('shapley and geopandas are required')

self.junctions = gpd.GeoDataFrame()
self.outfalls = gpd.GeoDataFrame()
self.storage = gpd.GeoDataFrame()
self.conduits = gpd.GeoDataFrame()
self.weirs = gpd.GeoDataFrame()
self.orifices = gpd.GeoDataFrame()
self.pumps = gpd.GeoDataFrame()

if isinstance(gis_data, dict):
for name in ["junctions", "outfalls", "storage",
"conduits", "weirs", "orifices", "pumps"]:
gdf = getattr(self, name)
if name in gis_data.keys():
assert isinstance(gis_data[name], gpd.GeoDataFrame)
gdf = gis_data[name]

def _create_gis(self, swn, crs: str = None) -> None:
"""
Create GIS data from a water network model.
This method is used by wntr.network.io.to_gis
Note: patterns, curves, rules, controls, sources, and options are not
saved to the GIS data
Parameters
----------
wn : WaterNetworkModel
Water network model
crs : str, optional
Coordinate reference system, by default None
"""

# create an updated swmmio model from inp file
filename = 'temp.inp'
swn._swmmio_model.inp.save(filename)
m = swmmio.Model(filename)

self.junctions = m.nodes.geodataframe.loc[swn.junction_name_list,:]
self.outfalls = m.nodes.geodataframe.loc[swn.outfall_name_list,:]
self.storage = m.nodes.geodataframe.loc[swn.storage_name_list,:]

self.conduits = m.links.geodataframe.loc[swn.conduit_name_list,:]
self.weirs = m.links.geodataframe.loc[swn.weir_name_list,:]
self.orifices = m.links.geodataframe.loc[swn.orifice_name_list,:]
self.pumps = m.links.geodataframe.loc[swn.pump_name_list,:]

self.set_crs(crs, allow_override=True)

def _create_swn(self, append=None):
raise NotImplementedError

def to_crs(self, crs):
"""
Transform CRS of the junctions, tanks, reservoirs, pipes, pumps,
and valves GeoDataFrames.
Calls geopandas.GeoDataFrame.to_crs on each GeoDataFrame.
Parameters
----------
crs : str
Coordinate reference system
"""
for name in ["junctions", "outfalls", "storage",
"conduits", "weirs", "orifices", "pumps"]:
gdf = getattr(self, name)
if 'geometry' in gdf.columns:
gdf = gdf.to_crs(crs, inplace=True)

def set_crs(self, crs, allow_override=False):
"""
Set CRS of the junctions, tanks, reservoirs, pipes, pumps,
and valves GeoDataFrames.
Calls geopandas.GeoDataFrame.set_crs on each GeoDataFrame.
Parameters
----------
crs : str
Coordinate reference system
allow_override : bool (optional)
Allow override of existing coordinate reference system
"""

for name in ["junctions", "outfalls", "storage",
"conduits", "weirs", "orifices", "pumps"]:
gdf = getattr(self, name)
if 'geometry' in gdf.columns:
gdf = gdf.set_crs(crs, inplace=True,
allow_override=allow_override)

def add_node_attributes(self, values, name):
raise NotImplementedError

def add_link_attributes(self, values, name):
raise NotImplementedError

def _read(self, files, index_col='index'):

for name in ["junctions", "outfalls", "storage",
"conduits", "weirs", "orifices", "pumps"]:
gdf = getattr(self, name)
if name in files.keys():
data = gpd.read_file(files[name]).set_index(index_col)
gdf = pd.concat([gdf, data])

def read_geojson(self, files, index_col='index'):
"""
Append information from GeoJSON files to a WaterNetworkGIS object
Parameters
----------
files : dictionary
Dictionary of GeoJSON filenames, where the keys are in the set
('junction', 'tanks', 'reservoirs', 'pipes', 'pumps', 'valves') and
values are the corresponding GeoJSON filename
index_col : str, optional
Column that contains the element name
"""
self._read(files, index_col)

def read_shapefile(self, files, index_col='index'):
raise NotImplementedError

def _write(self, prefix: str, driver="GeoJSON") -> None:
"""
Write the WaterNetworkGIS object to GIS files
One file will be created for each type of network element (junctions,
pipes, etc.) if those elements exists in the network
Parameters
----------
prefix : str
Filename prefix, will have the element type (junctions,
pipes, etc.) appended
driver : str, optional
GeoPandas driver. Use "GeoJSON" for GeoJSON files, use :code:`None`
for Esri Shapefile folders, by default "GeoJSON"
"""

if driver is None or driver == "":
extension = ""
else:
extension = "." + driver.lower()

for name in ["junctions", "outfalls", "storage",
"conduits", "weirs", "orifices", "pumps"]:
gdf = getattr(self, name)
if len(gdf) > 0:
filename = prefix + "_" + name + extension
gdf.to_file(filename, driver=driver)

def write_geojson(self, prefix: str):
"""
Write the WaterNetworkGIS object to a set of GeoJSON files, one file
for each network element.
Parameters
----------
prefix : str
File prefix
"""
self._write(prefix=prefix, driver="GeoJSON")

def write_shapefile(self, prefix: str):
raise NotImplementedError

def _valid_names(self, complete_list=True, truncate_names=None):
raise NotImplementedError

def _shapefile_field_name_map(self):
raise NotImplementedError
Loading

0 comments on commit 7e621f0

Please sign in to comment.