Skip to content

Commit 2cf3c06

Browse files
committed
Polish text in notebook
1 parent 57b9673 commit 2cf3c06

File tree

1 file changed

+116
-40
lines changed

1 file changed

+116
-40
lines changed

examples/a2-maastricht-gef/a2_maastricht_gef.py

Lines changed: 116 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,46 +18,71 @@
1818

1919
import marimo
2020

21-
__generated_with = "0.13.2"
21+
__generated_with = "0.13.11"
2222
app = marimo.App(width="medium")
2323

2424

25-
@app.cell
25+
@app.cell(hide_code=True)
2626
def _(mo):
2727
mo.md(
2828
"""
29-
# GEF Data for A2 Tunnel Maastricht
29+
# GEF Data for A2 Tunnel Maastricht
3030
31-
This notebook demonstrates how to
31+
This notebook demonstrates how to
3232
33-
1. Read in GEF files using [pygef](https://cemsbv.github.io/pygef/)
34-
1. Use `bedrock-ge` to load Ground Investigation (GI) data from these GEF files
35-
1. Convert that data into a standardized GI database using `bedrock-ge`
36-
1. Transform the GI data into 3D GIS features with proper coordinates and geometry ([OGC Simple Feature Access](https://en.wikipedia.org/wiki/Simple_Features))
37-
1. Explore and analyze the GI data using:
38-
* Interactive filtering with Pandas dataframes
39-
* Visualization on interactive maps with GeoPandas
40-
1. Export the processed GI database to a GeoPackage file for use in GIS software
33+
1. Read in Ground Investigation (GI) data from [GEF files]() using [pygef](https://cemsbv.github.io/pygef/)
34+
1. Use `bedrock-ge` to convert that data into a standardized GI database using `bedrock-ge`
35+
1. Transform the GI data into 3D spatial features with proper coordinates and geometry ([OGC Simple Feature](https://en.wikipedia.org/wiki/Simple_Features))
36+
1. Explore and analyze the GI data using interactive filtering with Pandas DataFrames and interactive visualization on a map with GeoPandas.
37+
1. Export the processed GI database to a GeoPackage file for use in other software, like QGIS.
4138
42-
## Context
39+
<details>
40+
<summary>What are GEF files?</summary>
41+
<p>
42+
<abbr>Geotechnical Exchange Format (GEF)</abbr> is a standardized, text-based format designed to facilitate the reliable exchange and archiving of geotechnical investigation data, particularly CPT results, across different organizations and software platforms. GEF can also be used for other types of soil tests and borehole data. It is widely used in the Netherlands in ground investigration.
43+
</p>
44+
</details>
4345
44-
The Koning Willem-Alexander Tunnel is a double-deck tunnel for motorized traffic in the Dutch city of Maastricht. The tunnel has a length of 2.5 kilometers (lower tunnel tubes) and 2.3 kilometers (upper tunnel tubes).
46+
<details>
47+
<summary>What is a DataFrame?</summary>
48+
<p>
49+
A DataFrame is like a spreadsheet, it is a two-dimensional data structure that holds data like a table with rows and columns.
50+
</p>
51+
</details>
4552
46-
The tunnel has moved the old A2 highway underground. It previously formed a barrier for the city and slowed traffic.
53+
## Context
4754
48-
### Geology
55+
The Koning Willem-Alexander Tunnel is a double-deck tunnel for motorized traffic in the Dutch city of Maastricht. The tunnel has a length of 2.5 kilometers (lower tunnel tubes) and 2.3 kilometers (upper tunnel tubes).
4956
57+
The tunnel has moved the old A2 highway underground. This highway previously formed a barrier for the city and slowed traffic.
5058
51-
The soil here consists of a coarse gravel layer with limestone limestone with karst phenomena underneath. There are also faults.
52-
Zwerfkeien
59+
### Geology
5360
54-
[Geotechniek-en-Risicos bij A2 Maastricht](https://www.cob.nl/magazines-brochures-en-nieuws/verdieping/verdieping-sept2012/geotechniek-en-risicos-bij-a2-maastricht/)
55-
[Source](https://archisarchief.cultureelerfgoed.nl/Archis2/Archeorapporten/24/AR26905/RAP%202709_4130060%20Maastricht%20A2-traverse.pdf)
61+
The uppermost layer consists of topsoil, clay, and loam, with a thickness of about 2 to 4 meters. These soft Holocene deposits are attributed to the Boxtel Formation, laid down by the Meuse River, as the tunnel is situated in a former river arm.
5662
57-
## Ground Investigation Data
63+
Beneath the surface layer lies an approximately 8-meter-thick gravel deposit. This gravel acts as a significant aquifer and was a key factor in the groundwater management strategies required for the tunnel construction.
5864
59-
The GI data was downloaded from [Dinoloket](https://www.dinoloket.nl/ondergrondgegevens), a platform where you can view and request data and models from TNO and BRO about the subsurface of the Netherlands.
60-
"""
65+
Below the gravel lies a fissured limestone layer belonging to the Maastricht Formation (mergel). This layer is a very weak, porous, sandy, shallow marine limestone, often weathered, and includes chalk and calcarenite components.
66+
67+
The limestone is relatively young and shallow, resulting in low compaction and cementation. Its mechanical strength is highly variable and generally low, especially when saturated with groundwater.
68+
69+
Extensive geophysical surveys and borehole investigations were conducted to map the subsurface, identify faults, flint layers, and assess the risk of cavities within the limestone. While faults were detected, no significant cavities were found.
70+
71+
The stability of the excavation pit was monitored in real-time, with groundwater levels and pressures carefully controlled to prevent collapse or excessive deformation of the pit walls.
72+
73+
Due to the high permeability of the gravel and fissured limestone, groundwater management was a major challenge. Over 500 wells were drilled to depths of up to 32 meters for dewatering, and a reinfiltration system was implemented to return nearly all pumped water to the ground, protecting local buildings and ecosystems.
74+
75+
#### Sources
76+
77+
* [Tunnel A2 Maastricht: Groundwater Management with DSI System](https://www.tunnel-online.info/en/artikel/tunnel-a2-maastricht-groundwater-management-with-dsi-system-1564115.html)
78+
* [Geotechniek-en-Risicos bij A2 Maastricht](https://www.cob.nl/magazines-brochures-en-nieuws/verdieping/verdieping-sept2012/geotechniek-en-risicos-bij-a2-maastricht/)
79+
* [Laboratory Tests on Dutch Limestone (Mergel) ](https://onepetro.org/ISRMEUROCK/proceedings-abstract/EUROCK15/All-EUROCK15/ISRM-EUROCK-2015-072/43534)
80+
* [Eduard van Herk en Bjorn Vink](https://a2maastricht.nl/application/files/3315/2060/1222/Interview_Eduard_van_Herk_en_Bjorn_Vink.pdf)
81+
82+
## Ground Investigation Data
83+
84+
The GI data was downloaded from [Dinoloket](https://www.dinoloket.nl/ondergrondgegevens), a platform where you can view and request data and models from TNO and BRO about the subsurface of the Netherlands.
85+
"""
6186
)
6287
return
6388

@@ -106,25 +131,35 @@ def _(boreholes, index, pygef):
106131
def _(mo):
107132
mo.md(
108133
r"""
109-
## Converting multiple GEF files to a relational database
134+
## Converting multiple GEF files to a relational database
110135
111-
First, let's check in which projected coordinate system the provided data was recorded
112-
"""
136+
Rather than dealing with a folder of files, we would like to combine all files into a single database with spatial information. This is where Bedrock comes in.
137+
138+
### Relational Databases
139+
140+
A [relational database](https://observablehq.com/blog/databases-101-basics-data-analysts#what-are-relational-databases) is a database with multiple tables that are linked to each other with relations. This type of database is ideal for storing GI data, given its [hierarchical structure](https://bedrock.engineer/docs/#hierarchical-nature-of-gi-data).
141+
142+
In Python it's convenient to represent a relational database as a dictionary of DataFrame's.
143+
144+
### Coordinated Reference System (CRS)
145+
146+
First, let's check in which projected coordinate system the provided data was recorded.
147+
"""
113148
)
114149
return
115150

116151

117152
@app.cell
118153
def _(boreholes):
119-
boreholes[1].delivered_location.srs_name
154+
code = {bore.delivered_location.srs_name for bore in boreholes}.pop()
155+
orig_epsg_code = code.split("EPSG::")[-1]
156+
orig_crs = f"EPSG:{orig_epsg_code}"
157+
orig_crs
120158
return
121159

122160

123161
@app.cell
124-
def _(boreholes):
125-
code = {bore.delivered_location.srs_name for bore in boreholes}.pop()
126-
# epsg_code = code.split("EPSG::")[-1]
127-
# crs = f"EPSG:{epsg_code}"
162+
def _():
128163
crs = "EPSG:7415"
129164
return (crs,)
130165

@@ -133,10 +168,11 @@ def _(boreholes):
133168
def _(mo):
134169
mo.md(
135170
r"""
136-
EPSG:28992 is [Rijksdriehoekscoördinaten](https://nl.wikipedia.org/wiki/Rijksdriehoeksco%C3%B6rdinaten), also called Amersfoort / RD New.
171+
The data is in EPSG:28992, which is the [Rijksdriehoekscoördinaten (NL)](https://nl.wikipedia.org/wiki/Rijksdriehoeksco%C3%B6rdinaten) system, also called "Amersfoort / RD New". This reference system does not include elevation.
137172
138-
EPSG:7415 is with Amersfoort / RD New + NAP height. ie with elevation which we need for 3D geometry
139-
"""
173+
To represent GI data spatially in 3D geometry we need a CRS with elevation. That's why we will use
174+
EPSG:7415 Amersfoort / RD New + NAP height.
175+
"""
140176
)
141177
return
142178

@@ -149,7 +185,7 @@ def _():
149185

150186
@app.cell
151187
def _():
152-
project_uid = "Maastricht A2"
188+
project_uid = "Maastricht A2 tunnel"
153189
return (project_uid,)
154190

155191

@@ -181,6 +217,18 @@ def process_data(bore):
181217
return df
182218

183219

220+
@app.cell(hide_code=True)
221+
def _(mo):
222+
mo.md(
223+
r"""
224+
Here, we create a new DataFrame for locations and remap the GEF keys to follow Bedrock's conventions.
225+
We need to map `alias` to `location_source_id` and `delivered_vertical_position_offset` to `ground_level_elevation` for example.
226+
We also need to create a **unique identifier** and add `project_uid` as a key to relate it the project.
227+
"""
228+
)
229+
return
230+
231+
184232
@app.cell
185233
def _(boreholes, pd, project_uid):
186234
locations_df = pd.DataFrame([
@@ -208,9 +256,31 @@ def _(calculate_location_gis_geometry, crs, locations_df):
208256
return (locations,)
209257

210258

259+
@app.cell(hide_code=True)
260+
def _(mo):
261+
mo.md(
262+
r"""
263+
## Displaying the GI locations on a map
264+
265+
Rather than multiple tables (DataFrames) and soil profiles, we would like see an overview of what this ground investigation covers. It's **spatial** data after all, let's view it in a spatial context.
266+
267+
### Web Mapping Caveats
268+
269+
Web-mapping tools are rarely capable of handling geometry in non-WGS84 coordinates. Additionally, vertical lines are not visible when looking at a map from straight above. That's why use `create_lon_lat_height_table` to create points in the WGS84 CRS so we can view the locations of the boreholes.
270+
"""
271+
)
272+
return
273+
274+
211275
@app.cell
212276
def _(create_lon_lat_height_table, crs, locations):
213-
create_lon_lat_height_table(locations, crs).explore()
277+
create_lon_lat_height_table(locations, crs).explore(marker_kwds={"radius":5})
278+
return
279+
280+
281+
@app.cell
282+
def _(mo):
283+
mo.md(r"""Here we create a DataFrame for the In-Situ data of all locations. To relate to locations and the project we add foreign keys.""")
214284
return
215285

216286

@@ -236,6 +306,12 @@ def _(insitu):
236306
return
237307

238308

309+
@app.cell
310+
def _(mo):
311+
mo.md(r"""In-situ data is also spatial data. It has a location, a depth and a height. We can also turn it into spatial data using Bedrock's `calculate_in_situ_gis_geometry` """)
312+
return
313+
314+
239315
@app.cell
240316
def _(calculate_in_situ_gis_geometry, crs, insitu, locations):
241317
insitu_geo = calculate_in_situ_gis_geometry(insitu, locations, crs)
@@ -252,12 +328,12 @@ def _(insitu_geo):
252328
def _(mo):
253329
mo.md(
254330
r"""
255-
## Saving the GI geospatial database as a GeoPackage (.gpkg)
331+
## Saving the GI geospatial database as a GeoPackage (.gpkg)
256332
257-
Finally, lets write it to an actual geospatial database file, so we can share our GI data with others. For example, to reuse it in other notebooks, create dashboards, access the GI data in QGIS or ArcGIS, and more...
333+
Finally, we'll write it to an actual geospatial database file, a GeoPackage, so we can share our GI data with others, for example, to reuse it in other computational notebooks, create dashboards, access the GI data in QGIS or ArcGIS, and more...
258334
259-
A GeoPackage is an <abbr title="Open Geospatial Consortium">OGC-standardized</abbr> extension of SQLite (a relational database in a single file, .sqlite or .db) that allows you to store any type of GIS data (both raster as well as vector data) in a single file that has the .gpkg extension. Therefore, many (open-source) GIS software packages support GeoPackage!
260-
"""
335+
A GeoPackage is an <abbr title="Open Geospatial Consortium">OGC-standardized</abbr> extension of SQLite (a relational database in a single file, .sqlite or .db) that allows you to store any type of GIS data (both raster as well as vector data) in a single file that has the .gpkg extension. Therefore, many (open-source) GIS software packages support GeoPackage!
336+
"""
261337
)
262338
return
263339

0 commit comments

Comments
 (0)