Example of DOV search methods for samples (monsters)
Use cases explained below
Get samples in a bounding box
Get samples in a bounding box based on specific properties
Get sample based on fields not available in the standard output dataframe
Get a boxplot with the depth distribution of samples with sampling instrument ‘steekbuis’
Finding the boreholes associated with the monsters and visualize results
Adding the sampled object to the monster dataframe
[51]:
%matplotlib inline
import inspect, sys
[52]:
# check pydov path
import pydov
Get information about the datatype ‘Monster’
[61]:
from pydov.search.monster import MonsterSearch
monster = MonsterSearch()
A description is provided for the ‘Monster’ datatype:
[62]:
print(monster.get_description())
Deze kaartlaag bevat monsters die gekoppeld zijn aan een of meerdere boringen of aan een of meerdere monsters. Deze monsters zijn gekenmerkt door een diepte ten opzichte van het maaiveld, door de manier van staalname en de materiaalklasse. De geografische ligging (X en Y (mL72) en Z (mTAW)) nemen ze over van de gekoppelde boring(en). Het type bemonsterd materiaal wordt beschreven in de 'Materiaalklasse'. Aan deze monsters kunnen er observaties gekoppeld zijn, zoals waarnemingen en resultaten van kwaliteitsanalyses in het laboratorium of in het veld en/of referenties naar bepaalde analyses. De gegevens van de monsters en bepaalde observaties kunnen worden geëxporteerd in een rapport.
The different fields that are available for objects of the ‘Monster’ datatype can be requested with the get_fields() method:
[63]:
fields = monster.get_fields()
# print available fields
for f in fields.values():
print(f['name'])
id
naam
pkey_monster
gekoppeld_aan
pkey_parents
materiaalklasse
diepte_van_m
diepte_tot_m
aantal_observaties
datum_monstername
monstersamenstelling
monstertype
bemonsteringsprocedure
bemonsteringsinstrument
bemonstering_door
opmerkingen
actuele_opslaglocatie
opdracht
permkey_monster
geom
You can get more information of a field by requesting it from the fields dictionary:
name: name of the field
definition: definition of this field
cost: currently this is either 1 or 10, depending on the datasource of the field. It is an indication of the expected time it will take to retrieve this field in the output dataframe.
notnull: whether the field is mandatory or not
type: datatype of the values of this field
Alternatively, you can list all the fields and their details by inspecting the get_fields() output or the search instance itself in a notebook:
[ ]:
monster
Deze kaartlaag bevat monsters die gekoppeld zijn aan een of meerdere boringen of aan een of meerdere monsters. Deze monsters zijn gekenmerkt door een diepte ten opzichte van het maaiveld, door de manier van staalname en de materiaalklasse. De geografische ligging (X en Y (mL72) en Z (mTAW)) nemen ze over van de gekoppelde boring(en). Het type bemonsterd materiaal wordt beschreven in de 'Materiaalklasse'. Aan deze monsters kunnen er observaties gekoppeld zijn, zoals waarnemingen en resultaten van kwaliteitsanalyses in het laboratorium of in het veld en/of referenties naar bepaalde analyses. De gegevens van de monsters en bepaalde observaties kunnen worden geëxporteerd in een rapport.
id - Uniek referentienummer in de databank.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
naam - Naam van het monster.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
pkey_monster - Permanente URL die verwijst naar de gegevens van het monster op de website.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
gekoppeld_aan - Het ouder-object (parent) waaraan een monster gekoppeld is. Bijvoorbeeld een boring, een ander monster, ...
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
pkey_parents - Permanente URL die verwijst naar de gegevens van het gekoppeld ouder-object (parent) op de website.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: True
materiaalklasse - Aard van het materiaal waaruit het monster bestaat, ingedeeld volgens een classificatie bijvoorbeeld sediment, hard gesteente.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
diepte_van_m - Minimum diepte van het monster ten opzichte van het aanvangspeil van het gekoppeld ouder-object, in meter.
- type: float
- notnull: False
- query: True
- cost: 1
- multivalue: False
diepte_tot_m - Maximum diepte van het monster ten opzichte van het aanvangspeil van het gekoppeld ouder-object, in meter.
- type: float
- notnull: False
- query: True
- cost: 1
- multivalue: False
aantal_observaties - Aantal observaties die beschikbaar zijn bij het monster.
- type: integer
- notnull: False
- query: True
- cost: 1
- multivalue: False
datum_monstername - Datum van monstername.
- type: date
- notnull: False
- query: True
- cost: 1
- multivalue: False
monstersamenstelling - Samenstelling van het monster: enkelvoudig monster of mengmonster.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
monstertype - Type monster of bemonstering: geroerd, ongeroerd, vloeistof.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
- codelist:
geroerd - Geroerd - Monstername waarbij de oorspronkelijke structuur en gelaagdheid van het materiaal niet bewaard wordt. Het resulterende monster laat het niet toe een gedetailleerde beschrijving of bepaalde analyses met betrekking tot de structuur of gelaagdheid (bv. Bulkdensiteit, volumemassa, grondmechanische proeven, ....) uit te voeren.
ongeroerd - Ongeroerd - Monstername waarbij de oorspronkelijke structuur en gelaagdheid van het materiaal maximaal bewaard wordt.
vloeistof - Vloeistof - Het monster bestaat uit een van nature vloeibare stof (een stof die gemakkelijk vormveranderingen ondergaat, samendrukbaar is, maar zich verzet tegen deze volumeverandering). Het begrip gelaagdheid is niet relevant voor het karakteriseren van het materiaal waaruit het monster is genomen.
bemonsteringsprocedure - Een workflow, protocol, plan, algoritme of berekeningswijze waarin wordt gespecifieerd hoe de bemonstering moet worden uitgevoerd.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
bemonsteringsinstrument - Het instrument waarmee de bemonstering is uitgevoerd.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: True
bemonstering_door - De agent (persoon of organisatie) die de bemonstering heeft uitgevoerd.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
opmerkingen - Aantal opmerkingen bij het monster.
- type: integer
- notnull: False
- query: True
- cost: 1
- multivalue: False
actuele_opslaglocatie - De plaats waar het monster is bewaard.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
opdracht - Opdracht waaraan een monster gekoppeld is.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
permkey_monster - Permkey van het monster als deel van de permanente URL.
- type: string
- notnull: False
- query: True
- cost: 1
- multivalue: False
geom - None
- type: geometry
- notnull: False
- query: False
- cost: 1
- multivalue: False
Example use cases
Get samples in a bounding box
Get data for all the samples that are geographically located within the bounds of the specified box.
The coordinates are in the Belgian Lambert72 (EPSG:31370) coordinate system and are given in the order of lower left x, lower left y, upper right x, upper right y.
[7]:
from pydov.util.location import Within, Box
df = monster.search(location=Within(Box(122000, 187000, 124000, 189000, epsg=31370)))
df.head()
[000/001] .
[7]:
| pkey_monster | naam | pkey_parents | materiaalklasse | datum_monstername | diepte_van_m | diepte_tot_m | monstertype | monstersamenstelling | bemonsteringsprocedure | bemonsteringsinstrument | bemonstering_door | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | https://www.dov.vlaanderen.be/data/monster/201... | 12 | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 5.50 | 6.00 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek |
| 1 | https://www.dov.vlaanderen.be/data/monster/201... | 16A | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 7.00 | 7.12 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek |
| 2 | https://www.dov.vlaanderen.be/data/monster/201... | 16B | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 7.12 | 7.27 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek |
| 3 | https://www.dov.vlaanderen.be/data/monster/201... | 16C | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 7.27 | 7.43 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek |
| 4 | https://www.dov.vlaanderen.be/data/monster/201... | 16D | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 7.43 | 7.50 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek |
The dataframe contains samples. The available data are flattened to represent unique attributes per row of the dataframe.
Using the pkey_monster field one can request the details of this sample in a webbrowser: https://www.dov.vlaanderen.be/data/monster/pkey_monster
[8]:
for pkey_monster in set(df.loc[df.naam == '16C'].pkey_monster):
print(pkey_monster)
https://www.dov.vlaanderen.be/data/monster/2017-180446
Get samples with specific properties
Next to querying samples based on their geographic location within a bounding box, we can also search for borehole samples matching a specific set of properties. For this we can build a query using a combination of the ‘Monster’ fields and operators provided by the WFS protocol.
A list of possible operators can be found below:
[9]:
[i for i,j in inspect.getmembers(sys.modules['owslib.fes2'], inspect.isclass) if 'Property' in i]
[9]:
['PropertyIsBetween',
'PropertyIsEqualTo',
'PropertyIsGreaterThan',
'PropertyIsGreaterThanOrEqualTo',
'PropertyIsLessThan',
'PropertyIsLessThanOrEqualTo',
'PropertyIsLike',
'PropertyIsNotEqualTo',
'PropertyIsNull',
'SortProperty']
In this example we build a query using the PropertyIsEqualTo operator to find all samples where monstertype equals ‘geroerd’:
[10]:
from owslib.fes2 import PropertyIsEqualTo
query = PropertyIsEqualTo(propertyname='monstertype',
literal='geroerd')
df = monster.search(query=query, max_features=10)
df.head()
[000/001] .
[10]:
| pkey_monster | naam | pkey_parents | materiaalklasse | datum_monstername | diepte_van_m | diepte_tot_m | monstertype | monstersamenstelling | bemonsteringsprocedure | bemonsteringsinstrument | bemonstering_door | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/199... | sediment | 1996-06-01 | 79.0 | 79.0 | geroerd | Enkelvoudig monster | NaN | (spoelboor,) | NaN |
| 1 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/199... | sediment | 1998-05-20 | 7.0 | 7.0 | geroerd | Enkelvoudig monster | NaN | (avegaarbooras,) | NaN |
| 2 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/199... | sediment | 1999-05-06 | 10.5 | 10.5 | geroerd | Enkelvoudig monster | NaN | (boor,) | NaN |
| 3 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/198... | sediment | 1981-05-17 | 0.1 | 0.1 | geroerd | Enkelvoudig monster | NaN | (boor,) | NaN |
| 4 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/196... | sediment | 1963-06-01 | 11.0 | 12.0 | geroerd | Enkelvoudig monster | NaN | (spoelboor,) | NaN |
Once again we can use the pkey_monster as a permanent link to the information of these samples:
[11]:
for pkey_monster in df['pkey_monster']:
print(pkey_monster)
https://www.dov.vlaanderen.be/data/monster/2017-127061
https://www.dov.vlaanderen.be/data/monster/2017-127081
https://www.dov.vlaanderen.be/data/monster/2017-127099
https://www.dov.vlaanderen.be/data/monster/2017-131193
https://www.dov.vlaanderen.be/data/monster/2017-131408
https://www.dov.vlaanderen.be/data/monster/2017-137853
https://www.dov.vlaanderen.be/data/monster/2017-137878
https://www.dov.vlaanderen.be/data/monster/2017-137903
https://www.dov.vlaanderen.be/data/monster/2017-131795
https://www.dov.vlaanderen.be/data/monster/2017-131804
Get samples in a bounding box based on specific properties
We can combine a query on attributes with a query on geographic location to get the samples within a bounding box that have specific properties.
The following example requests the samples with a depth greater than or equal to 15 meters within the given bounding box.
(Note that the datatype of the literal parameter should be a string, regardless of the datatype of this field in the output dataframe.)
[12]:
from owslib.fes2 import PropertyIsGreaterThanOrEqualTo
query = PropertyIsGreaterThanOrEqualTo(
propertyname='diepte_tot_m',
literal='15')
df = monster.search(
location=Within(Box(122000, 187000, 124000, 189000, epsg=31370)),
query=query
)
df.head()
[000/001] .
[12]:
| pkey_monster | naam | pkey_parents | materiaalklasse | datum_monstername | diepte_van_m | diepte_tot_m | monstertype | monstersamenstelling | bemonsteringsprocedure | bemonsteringsinstrument | bemonstering_door | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | https://www.dov.vlaanderen.be/data/monster/201... | 39A | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 17.00 | 17.37 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek |
| 1 | https://www.dov.vlaanderen.be/data/monster/201... | 39B | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 17.37 | 17.40 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek |
| 2 | https://www.dov.vlaanderen.be/data/monster/201... | N4A | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2009-05-28 | 15.75 | 15.90 | ongeroerd | Enkelvoudig monster | 22475-1-2007 | (steekbus,) | VO - Afdeling Geotechniek |
| 3 | https://www.dov.vlaanderen.be/data/monster/201... | N4B | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2009-05-28 | 15.90 | 16.15 | ongeroerd | Enkelvoudig monster | 22475-1-2007 | (steekbus,) | VO - Afdeling Geotechniek |
| 4 | https://www.dov.vlaanderen.be/data/monster/201... | N8 | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2005-01-18 | 16.50 | 17.00 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek |
Get sample based on fields not available in the standard output dataframe
To keep the output dataframe size acceptable, not all available WFS fields are included in the standard output. However, one can use this information to select samples as illustrated below.
For example, make a selection of the monsters with 100 or more observations:
[50]:
from pydov.types.monster import Monster
query = PropertyIsGreaterThanOrEqualTo(
propertyname='aantal_observaties',
literal='100')
fields = Monster.get_field_names()
fields.append('aantal_observaties')
df = monster.search(query=query, max_features = 10, return_fields=fields)
df.head()
[000/001] .
[50]:
| pkey_monster | naam | pkey_parents | materiaalklasse | datum_monstername | diepte_van_m | diepte_tot_m | monstertype | monstersamenstelling | bemonsteringsprocedure | bemonsteringsinstrument | bemonstering_door | aantal_observaties | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | https://www.dov.vlaanderen.be/data/monster/202... | 000/00/2-F1/M2024 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | 2024-05-22 | NaN | 3.0 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Eurofins Analytico B.V. | 101 |
| 1 | https://www.dov.vlaanderen.be/data/monster/202... | 000/32/3-F1/M2024 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | 2024-05-15 | NaN | 3.0 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Eurofins Analytico B.V. | 104 |
| 2 | https://www.dov.vlaanderen.be/data/monster/202... | 000/32/5-F1/M2024 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | 2024-05-16 | NaN | 3.0 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Eurofins Analytico B.V. | 101 |
| 3 | https://www.dov.vlaanderen.be/data/monster/202... | 010/32/2-F1/M2024 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | 2024-05-16 | NaN | 2.5 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Eurofins Analytico B.V. | 104 |
| 4 | https://www.dov.vlaanderen.be/data/monster/202... | 011/00/4-F1/M2024 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | 2024-05-22 | NaN | 3.0 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Eurofins Analytico B.V. | 104 |
Get sample with data from a subtype
There are different subtypes available within monster search: ‘BemonsterdObject’, ‘Opslaglocatie’, ‘Monsterbehandeling’
[16]:
from pydov.search.monster import MonsterSearch
from pydov.types.monster import Monster, Monsterbehandeling
from owslib.fes2 import PropertyIsLike
monster = MonsterSearch(
objecttype=Monster.with_subtype(Monsterbehandeling))
query = PropertyIsLike(propertyname='pkey_monster', literal='%/2021-339689')
df = monster.search(query=query)
df.head()
[000/001] .
[000/001] .
[16]:
| pkey_monster | naam | pkey_parents | materiaalklasse | datum_monstername | diepte_van_m | diepte_tot_m | monstertype | monstersamenstelling | bemonsteringsprocedure | bemonsteringsinstrument | bemonstering_door | monsterbehandeling_door | monsterbehandeling_datum | monsterbehandeling_tijdstip | monsterbehandeling_behandeling | monsterbehandeling_behandeling_waarde | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | https://www.dov.vlaanderen.be/data/monster/202... | CN_142439_2021_M | (https://www.dov.vlaanderen.be/data/bodemlocat... | bodem | 2021-04-03 | 0.0 | 0.1 | geroerd | Mengmonster | NaN | (pvcaangescherpt30mm,) | Deelnemers citizen science project | Universiteit Antwerpen | NaN | NaN | Monstervoorbereiding door | Universiteit Antwerpen |
Get a boxplot with the depth distribution of samples with sampling instrument ‘steekbus’
[17]:
from pydov.util.query import PropertyLikeList
monster = MonsterSearch()
query = PropertyLikeList(propertyname='bemonsteringsinstrument',
lst=['steekbus'])
df = monster.search(query=query, return_fields=[
'diepte_van_m', 'diepte_tot_m'
])
[000/004] ....
[18]:
df.describe()
[18]:
| diepte_van_m | diepte_tot_m | |
|---|---|---|
| count | 33344.000000 | 33361.000000 |
| mean | 6.887490 | 7.223054 |
| std | 7.172918 | 7.213257 |
| min | 0.000000 | 0.100000 |
| 25% | 2.000000 | 2.320000 |
| 50% | 4.500000 | 4.850000 |
| 75% | 9.000000 | 9.400000 |
| max | 60.000000 | 60.300000 |
[19]:
ax = df[df.diepte_tot_m != 0].boxplot()
ax.set_ylabel("depth (m)")
ax.set_title("Depth distribution samples with sampling instrument 'steekbus'")
[19]:
Text(0.5, 1.0, "Depth distribution samples with sampling instrument 'steekbus'")
Adding the sampled object to the monster dataframe
The default dataframe of the Monster datatype doesn’t contains information about the ‘sampled object’ by default. This can be added to the dataframe as its subtype.
You can find which extra subtypes are available for a certain type with the get_subtypes method:
[24]:
from pydov.types.monster import Monster
Monster.get_subtypes()
[24]:
{'BemonsterdObject': {'name': 'BemonsterdObject',
'class': pydov.types.monster.BemonsterdObject,
'definition': 'Subtype listing the sampled object(s) of the sample. It has the following fields: bemonsterd_object_type, bemonsterd_object_naam, bemonsterd_object_permkey.'},
'Monsterbehandeling': {'name': 'Monsterbehandeling',
'class': pydov.types.monster.Monsterbehandeling,
'definition': 'Subtype containing fields about the\ntreatment of the sample. It has the following fields: monsterbehandeling_door, monsterbehandeling_datum, monsterbehandeling_tijdstip, monsterbehandeling_behandeling, monsterbehandeling_behandeling_waarde.'},
'Opslaglocatie': {'name': 'Opslaglocatie',
'class': pydov.types.monster.Opslaglocatie,
'definition': 'Subtype listing the storage location(s) of the sample. It has the following fields: opslaglocatie_naam, opslaglocatie_van, opslaglocatie_tot.'}}
To get the details about the sampled objects, we can instantiate the search class with the BemonsterdObject subtype:
[25]:
from pydov.types.monster import BemonsterdObject
monster_search = MonsterSearch(
objecttype=Monster.with_subtype(BemonsterdObject)
)
When we now request information about the fields, this will include the extra fields from the subtype:
[26]:
monster_search.get_fields()['bemonsterd_object_permkey']
[26]:
bemonsterd_object_permkey - Een unieke DOV identifier in de vorm van een permkey.
- type: string
- notnull: False
- query: False
- cost: 10
- multivalue: False
And when we query the data, the extra fields will be part of the resulting dataframe:
[27]:
df = monster_search.search(location=Within(Box(122000, 187000, 124000, 189000, epsg=31370)), max_features = 10)
df.head()
[000/001] .
[000/010] ..........
[27]:
| pkey_monster | naam | pkey_parents | materiaalklasse | datum_monstername | diepte_van_m | diepte_tot_m | monstertype | monstersamenstelling | bemonsteringsprocedure | bemonsteringsinstrument | bemonstering_door | bemonsterd_object_type | bemonsterd_object_naam | bemonsterd_object_permkey | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | https://www.dov.vlaanderen.be/data/monster/201... | 12 | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 5.50 | 6.00 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek | BORING | GEO-02/028-B5 | 2002-003282 |
| 1 | https://www.dov.vlaanderen.be/data/monster/201... | 16A | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 7.00 | 7.12 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek | BORING | GEO-02/028-B5 | 2002-003282 |
| 2 | https://www.dov.vlaanderen.be/data/monster/201... | 16B | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 7.12 | 7.27 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek | BORING | GEO-02/028-B5 | 2002-003282 |
| 3 | https://www.dov.vlaanderen.be/data/monster/201... | 16C | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 7.27 | 7.43 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek | BORING | GEO-02/028-B5 | 2002-003282 |
| 4 | https://www.dov.vlaanderen.be/data/monster/201... | 16D | (https://www.dov.vlaanderen.be/data/boring/200... | sediment | 2002-03-04 | 7.43 | 7.50 | ongeroerd | Enkelvoudig monster | NaN | (steekbus,) | MVG - Afdeling Geotechniek | BORING | GEO-02/028-B5 | 2002-003282 |
Mind that one sample can originate from multiple ‘sampled objects’, so it’s possible for one sample to be split into multiple rows. Also, since we are now requesting fields from XML, querying will be significantly slower than before.
Get more details about a sample
To get more details about a sample than is available in the default dataframe, you can add an extra fieldset containing extra details.
You can find which extra fieldsets are available for a certain type with the get_fieldsets method:
[28]:
from pydov.types.monster import Monster
Monster.get_fieldsets()
[28]:
{'MonsterDetails': {'name': 'MonsterDetails',
'class': pydov.types.monster.MonsterDetails,
'definition': 'Fieldset containing fields with extra\ndetails about the sample.\n It has the following fields: tijdstip_monstername.'}}
In this case, the fieldset MonsterDetails is available, which will add the extra field tijdstip_monstername.
To use it, we can add the extra fields from the fieldset when instantiating our search instance:
[29]:
from pydov.search.monster import MonsterSearch
from pydov.types.monster import Monster, MonsterDetails
monster_search = MonsterSearch(
objecttype=Monster.with_extra_fields(MonsterDetails))
When we now request information about the fields, this will include the extra fields from the fieldset:
[30]:
monster_search.get_fields()['tijdstip_monstername']
[30]:
tijdstip_monstername - Tijdstip waarop het monster werd verkregen uit het bemonsterdObject.
- type: string
- notnull: False
- query: False
- cost: 10
- multivalue: False
And when we query the data, the extra details will be part of the resulting dataframe:
[32]:
from owslib.fes2 import PropertyIsLike
monster_search.search(
query=PropertyIsLike(
'pkey_monster', '%/2022-400005')
)
[000/001] .
[000/001] .
[32]:
| pkey_monster | naam | pkey_parents | materiaalklasse | datum_monstername | diepte_van_m | diepte_tot_m | monstertype | monstersamenstelling | bemonsteringsprocedure | bemonsteringsinstrument | bemonstering_door | tijdstip_monstername | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | https://www.dov.vlaanderen.be/data/monster/202... | CMON_test_ilvo_laag_0_10_MG_2022 | (https://www.dov.vlaanderen.be/data/bodemdiept... | bodem | 2022-03-10 | 0.0 | 0.1 | geroerd | Mengmonster | csp | (steekguts30mm,) | Departement Omgeving | 10:45:00 |
Visualise results on a map
Using Folium, we can display the results of our search on a map.
[33]:
# import the necessary modules (not included in the requirements of pydov!)
import folium
import geopandas as gpd
[34]:
from pydov.search.monster import MonsterSearch
from pydov.types.monster import Monster
from pydov.search.fields import GeometryReturnField
ms = MonsterSearch()
return_fields = Monster.get_field_names()
return_fields.remove('datum_monstername')
return_fields.append(GeometryReturnField('geom', 31370))
df = ms.search(max_features=100, return_fields=return_fields)
df
[000/001] .
[34]:
| pkey_monster | naam | pkey_parents | materiaalklasse | diepte_van_m | diepte_tot_m | monstertype | monstersamenstelling | bemonsteringsprocedure | bemonsteringsinstrument | bemonstering_door | geom | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/199... | sediment | 79.0 | 79.0 | geroerd | Enkelvoudig monster | NaN | (spoelboor,) | NaN | POINT (236820 181175) |
| 1 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/199... | sediment | 7.0 | 7.0 | geroerd | Enkelvoudig monster | NaN | (avegaarbooras,) | NaN | POINT (160032.9 175678.8) |
| 2 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/199... | sediment | 10.5 | 10.5 | geroerd | Enkelvoudig monster | NaN | (boor,) | NaN | POINT (153903 178252) |
| 3 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/198... | sediment | 288.8 | 288.8 | ongeroerd | Enkelvoudig monster | NaN | (buis,) | NaN | POINT (78776 226370) |
| 4 | https://www.dov.vlaanderen.be/data/monster/201... | 0 | (https://www.dov.vlaanderen.be/data/boring/198... | sediment | 0.1 | 0.1 | geroerd | Enkelvoudig monster | NaN | (boor,) | NaN | POINT (214069.5 216345.4) |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 95 | https://www.dov.vlaanderen.be/data/monster/200... | 000/32/2/M0504 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | NaN | 3.0 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Bodemkundige Dienst van België | POINT (29001.35 187051.01) |
| 96 | https://www.dov.vlaanderen.be/data/monster/200... | 000/32/2/M0602 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | NaN | 6.5 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Eurofins Envirotox NV | POINT (29001.35 187051.01) |
| 97 | https://www.dov.vlaanderen.be/data/monster/200... | 000/32/2/M0602 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | NaN | 3.0 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Eurofins Envirotox NV | POINT (29001.35 187051.01) |
| 98 | https://www.dov.vlaanderen.be/data/monster/200... | 000/32/2/M0603 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | NaN | 6.5 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Eurofins Envirotox NV | POINT (29001.35 187051.01) |
| 99 | https://www.dov.vlaanderen.be/data/monster/200... | 000/32/2/M0603 | (https://www.dov.vlaanderen.be/data/filter/200... | grondwater | NaN | 3.0 | vloeistof | Enkelvoudig monster | NaN | (pomp,) | Eurofins Envirotox NV | POINT (29001.35 187051.01) |
100 rows × 12 columns
[35]:
geo_df = gpd.GeoDataFrame(df, geometry='geom', crs='EPSG:31370')
popup = folium.GeoJsonPopup(fields=["naam", "diepte_van_m", "diepte_tot_m", 'pkey_parents'])
geo_json = folium.GeoJson(data=geo_df, popup=popup)
[36]:
# initialize the Folium map on the centre of the selected locations, play with the zoom until ok
fmap = folium.Map(zoom_start=12)
geo_json.add_to(fmap)
fmap.fit_bounds(fmap.get_bounds())
fmap
[36]: