Spatial join in QGIS: op locatie, dichtstbij of met AI
Gepubliceerd op

Een spatial join kopieert de velden van de ene laag naar de andere op basis van waar de objecten liggen, niet op basis van een gedeeld ID. Open in QGIS Vector > Data Management Tools > Join Attributes by Location…, kies de laag die de nieuwe velden moet krijgen, de laag waar ze vandaan komen en een regel zoals "intersect", en voer de tool uit. Voor vragen als "wat ligt het dichtstbij" gebruik je Join Attributes by Nearest. Of je typt de hele opdracht in één zin in AI Agent.
| Wat je wilt | Tool | Tijd in onze test |
|---|---|---|
| Elk punt de naam geven van het gebied waarin het ligt | Join Attributes by Location | 0,21 s, 382 scholen |
| Hetzelfde, getypt als één zin | AI Agent | 22 s, tellen en dichtstbij samen |
| Punten tellen of optellen per gebied | Join Attributes by Location (Summary) | 0,02 s, 9 gebieden |
| Het dichtstbijzijnde object en de afstand vinden | Join Attributes by Nearest | 0,06 s, 382 scholen |
De testdata
Elk getal in deze gids komt uit één run op echte open data van Lyon in Frankrijk, op 15 oktober 2026:
- 9 arrondissementen (de stadsdelen) en 382 scholen uit OpenStreetMap.
- 106 tramhaltes uit OpenStreetMap.
- 103.910 gebouwen uit de IGN BD TOPO, de Franse nationale topografische database.
Alle lagen staan in Lambert-93 (EPSG:2154), een geprojecteerd systeem in meters. De tijden komen van QGIS 3.44 op een MacBook Air M4.
Methode 1: Join attributes by location
Dit is de klassieke spatial join. Hier krijgt elke school de naam van zijn arrondissement.
Open de tool
Vector > Data Management Tools > Join Attributes by Location…. Je kunt ook "join attributes" zoeken in de Processing Toolbox (Ctrl+Alt+T).
Kies de twee lagen
Join to features in is de laag die de nieuwe velden krijgt, hier schools. By comparing to is de laag waar je ze vandaan haalt, hier arrondissements.
Vink een predicaat aan
intersect is de veilige standaard voor punten in polygonen. In het stuk hieronder zie je wat elk vakje betekent.
Kies de velden en het jointype
Houd bij Fields to add alleen wat je nodig hebt, hier name. Zet Join type op one-to-one en voeg een prefix toe zoals arr_, zodat het nieuwe veld makkelijk te vinden is.
Voer de tool uit
Laat Joined layer eerst een tijdelijke laag, zodat je het resultaat kunt controleren. Sla het daarna op als GeoPackage.

Vink Discard records which could not be joined alleen aan als je de missers wilt weggooien. Laat het eerst uit: de lege rijen laten zien wat er misging.
Gebruik het als: je één of een paar velden wilt van het object waarin elk ding ligt of dat het raakt.
Sla het over als: de objecten elkaar nooit raken, zoals een school en een tramhalte. Dat is Methode 4.
Methode 2: Vraag het aan AI Agent in één zin
AI Agent is onze QGIS-plugin die taken uitvoert op basis van een getypte opdracht. Het leest je laagnamen en velden, kiest de tools en voert ze uit in je project.
We gaven het dit, met dezelfde Lyon-lagen geladen:
Count the schools in each arrondissement, then give every school the name of its nearest tram stop and the distance to it in metres.
Het draaide twee QGIS-processingtools en daarna een korte Python-stap die de twee nieuwe velden in de laag met scholen schreef. Het paneel toonde "Worked for 22 s". Het vroeg één keer om toestemming, omdat het het GeoPackage op schijf ging aanpassen. De aantallen kwamen exact overeen met onze handmatige run: 382 scholen, van 27 in het 2e en 4e tot 56 in het 5e.

