Example of DOV search methods for soil data (bodemgegevens)

Binder

Use cases explained below

  • Introduction to the bodem-objects

  • Get bodemsites in a bounding box

  • Get bodemlocaties with specific properties

  • Get all direct and indirect bodemobservaties linked to a bodemlocatie

  • Get all bodemobservaties in a bodemmonster

  • Find all bodemlocaties where observations exist for organic carbon percentage in East-Flanders between 0 and 30 cm deep

  • Calculate carbon stock in Ghent in the layer 0 - 23 cm

[50]:
%matplotlib inline

import inspect, sys
import warnings; warnings.simplefilter('ignore')
[51]:
# check pydov path
import pydov

Get information about the datatype ‘Bodemlocatie’

Other datatypes are also possible: * Bodemsite: BodemsiteSearch * Bodemmonster: BodemmonsterSearch * Bodemobservatie: BodemobservatieSearch

[52]:
from pydov.search.bodemlocatie import BodemlocatieSearch
bodemlocatie = BodemlocatieSearch()

A description is provided for the ‘Bodemlocatie’ datatype:

[53]:
bodemlocatie.get_description()
[53]:
"Een bodemlocatie is ofwel een profielput of een boring. Een boring is altijd één puntlocatie (x,y,z) en een profielput heeft minimum één en maximum twee puntlocaties (begin- en eindpunt van de profielput). \r\nEen profielput is een uitgegraven put in de bodem waarin profielbeschrijvingen, monsternames of bodemobservaties worden uitgevoerd. Een profielbeschrijving is een waarneming van bodemhorizonten en/of bodemlagen in een uitgegraven profielput. Een bodemhorizont is een visueel te onderscheiden deel van de bodem dat ontstaan is door omzetting van het moedermateriaal door pedogenetische processen of door het afzetten van organisch materiaal. Een bodemhorizont heeft voor de meeste bodemvariabelen homogene morfologische en analytische karakteristieken. Een bodemlaag daarentegen is ontstaan door niet-pedogenetische processen. Aan de hand van een profielput krijg je een beeld van de bodemkundige opbouw.\r\nEen boring is het resultaat van het boren in de ondergrond met verwijdering van bodem door middel van een gereedschap in de vorm van een holle buis. Aan de hand van dit opgeboorde bodemmateriaal worden bodembeschrijvingen, bodemobservaties en monsternames uitgevoerd.\r\nDe bodemlocaties uit de 'Aardewerk-Vlaanderen-2010' databank worden afzonderlijk ontsloten in de datasets 'Bodemprofielen kartering Belgische bodemkaart' en 'Oppervlaktemonsters kartering Belgische bodemkaart'."

The different fields that are available for objects of the ‘Bodemlocatie’ datatype can be requested with the get_fields() method:

[54]:
fields = bodemlocatie.get_fields()

# print available fields
for f in fields.values():
    print(f['name'])
naam
pkey_bodemlocatie
type
rapport_bodemlocatie
profielbeschrijving
waarnemingsdatum
doel
x
y
mv_mtaw
Auteurs
Aantal_classificaties
Aantal_opbouwen
erfgoed
Aantal_observaties
Aantal_monsters
bodemstreek
Bodemsite
pkey_bodemsite
Opdrachten
eerste_invoer
geom
invoerdatum
educatieve_waarde

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

[55]:
fields['type']
[55]:
{'name': 'type',
 'definition': 'Het type van de bodemlocatie: boring of profielput.',
 'type': 'string',
 'notnull': False,
 'query': True,
 'cost': 1,
 'values': {'boring': 'Een boring is het resultaat van het boren in de ondergrond met verwijdering van bodem door middel van een gereedschap in de vorm van een holle buis. Aan de hand van dit opgeboorde bodemmateriaal worden bodembeschrijvingen, bodemobservaties en monsternames uitgevoerd.',
  'profielput': 'Een profielput is een uitgegraven put in de bodem waarin profielbeschrijvingen, monsternames of bodemobservaties worden uitgevoerd. Een profielbeschrijving is een waarneming van bodemhorizonten en/of bodemlagen in een uitgegraven profielput. Een bodemhorizont is een visueel te onderscheiden deel van de bodem dat ontstaan is door omzetting van het moedermateriaal door pedogenetische processen of door het afzetten van organisch materiaal. Een bodemhorizont heeft voor de meeste bodemvariabelen homogene morfologische en analytische karakteristieken. Een bodemlaag daarentegen is ontstaan door niet-pedogenetische processen. Aan de hand van een profielput krijg je een beeld van de bodemkundige opbouw.'}}

Optionally, if the values of the field have a specific domain the possible values are listed as values:

