Skip to content

Commit 12dcfcd

Browse files
committed
Tweaks
1 parent 269989a commit 12dcfcd

File tree

1 file changed

+87
-57
lines changed

1 file changed

+87
-57
lines changed

examples/a2_maastricht_gef/a2_maastricht_gef_to_brgi_geodb.py

Lines changed: 87 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,44 @@
11
# /// script
22
# requires-python = ">=3.12"
33
# dependencies = [
4-
# "bedrock-ge==0.3.1",
4+
# "bedrock-ge==0.3.2",
55
# "folium==0.20.0",
6-
# "geopandas==1.1.0",
7-
# "mapclassify==2.9.0",
8-
# "marimo",
9-
# "matplotlib==3.10.1",
6+
# "geopandas==1.1.1",
7+
# "mapclassify==2.8.1",
8+
# "marimo[mcp]",
9+
# "matplotlib==3.10.7",
1010
# "pyproj==3.7.1",
1111
# "requests==2.32.3",
12-
# "shapely==2.1.1",
13-
# "pygef"==0.11.1"
12+
# "shapely==2.1.2",
13+
# "pygef==0.13.0",
14+
# "pandas==2.3.3",
15+
# "pyarrow==21.0.0",
1416
# ]
1517
# ///
1618

1719
import marimo
1820

19-
__generated_with = "0.14.7"
20-
app = marimo.App(width="medium")
21+
__generated_with = "0.17.6"
2122
app = marimo.App(
22-
app_title="Maastricht, GEF boreholes to a Bedrock GI Geospatial Database",
23+
width="medium",
24+
app_title="Maastricht A2 Tunnel GEF-BORE data to a Bedrock GI Geospatial Database",
2325
)
2426