Gebruik het als: je de vraag kent maar niet weet welke van de vier jointools het antwoord geeft, of als je meerdere stappen aan elkaar koppelt.
Sla het over als: je elke week dezelfde join draait. Sla hem dan eenmalig op als model of Python-script.
Prijs: gratis plan, geen creditcard. Pro kost € 49 per maand, exclusief btw.
Methode 3: Tellen en samenvatten met een spatial join
Methode 1 geeft elke school zijn district. De omgekeerde vraag, hoeveel scholen elk district heeft, vraagt om de summary-versie.
Zoek Join attributes by location (summary) in de Processing Toolbox. Zet de polygonen bij Join to features in, de punten bij By comparing to en kies statistieken bij Summaries to calculate: count, sum, mean, median, minimum, maximum en meer. QGIS voegt per statistiek één veld toe, met een naam zoals osm_id_count.

Het telt ook getallen op. Op de IGN-gebouwen gaf één run elk arrondissement zijn aantal gebouwen en de woningen die erin geregistreerd staan: 9.474 gebouwen en 51.743 woningen in het 3e, het grootste van beide.
Voor een gewone telling doet Vector > Analysis Tools > Count Points in Polygon… hetzelfde met minder instellingen.
Gebruik het als: het antwoord een getal per gebied is: aantal, totaal, gemiddelde.
Sla het over als: je de lijst met matches zelf nodig hebt. Gebruik dan Methode 1 met one-to-many.
Methode 4: Join attributes by nearest
Als objecten elkaar nooit raken, koppel je ze op afstand. Zoek Join attributes by nearest in de Processing Toolbox.
Zet Input layer op schools, Input layer 2 op tram_stops en Maximum nearest neighbors op 1. QGIS voegt de velden van de halte toe, plus een veld distance en de coördinaten van beide uiteinden.

Twee instellingen veranderen het resultaat:
- Maximum distance. Met 300 m kregen maar 86 scholen een halte. De andere 296 bleven met lege velden in de uitvoer staan, tenzij je Discard records which could not be joined aanvinkt.
- Maximum nearest neighbors. Met 3 werden de 382 scholen 1.146 rijen, één per school en halte. Een exacte gelijkstand voegt ook een rij toe: op de 103.910 IGN-gebouwen kregen we 103.911 rijen.
De afstand is hemelsbreed, niet de loopafstand langs straten.
Gebruik het als: je vraagt "wat ligt het dichtstbij" en "hoe ver".
Sla het over als: je reisafstand nodig hebt. Gebruik dan de Network analysis-tools in de Processing Toolbox.
Welk predicaat je aanvinkt
Het predicaat is de ruimtelijke regel die bepaalt wat een match is. QGIS leest het als "laag A [predicaat] laag B", waarbij A de laag is die de velden krijgt.