[56]:
fields['type']['values']
[56]:
{'boring': 'Een boring is het resultaat van het boren in de ondergrond met verwijdering van bodem door middel van een gereedschap in de vorm van een holle buis. Aan de hand van dit opgeboorde bodemmateriaal worden bodembeschrijvingen, bodemobservaties en monsternames uitgevoerd.',
 'profielput': 'Een profielput is een uitgegraven put in de bodem waarin profielbeschrijvingen, monsternames of bodemobservaties worden uitgevoerd. Een profielbeschrijving is een waarneming van bodemhorizonten en/of bodemlagen in een uitgegraven profielput. Een bodemhorizont is een visueel te onderscheiden deel van de bodem dat ontstaan is door omzetting van het moedermateriaal door pedogenetische processen of door het afzetten van organisch materiaal. Een bodemhorizont heeft voor de meeste bodemvariabelen homogene morfologische en analytische karakteristieken. Een bodemlaag daarentegen is ontstaan door niet-pedogenetische processen. Aan de hand van een profielput krijg je een beeld van de bodemkundige opbouw.'}

Example use cases

Get bodemsites in a bounding box

Get data for all the bodemsites that are geographically located completely 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.

The same methods can be used for other bodem objects.

[57]:
from pydov.search.bodemsite import BodemsiteSearch
bodemsite = BodemsiteSearch()
[58]:
from pydov.util.location import Within, Box

df = bodemsite.search(location=Within(Box(148000, 160800, 160000, 169500)))
df.head()
[000/001] .
[000/029] ccccccccccccccccccccccccccccc
[58]:
pkey_bodemsite naam waarnemingsdatum beschrijving invoerdatum
0 https://www.dov.vlaanderen.be/data/bodemsite/2... CGAR_Pafed294_Plot 2019-10-29 Park. Deze bodemsite beschrijft de geometrie w... 2020-07-27
1 https://www.dov.vlaanderen.be/data/bodemsite/2... CGAR_Pafed295_Plot 2019-10-29 Park 2020-07-27
2 https://www.dov.vlaanderen.be/data/bodemsite/2... Zoniënwoud_Groenendaal NaN Zachte helling op plateau, Bodem nooit onder l... NaN
3 https://www.dov.vlaanderen.be/data/bodemsite/2... Zoniënwoud_Rood Klooster NaN Zeer zachte helling op plateau NaN
4 https://www.dov.vlaanderen.be/data/bodemsite/1... Zoniënwoud_Tertiair 1983-01-01 NNW gerichte helling van een 10% langs vallei ... NaN

The dataframe contains a list of bodemsites. The available data are flattened to represent unique attributes per row of the dataframe.

Using the pkey_bodemsite field one can request the details of this bodemsite in a webbrowser:

[59]:
for pkey_bodemsite in set(df.pkey_bodemsite):
    print(pkey_bodemsite)
https://www.dov.vlaanderen.be/data/bodemsite/2022-004918
https://www.dov.vlaanderen.be/data/bodemsite/2017-000215
https://www.dov.vlaanderen.be/data/bodemsite/2022-006380
https://www.dov.vlaanderen.be/data/bodemsite/2021-006806
https://www.dov.vlaanderen.be/data/bodemsite/2017-000306
https://www.dov.vlaanderen.be/data/bodemsite/2021-006836
https://www.dov.vlaanderen.be/data/bodemsite/2022-004903
https://www.dov.vlaanderen.be/data/bodemsite/2021-007552
https://www.dov.vlaanderen.be/data/bodemsite/2022-004663
https://www.dov.vlaanderen.be/data/bodemsite/2021-007116
https://www.dov.vlaanderen.be/data/bodemsite/2022-004803
https://www.dov.vlaanderen.be/data/bodemsite/2021-007484
https://www.dov.vlaanderen.be/data/bodemsite/2022-004240
https://www.dov.vlaanderen.be/data/bodemsite/2021-007106
https://www.dov.vlaanderen.be/data/bodemsite/2022-005318
https://www.dov.vlaanderen.be/data/bodemsite/2017-000229
https://www.dov.vlaanderen.be/data/bodemsite/2022-003988
https://www.dov.vlaanderen.be/data/bodemsite/2011-000247
https://www.dov.vlaanderen.be/data/bodemsite/2022-006682
https://www.dov.vlaanderen.be/data/bodemsite/2021-000310
https://www.dov.vlaanderen.be/data/bodemsite/1983-000216
https://www.dov.vlaanderen.be/data/bodemsite/2017-000305
https://www.dov.vlaanderen.be/data/bodemsite/2022-005641
https://www.dov.vlaanderen.be/data/bodemsite/2021-006280
https://www.dov.vlaanderen.be/data/bodemsite/2022-005777
https://www.dov.vlaanderen.be/data/bodemsite/2017-000210
https://www.dov.vlaanderen.be/data/bodemsite/2022-004072
https://www.dov.vlaanderen.be/data/bodemsite/2021-005946
https://www.dov.vlaanderen.be/data/bodemsite/2021-000309

Get bodemlocaties with specific properties

Next to querying bodem objects based on their geographic location within a bounding box, we can also search for bodem objects matching a specific set of properties. The same methods can be used for all bodem objects. For this we can build a query using a combination of the ‘Bodemlocatie’ fields and operators provided by the WFS protocol.

A list of possible operators can be found below:

[60]:
[i for i,j in inspect.getmembers(sys.modules['owslib.fes2'], inspect.isclass) if 'Property' in i]
[60]:
['PropertyIsBetween',
 'PropertyIsEqualTo',
 'PropertyIsGreaterThan',
 'PropertyIsGreaterThanOrEqualTo',
 'PropertyIsLessThan',
 'PropertyIsLessThanOrEqualTo',
 'PropertyIsLike',
 'PropertyIsNotEqualTo',
 'PropertyIsNull',
 'SortProperty']

In this example we build a query using the PropertyIsEqualTo operator to find all bodemlocaties with bodemstreek ‘zandstreek’. We use max_features=10 to limit the results to 10.

[61]:
from owslib.fes2 import PropertyIsEqualTo

query = PropertyIsEqualTo(propertyname='bodemstreek',
                          literal='Zandstreek')
df = bodemlocatie.search(query=query, max_features=10)

df.head()
[000/001] .
[000/010] cccccccccc
[61]:
pkey_bodemlocatie pkey_bodemsite naam type waarnemingsdatum doel x y mv_mtaw erfgoed bodemstreek invoerdatum educatieve_waarde
0 https://www.dov.vlaanderen.be/data/bodemlocati... NaN ARCH_2017C381_WP0001BP01 profielput 2017-03-27 archeologische proefputten ifv prehistorische ... 100951.02 197304.89 6.11 False Zandstreek 2022-03-02 NaN
1 https://www.dov.vlaanderen.be/data/bodemlocati... NaN ARCH_2018D174_1 profielput 2018-11-07 archeologische proefsleuven en proefputten 136567.44 209067.73 13.17 False Zandstreek 2022-03-02 NaN
2 https://www.dov.vlaanderen.be/data/bodemlocati... NaN ARCH_2018D174_2 profielput 2018-11-07 archeologische proefsleuven en proefputten 136520.06 209040.88 13.75 False Zandstreek 2022-03-02 NaN
3 https://www.dov.vlaanderen.be/data/bodemlocati... NaN ARCH_2018D174_3 profielput 2018-11-07 archeologische proefsleuven en proefputten 136458.47 209006.77 13.41 False Zandstreek 2022-03-02 NaN
4 https://www.dov.vlaanderen.be/data/bodemlocati... NaN ARCH_2021L196_463.1 profielput 2021-12-21 archeologische proefsleuven en proefputten 119075.97 201394.21 5.75 False Zandstreek 2022-03-07 NaN

Once again we can use the pkey_bodemlocatie as a permanent link to the information of these bodemlocaties:

[62]:
for pkey_bodemlocatie in set(df.pkey_bodemlocatie):
    print(pkey_bodemlocatie)
https://www.dov.vlaanderen.be/data/bodemlocatie/2018-022980
https://www.dov.vlaanderen.be/data/bodemlocatie/2021-024094
https://www.dov.vlaanderen.be/data/bodemlocatie/2021-024151
https://www.dov.vlaanderen.be/data/bodemlocatie/2017-018199
https://www.dov.vlaanderen.be/data/bodemlocatie/2012-000041
https://www.dov.vlaanderen.be/data/bodemlocatie/2007-000102
https://www.dov.vlaanderen.be/data/bodemlocatie/2021-024152
https://www.dov.vlaanderen.be/data/bodemlocatie/2018-022978
https://www.dov.vlaanderen.be/data/bodemlocatie/2018-022979
https://www.dov.vlaanderen.be/data/bodemlocatie/2022-024351

Get all direct and indirect bodemobservaties in bodemlocatie

Get all bodemobservaties in a specific bodemlocatie. Direct means bodemobservaties directly linked with a bodemlocatie. Indirect means bodemobservaties linked with child-objects of the bodemlocatie, like bodemmonsters.

[63]:
from pydov.search.bodemobservatie import BodemobservatieSearch
from pydov.search.bodemlocatie import BodemlocatieSearch
bodemobservatie = BodemobservatieSearch()
bodemlocatie = BodemlocatieSearch()
[64]:
from owslib.fes2 import PropertyIsEqualTo
from pydov.util.query import Join

bodemlocaties = bodemlocatie.search(query=PropertyIsEqualTo(propertyname='naam', literal='VMM_INF_52'),
                                   return_fields=('pkey_bodemlocatie',))

bodemobservaties = bodemobservatie.search(query=Join(bodemlocaties, 'pkey_bodemlocatie'))
bodemobservaties.head()
[000/001] .
[000/001] .
[000/021] ccccccccccccccccccccc
[64]:
pkey_bodemobservatie pkey_bodemlocatie pkey_parent x y mv_mtaw diepte_van_cm diepte_tot_cm observatiedatum invoerdatum ... parameter detectie waarde eenheid veld_labo methode betrouwbaarheid fractiemeting_ondergrens fractiemeting_bovengrens fractiemeting_waarde
0 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-07 ... Ksat NaN 0.0000154321 m/s veld Ksat_Soakaway_methode goed NaN NaN NaN
1 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-07 ... Ksat NaN 0.0000029437 m/s veld Ksat Enkele-ring-methode goed NaN NaN NaN
2 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-07 ... Ksat NaN 0.0000100245 m/s veld Ksat Porchet-methode goed NaN NaN NaN
3 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 129586.0 182459.0 30.7 40.0 85.0 2015-08-27 2019-02-07 ... Textuur - granulometrisch - klassen bodemkarte... NaN E - Klei - labo Textuur pipetmethode Robinson-Köhn goed NaN NaN NaN
4 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-07 ... Ksat NaN 0.0000036111 m/s veld Ksat Enkele-ring-methode goed NaN NaN NaN

5 rows × 21 columns

Get all bodemobservaties in a bodemmonster

Get all bodemobservaties linked with a bodemmonster

[65]:
from pydov.search.bodemmonster import BodemmonsterSearch
bodemmonster = BodemmonsterSearch()

bodemmonsters = bodemmonster.search(query=PropertyIsEqualTo(propertyname = 'identificatie', literal='A0057359'),
                                   return_fields=('pkey_bodemmonster',))

bodemobservaties = bodemobservatie.search(query=Join(bodemmonsters, on = 'pkey_parent', using='pkey_bodemmonster'))
bodemobservaties.head()
[000/001] .
[000/001] .
[000/003] ccc
[65]:
pkey_bodemobservatie pkey_bodemlocatie pkey_parent x y mv_mtaw diepte_van_cm diepte_tot_cm observatiedatum invoerdatum ... parameter detectie waarde eenheid veld_labo methode betrouwbaarheid fractiemeting_ondergrens fractiemeting_bovengrens fractiemeting_waarde
0 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 129586.0 182459.0 30.7 40.0 85.0 2015-08-27 2019-02-07 ... Textuur - granulometrisch - klassen bodemkarte... NaN E - Klei - labo Textuur pipetmethode Robinson-Köhn goed NaN NaN NaN
1 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 129586.0 182459.0 30.7 40.0 85.0 2015-08-27 2019-02-07 ... Textuur - handmatig - klassen bodemkartering NaN A - Leem - labo Textuur manuele schatting (palpatie) goed NaN NaN NaN
2 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-19 ... Textuurfracties NaN Fractiemetingen % labo Textuur pipetmethode Robinson-Köhn goed 0.0 2.0 21.58
3 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-19 ... Textuurfracties NaN Fractiemetingen % labo Textuur pipetmethode Robinson-Köhn goed 2.0 10.0 5.19
4 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-19 ... Textuurfracties NaN Fractiemetingen % labo Textuur pipetmethode Robinson-Köhn goed 10.0 20.0 12.26

5 rows × 21 columns

Find all soil locations with a given soil classification

Get all soil locations with a given soil classification:

[66]:
from owslib.fes2 import PropertyIsEqualTo
from pydov.util.query import Join

from pydov.search.bodemclassificatie import BodemclassificatieSearch
from pydov.search.bodemlocatie import BodemlocatieSearch

bodemclassificatie = BodemclassificatieSearch()
bl_Scbz = bodemclassificatie.search(query=PropertyIsEqualTo('bodemtype', 'Scbz'), return_fields=['pkey_bodemlocatie'])

bodemlocatie = BodemlocatieSearch()
bl = bodemlocatie.search(query=Join(bl_Scbz, 'pkey_bodemlocatie'))
bl.head()
[000/001] .
[000/001] .
[000/010] cccccccccc
[66]:
pkey_bodemlocatie pkey_bodemsite naam type waarnemingsdatum doel x y mv_mtaw erfgoed bodemstreek invoerdatum educatieve_waarde
0 https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemsite/2... HAAST_16 profielput 2015-04-16 archeologische landschappelijke profielputten 248905.67 200391.29 32.88 True Kempen 2015-04-16 ZEER
1 https://www.dov.vlaanderen.be/data/bodemlocati... NaN KART_PROF_071E/28 profielput 1960-09-30 bodemprofielen en oppervlaktemonsters karterin... 129724.00 186794.00 7.00 False Zandstreek 2019-10-11 OK
2 https://www.dov.vlaanderen.be/data/bodemlocati... NaN KART_PROF_071E/24 profielput 1960-09-29 bodemprofielen en oppervlaktemonsters karterin... 128409.00 185764.00 5.00 False Zandleemstreek 2019-10-11 OK
3 https://www.dov.vlaanderen.be/data/bodemlocati... NaN KART_PROF_071E/21 profielput 1960-09-28 bodemprofielen en oppervlaktemonsters karterin... 127729.00 185179.00 5.00 False Zandleemstreek 2019-10-11 OK
4 https://www.dov.vlaanderen.be/data/bodemlocati... NaN KART_OPP_053W/030 boring 1968-01-01 bodemprofielen en oppervlaktemonsters karterin... 73845.00 195091.00 -9999.00 False Kunstmatige gronden 2019-10-12 OK

We can also get their observations:

