Aan de slag¶
Deze handleiding neemt je stap voor stap mee om de Wasstraat Archeologische Data voor het eerst te installeren, te configureren en te draaien. Na het doorlopen heb je een werkende omgeving met verwerkte archeologische data die je kunt bekijken in de webapplicatie.
1. Downloaden en installeren¶
Vereisten¶
Zorg dat de volgende software op je systeem is geïnstalleerd:
- Docker Desktop — Minimaal versie 20.10
- Docker Compose — Wordt meegeleverd met Docker Desktop
- Git — Voor het clonen van de repository
- Minimaal 12 GB RAM beschikbaar voor Docker (stel dit in via Docker Desktop → Settings → Resources)
- Minimaal 2 Cores beschikbaar voor Docker (stel dit in via Docker Desktop → Settings → Resources)
- Minimaal 256 GB schijfruimte beschikbaar voor Docker (stel dit in via Docker Desktop → Settings → Resources)
Docker Desktop resources
De Wasstraat draait 8 containers tegelijk. Stel in Docker Desktop het beschikbare geheugen in op minimaal 12 GB met 2 cores. Bij productiegebruik zijn meer resources aangeraden; voor Delft is gewerkt met 32 GB RAM, 10 Cores en 521 GB Schijfruimte.
Je hebt deze resources overigens maar heel tijdelijk nodig: denk aan een run om alle data te "wassen" van 20 min tot uiterlijk 24 uur.
Repository clonen¶
git clone https://github.com/brienen/wasstraat_archeologische_data.git
cd wasstraat_archeologische_data
Configuratie¶
Bij de eerste start genereert het systeem automatisch alle configuratiebestanden met unieke wachtwoorden. Je hoeft zelf niets in te stellen — het werkt direct out-of-the-box.
De configuratiebestanden worden aangemaakt in config/ op basis van de meegeleverde .env.example templates. Elk bestand krijgt automatisch een veilig, willekeurig wachtwoord. De gegenereerde wachtwoorden worden in de terminal getoond zodat je ze kunt bewaren.
Handmatig configureren
Wil je de configuratie handmatig aanpassen? Kopieer de .env.example bestanden:
bash
for f in config/*.env.example; do cp "$f" "${f%.example}"; done
Pas vervolgens de wachtwoorden in config/*.env aan naar wens.
2. Wasstraat starten¶
Start de wasstraat:
make app
Bij de allereerste start duurt het enkele minuten omdat Docker alle images moet downloaden en bouwen. Je ziet de voortgang in de terminal.
Controleer of alle containers draaien:
make ps
Je zou deze 8 containers moeten zien:
| Container | Poort | Status verwacht |
|---|---|---|
wasstraat_airflow |
:8080 | Up |
wasstraat_flask |
:5051 | Up |
wasstraat_postgres |
:5432 | Up |
wasstraat_mongo |
:27017 | Up |
wasstraat_elasticsearch |
:9200 | Up |
wasstraat_redis |
:6379 | Up |
wasstraat_apache |
:5052 | Up |
wasstraat_jupyter |
:8888 | Up |
Containers starten niet?
Als een container niet wil starten, bekijk de logs: ```bash make logs
Of voor één specifieke container:¶
docker logs wasstraat_airflow ``` De meest voorkomende oorzaak is onvoldoende geheugen in Docker Desktop.
3. Webpagina's bekijken¶
Na het starten zijn er drie webapplicaties beschikbaar:
Airflow — Data verwerken (ETL)¶
http://localhost:8080
Hier beheer je de dataverwerkingspipeline. Je ziet een overzicht van alle beschikbare DAGs (Directed Acyclic Graphs — de verwerkingsprocessen). Inloggen doe je met de standaard Airflow-credentials die bij de installatie zijn gegenereerd (standaard: admin / het gegenereerde wachtwoord, te vinden in config/airflow.env onder SECURITY__ADMIN_PASSWORD).
Flask App — Data inzien¶
http://localhost:5051
De webapplicatie voor het bekijken van de verwerkte data. Na een succesvolle verwerking zie je hier een interactieve kaart van Delft met alle opgravingslocaties, en kun je doorklikken naar projecten, vondsten, artefacten, foto's en meer.
Nog geen data?
Bij een verse installatie is de Flask App nog leeg. Dat klopt — je moet eerst data verwerken via Airflow (stap 5–7 van deze handleiding).
Jupyter Lab — Data analyseren¶
http://localhost:8888
Jupyter Lab voor eigen data-analyse. Er zijn 68+ bestaande notebooks beschikbaar met voorbeelden van data-exploratie en transformatie-validatie. Het wachtwoord staat in config/jupyter.env.
4. Bestanden klaarzetten¶
Voorbeelddata: direct aan de slag¶
De repository bevat synthetische voorbeelddata in data/synthetic/data/ — twee fictieve opgravingsprojecten waarmee je de volledige pipeline kunt testen zonder eigen brondata. Deze data wordt automatisch gebruikt bij make integration en dient als werkend voorbeeld van de verwachte bestandsstructuur.
Snel testen zonder eigen data
De synthetische data is klaar voor gebruik. Start de Wasstraat met make app en trigger de verwerkingspipeline in Airflow om te zien hoe het platform werkt. Zie data/synthetic/README.md voor de inhoud van de voorbeeldprojecten.
Eigen data klaarzetten¶
Gemeenten kunnen hun eigen opgravingsdata klaarzetten conform dezelfde directorystructuur als de Delftse pijplijn. De echte Delftse data is niet opgenomen in de repository, maar de synthetische voorbeelddata in data/synthetic/data/ toont exact welke bestanden en structuren het platform verwacht.
De Wasstraat leest brondata uit de directory data/input/basefiles/projectdatabase/. Elke subdirectory heeft een specifiek doel:
data/input/basefiles/projectdatabase/
├── digidepot/ ← Projectdatabases (.mdb/.accdb)
├── Delf-IT/ ← DelfIT administratie (.mdb + .xlsx)
├── magazijnlijst/ ← Depotregistratie (.mdb)
├── digifotos/ ← Foto-metadata (.mdb)
├── monsterdatabase/ ← Monsterregistratie (.mdb/.accdb)
├── rapporten/ ← Rapportendatabases (.mdb)
│ ├── DAN/ ← Delfts Archeologische Notities
│ └── DAR/ ← Delfts Archeologische Rapporten
└── referentietabellen/ ← ABR-codes en standaardtabellen (.xlsx/.mdb)
Wat moet waar?¶
| Directory | Wat erin hoort | Bestandstype | Verplicht? |
|---|---|---|---|
digidepot/ |
Per opgraving een subdirectory met de projectdatabase | .mdb / .accdb |
Ja — dit is de hoofdbron |
Delf-IT/ |
De centrale administratiedatabase en projecttabel | .mdb + .xlsx |
Ja — bevat projectoverzicht |
magazijnlijst/ |
Depot- en magazijnadministratie | .mdb |
Aanbevolen |
digifotos/ |
Digitale fotolijst met metadata | .mdb |
Aanbevolen (voor foto-koppeling) |
monsterdatabase/ |
Monster- en residuregistratie | .mdb / .accdb |
Optioneel |
rapporten/DAN/ en DAR/ |
Rapportenlijstdatabases | .mdb |
Optioneel |
referentietabellen/ |
ABR-classificatie, bestandslijsten | .xlsx / .mdb |
Ja — nodig voor harmonisatie |
Hoe worden bestanden gevonden?¶
De Wasstraat doorzoekt elke directory recursief op .mdb en .accdb bestanden. Je kunt dus subdirectories gebruiken om bestanden te organiseren. In digidepot/ is het gebruikelijk om per project een subdirectory aan te maken:
digidepot/
├── DB008_Leeuwenstein/
│ └── DB008.mdb
├── DC001_Oude_Delft_96/
│ └── DC001.mdb
└── DC002_Oude_Delft_188/
└── DC002.mdb
Foto's en media¶
Foto's en andere mediabestanden worden verwacht in een aparte directory die via een Docker-volume gemount wordt als /input/images. De standaard locatie hiervoor is data/input/basefiles/ (de bovenliggende map). De Wasstraat zoekt daar naar bestanden in mappen die velddocument, fotos, tekening, DAN of DAR in het pad bevatten.
Ondersteunde bestandstypen voor media: .jpg, .jpeg, .png, .gif, .tif, .psd, .pdf, .jp2, .doc, .docx.
Minimale proefset
Voor een eerste test volstaat het om één .mdb projectdatabase in digidepot/ te plaatsen, samen met de referentietabellen. De extractie verwerkt dan alleen dat ene project.
5. Wasstraat_Config_Harmonize configureren¶
Het bestand Wasstraat_Config_HarmonizeV3.xlsx is het hart van de dataverwerkingsconfiguratie. Het vertelt de Wasstraat hoe brondata uit diverse Access-databases moet worden omgezet naar een geüniformeerd datamodel.
Het bestand bevindt zich in:
data/wasstraat_config/Wasstraat_Config_HarmonizeV3.xlsx
De locatie wordt geconfigureerd via de environment-variabele AIRFLOW_WASSTRAAT_CONFIG in config/airflow.env.
Structuur van het configuratiebestand¶
Het Excel-bestand bevat twee soorten tabbladen:
Tabblad "Objecten" — Het hoofdoverzicht¶
Dit tabblad definieert welke entiteiten (objecten) de Wasstraat herkent en hoe tabellen in de brondatabases daaraan worden gekoppeld:
| Kolom | Uitleg | Voorbeeld |
|---|---|---|
| Object | Naam van het entiteitstype | Vondst, Artefact, Aardewerk |
| Tabellen | Regex-patronen die brontabellen matchen | ["^VONDSTENLIJST", "^VONDST$"] |
| Overerven | Ouder-entiteit waarvan attributen worden overgenomen | Artefact (voor Aardewerk, Glas, etc.) |
| Samenvoegen | Entiteit waarmee samengevoegd wordt | — |
| ABR-materiaal | URI naar ABR-materiaalclassificatie | https://data.cultureelerfgoed.nl/... |
| ABR-submateriaal | URI naar ABR-submateriaalclassificatie | https://data.cultureelerfgoed.nl/... |
De kolom Tabellen bevat regex-patronen als JSON-lijst. Wanneer een tabel in een brondatabase overeenkomt met een van deze patronen, wordt deze herkend als dat objecttype. Bijvoorbeeld: een tabel genaamd VONDSTENLIJST_2019 matcht het patroon ^VONDSTENLIJST en wordt dus behandeld als Vondst.
De speciale rij Ignore bevat patronen voor tabellen die moeten worden overgeslagen, zoals .*backup.*, .*kopie.* en .*tijdelijk.*.
Overerving van artefacten¶
Artefacttypen zoals Aardewerk, Glas, Metaal, Hout enzovoort hebben in de kolom Overerven de waarde Artefact. Dit betekent dat ze eerst de standaard artefact-attributen overnemen en daar hun eigen specifieke attributen aan toevoegen. Zo heeft Aardewerk naast de algemene artefactvelden ook velden voor baksel, glazuur en vormcode.
Attributen-tabbladen — Eén per objecttype¶
Voor elk objecttype in het Objecten-tabblad bestaat een apart tabblad met dezelfde naam (bijv. "Vondst", "Spoor", "Aardewerk"). Elk attributen-tabblad heeft twee kolommen:
| Kolom | Uitleg | Voorbeeld |
|---|---|---|
| Attribute | De geharmoniseerde veldnaam in het doelmodel | putnr, spoornr, datum |
| Kolommen | Bronkolommen als JSON-lijst met fallback-volgorde | ["PUT", "PUTNO"] |
De Kolommen-lijst werkt als een prioriteitsvolgorde: de Wasstraat probeert eerst de eerste kolomnaam, dan de tweede, enzovoort. Dit is essentieel omdat verschillende brondatabases andere kolomnamen gebruiken voor hetzelfde gegeven. Bijvoorbeeld: het putnummer kan in de ene database PUT heten en in een andere PUTNO.
Voorbeeld uit het tabblad "Spoor":
| Attribute | Kolommen |
|---|---|
aard |
["AARD", "INTERPRET", "INTERPRETATIE", "SPOORAARD"] |
putnr |
["PUT", "PUTNO"] |
spoornr |
["SPOOR", "SPOORNO"] |
beschrijving |
["BESCHRIJVING"] |
Aanpassen voor je eigen situatie¶
Om de Wasstraat te gebruiken voor je eigen archeologische data, pas je het configuratiebestand aan in drie stappen:
Stap 1: Tabellen herkennen¶
Open je eigen .mdb-bestanden en noteer welke tabellen erin zitten. Pas vervolgens de regex-patronen in het tabblad "Objecten" aan zodat jouw tabelnamen worden herkend. Als jouw vondstentabel bijvoorbeeld Vondsten_Registratie heet, voeg dan "Vondsten_Registratie" toe aan de Tabellen-lijst van het object "Vondst".
Tabellen bekijken
Je kunt de tabellen in een .mdb-bestand bekijken met:
```bash
Vanuit de Airflow-container:¶
docker exec wasstraat_airflow mdb-tables /input/projecten/
Stap 2: Kolomnamen toevoegen¶
Bekijk de kolomnamen in je tabellen en voeg ontbrekende namen toe aan de Kolommen-lijsten in het attributen-tabblad. Als jouw database het veld PUTNUMMER gebruikt in plaats van PUT of PUTNO, voeg je dit toe:
Van: ["PUT", "PUTNO"]
Naar: ["PUT", "PUTNO", "PUTNUMMER"]
Kolomnamen bekijken
bash
docker exec wasstraat_airflow mdb-export -H /input/projecten/<bestand>.mdb <tabelnaam> | head -1
Stap 3: Nieuwe objecttypen toevoegen (optioneel)¶
Als je een entiteitstype hebt dat nog niet bestaat (bijvoorbeeld een specifiek artefacttype), voeg dan een nieuwe rij toe aan het "Objecten"-tabblad en maak een bijbehorend attributen-tabblad aan. Als het een artefacttype is, zet dan Artefact in de kolom "Overerven" zodat de standaard artefact-attributen worden overgenomen.
Huidige objecttypen¶
Het configuratiebestand bevat de volgende objecttypen:
Basisentiteiten: Put, Vlak, Spoor, Vulling, Vondst, Monster, Tekening, Foto, Rapport
Artefacttypen (overerven van Artefact): Aardewerk, Bouwaardewerk, Dierlijk Bot, Glas, Hout, Kleipijp, Leer, Menselijk Bot, Metaal, Munt, Schelp, Steen, Textiel
Referentiedata: ABR, DT_Soort_Plant, DT_Soort_Schelp, DT_Soort_Deel, DT_Soort_Staat
Speciaal: Monster_Botanie, Monster_Schelp, Fotobeschrijving, Fotokoppel
6. Voor de eerste keer draaien¶
Airflow UI openen¶
Ga naar http://localhost:8080 en log in. Je ziet een overzicht van alle beschikbare DAGs:
| DAG | Beschrijving | Wanneer gebruiken |
|---|---|---|
Extract_Transform_Load_Full_Cycle |
Volledige pipeline | Eerste keer — gebruik deze |
Extract_Only |
Alleen data inlezen | Testen of extractie werkt |
Transform1_Harmonize_Only |
Alleen harmonisatie | Stapsgewijs debuggen |
Load_Only |
Alleen naar PostgreSQL laden | Na handmatige correcties |
Volledige verwerking starten¶
- Klik op de DAG
Extract_Transform_Load_Full_Cycle - Zet de DAG aan met de schakelaar links (van "paused" naar "active")
- Klik rechtsboven op de play-knop (▶) → Trigger DAG
- De verwerking start nu automatisch
Voortgang volgen¶
Klik op de DAG en open de Graph-weergave om de voortgang live te volgen. Elke stap wordt gekleurd:
- Groen — Succesvol afgerond
- Geel — Bezig met uitvoeren
- Rood — Fout opgetreden (klik op de stap voor details in de logs)
De volledige verwerking doorloopt deze stappen:
- Drop All Databases — Schoont de tussentijdse databases op
- Extract — Leest alle bronbestanden in naar MongoDB (as-is, zonder transformatie)
- Transform1 Harmonize — Harmoniseert veldnamen over alle bronnen heen
- Transform2 Enhance Attributes — Normaliseert inhoud (datumformaten, codes, metadata)
- Transform3 Set Keys — Genereert unieke sleutels per entiteit
- Transform4 Move and Merge — Voegt dubbele entiteiten samen
- Transform5 Set References — Zet referenties om naar integer-sleutels
- Load to Database & Index — Kopieert naar PostgreSQL en bouwt de Elasticsearch-index
Verwerkingstijd
Voor een kleine proefset (1–5 projectdatabases) duurt de verwerking enkele minuten. Voor de volledige Delft-dataset (1.000+ databases, ~1 TB) kan het enkele uren duren.
Stapsgewijs draaien (optioneel)¶
Als je stap voor stap wilt werken, draai de individuele DAGs in deze volgorde:
1. Extract_Only
2. Transform1_Harmonize_Only
3. Transform2_Enhance_Attributes_Only
4. Transform3_Keys_Only
5. Transform_Move_Only
6. Transform4_Refs_Only
7. Load_Only
Dit is handig voor het debuggen van je configuratie: na stap 3 (Harmonize) kun je in MongoDB controleren of de veldnamen correct zijn geharmoniseerd.
7. Resultaten bekijken¶
Flask webapplicatie¶
Open http://localhost:5051. Na een succesvolle verwerking zie je:
- Interactieve kaart — Een kaart van Delft met alle opgravingslocaties. Blauwe markers zijn projecten zonder verwerkte artefacten, rode markers projecten mét verwerkte artefacten. Klik op een marker om naar het project te navigeren.
- Projecten — Overzicht van alle geïmporteerde opgravingsprojecten met doorklik naar details
- Vondsten, Sporen, Putten — Alle archeologische entiteiten met relaties onderling
- Artefacten — Per materiaalcategorie (aardewerk, glas, metaal, etc.) met hun specifieke attributen
- Bestanden — Foto's, tekeningen en rapporten, gekoppeld aan de bijbehorende entiteiten
- Depot — Dozen, stellingen en bruiklenen
- Zoeken — Fulltext-zoekmogelijkheid via Elasticsearch over alle data
Tussenresultaten in MongoDB¶
Je kunt de ruwe en getransformeerde data direct in MongoDB bekijken:
# Verbind met MongoDB
docker exec -it wasstraat_mongo mongosh \
--username root --password <wachtwoord> --authenticationDatabase admin
# Bekijk staging-data
use Arch_Staging
db.getCollectionNames().forEach(c => print(c + ": " + db[c].countDocuments()))
# Bekijk getransformeerde data
use Arch_Analyse
db.getCollectionNames().forEach(c => print(c + ": " + db[c].countDocuments()))
Het MongoDB-wachtwoord vind je in config/mongo.env (variabele MONGO_INITDB_ROOT_PASSWORD).
Definitieve data in PostgreSQL¶
De uiteindelijke, gestructureerde data staat in PostgreSQL:
docker exec -it wasstraat_postgres psql -U airflow -d flask
-- Overzicht van alle tabellen met aantallen
SELECT schemaname, tablename FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename;
-- Aantal records per hoofdtabel
SELECT 'Def_Project' as tabel, count(*) FROM public."Def_Project"
UNION ALL SELECT 'Def_Vondst', count(*) FROM public."Def_Vondst"
UNION ALL SELECT 'Def_Artefact', count(*) FROM public."Def_Artefact"
UNION ALL SELECT 'Def_Spoor', count(*) FROM public."Def_Spoor";
Elasticsearch zoekindex¶
Controleer of de zoekindex is opgebouwd:
curl -s http://localhost:9200/_cat/indices?v
curl -s http://localhost:9200/_count | python3 -m json.tool
Veelvoorkomende problemen¶
Containers starten niet op¶
Oorzaak: Onvoldoende geheugen of poortconflicten.
Oplossing: Controleer dat poorten 8080, 5051, 5432, 27017, 9200, 6379, 5052 en 8888 niet door andere applicaties worden gebruikt. Verhoog het Docker-geheugen naar minimaal 8 GB.
Extractie mislukt met mdb-export error¶
Oorzaak: Het .mdb-bestand is corrupt of in een niet-ondersteund formaat.
Oplossing: De mdbtools-suite werkt het best met Access 2000/2003 bestanden (.mdb). Modernere .accdb bestanden worden beperkt ondersteund.
Tabellen worden niet herkend bij harmonisatie¶
Oorzaak: De tabelnamen in je database matchen niet met de regex-patronen in het configuratiebestand.
Oplossing: Bekijk de tabelnamen in je database en pas de patronen aan in Wasstraat_Config_HarmonizeV3.xlsx (zie sectie 5).
Flask App toont lege lijsten¶
Oorzaak: De data is niet (volledig) verwerkt of de Load-stap is niet uitgevoerd.
Oplossing: Controleer in Airflow of alle stappen groen zijn. Controleer in PostgreSQL of de Def_*-tabellen records bevatten.
Zoekfunctie werkt niet¶
Oorzaak: Elasticsearch-index is niet opgebouwd.
Oplossing: Controleer of Elasticsearch draait (curl localhost:9200) en herstart eventueel de Load_Only DAG.