Drie regels dekken het meeste werk:
- intersect voor punten in polygonen en voor alles wat alleen maar contact hoeft te hebben. Het vangt ook objecten op de grens.
- are within als het object helemaal binnen moet liggen. Bij onze gebouwen lagen er 112 die Lyon snijden niet helemaal binnen één arrondissement: 108 kruisen de stadsgrens en 4 een interne grens.
- contain voor de omgekeerde richting, polygonen die punten bevatten.
Je kunt meerdere vakjes aanvinken. Een object is dan een match als één ervan klopt.
One-to-one, one-to-many of largest overlap
Een gebouw op een grens raakt twee districten. Het Join type bepaalt wat er dan gebeurt. Op de 46.250 IGN-gebouwen die Lyon snijden:
| Jointype | Rijen uit | Tijd |
|---|---|---|
| One-to-many (een object per match) | 46.254 | 1,13 s |
| Alleen eerste matchende object (one-to-one) | 46.250 | 0,99 s |
| Alleen grootste overlap (one-to-one) | 46.250 | 9,62 s |
One-to-many dupliceerde de 4 gebouwen die over een interne grens liggen. Dat is goed voor een lijst met matches en fout voor elke som: die gebouwen zouden dubbel geteld worden.
"First matching" houdt de match die QGIS het eerst tegenkomt, dus een gebouw op een grens kan in beide districten terechtkomen. "Largest overlap" kiest het district dat het grootste deel bevat. Dat is het eerlijke antwoord, maar het duurde hier tien keer zo lang.
CRS-valkuilen
Een verkeerd coördinatenstelsel stopt een join zelden. Het verandert stilletjes het resultaat.
- Gemengde CRS werkt bij locatiejoins. We lieten de scholen in WGS 84 (EPSG:4326) staan en de districten in Lambert-93. QGIS herprojecteerde on the fly en alle 382 kregen een match.
- Afstanden volgen de eenheden van de invoerlaag. Draai Join by nearest op de WGS 84-bestanden en de mediane "afstand" komt uit op 0,0071. Dat zijn graden, geen meters. Herproject eerst beide lagen naar een geprojecteerde CRS in meters, met
Vector > Data Management Tools > Reproject Layer…. - Maximum distance gebruikt dezelfde eenheden. Een 300 in graden dekt de hele planeet.
Onze gids over wat een CRS is legt graden en meters uit en hoe je een laag op de verkeerde plek herstelt.
Snelheid bij grote lagen
QGIS regelt joins op stadsschaal in seconden. Op de 103.910 IGN-gebouwen:
- One-to-one join met de 9 districten: 0,97 s vanuit een GeoPackage.
- Dezelfde laag als Shapefile: 1,69 s. Na
Vector > Data Management Tools > Create Spatial Index…: 1,04 s. - Dichtstbijzijnde tramhalte voor elk gebouw: 3,5 s.
- Largest overlap: 9,62 s, de traagste optie.
Vier gewoontes houden grote joins snel:
- Werk vanuit GeoPackage. Dat heeft een spatial index. Een Shapefile heeft zijn
.qix-bestand nodig, dat Create Spatial Index schrijft. - Vraag om minder velden. Vul Fields to add in in plaats van alles te kopiëren.
- Vermijd largest overlap tenzij objecten op de grens echt belangrijk zijn.
- Repareer eerst de geometrieën. Een ongeldige polygoon stopt de run met "has invalid geometry". De tool Fix geometries in de Processing Toolbox herstelt hem. Je kunt ook Invalid feature filtering aanpassen onder het moersleutelicoon naast de invoerlaag.
Kijk ook waar je punten liggen. Maar 211 van de 382 schoolpunten vielen binnen een IGN-gebouw. De rest markeert speelplaatsen en binnenplaatsen, dus "school in gebouw" had 171 scholen gemist.
Wat je moet onthouden
Gebruik Join Attributes by Location met intersect om punten de naam van hun gebied te geven.
Gebruik de Summary-versie om per gebied te tellen of op te tellen, en Join Attributes by Nearest voor het dichtstbijzijnde object en zijn afstand.
Kies one-to-one voor totalen en one-to-many als je elke match nodig hebt.
Herproject naar een CRS in meters voor je een afstand berekent.
Weet je niet zeker welke tool past, beschrijf dan het resultaat dat je wilt aan AI Agent en controleer wat het gebouwd heeft.
Veelgestelde vragen
Wat is een spatial join in QGIS?
Een spatial join voegt de velden van de ene laag toe aan een andere op basis van locatie: erbinnen, rakend of dichtstbij. In QGIS zijn de belangrijkste tools Join Attributes by Location, de Summary-versie voor tellingen en statistieken, en Join Attributes by Nearest voor afstanden.
Hoe koppel ik attributen op locatie in QGIS?
Open Vector > Data Management Tools > Join Attributes by Location…. Zet de laag die de velden krijgt bij Join to features in en de bronlaag bij By comparing to, vink intersect aan, kies de velden en een one-to-one jointype, en voer de tool uit.
Wat is het verschil tussen join by location en join by nearest?
Join by location vraagt dat de objecten elkaar raken of overlappen, volgens het predicaat dat je aanvinkt. Join by nearest vraagt geen contact: het zoekt het dichtstbijzijnde object en voegt een afstandsveld toe, in de eenheden van de CRS van de invoerlaag.
Waarom geeft mijn spatial join lege velden?
Meestal voldoen de objecten niet aan het predicaat: punten net buiten de polygonen, een te strikt predicaat zoals "are within", of ongeldige geometrieën. Bekijk beide lagen op de kaart, probeer "intersect" en draai Fix Geometries. Een ontbrekende CRS op één laag zet die laag ook op de verkeerde plek.
Kan AI een spatial join doen in QGIS?
Ja. AI Agent voert de QGIS-tools uit op basis van een getypte opdracht. In onze Lyon-test deed het een telling per district en een nearest-join uit één zin in 22 seconden, met dezelfde resultaten als de handmatige run.


