Introductory tutorial

Binder

pydov provides machine access to the data that can be visualized with the DOV viewer.

All the pydov functionalities rely on the existing DOV webservices. An in-depth overview of the available services and endpoints is provided on the accessing DOV data page. To retrieve data, pydov uses a combination of the available WFS services and the XML representation of the core DOV data.

As pydov relies on the XML data returned by the existing DOV webservices, downloading DOV data with pydov is governed by the same disclaimer that applies to the other DOV services. Be sure to consult it when using pydov!

pydov interfaces data and services hosted by the Flemish governement. Therefore, some syntax of the API as well as the descriptions provided by the backend are in Dutch.

Use case: gather data for a hydrogeological model

[61]:
%matplotlib inline
import inspect, sys
[62]:
import pydov
import pandas as pd

pydov: general info

To get started with pydov you should first determine which information you want to search for. DOV provides a lot of different datasets about soil, subsoil and groundwater of Flanders, some of which can be queried using pydov. Supported datasets are listed in the quickstart.

In this case, to start with a hydrogeological model, we are interested in the hydrostratigraphic interpretation of the borehole data and the groundwater level. These datasets can be found with the following search objects: - Hydrostratigraphic interpretation - Groundwater level

Indeed, each of the datasets can be queried using a search object for the specific dataset. While the search objects are different, the workflow is the same for each dataset. Relevant classes can be imported from the pydov.search package, for example if we’d like to query the dataset with hydrostratigraphic interpretations of borehole data:

[63]:
from pydov.search.interpretaties import HydrogeologischeStratigrafieSearch
hs = HydrogeologischeStratigrafieSearch()

If you would like some more information or metadata about the data you can retrieve, you can query the search object. Since pydov interfaces services and metadata from Flemish government agencies, the descriptions are in Dutch:

[64]:
hs.get_description()
[64]:
'De hydrostratigrafie geeft, op basis van de (gecodeerde) lithologie, een indeling weer naar de al dan niet watervoerende eigenschappen van een bepaald beschreven diepte-interval. Deze interpretatie respecteert de lithostratigrafie van het Tertiair, maar deelt deze anders in. De hiervoor gebruikte standaard is de Hydrogeologische Codering van de Ondergrond van Vlaanderen (HCOV). Deze kan beschouwd worden als de officiele hydrogeologische codering voor het Vlaams Gewest.'

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

[65]:
fields = hs.get_fields()
# print available fields
for f in fields.values():
    print(f['name'])
pkey_interpretatie
Type_proef
Proefnummer
pkey_boring
x
y
start_interpretatie_mtaw
diepte_tot_m
gemeente
Auteurs
Datum
Opdrachten
betrouwbaarheid_interpretatie
Geldig_van
Geldig_tot
eerste_invoer
geom
diepte_laag_van
diepte_laag_tot
aquifer

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

  • query: whether you can use this field in an attribute query

[66]:
fields['pkey_interpretatie']
[66]:
{'name': 'pkey_interpretatie',
 'definition': "URL die verwijst naar de gegevens van deze hydrogeologische stratigrafie op de website. Voeg '.xml' toe om een XML voorstelling van deze gegevens te verkrijgen.",
 'type': 'string',
 'notnull': False,
 'query': True,
 'cost': 1}