[67]:
from pydov.search.bodemobservatie import BodemobservatieSearch

bodemobservatie = BodemobservatieSearch()
obs = bodemobservatie.search(query=Join(bl_Scbz, 'pkey_bodemlocatie'), max_features=10)
obs.head()
[000/001] .
[000/010] cccccccccc
[67]:
pkey_bodemobservatie pkey_bodemlocatie pkey_parent x y mv_mtaw diepte_van_cm diepte_tot_cm observatiedatum invoerdatum ... parameter detectie waarde eenheid veld_labo methode betrouwbaarheid fractiemeting_ondergrens fractiemeting_bovengrens fractiemeting_waarde
0 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 127729.0 185179.0 5.0 62.0 85.0 1960-09-28 NaN ... Reductie in horizont(ja/nee) NaN nee NaN veld NaN onbekend NaN NaN NaN
1 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 73845.0 195091.0 -9999.0 0.0 20.0 1968-01-01 NaN ... Textuur - granulometrie - klasse bodemkartering NaN S - Lemig zand NaN labo NaN onbekend NaN NaN NaN
2 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129724.0 186794.0 7.0 48.0 65.0 1960-09-30 NaN ... Gley roest - grootte NaN Rg2 - Matig groot / middelmatig NaN veld NaN onbekend NaN NaN NaN
3 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129724.0 186794.0 7.0 65.0 112.0 1960-09-30 NaN ... Kleur volgens Munsell - CHROMA (kleur1) NaN 3.0 NaN veld NaN onbekend NaN NaN NaN
4 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129724.0 186794.0 7.0 126.0 140.0 1960-09-30 NaN ... Gley roest - aantal NaN Ra3 - Veel (> 20 %) - Sterk roestig NaN veld NaN onbekend NaN NaN NaN

5 rows × 21 columns

Get all depth intervals and observations from a soil location

[68]:
from pydov.search.bodemlocatie import BodemlocatieSearch
from pydov.search.bodemdiepteinterval import BodemdiepteintervalSearch
from pydov.util.query import Join
from owslib.fes2 import PropertyIsEqualTo

bodemlocatie = BodemlocatieSearch()
bodemdiepteinterval = BodemdiepteintervalSearch()

bodemlocaties = bodemlocatie.search(query=PropertyIsEqualTo(propertyname='naam', literal='VMM_INF_52'),
                                    return_fields=('pkey_bodemlocatie',))

bodemdiepteintervallen = bodemdiepteinterval.search(
    query=Join(bodemlocaties, on='pkey_bodemlocatie'))
bodemdiepteintervallen
[000/001] .
[000/001] .
[68]:
pkey_diepteinterval pkey_bodemopbouw pkey_bodemlocatie nr type naam bovengrens1_cm bovengrens2_cm ondergrens1_cm ondergrens2_cm ondergrens_bereikt grensduidelijkheid grensregelmatigheid beschrijving x y mv_mtaw
0 https://www.dov.vlaanderen.be/data/bodemdiepte... https://www.dov.vlaanderen.be/data/bodemopbouw... https://www.dov.vlaanderen.be/data/bodemlocati... 2 horizont NaN 10.0 NaN 40.0 NaN NVT NaN NaN - 129586.0 182459.0 30.7
1 https://www.dov.vlaanderen.be/data/bodemdiepte... https://www.dov.vlaanderen.be/data/bodemopbouw... https://www.dov.vlaanderen.be/data/bodemlocati... 4 horizont NaN 85.0 NaN 130.0 NaN NVT NaN NaN - 129586.0 182459.0 30.7
2 https://www.dov.vlaanderen.be/data/bodemdiepte... https://www.dov.vlaanderen.be/data/bodemopbouw... https://www.dov.vlaanderen.be/data/bodemlocati... 5 horizont NaN 130.0 NaN 200.0 NaN NEE NaN NaN - 129586.0 182459.0 30.7
3 https://www.dov.vlaanderen.be/data/bodemdiepte... https://www.dov.vlaanderen.be/data/bodemopbouw... https://www.dov.vlaanderen.be/data/bodemlocati... 1 horizont NaN 0.0 NaN 10.0 NaN NVT NaN NaN - 129586.0 182459.0 30.7
4 https://www.dov.vlaanderen.be/data/bodemdiepte... https://www.dov.vlaanderen.be/data/bodemopbouw... https://www.dov.vlaanderen.be/data/bodemlocati... 3 horizont NaN 40.0 NaN 85.0 NaN NVT NaN NaN horizont gebruikt voor infiltratiemetingen 129586.0 182459.0 30.7

And get their observations:

[69]:
from pydov.search.bodemobservatie import BodemobservatieSearch

bodemobservatie = BodemobservatieSearch()

bodemobservaties = bodemobservatie.search(query=Join(
    bodemdiepteintervallen, on='pkey_parent', using='pkey_diepteinterval'))
