{ "cells": [ { "cell_type": "markdown", "id": "7193aee8", "metadata": {}, "source": [ "# Make a mesh with MeshMaker\n", "\n", "This tutorial guides you through the process of creating a mesh for a field-based hydraulic study using QGIS and the `MeshMaker` class from Watlab.\n", "\n", "## Step 1: Shapefile in QGIS\n", "\n", "To begin, make sure QGIS is installed and that you have a clear understanding of your zones, boundaries, and regions. You’ll first create a shapefile (`.shp`) that represents the structure of your mesh.\n", "\n", "### Create the file .shp\n", "\n", "In QGIS, go to `Layer` → `Create Layer` → `New Shapefile Layer` and follow these steps:\n", "\n", "- Choose a clear and consistent file name, and save the layer in your working folder.\n", "- Geometry type: LineString\n", "- Coordinate Reference System (CRS): `Lambert 72` (EPSG:31370)\n", "- Add the following **attributes** (by adding `New Field`). Be careful to use these exact names (lowercase, no extra spaces or capital letters):\n", "\n", "| Name | Type |\n", "|----------|----------|\n", "| `zone` | Text | \n", "| `region` | Text | \n", "| `type` | Text | \n", "| `res` | Decimal |\n", "\n", "
\n", "\n", "
\n", "\"Create\n", "
\n", "\n", "### \"Draw\" the shapefile\n", "\n", "Use the editing tools (yellow pencil icon) to draw segments. Right‑click when you want to assign attributes. The idea is to draw lines around each zone, but the meaning of the attributes depends on the role of the line:\n", "\n", "- `zone` \n", " - If the line connects **two different zones** and participates in the closure of both, list them separated by a semicolon: `\"Foret 1 ; Ville 1\"`.\n", " - If the line is **internal to a single zone** (e.g., representing a weir, where you would apply a discharge or water level), then the `zone` field must remain empty (*NULL* by default in QGIS). \n", " - If the line **does not serve to close a zone** (for example, an island within a river that does not close the river zone), then you only need to specify the zone name of the island in the attribute field.\n", "\n", "- `region`\n", " - A region is a group of zones (e.g., several forest zones grouped under `\"Foret\"`). \n", " - If the line connects **two different regions** and participates in the closure of both, list them separated by a semicolon: `\"Foret ; Ville\"`.\n", " - If the line is **internal to a zone** (like a weir), the `region` field is left empty (*NULL* by default in QGIS). \n", " - If the line **does not serve to close a region** (for example, an island within a river that does not close the river region), then you only need to specify the region of the island in the attribute field.\n", "\n", "- `type` \n", " - Mandatory for **boundaries** where you want to apply conditions (e.g., `\"deversoir\"` for a weir, `\"Qin\"` for an imposed discharge, `\"Qout\"` at the end of the zone).\n", " - Leave empty if the line is simply a mesh boundary without specific hydraulic meaning.\n", "\n", "- `res`\n", " - Defines the **mesh resolution** near the line. For example, near riverbanks you may want a finer resolution than at the outer mesh boundary.\n", "\n", "\n", "The illustration below shows an example of a simple shapefile. \n", "- Red areas represent different zones. \n", "- Black labels indicate where the `type` attribute is defined (boundaries where conditions such as inflow or wate)\n", "\n", "
\n", "
\n", " \"example\n", "

Example shapefile with zones

\n", "
\n", "
\n", " \"attribute\n", "

Correctly structured attribute table

\n", "
\n", "
\n", "\n", "\n", "The illustration below shows an example of an internal line (here a weir) and the associated attributes:\n", "\n", "
\n", "\"Internal\n", "

Example of an internal boundary (weir) with attributes

\n", "
\n", "\n", "The illustration below shows a line inside a river (forming a small island) and the associated attribute table:\n", "\n", "
\n", "\"Island\n", "

Example of an island boundary with attribute table

\n", "
\n", "\n", "\n", "🚨 *Ensure all attributes are correctly filled in. Even a small typo or missing value can prevent the mesh from generating properly. Always double-check your attribute table.*\n", "\n", "\n", "### Save the .shp file\n", "\n", "Once your edits are complete, save the layer. In your chosen folder, you’ll find the main `.shp` file along with accompanying files (`.dbf`, `.shx`, `.prj`, etc.). Keep them together, they’re all needed for mesh generation." ] }, { "cell_type": "markdown", "id": "1428f26c", "metadata": {}, "source": [ "## Step 2: Load the shapefile and generate the mesh\n", "\n", "Now it's time to create the mesh using the geometry and attributes you defined in your shapefile. To do this, use the `MeshMaker` class from Watlab and provide the filename of your shapefile, then, use the `make_mesh()` function to generate the mesh. You can print the detected zones and regions to check if everything was correctly identified. \n", "\n", "💡 *The `MeshMaker` class includes other useful functions, feel free to explore them!*\n", "\n", "If you want to visualize the mesh directly while the code is running, set `display_ui=True` when calling `make_mesh`.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "d4c00280", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Zones: ['bois 2', 'ville 2', 'bois 1', 'ville 1', 'champs 1', 'Meuse 1']\n", "Regions: ['ville', 'champs', 'bois', 'Meuse']\n" ] } ], "source": [ "import watlab\n", "\n", "filename = \"sclayn.shp\"\n", "meshMaker = watlab.utils.MeshMaker(filename, type = \"shp\")\n", "\n", "# Optional: check detected zones and regions\n", "print(\"Zones:\", list(meshMaker.data.zones.keys()))\n", "print(\"Regions:\", list(meshMaker.data.regions.keys()))\n", "\n", "# Generate the mesh\n", "mesh_name = \"mesh_sclayn.msh\"\n", "meshMaker.make_mesh(mesh_name, display_ui=False)" ] }, { "cell_type": "markdown", "id": "63eab04b", "metadata": {}, "source": [ "\n", "\n", "
\n", "\"Mesh\"\n", "
" ] }, { "cell_type": "markdown", "id": "f5fe20dd", "metadata": {}, "source": [ "## Optionnal: Convert the mesh file to open it in QGIS ##\n", "\n", "The mesh file will be used in your Watlab model, but if you want to visualize it in QGIS, you need to convert it into a **GeoPackage (.gpkg)** file. This conversion can be done using **Gmsh**." ] }, { "cell_type": "code", "execution_count": 9, "id": "6fd4a151", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " * Convert \"mesh_Sclayn.msh\" into \"mesh_Sclayn.gpkg\" * \n" ] } ], "source": [ "import seamsh.gmsh\n", "import seamsh.geometry\n", "from osgeo import osr\n", "\n", "domain_srs = osr.SpatialReference()\n", "domain_srs.ImportFromEPSG(31370)\n", "\n", "domain = seamsh.geometry.Domain(domain_srs)\n", "\n", "output_srs = osr.SpatialReference() \n", "output_srs.ImportFromEPSG(31370)\n", "\n", "\n", "seamsh.gmsh.convert_to_gis(\"mesh_Sclayn.msh\", output_srs, \"mesh_Sclayn.gpkg\")" ] }, { "cell_type": "markdown", "id": "8ab42fed", "metadata": {}, "source": [ "
\n", "\"Mesh\n", "
\n" ] } ], "metadata": { "kernelspec": { "display_name": "watlab", "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.11.13" } }, "nbformat": 4, "nbformat_minor": 5 }