ImperialCollegeLondon / SWMManywhere

SWMManywhere is used to derive and simulate a sewer network anywhere in the world
https://imperialcollegelondon.github.io/SWMManywhere/
BSD 3-Clause "New" or "Revised" License
2 stars 0 forks source link

Derive rivers from DEM rather than OSM #154

Open barneydobson opened 4 months ago

barneydobson commented 4 months ago

The OSM rivers layer seems a bit temperamental - the ones that it has are accurate but it is missing obvious ones. Something like pysheds and presumably pyflwdir enable river creation - this might be more reliable.

Also should be something to handle no rivers present - I guess related to #125

barneydobson commented 4 months ago

Below might be outdated - see also code in #191

Can be done by adding to geospatial_utilities.py/derive_subbasins_streamorder

    streams_feat = flw.streams(min_sto=streamorder)
    gdf_streams = gpd.GeoDataFrame.from_features(streams_feat, crs=grid.crs)

    return gdf_bas, gdf_streams

Can be done by adding to graph_utilities.py/clip_to_catchments

        subbasins, streams = go.derive_subbasins_streamorder(addresses.elevation,
                                subcatchment_derivation.subbasin_streamorder)

        # Insert rivers
        streams['edge_type'] = 'river'
        streams['id'] = [f'subbasin-river-{ix}' for ix in range(len(streams))]
        streams['length'] = streams['geometry'].length
        streams = streams[['geometry','edge_type','id','length']]
        G.add_edges_from([(u, v, d) for u, v, d in streams.itertuples(index=False)])

Initial check of this is promising - though probably will also need to include the rivers in the SWMM model as the generated rivers can go quite deep into the catchments - maybe this is not so difficult with #84

And a test:

def test_derive_subbasins():
    """Test the derive_subbasins_streamorder function."""
    elevation_fid = Path(__file__).parent / 'test_data' / 'elevation.tif'
    basins, streams = go.derive_subbasins_streamorder(elevation_fid,3)
    assert basins.shape[0] == 5
    assert streams.shape[0] == 6
    assert (streams.strord >= 3).all()