bodemobservaties.head()
[000/001] .
[000/016] cccccccccccccccc
[69]:
pkey_bodemobservatie pkey_bodemlocatie pkey_parent x y mv_mtaw diepte_van_cm diepte_tot_cm observatiedatum invoerdatum ... parameter detectie waarde eenheid veld_labo methode betrouwbaarheid fractiemeting_ondergrens fractiemeting_bovengrens fractiemeting_waarde
0 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-07 ... Ksat NaN 0.0000154321 m/s veld Ksat_Soakaway_methode goed NaN NaN NaN
1 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-07 ... Ksat NaN 0.0000029437 m/s veld Ksat Enkele-ring-methode goed NaN NaN NaN
2 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-07 ... Ksat NaN 0.0000100245 m/s veld Ksat Porchet-methode goed NaN NaN NaN
3 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-07 ... Ksat NaN 0.0000036111 m/s veld Ksat Enkele-ring-methode goed NaN NaN NaN
4 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemdiepte... 129586.0 182459.0 30.7 40.0 85.0 2015-09-08 2019-02-07 ... Ksat NaN 0.0000146735 m/s veld Ksat_Soakaway_methode goed NaN NaN NaN

5 rows × 21 columns

Find all bodemlocaties where observations exist for organic carbon percentage in East-Flanders between 0 and 30 cm deep

Get boundaries of East-Flanders by using a WFS

[70]:
from owslib.etree import etree
from owslib.wfs import WebFeatureService
from pydov.util.location import (
    GmlFilter,
    Within,
)

from owslib.fes import PropertyIsEqualTo

provinciegrenzen = WebFeatureService(
    'https://geo.api.vlaanderen.be/VRBG/wfs',
    version='1.1.0')

provincie_filter = PropertyIsEqualTo(propertyname='NAAM', literal='Oost-Vlaanderen')
provincie_poly = provinciegrenzen.getfeature(
    typename='VRBG:Refprv',
    filter=etree.tostring(provincie_filter.toXML()).decode("utf8"),
    outputFormat='text/xml; subtype=gml/3.2').read()

Get bodemobservaties in East-Flanders with the requested properties

[71]:
from owslib.fes2 import PropertyIsEqualTo
from owslib.fes2 import And

from pydov.search.bodemobservatie import BodemobservatieSearch

bodemobservatie = BodemobservatieSearch()

# Select only layers with the boundaries 10-30
bodemobservaties = bodemobservatie.search(
        location=GmlFilter(provincie_poly, Within),
        query=And([
            PropertyIsEqualTo(propertyname="parameter", literal="Organische C - percentage"),
            PropertyIsEqualTo(propertyname="diepte_tot_cm", literal = '30'),
            PropertyIsEqualTo(propertyname="diepte_van_cm", literal = '0')
        ]))


bodemobservaties.head()
[000/001] .
[000/066] cccccccccccccccccccccccccccccccccccccccccccccccccc
[050/066] cccccccccccccccc
[71]:
pkey_bodemobservatie pkey_bodemlocatie pkey_parent x y mv_mtaw diepte_van_cm diepte_tot_cm observatiedatum invoerdatum ... parameter detectie waarde eenheid veld_labo methode betrouwbaarheid fractiemeting_ondergrens fractiemeting_bovengrens fractiemeting_waarde
0 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 109922.0 189993.0 10.5 0.0 30.0 1949-02-11 NaN ... Organische C - percentage NaN 0.726991492652745 % veld Aardewerk oude methode organische koolstof onbekend NaN NaN NaN
1 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 118343.0 188413.0 13.0 0.0 30.0 1951-03-01 NaN ... Organische C - percentage NaN 1.20649651972158 % veld Aardewerk oude methode organische koolstof onbekend NaN NaN NaN
2 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 132594.0 193978.0 3.0 0.0 30.0 1952-04-22 NaN ... Organische C - percentage NaN 1.12142304717711 % veld Aardewerk oude methode organische koolstof onbekend NaN NaN NaN
3 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 138392.0 217983.0 2.0 0.0 30.0 1950-02-08 NaN ... Organische C - percentage NaN 1.52358855375097 % veld Aardewerk oude methode organische koolstof onbekend NaN NaN NaN
4 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 102902.0 188823.0 8.0 0.0 30.0 1953-07-07 NaN ... Organische C - percentage NaN 1.430781129157 % veld Aardewerk oude methode organische koolstof onbekend NaN NaN NaN

5 rows × 21 columns

Now we have all observations with the requested properties. Next we need to link them with the bodemlocatie

[72]:
from pydov.search.bodemlocatie import BodemlocatieSearch
from pydov.util.query import Join
import pandas as pd

# Find bodemlocatie information for all observations
bodemlocatie = BodemlocatieSearch()
bodemlocaties = bodemlocatie.search(query=Join(bodemobservaties, on = 'pkey_bodemlocatie', using='pkey_bodemlocatie'))

# remove x, y, mv_mtaw from observatie dataframe to prevent duplicates while merging
bodemobservaties = bodemobservaties.drop(['x', 'y', 'mv_mtaw'], axis=1)