27+
2528
@app.cell(hide_code=True)
2629
def _(mo):
27-
mo.md(
28-
"""
30+
mo.md("""
2931
# GEF Data for A2 Tunnel Maastricht
3032
33+
<img src="https://bedrock.engineer/Bedrock_TextRight.png" alt="Bedrock logo" width="180" />
34+
3135
This notebook demonstrates how to
3236
33-
1. Read in Ground Investigation (GI) data from [GEF files]() using the [pygef](https://cemsbv.github.io/pygef/) library.
34-
1. Use `bedrock-ge` to convert that data into a standardized GI database.
37+
1. Read in Ground Investigation (GI) data from [GEF files](https://bedrock.engineer/reference/formats/gef/gef/) using the [pygef](https://cemsbv.github.io/pygef/) library.
38+
1. Use [`bedrock-ge`](https://github.com/bedrock-engineer/bedrock-ge) to convert that data into a standardized GI database.
3539
1. Transform the GI data into 3D spatial features with proper coordinates and geometry ([OGC Simple Feature](https://en.wikipedia.org/wiki/Simple_Features))
3640
1. Explore and analyze the GI data using interactive filtering with Pandas DataFrames and interactive visualization on a map using GeoPandas.
37-
1. Export the processed GI database to a GeoPackage file for use in GIS software.
41+
1. Export the processed GI database to a GeoPackage file for use in GIS software, like QGIS or ArcGIS.
3842
3943
<details>
4044
<summary>What are GEF files?</summary>
@@ -43,7 +47,7 @@ def _(mo):
4347
text-based format designed to facilitate the reliable exchange and archiving
4448
of geotechnical investigation data, particularly CPT results, across
4549
different organizations and software platforms. GEF can also be used for
46-
other types of soil tests and borehole data. It is widely used in the
50+
other types of soil tests, like <a href="https://bedrock.engineer/reference/formats/gef/gef-cpt/">CPTs</a>. It is widely used in the
4751
Netherlands in ground investigation.
4852
</p>
4953
</details>
@@ -58,11 +62,11 @@ def _(mo):
5862
## Ground Investigation Data
5963
6064
The GI data was downloaded from [Dinoloket](https://www.dinoloket.nl/ondergrondgegevens), a platform for viewing and request data from the Dutch Geological Survey and Basisregistratie Ondergrond about the subsurface of the Netherlands.
61-
We are using GEF files that contain borehole data.
65+
We are using [GEF files](https://bedrock.engineer/reference/formats/gef/gef/) that contain borehole data, [GEF-BORE](https://bedrock.engineer/reference/formats/gef/gef-bore/).
6266
6367
## Context
6468
65-
The Koning Willem-Alexander Tunnel is a double-deck tunnel for motorized traffic in the city Maastricht, the Netherlands. The tunnel has a length of 2.5 kilometers (lower tunnel tubes) and 2.3 kilometers (upper tunnel tubes).
69+
The [Koning Willem-Alexander Tunnel](https://www.rijkswaterstaat.nl/wegen/wegenoverzicht/a2/koning-willem-alexandertunnel-a2-n2) is a double-deck tunnel for motorized traffic in the city Maastricht, the Netherlands. The tunnel has a length of 2.5 kilometers (lower tunnel tubes) and 2.3 kilometers (upper tunnel tubes).
6670
6771
The tunnel has moved the old A2 highway underground. This highway previously formed a barrier for the city and slowed traffic.
6872
@@ -76,11 +80,13 @@ def _(mo):
7680
7781
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.
7882
83+
## Ground Investigation & Operations
84+
7985
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.
8086
8187
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.
8288
83-
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.
89+
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 m for dewatering, and a reinfiltration system was implemented to return nearly all pumped water to the ground, protecting local buildings and ecosystems.
8490
8591
<details>
8692
<summary>
@@ -93,9 +99,7 @@ def _(mo):
9399
<li><a href="https://a2maastricht.nl/application/files/3315/2060/1222/Interview_Eduard_van_Herk_en_Bjorn_Vink.pdf">Interview Eduard van Herk en Bjorn Vink</li>
94100
</ul>
95101
</details>
96-
97-
"""
98-
)
102+
""")
99103
return
100104

101105

@@ -134,15 +138,14 @@ def _(boreholes, index):
134138

135139

136140
@app.cell
137-
def _(boreholes, index, pygef):
138-
pygef.plotting.plot_bore(boreholes[index])
141+
def _(boreholes, index, plot_bore):
142+
plot_bore(boreholes[index])
139143
return
140144

141145

142146
@app.cell(hide_code=True)
143147
def _(mo):
144-
mo.md(
145-
r"""
148+
mo.md(r"""
146149
## Converting multiple GEF files to a relational database
147150
148151
Rather than dealing with a folder of files in a format that very few software can handle, we would like to combine all of these files into a single database with spatial information. This is where `bedrock-ge` comes in.
@@ -156,30 +159,26 @@ def _(mo):
156159
### Coordinated Reference System (CRS)
157160
158161
First, let's check in which projected coordinate system the provided data was recorded.
159-
"""
160-
)
162+
""")
161163
return
162164

163165

164166
@app.cell
165167
def _(CRS, boreholes):
166168
code = {bore.delivered_location.srs_name for bore in boreholes}.pop()
167-
orig_epsg_code = code.split("EPSG::")[-1]
168-
orig_crs = CRS(f"EPSG:{orig_epsg_code}")
169+
orig_crs = CRS(code)
169170
orig_crs
170171
return (orig_crs,)
171172

172173

173174
@app.cell(hide_code=True)
174175
def _(mo):
175-
mo.md(
176-
r"""
176+
mo.md(r"""
177177
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.
178178
179179
To represent GI data spatially in 3D geometry we need a CRS **with elevation**. That's why we will use
180180
EPSG:5709 NAP height as the vertical CS.
181-
"""
182-
)
181+
""")
183182
return
184183

185184

@@ -213,13 +212,11 @@ def _(orig_crs, pd, project_uid, vertical_crs):
213212

214213
@app.cell(hide_code=True)
215214
def _(mo):
216-
mo.md(
217-
r"""
218-
Here, we create a new DataFrame for locations and remap the GEF keys to follow Bedrock's conventions.
215+
mo.md(r"""
216+
Here, we create a new DataFrame for locations and remap the GEF keys to follow Bedrock's conventions.
219217
We need to map `alias` to `location_source_id` and `delivered_vertical_position_offset` to `ground_level_elevation` for example.
220218
We also need to create a **unique identifier** and add `project_uid` as a key to relate it the project.
221-
"""
222-
)
219+
""")
223220
return
224221

225222

@@ -245,8 +242,16 @@ def _(boreholes, pd, project_uid):
245242

246243

247244
@app.cell
245+
def _(locations_df):
246+
locations_df
247+
return
248+
249+
250+
@app.cell(hide_code=True)
248251
def _(mo):
249-
mo.md(r"""Here we create a DataFrame for the In-Situ data of all locations. To relate the in-situ data to locations and the project, we add foreign keys.""")
252+
mo.md(r"""
253+
Here we create a DataFrame for the In-Situ data of all GI locations. To relate the in-situ data to locations and the project, we add foreign keys.
254+
""")
250255
return
251256

252257

@@ -284,6 +289,12 @@ def _(brgi_db, create_brgi_geodb):
284289
return (brgi_geodb,)
285290

286291

292+
@app.cell
293+
def _(brgi_geodb):
294+
brgi_geodb.InSituTests["interpretation"]
295+
return
296+
297+
287298
@app.function
288299
def process_data(bore):
289300
df = bore.data.to_pandas().dropna(axis=1, how='all').rename(columns=
@@ -299,38 +310,41 @@ def process_data(bore):
299310

300311
@app.cell(hide_code=True)
301312
def _(mo):
302-
mo.md(
303-
r"""
313+
mo.md(r"""
304314
## Displaying the GI locations on a map
305315
306316
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.
307317
308-
`create_brgi_geodb` creates a `LonLatHeight` table which contains the GI locations at ground level in WGS84 - World Geodetic System 1984 - EPSG:4326 coordinates (Longitude, Latitude, Ellipsoidal Height).
318+
`create_brgi_geodb` creates a `LonLatHeight` table which contains the GI locations at ground level as points in WGS84 - World Geodetic System 1984 - EPSG:4326 coordinates (Longitude, Latitude, Ellipsoidal Height).
309319
310320
311321
The reason for creating the `LonLatHeight` table is that vertical lines in projected Coordinate Reference Systems (CRS) are often not rendered nicely by default in all web-mapping software. Vertical lines are often not visible when looking at a map from above, and not all web-mapping software is capable of handling geometry in non-WGS84, i.e. (Lon, Lat) coordinates.
312-
"""
313-
)
322+
""")
314323
return
315324

316325

317326
@app.cell
318327
def _(brgi_geodb):
319-
brgi_geodb.LonLatHeight.explore(marker_kwds={"radius":5})
328+
brgi_geodb.LonLatHeight
329+
return
330+
331+
332+
@app.cell
333+
def _(brgi_geodb):
334+
map = brgi_geodb.LonLatHeight.explore(marker_kwds={"radius":5})
335+
map
320336
return
321337

322338

323339
@app.cell(hide_code=True)
324340
def _(mo):
325-
mo.md(
326-
r"""
341+
mo.md(r"""
327342
## Saving the GI geospatial database as a GeoPackage (.gpkg)
328343
329344
Finally, we'll write it to an actual geospatial database file, a [GeoPackage](https://www.geopackage.org/), 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...
330345
331346
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!
332-
"""
333-
)
347+
""")
334348
return
335349

336350

@@ -341,15 +355,35 @@ def _(brgi_db, check_brgi_geodb):
341355

342356

343357
@app.cell
344-
def _(Path, brgi_db, write_brgi_db_to_file):
345-
write_brgi_db_to_file(brgi_db, path=Path("./output/A2_Maastricht.gpkg"), driver="GPKG")
358+
def _(brgi_db, write_brgi_db_to_file):
359+
write_brgi_db_to_file(brgi_db, path="./output/A2_Maastricht.gpkg", driver="GPKG")
360+
return
361+
362+
363+
@app.cell
364+
def _(mo):
365+
mo.md(r"""
366+
## Visualising the Data in a 3D Webmap
367+
368+
As standardized geospatial data, we can visualize our GI in a wealth of ways.
369+
370+
View one of the Bedrock guides to see what you can do with your data.
371+
372+
* [Viewing Geotechnical Data in QGIS](https://bedrock.engineer/guides/viewing-qgis/)
373+
* [Viewing Geotechnical Data on a Web Map](https://bedrock.engineer/guides/viewing-webmap/)
374+
375+
### 3D Webmap with Cesium.js
376+
377+
View the data from this example interactively in a 3D webmap.
378+
""")
346379
return
347380

348381

349382
@app.cell
350383
def _():
351384
import marimo as mo
352385
import pygef
386+
from pygef.plotting import plot_bore
353387
import os
354388
from pathlib import Path
355389
import pandas as pd
@@ -377,15 +411,11 @@ def _():
377411
create_brgi_geodb,
378412
mo,
379413
pd,
414+
plot_bore,
380415
pygef,
381416
write_brgi_db_to_file,
382417
)
383418

384419

385-
@app.cell
386-
def _():
387-
return
388-
389-
390420
if __name__ == "__main__":
391421
app.run()

0 commit comments

Comments
 (0)