If the sewer data contain pipes which discharge to more than one sewer plant, we need to select pipes only for the one sewer plant of interest. The process to create a sub-sewershed for a branch is similar if a whole branch has a name or identifier specified in the attribute table.
We will use a couple of standard Python packages and GRASS GIS.
For now, the setup here assumes Linux. Instructions for Windows are available at GRASS GIS Jupyter notebooks wiki page.
# Import Python standard library and IPython packages we need.
import os
import subprocess
import sys
import json
from pathlib import Path
# Ask GRASS GIS where its Python packages are.
sys.path.append(
subprocess.check_output(["grass", "--config", "python_path"], text=True).strip()
)
# Import the GRASS GIS packages we need.
import grass.script as gs
import grass.jupyter as gj
This notebooks needs gravity mains (or all mains) as vector lines and census blocks as vector polygons with attributes. The gravity mains file should be in directory data/sewers
and should be named mains
with file extension appropriate for the format, e.g. mains.shp
. Census blocks should be in data/census
directory and named blocks
plus a file extension. Either rename the files or modify the code below if needed.
The paths can be not only directories but also ZIP files. Similarly, the files can also be layers. The names will be passed to GDAL.
sewers_directory = "data/sewers"
sewers_file = "mains"
grass_project = "data/sewershed_selection"
To compute the data, we will use a GRASS project (aka location).
!grass -e -c $sewers_directory $grass_project
session = gj.init(grass_project)
We will use vector lines of gravity mains as our sewershed network. Here, we are using Raleigh as an example. We will also use the US 2020 census blocks for North Carolina. The census blocks are polygons (i.e., areas).
We store the names of GRASS vector maps in Python variables and will use the variables from now on.
sewer_vector = "mains"
gs.run_command(
"v.import", input=sewers_directory, layer=sewers_file, output=sewer_vector
)
To specify selection according to a column name, see what columns are in the dataset:
gs.vector_columns(sewer_vector)
Let's see all unique values for the column of interest in the dataset:
sewer_select_column = "Discharge"
[
record[sewer_select_column]
for record in json.loads(
gs.read_command(
"v.db.select",
map=sewer_vector,
format="json",
columns=sewer_select_column,
group=sewer_select_column,
)
)["records"]
]
We need to specify both column name where the name or id attribute is stored and the specific name. For example, the attribute column name value can be be "Plant" and the value "Mill Creek".
Name of attribute column as a string, e.g., "Plant". None (without quotes) or ""
(only quotes) for no selection, but still running this code.
We already picked the column, so here we just check it:
sewer_select_column
Set the column value:
sewer_select_value = "Little Creek" # Name of plant or branch, e.g., "Mill Creek".
if sewer_select_column:
# Decide if the value needs quoting.
try:
float(sewer_select_value)
except ValueError:
sewer_select_value = f"'{sewer_select_value}'"
# Name for the selected pipes
sewershed_selection_vector = "tmp_sewershed_selection"
# Select only relevant part of the sewer network.
gs.run_command(
"v.extract",
input=sewer_vector,
output=sewershed_selection_vector,
where=f"{sewer_select_column} = {sewer_select_value}",
)
else:
# Using all the data without any selection.
sewershed_selection_vector = sewer_vector
Inspect the result:
gs.run_command("g.region", vector=sewer_vector, grow="5000", res=1)
sewer_pipes_map = gj.Map(width=600, use_region=True)
sewer_pipes_map.d_background(color="white")
sewer_pipes_map.d_vect(map=sewer_vector, color="#0D0887", legend_label="Not selected")
sewer_pipes_map.d_vect(
map=sewershed_selection_vector, color="#d95f02", legend_label="Selected"
)
sewer_pipes_map.d_legend_vect(flags="b", at=(75, 25), title="Sewer mains")
sewer_pipes_map.d_barscale(flags="n", at=(65, 7))
sewer_pipes_map.show()
Save results in a file:
output_file = (
Path(sewers_directory) / "sewershed_selection_vector.shp"
) # Modify as needed.
gs.run_command("v.out.ogr", input=sewershed_selection_vector, output=output_file)
Alternatively, in the following notebooks, we can continue using the GRASS project we created here.