# Merge the bodemlocatie information together with the observation information
merged = pd.merge(bodemobservaties, bodemlocaties, on="pkey_bodemlocatie", how='left')

merged.head()
[000/001] .
[000/066] cccccccccccccccccccccccccccccccccccccccccccccccccc
[050/066] cccccccccccccccc
[72]:
pkey_bodemobservatie pkey_bodemlocatie pkey_parent diepte_van_cm diepte_tot_cm observatiedatum invoerdatum_x parametergroep parameter detectie ... type waarnemingsdatum doel x y mv_mtaw erfgoed bodemstreek invoerdatum_y educatieve_waarde
0 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 0.0 30.0 1949-02-11 NaN Bodem_chemisch Organische C - percentage NaN ... profielput 1949-02-11 bodemprofielen en oppervlaktemonsters karterin... 109922.0 189993.0 10.5 False Zandstreek 2019-10-11 OK
1 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 0.0 30.0 1951-03-01 NaN Bodem_chemisch Organische C - percentage NaN ... profielput 1951-03-01 bodemprofielen en oppervlaktemonsters karterin... 118343.0 188413.0 13.0 False Zandstreek 2019-10-11 OK
2 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 0.0 30.0 1952-04-22 NaN Bodem_chemisch Organische C - percentage NaN ... profielput 1952-04-22 bodemprofielen en oppervlaktemonsters karterin... 132594.0 193978.0 3.0 False Zandstreek 2019-10-11 OK
3 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 0.0 30.0 1950-02-08 NaN Bodem_chemisch Organische C - percentage NaN ... profielput 1950-02-08 bodemprofielen en oppervlaktemonsters karterin... 138392.0 217983.0 2.0 False Doel 2019-10-11 OK
4 https://www.dov.vlaanderen.be/data/bodemobserv... https://www.dov.vlaanderen.be/data/bodemlocati... https://www.dov.vlaanderen.be/data/bodemmonste... 0.0 30.0 1953-07-07 NaN Bodem_chemisch Organische C - percentage NaN ... profielput 1953-07-07 bodemprofielen en oppervlaktemonsters karterin... 102902.0 188823.0 8.0 False Zandstreek 2019-10-11 OK

5 rows × 30 columns

To export the results to CSV, you can use for example:

merged.to_csv("test.csv")

We can plot also the results on a map This can take some time!

[73]:
import folium
from folium.plugins import MarkerCluster
from pyproj import Transformer

# convert the coordinates to lat/lon for folium
def convert_latlon(x1, y1):
    transformer = Transformer.from_crs("epsg:31370", "epsg:4326", always_xy=True)
    x2,y2 = transformer.transform(x1, y1)
    return x2, y2

#convert coordinates to wgs84
merged['lon'], merged['lat'] = zip(*map(convert_latlon, merged['x'], merged['y']))

# Get only location and value
loclist = merged[['lat', 'lon']].values.tolist()

# initialize the Folium map on the centre of the selected locations, play with the zoom until ok
fmap = folium.Map(location=[merged['lat'].mean(), merged['lon'].mean()], zoom_start=10)
marker_cluster = MarkerCluster().add_to(fmap)
for loc in range(0, len(loclist)):
    popup = 'Bodemlocatie: ' + merged['pkey_bodemlocatie'][loc]
    popup = popup + '<br> Bodemobservatie: ' + merged['pkey_bodemobservatie'][loc]
    popup = popup + '<br> Value: ' + merged['waarde'][loc] + "%"
    folium.Marker(loclist[loc], popup=popup).add_to(marker_cluster)
fmap
[73]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Calculate carbon stock in Tervuren in the layer 0 - 23 cm

Get boundaries of Tervuren using WFS

[74]:
from owslib.etree import etree
from owslib.fes import PropertyIsEqualTo
from owslib.wfs import WebFeatureService
from pydov.util.location import (
    GmlFilter,
    Within,
)

stadsgrenzen = WebFeatureService(
    'https://geo.api.vlaanderen.be/VRBG/wfs',
    version='1.1.0')

gemeente_filter = PropertyIsEqualTo(propertyname='NAAM', literal='Tervuren')
gemeente_poly = stadsgrenzen.getfeature(
    typename='VRBG:Refgem',
    filter=etree.tostring(gemeente_filter.toXML()).decode("utf8"),
    outputFormat='text/xml; subtype=gml/3.2').read()

First get all observations in Tervuren for organisch C percentage in requested layer

[75]:
from owslib.fes2 import PropertyIsEqualTo, PropertyIsGreaterThan, PropertyIsLessThan
from owslib.fes2 import And

from pydov.search.bodemobservatie import BodemobservatieSearch

bodemobservatie = BodemobservatieSearch()

# all layers intersect the layer 0-23cm
carbon_observaties = bodemobservatie.search(
        location=GmlFilter(gemeente_poly, Within),
        query=And([
            PropertyIsEqualTo(propertyname="parameter", literal="Organische C - percentage"),
            PropertyIsGreaterThan(propertyname="diepte_tot_cm", literal = '0'),
            PropertyIsLessThan(propertyname="diepte_van_cm", literal = '23')
        ]),
        return_fields=('pkey_bodemlocatie', 'waarde'))