The fields pkey_interpretatie and pkey_boring are important identifiers. In this case pkey_interpretatie is the unique identifier of this interpretation and is also the permanent url where the data can be consulted (~https://www.dov.vlaanderen.be/data/interpretatie/…). You can retrieve an XML representation by appending ‘.xml’ to the URL, or a JSON equivalent by appending ‘.json’.

The pkey_boring is the identifier of the borehole from which this interpretation was made. As mentioned before, it is also the permanent url (~https://www.dov.vlaanderen.be/data/boring/…).

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

[67]:
fields['aquifer']['values']
[67]:
{'0000': 'Onbekend',
 '0100': 'Quartaire aquifersystemen',
 '0110': 'Ophogingen',
 '0120': 'Duinen',
 '0130': 'Polderafzettingen',
 '0131': 'Kleiige polderafzettingen van de kustvlakte',
 '0132': 'Kleiige polderafzettingen van het Meetjesland',
 '0133': 'Kleiige polderafzettingen van Waasland-Antwerpen',
 '0134': 'Zandige kreekruggen',
 '0135': 'Veen-kleiige poelgronden',
 '0140': 'Alluviale deklagen',
 '0150': 'Deklagen',
 '0151': 'Zandige deklagen',
 '0152': 'Zand-lemige deklagen',
 '0153': 'Lemige deklagen',
 '0154': 'Kleiige deklagen',
 '0160': 'Pleistocene afzettingen',
 '0161': 'Pleistoceen van de kustvlakte',
 '0162': 'Pleistoceen van de Vlaamse Vallei',
 '0163': 'Pleistoceen van de riviervalleien',
 '0170': 'Maas- en Rijnafzettingen',
 '0171': 'Afzettingen Hoofdterras',
 '0172': 'Afzettingen Tussenterassen',
 '0173': 'Afzettingen Maasvlakte',
 '0200': 'Kempens Aquifersysteem',
 '0210': 'Kiezeloolietformatie ten noorden van Feldbiss',
 '0211': 'Zandige eenheid boven de Brunssum I-klei',
 '0212': 'Brunssum I-Klei',
 '0213': 'Zand van Pey',
 '0214': 'Brunssum II-klei',
 '0215': 'Zand van Waubach',
 '0220': 'Klei-zand-complex van de Kempen',
 '0221': 'Klei van Turnhout',
 '0222': 'Zand van Beerse',
 '0223': 'Klei van Rijkevorsel',
 '0230': 'Pleistoceen en Plioceen aquifer',
 '0231': 'Zanden van Brasschaat en/of Merksplas',
 '0232': 'Zand van Mol',
 '0233': 'Zandige top van Lillo',
 '0234': 'Zand van Poederlee en/of zandige top van Kasterlee',
 '0240': 'Pliocene kleiige laag',
 '0241': 'Kleiig deel van Lillo en/of van de overgang Lillo-Kattendijk',
 '0242': 'Kleiige overgang tussen de zanden van Kasterlee en Diest',
 '0250': 'Mioceen Aquifersysteem',
 '0251': 'Zand van Kattendijk en/of onderste zandlaag van Lillo',
 '0252': 'Zand van Diest',
 '0253': 'Zand van Bolderberg',
 '0254': 'Zanden van Berchem en/of Voort',
 '0255': 'Klei van Veldhoven',
 '0256': 'Zand van Eigenbilzen',
 '0300': 'Boom Aquitard',
 '0301': 'Kleiig deel van Eigenbilzen',
 '0302': 'Klei van Putte',
 '0303': 'Klei van Terhagen',
 '0304': 'Klei van Belsele-Waas',
 '0400': 'Oligoceen Aquifersysteem',
 '0410': 'Zand van Kerniel',
 '0420': 'Klei van Kleine-Spouwen',
 '0430': 'Ruisbroek-Berg Aquifer',
 '0431': 'Zand van Berg',
 '0432': 'Zand van Kerkom',
 '0433': 'Kleiig zand van Oude Biezen',
 '0434': 'Zand van Boutersem',
 '0435': 'Zand van Ruisbroek',
 '0436': 'Zand van Wintham',
 '0440': 'Tongeren Aquitard',
 '0441': 'Klei van Henis',
 '0442': 'Klei van Watervliet',
 '0450': 'Onder-Oligoceen Aquifersysteem',
 '0451': 'Zand van Neerrepen',
 '0452': 'Zand-Klei van Grimmertingen',
 '0453': 'Kleiig zand van Bassevelde',
 '0500': 'Bartoon Aquitardsysteem',
 '0501': 'Klei van Onderdijke',
 '0502': 'Zand van Buisputten',
 '0503': 'Klei van Zomergem',
 '0504': 'Zand van Onderdaele',
 '0505': 'Kleien van Ursel en/of Asse',
 '0600': 'Ledo Paniseliaan Brusseliaan Aquifersysteem',
 '0610': 'Wemmel-Lede Aquifer',
 '0611': 'Zand van Wemmel',
 '0612': 'Zand van Lede',
 '0620': 'Zand van Brussel',
 '0630': 'Afzettingen van het Boven-Paniseliaan',
 '0631': 'Zanden van Aanlter en/of Oedelem',
 '0632': 'Zandige klei van Beernem',
 '0640': 'Zandige afzettingen van het Onder-Paniseliaan (Vlierzele en/of Aalterbrugge)',
 '0700': 'Paniseliaan Aquitard',
 '0701': 'Klei van Pittem',
 '0702': 'Klei van Merelbeke',
 '0800': 'Ieperiaan Aquifer (Egem en of Mont-Panisel)',
 '0900': 'Ieperiaan aquitardsysteem',
 '0910': 'Silt van Kortemark',
 '0920': 'Afzettingen van Kortrijk',
 '0921': 'Klei van Aalbeke',
 '0922': 'Klei van Moen',
 '0923': 'Zand van Mons-en-Pévèle',
 '0924': 'Klei van Saint-Maur',
 '0925': 'Klei van Mont-Héribu',
 '1000': 'Paleoceen Aquifersysteem',
 '1010': 'Landeniaan Aquifersysteem',
 '1011': 'Zand van Knokke',
 '1012': 'Zandige afzettingen van Loksbergen en/of Dormaal',
 '1013': 'Zand van Grandglise en/of Hoegaarden',
 '1014': 'Kleiig deel van Lincent',
 '1015': 'Versteend deel van Lincent',
 '1020': 'Landeniaan en Heersiaan Aquitard',
 '1021': 'Siltige afzetting van Halen',
 '1022': 'Klei van Waterschei',
 '1023': 'Slecht doorlatend deel van de mergels van Gelinden',
 '1030': 'Heersiaan en Opglabbeek Aquifersysteem',
 '1031': 'Doorlatend deel van de Mergels van Gelinden',
 '1032': 'Zand van Orp',
 '1033': 'Zand van Eisden',
 '1034': 'Klei van Opoeteren',
 '1035': 'Zand van Maasmechelen',
 '1100': 'Krijt Aquifersysteem',
 '1110': 'Krijt Aquifer',
 '1111': 'Kalksteen van Houthem',
 '1112': 'Tufkrijt van Maastricht',
 '1113': 'Krijt van Gulpen',
 '1120': 'Afzettingen van Vaals (Smectiet van Herve)',
 '1130': 'Zand van Aken',
 '1140': 'Turoonmergels op Massief van Brabant',
 '1150': 'Wealdiaan',
 '1200': 'Jura-Trias-Perm',
 '1210': 'Jura',
 '1220': 'Trias',
 '1230': 'Perm',
 '1300': 'Sokkel',
 '1310': 'Boven-Carboon',
 '1320': 'Kolenkalk',
 '1330': 'Devoon',
 '1340': 'Cambro-Siluur Massief van Brabant'}

Query the data with pydov

Attributes

The data can be queried on attributes, location or both. To query on attributes, the OGC filter functions from OWSLib are used:

[68]:
# list available query methods
methods = [i for i,j in inspect.getmembers(sys.modules['owslib.fes2'],
                                           inspect.isclass)
           if 'Property' in i]
print(*methods, sep = "\n")
PropertyIsBetween
PropertyIsEqualTo
PropertyIsGreaterThan
PropertyIsGreaterThanOrEqualTo
PropertyIsLessThan
PropertyIsLessThanOrEqualTo
PropertyIsLike
PropertyIsNotEqualTo
PropertyIsNull
SortProperty

If you are for example interested in all the hydrostratigraphic interpretations in the city of Leuven, you compose the query like below (mind that the values are in Dutch):

[69]:
from owslib.fes2 import PropertyIsEqualTo
query = PropertyIsEqualTo(
            propertyname='gemeente',
            literal='Leuven')
dfhs = hs.search(query=query)
dfhs.head()
[000/001] .
[000/038] cccccccccccccccccccccccccccccccccccccc
[69]:
pkey_interpretatie pkey_boring betrouwbaarheid_interpretatie x y start_interpretatie_mtaw diepte_laag_van diepte_laag_tot aquifer
0 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1889... goed 169506.0 173442.0 38.0 0.0 5.5 0163
1 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1889... goed 169506.0 173442.0 38.0 5.5 22.8 0450
2 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1934... goed 177360.0 175051.0 60.0 0.0 21.0 0000
3 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1934... goed 177360.0 175051.0 60.0 21.0 25.0 0450
4 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1934... goed 177360.0 175051.0 60.0 25.0 33.0 0612

This yielded 38 interpretations from 38, or less, boreholes. It can be less than 38 boreholes because multiple interpretations can be made of a single borehole.

If you would like to narrow the search down to for example interpretations deeper than 200 meters, you can combine features in the search using the logical operators And, Or provided by OWSLib:

[70]:
from owslib.fes2 import And
from owslib.fes2 import PropertyIsGreaterThan
query = And([
    PropertyIsEqualTo(
            propertyname='gemeente',
            literal='Leuven'),
    PropertyIsGreaterThan(
            propertyname='diepte_tot_m',
            literal='200')
    ])
dfhs = hs.search(query=query)
dfhs.head()
[000/001] .
[000/001] c
[70]:
pkey_interpretatie pkey_boring betrouwbaarheid_interpretatie x y start_interpretatie_mtaw diepte_laag_van diepte_laag_tot aquifer
0 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 0.0 4.5 0162
1 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 4.5 59.0 0620
2 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 59.0 90.7 0900
3 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 90.7 110.0 1013
4 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 110.0 130.0 1014

Mind the difference between attributes diepte_tot_m and diepte_laag_.... The former is defined in the WFS service and can be used as attribute in the query. The latter attributes are defined in the linked XML document, from which the information is only available after it has been gathered from the DOV webservice. All the attributes with cannot be used in the intial query and should be used in a subsequent filtering of the Pandas DataFrame.

More information on querying attribute properties is given in the docs. Worth mentioning is the query using lists where pydov extends the default OGC filter expressions described with a new expression PropertyInList that allows you to use lists (of strings) in search queries.

One last goodie is the possibility to join searches using common attibutes. For example the pkey_boring field, denoting the borehole. As such, you can get the boreholes for which a hydrostratigraphical interpretation is available, and also query the lithological description of that borehole. Like below:

[71]:
from pydov.util.query import Join
from pydov.search.interpretaties import LithologischeBeschrijvingenSearch

ls = LithologischeBeschrijvingenSearch()
dfls = ls.search(query=Join(dfhs, 'pkey_boring'))
df_joined = pd.merge(dfhs, dfls.loc[:, ['pkey_boring','diepte_laag_van', 'diepte_laag_tot', 'beschrijving']],
                     how='left',
                     left_on=['pkey_boring','diepte_laag_van', 'diepte_laag_tot'],
                     right_on = ['pkey_boring','diepte_laag_van', 'diepte_laag_tot']
                    )
df_joined.head()
[000/001] .
[000/001] c
[71]:
pkey_interpretatie pkey_boring betrouwbaarheid_interpretatie x y start_interpretatie_mtaw diepte_laag_van diepte_laag_tot aquifer beschrijving
0 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 0.0 4.5 0162 NaN
1 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 4.5 59.0 0620 sable gris quartzeux, avec grès gris quartzeux...
2 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 59.0 90.7 0900 argile grise finement sableuse
3 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 90.7 110.0 1013 NaN
4 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1932... goed 173252.0 179257.0 17.0 110.0 130.0 1014 sable argileux gris, avec petits débris broyés...

Location

One can also query on location, using the location objects and spatial filters from the pydov.util.location module. For example, to request all hydrostratigraphic interpretations in a given bounding box:

[72]:
from pydov.util.location import Within, Box
location = Within(Box(170000, 171000, 172000, 173000))
df = hs.search(location=location)
df.head()
[000/001] .
[000/005] ccccc
[72]:
pkey_interpretatie pkey_boring betrouwbaarheid_interpretatie x y start_interpretatie_mtaw diepte_laag_van diepte_laag_tot aquifer
0 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/2016... goed 170085.97 171027.67 23.86 0.0 6.0 0140
1 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/2016... goed 170085.97 171027.67 23.86 6.0 10.0 0160
2 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/2016... goed 170085.97 171027.67 23.86 10.0 30.0 0920
3 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/2016... goed 170085.97 171027.67 23.86 30.0 39.0 1010
4 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 0.0 0.6 0110

Alternatively, you can define a Point or a GML document for the spatial query as is described in the docs. For example, if you are interested in a site you can define the point with a search radius of for example 500 meters like this:

[73]:
from pydov.util.location import WithinDistance, Point
location = WithinDistance(
            Point(171500, 172500),
            500,
            distance_unit='meter'
            )
df = hs.search(location=location)
df.head()
[000/001] .
[000/001] c
[73]:
pkey_interpretatie pkey_boring betrouwbaarheid_interpretatie x y start_interpretatie_mtaw diepte_laag_van diepte_laag_tot aquifer
0 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 0.0 0.6 0110
1 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 0.6 14.4 0100
2 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 14.4 95.1 0000
3 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 95.1 118.9 1100
4 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 118.9 124.5 1300

Groundwater head data

Querying the groundwater head data follows the same workflow as mentioned above for the interpretation of borehole data with the instantiation of a search object and the subsequent query with selection on attribute or location properties.

[74]:
from pydov.search.grondwaterfilter import GrondwaterFilterSearch
gws = GrondwaterFilterSearch()
fields = gws.get_fields()

# print available fields
for f in fields.values():
    print(f['name'])
gw_id
pkey_grondwaterlocatie
filternummer
pkey_filter
namen
filtergrafiek
putgrafiek
aquifer
diepte_onderkant_filter
lengte_filter
putsoort
filtertype
meetnet
x
y
start_grondwaterlocatie_mtaw
gemeente
grondwaterlichaam
afgesloten_volgens_gwdecreet
datum_in_filter
datum_uit_filter
stijghoogterapport
analyserapport
boornummer
boringfiche
peilmetingen_van
peilmetingen_tot
kwaliteitsmetingen_van
kwaliteitsmetingen_tot
recentste_exploitant
beheerder
eerste_invoer
recentste_installatie
geom
meetnet_code
aquifer_code
grondwaterlichaam_code
regime
datum
tijdstip
peil_mtaw
betrouwbaarheid
methode
filterstatus
filtertoestand
mv_mtaw

For example query all data in a bounding box:

[75]:
location = Within(Box(170000, 171000, 173000, 174000))
df = gws.search(location=location)
df.head()
[000/001] .
[000/052] cccccccccccccccccccccccccccccccccccccccccccccccccc
[050/052] cc
[75]:
pkey_filter pkey_grondwaterlocatie gw_id filternummer filtertype x y start_grondwaterlocatie_mtaw mv_mtaw gemeente ... regime diepte_onderkant_filter lengte_filter datum tijdstip peil_mtaw betrouwbaarheid methode filterstatus filtertoestand
0 https://www.dov.vlaanderen.be/data/filter/2021... https://www.dov.vlaanderen.be/data/put/2021-09... 2-103919 1 pompfilter 171580.45 171261.97 38.90 38.90 NaN ... freatisch 18.0 7.5 NaN NaN NaN NaN NaN NaN NaN
1 https://www.dov.vlaanderen.be/data/filter/2022... https://www.dov.vlaanderen.be/data/put/2022-10... 2-105034 1 peilfilter 171254.51 172800.78 29.74 NaN NaN ... freatisch 4.5 1.0 NaN NaN NaN NaN NaN NaN NaN
2 https://www.dov.vlaanderen.be/data/filter/2017... https://www.dov.vlaanderen.be/data/put/2019-01... 2-103155 1 pompfilter 170270.00 173561.00 -1.00 -1.00 Leuven ... freatisch NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 https://www.dov.vlaanderen.be/data/filter/1900... https://www.dov.vlaanderen.be/data/put/2019-01... 2-104085 1 pompfilter 170725.00 173055.00 47.63 47.63 Leuven ... freatisch NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 https://www.dov.vlaanderen.be/data/filter/2016... https://www.dov.vlaanderen.be/data/put/2019-01... 3008-066 1 peilfilter 170085.97 171027.67 23.86 23.86 Bertem ... freatisch 3.5 1.0 NaN NaN NaN NaN NaN NaN NaN

5 rows × 23 columns

One important difference is the presence of time-related data. More specifically the attributes datum and tijdstip. These can be combined to create a date.datetime object that can be used in the subsequent manipuliation of the Pandas DataFrame. Make sure to remove the records without a valid datum and fill the empty tijdstip fields with a default timestamp (!)

[76]:
import pandas as pd
df.reset_index(inplace=True)
df = df.loc[~df.datum.isna()]
df['tijdstip'] = df.tijdstip.fillna('00:00:00')
df['tijd'] = pd.to_datetime(df.datum.astype(str) + ' ' + df.tijdstip.astype(str))
df.tijd.head()
[76]:
15   1984-01-26
16   1984-09-30
17   1985-11-01
18   1986-04-04
19   1986-10-01
Name: tijd, dtype: datetime64[ns]

More examples for the timeseries processing and analysis is available in the Notebooks of pydov.

Data cache

Notice the cc in the progress bar while loading of the data? It means the data was loaded from your local cache instead of being downloaded, as it was already part of an earlier data request. See the caching documentation for more in-depth information about the default directory, how to change and/or clean it, and even how to create some custom cache format.

Putting it all together

[77]:
# imports
import pandas as pd
import pydov
from pydov.util.location import WithinDistance, Point
from pydov.util.query import Join
from pydov.search.interpretaties import LithologischeBeschrijvingenSearch
from pydov.search.interpretaties import HydrogeologischeStratigrafieSearch
from pydov.search.grondwaterfilter import GrondwaterFilterSearch
from owslib.fes2 import PropertyIsEqualTo

# define search objects
hs = HydrogeologischeStratigrafieSearch()
ls = LithologischeBeschrijvingenSearch()
gws = GrondwaterFilterSearch()

# search hydrostratigraphic interpretations based on location
location = WithinDistance(
    Point(171500, 172500),
    500,
    distance_unit='meter'
    )
dfhs = hs.search(location=location)

# join the lithostratigraphic desriptions
dfls = ls.search(query=Join(dfhs, 'pkey_boring'))
df_joined = pd.merge(dfhs, dfls.loc[:, ['pkey_boring','diepte_laag_van', 'diepte_laag_tot', 'beschrijving']],
                     how='left',
                     left_on=['pkey_boring','diepte_laag_van', 'diepte_laag_tot'],
                     right_on = ['pkey_boring','diepte_laag_van', 'diepte_laag_tot']
                    )

# search the groundwater head data in the neighbourhoud
dfgw = gws.search(location=location)

# create date.datetime objects for further processing
dfgw.reset_index(inplace=True)
dfgw = dfgw.loc[~dfgw.datum.isna()]
dfgw['tijdstip'] = dfgw.tijdstip.fillna('00:00:00')
dfgw['tijd'] = pd.to_datetime(dfgw.datum.astype(str) + ' ' + dfgw.tijdstip.astype(str))
[000/001] .
[000/001] c
[000/001] .
[000/002] cc
[000/001] .
[000/007] ccccccc
[78]:
df_joined.head()
[78]:
pkey_interpretatie pkey_boring betrouwbaarheid_interpretatie x y start_interpretatie_mtaw diepte_laag_van diepte_laag_tot aquifer beschrijving
0 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 0.0 0.6 0110 aangevulde grond
1 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 0.6 14.4 0100 NaN
2 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 14.4 95.1 0000 Brusseliaan - Ieperiaan en Landeniaan
3 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 95.1 118.9 1100 Krijt
4 https://www.dov.vlaanderen.be/data/interpretat... https://www.dov.vlaanderen.be/data/boring/1974... goed 171548.64 172680.85 26.21 118.9 124.5 1300 Primair
[79]:
dfgw.head()
[79]:
index pkey_filter pkey_grondwaterlocatie gw_id filternummer filtertype x y start_grondwaterlocatie_mtaw mv_mtaw ... diepte_onderkant_filter lengte_filter datum tijdstip peil_mtaw betrouwbaarheid methode filterstatus filtertoestand tijd
1 1 https://www.dov.vlaanderen.be/data/filter/1974... https://www.dov.vlaanderen.be/data/put/2017-00... 2-0005 1 peilfilter 171548.64 172680.85 26.21 26.21 ... 118.95 31.5 1984-01-26 00:00:00 12.54 goed peillint in rust 1.0 1984-01-26
2 2 https://www.dov.vlaanderen.be/data/filter/1974... https://www.dov.vlaanderen.be/data/put/2017-00... 2-0005 1 peilfilter 171548.64 172680.85 26.21 26.21 ... 118.95 31.5 1984-09-30 00:00:00 12.54 goed peillint in rust 1.0 1984-09-30
3 3 https://www.dov.vlaanderen.be/data/filter/1974... https://www.dov.vlaanderen.be/data/put/2017-00... 2-0005 1 peilfilter 171548.64 172680.85 26.21 26.21 ... 118.95 31.5 1985-11-01 00:00:00 11.58 goed peillint in rust 1.0 1985-11-01
4 4 https://www.dov.vlaanderen.be/data/filter/1974... https://www.dov.vlaanderen.be/data/put/2017-00... 2-0005 1 peilfilter 171548.64 172680.85 26.21 26.21 ... 118.95 31.5 1986-04-04 00:00:00 11.29 goed peillint in rust 1.0 1986-04-04
5 5 https://www.dov.vlaanderen.be/data/filter/1974... https://www.dov.vlaanderen.be/data/put/2017-00... 2-0005 1 peilfilter 171548.64 172680.85 26.21 26.21 ... 118.95 31.5 1986-10-01 00:00:00 10.87 goed peillint in rust 1.0 1986-10-01

5 rows × 25 columns