{ "cells": [ { "cell_type": "markdown", "id": "942c257a-82ba-4e59-8e96-c128bf4b77f2", "metadata": {}, "source": [ "# Select subsewershed\n", "\n", "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.\n", "\n", "## Data requirements\n", "\n", "- Sewer mains\n", " * Sewer gravity mains and possibly force mains." ] }, { "cell_type": "markdown", "id": "3940df54-9ff2-4f65-bf65-0f7ff441ed8b", "metadata": {}, "source": [ "## Software setup \n", "\n", "We will use a couple of standard Python packages and GRASS GIS.\n", "\n", "For now, the setup here assumes Linux. Instructions for Windows are available at [GRASS GIS Jupyter notebooks wiki page](https://grasswiki.osgeo.org/wiki/GRASS_GIS_Jupyter_notebooks#Running_a_Jupyter_notebook_locally)." ] }, { "cell_type": "code", "execution_count": null, "id": "fc0a5ebd-a5eb-4acb-bde8-163b4d3e7f75", "metadata": {}, "outputs": [], "source": [ "# Import Python standard library and IPython packages we need.\n", "import os\n", "import subprocess\n", "import sys\n", "import json\n", "from pathlib import Path\n", "\n", "# Ask GRASS GIS where its Python packages are.\n", "sys.path.append(\n", " subprocess.check_output([\"grass\", \"--config\", \"python_path\"], text=True).strip()\n", ")\n", "\n", "# Import the GRASS GIS packages we need.\n", "import grass.script as gs\n", "import grass.jupyter as gj" ] }, { "cell_type": "markdown", "id": "8db8aad3-63c1-459d-b52a-6f7a89604938", "metadata": {}, "source": [ "## Get the data ready\n", "\n", "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.\n", "\n", "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." ] }, { "cell_type": "code", "execution_count": null, "id": "a62836cf-b636-4489-8b33-c5b111aeb92e", "metadata": {}, "outputs": [], "source": [ "sewers_directory = \"data/sewers\"\n", "sewers_file = \"mains\"" ] }, { "cell_type": "code", "execution_count": null, "id": "683750f2-d799-4951-8d31-a33ad43c05c2", "metadata": {}, "outputs": [], "source": [ "grass_project = \"data/sewershed_selection\"" ] }, { "cell_type": "markdown", "id": "0165f3d1-ee98-4d1d-842c-369f165b7fc8", "metadata": {}, "source": [ "To compute the data, we will use a GRASS project (aka location)." ] }, { "cell_type": "code", "execution_count": null, "id": "f1be1e47-63f3-4215-af9d-3b73f7e3d126", "metadata": {}, "outputs": [], "source": [ "!grass -e -c $sewers_directory $grass_project" ] }, { "cell_type": "code", "execution_count": null, "id": "d62fc29e-7390-48a8-bee0-7b32f645c3df", "metadata": {}, "outputs": [], "source": [ "session = gj.init(grass_project)" ] }, { "cell_type": "markdown", "id": "0a15c8e9-ed27-444e-b812-a5681060f2f3", "metadata": {}, "source": [ "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).\n", "\n", "We store the names of GRASS vector maps in Python variables and will use the variables from now on." ] }, { "cell_type": "code", "execution_count": null, "id": "eea83cbc-b1db-4aab-8dc9-7526df1de665", "metadata": {}, "outputs": [], "source": [ "sewer_vector = \"mains\"" ] }, { "cell_type": "code", "execution_count": null, "id": "7b18a383-90ea-495b-ac29-5c6e7b48a277", "metadata": {}, "outputs": [], "source": [ "gs.run_command(\n", " \"v.import\", input=sewers_directory, layer=sewers_file, output=sewer_vector\n", ")" ] }, { "cell_type": "markdown", "id": "245a8f1c-2846-4b28-a08c-0a87efff4748", "metadata": {}, "source": [ "## Explore the data\n", "\n", "To specify selection according to a column name, see what columns are in the dataset:" ] }, { "cell_type": "code", "execution_count": null, "id": "f9f3baf0-7521-46b6-93d3-14dfc90df4cc", "metadata": {}, "outputs": [], "source": [ "gs.vector_columns(sewer_vector)" ] }, { "cell_type": "markdown", "id": "2598ec4e-bfe2-437b-af4f-47d2f4c39b28", "metadata": {}, "source": [ "Let's see all unique values for the column of interest in the dataset:" ] }, { "cell_type": "code", "execution_count": null, "id": "389a5324-681e-43a6-888f-dc01dc251e2e", "metadata": {}, "outputs": [], "source": [ "sewer_select_column = \"Discharge\"" ] }, { "cell_type": "code", "execution_count": null, "id": "ff0d786d-83c0-4bd9-b08c-675c3c34e186", "metadata": {}, "outputs": [], "source": [ "[\n", " record[sewer_select_column]\n", " for record in json.loads(\n", " gs.read_command(\n", " \"v.db.select\",\n", " map=sewer_vector,\n", " format=\"json\",\n", " columns=sewer_select_column,\n", " group=sewer_select_column,\n", " )\n", " )[\"records\"]\n", "]" ] }, { "cell_type": "markdown", "id": "f0df6243-5580-4f0b-8c12-da7e38e65c62", "metadata": {}, "source": [ "## Select relevant part of the sewer data using attributes\n", "\n", "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\".\n", "\n", "Name of attribute column as a string, e.g., \"Plant\". None (without quotes) or `\"\"` (only quotes) for no selection, but still running this code.\n", "\n", "We already picked the column, so here we just check it:" ] }, { "cell_type": "code", "execution_count": null, "id": "53e4b0f8-5d91-44cc-a6a9-2bca7c74085d", "metadata": {}, "outputs": [], "source": [ "sewer_select_column" ] }, { "cell_type": "markdown", "id": "8871aa75-e053-48db-85bf-f706c07a3236", "metadata": {}, "source": [ "Set the column value:" ] }, { "cell_type": "code", "execution_count": null, "id": "3e632699-3c4d-43e5-8b5a-2eddfb702863", "metadata": {}, "outputs": [], "source": [ "sewer_select_value = \"Little Creek\" # Name of plant or branch, e.g., \"Mill Creek\"." ] }, { "cell_type": "code", "execution_count": null, "id": "3c5d5b39-05ce-419c-a1dc-fd451d321efb", "metadata": {}, "outputs": [], "source": [ "if sewer_select_column:\n", " # Decide if the value needs quoting.\n", " try:\n", " float(sewer_select_value)\n", " except ValueError:\n", " sewer_select_value = f\"'{sewer_select_value}'\"\n", "\n", " # Name for the selected pipes\n", " sewershed_selection_vector = \"tmp_sewershed_selection\"\n", "\n", " # Select only relevant part of the sewer network.\n", " gs.run_command(\n", " \"v.extract\",\n", " input=sewer_vector,\n", " output=sewershed_selection_vector,\n", " where=f\"{sewer_select_column} = {sewer_select_value}\",\n", " )\n", "else:\n", " # Using all the data without any selection.\n", " sewershed_selection_vector = sewer_vector" ] }, { "cell_type": "markdown", "id": "6b9dbe6f-e2af-47a6-a707-9d1526ac9ea5", "metadata": {}, "source": [ "Inspect the result:" ] }, { "cell_type": "code", "execution_count": null, "id": "c307820b-20f2-47dd-ab91-7fc49c04f718", "metadata": {}, "outputs": [], "source": [ "gs.run_command(\"g.region\", vector=sewer_vector, grow=\"5000\", res=1)\n", "sewer_pipes_map = gj.Map(width=600, use_region=True)\n", "sewer_pipes_map.d_background(color=\"white\")\n", "sewer_pipes_map.d_vect(map=sewer_vector, color=\"#0D0887\", legend_label=\"Not selected\")\n", "sewer_pipes_map.d_vect(\n", " map=sewershed_selection_vector, color=\"#d95f02\", legend_label=\"Selected\"\n", ")\n", "sewer_pipes_map.d_legend_vect(flags=\"b\", at=(75, 25), title=\"Sewer mains\")\n", "sewer_pipes_map.d_barscale(flags=\"n\", at=(65, 7))\n", "sewer_pipes_map.show()" ] }, { "cell_type": "markdown", "id": "d2ae2c1c-86e9-4414-8682-415dd7def45c", "metadata": {}, "source": [ "## Save result to file\n", "\n", "Save results in a file:" ] }, { "cell_type": "code", "execution_count": null, "id": "03d6735b-b962-49eb-9061-04c852864717", "metadata": {}, "outputs": [], "source": [ "output_file = (\n", " Path(sewers_directory) / \"sewershed_selection_vector.shp\"\n", ") # Modify as needed.\n", "gs.run_command(\"v.out.ogr\", input=sewershed_selection_vector, output=output_file)" ] }, { "cell_type": "markdown", "id": "8de5a20a-bf33-4f70-8dd3-36f35121778d", "metadata": {}, "source": [ "Alternatively, in the following notebooks, we can continue using the GRASS project we created here." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 5 }