carbon_observaties = carbon_observaties.rename(columns={"waarde": "organic_c_percentage"})
carbon_observaties.head()

[000/001] .
[75]:
pkey_bodemlocatie organic_c_percentage
0 https://www.dov.vlaanderen.be/data/bodemlocati... 1.54679040989946
1 https://www.dov.vlaanderen.be/data/bodemlocati... 1.39211136890951
2 https://www.dov.vlaanderen.be/data/bodemlocati... 1.08275328692962
3 https://www.dov.vlaanderen.be/data/bodemlocati... 0.67
4 https://www.dov.vlaanderen.be/data/bodemlocati... 0.765661252900232

Then get all observations in Tervuren for bulkdensity in requested layer

[76]:
density_observaties = bodemobservatie.search(
        location=GmlFilter(gemeente_poly, Within),
        query=And([
            PropertyIsEqualTo(propertyname="parameter",
                              literal="Bulkdensiteit - gemeten"),
            PropertyIsGreaterThan(propertyname="diepte_tot_cm", literal = '0'),
            PropertyIsLessThan(propertyname="diepte_van_cm", literal = '23')
        ]),
        return_fields=('pkey_bodemlocatie', 'waarde'))

density_observaties = density_observaties.rename(columns={"waarde": "bulkdensity"})
density_observaties.head()
[000/000] .
[76]:
pkey_bodemlocatie bulkdensity

Merge results together based on their bodemlocatie. Only remains the records where both parameters exists

[77]:
import pandas as pd

merged = pd.merge(carbon_observaties, density_observaties, on="pkey_bodemlocatie")

merged.head()
[77]:
pkey_bodemlocatie organic_c_percentage bulkdensity

Filter Aardewerk soil locations

Since we know that Aardewerk soil locations make use of a specific suffix, a query could be built filtering these out.

Since we only need to match a partial string in the name, we will build a query using the PropertyIsLike operator to find all Aardewerk bodemlocaties. We use max_features=10 to limit the results to 10.

[78]:
from owslib.fes2 import PropertyIsLike

query = PropertyIsLike(propertyname='naam',
                       literal='KART_PROF_%', wildCard='%')
df = bodemlocatie.search(query=query, max_features=10)

df.head()
[000/001] .
[000/010] ..........
[78]:
pkey_bodemlocatie pkey_bodemsite naam type waarnemingsdatum doel x y mv_mtaw erfgoed bodemstreek invoerdatum educatieve_waarde
0 https://www.dov.vlaanderen.be/data/bodemlocati... NaN KART_PROF_007W/40 profielput 1955-07-07 bodemprofielen en oppervlaktemonsters karterin... 167292.0 229988.0 19.0 False Kempen 2019-10-11 OK
1 https://www.dov.vlaanderen.be/data/bodemlocati... NaN KART_PROF_027W/36 profielput 1950-12-06 bodemprofielen en oppervlaktemonsters karterin... 132723.0 217683.0 3.0 False Doel 2019-10-11 OK
2 https://www.dov.vlaanderen.be/data/bodemlocati... NaN KART_PROF_023E/04 profielput 1951-11-28 bodemprofielen en oppervlaktemonsters karterin... 76267.0 216054.0 3.0 False Zwin 2019-10-11 OK
3 https://www.dov.vlaanderen.be/data/bodemlocati... NaN KART_PROF_001E/02 profielput 1954-05-31 bodemprofielen en oppervlaktemonsters karterin... 158367.0 240397.0 12.5 False Kempen 2019-10-11 OK
4 https://www.dov.vlaanderen.be/data/bodemlocati... NaN KART_PROF_037E/38 profielput 1952-02-01 bodemprofielen en oppervlaktemonsters karterin... 65969.0 207819.0 21.0 False Zandstreek 2019-10-11 OK

As seen in the soil data example, we can use the pkey_bodemlocatie as a permanent link to the information of these bodemlocaties:

[79]:
for pkey_bodemlocatie in set(df.pkey_bodemlocatie):
    print(pkey_bodemlocatie)
https://www.dov.vlaanderen.be/data/bodemlocatie/1958-000829
https://www.dov.vlaanderen.be/data/bodemlocatie/1954-000828
https://www.dov.vlaanderen.be/data/bodemlocatie/1954-000822
https://www.dov.vlaanderen.be/data/bodemlocatie/1952-000824
https://www.dov.vlaanderen.be/data/bodemlocatie/1955-000827
https://www.dov.vlaanderen.be/data/bodemlocatie/1951-000825
https://www.dov.vlaanderen.be/data/bodemlocatie/1950-000839
https://www.dov.vlaanderen.be/data/bodemlocatie/1951-000840
https://www.dov.vlaanderen.be/data/bodemlocatie/1957-000826
https://www.dov.vlaanderen.be/data/bodemlocatie/1955-000823