Spatial selectie geeft niet alle punten die op een lijn liggen in QGIS. Waarom?

Ik wil alle punten uit een laag selecteren die op een lijnenlaag liggen. In onderstaande afbeelding heb ik 4 punten getekent op 1 lijn. Een punt op de eindvertex, een punt op een vertex en 2 op het lijnstuk. Roze is geselecteerd.

In ArcGIS gebruikte ik altijd Intersect en dat levert alle 4 de punten als selectie op. Als ik de omschrijving van Intersect (kruisen met) lees in de QGIS documnetatie dan verwacht ik dat ook:

Intersect :
Tests whether a geometry intersects another. Returns 1 (true) if the geometries spatially intersect (share any portion of space - overlap or touch) and 0 if they don’t.

Share any portion of space, dat is toch niet alleen topologisch correcte gedeelde vertices, maar ook punten die op een segment liggen? (Ze liggen er echt op, ik heb ze getekend met snappen aan en in ArcGIs worden ze ook geselcteerd.)

De sql st_intersects() levert dezelfde selectie als de tool in QGIS.

Ik begrijp de omschrijving dus niet. Maar belangrijker:
hoe krijg ik dan wel alle punten geselecteerd?

Misschien valt een punt niet exact op de lijn vanwege afrondingsfouten (double waarden hebben de neiging om vanaf een decimaal of 8 af te wijken).

Je zou een buffer kunnen genereren en dan de punten in de buffer zoeken.

Of met een query zoals hier beschreven:

Ik vergat nog de belangrijkste reden om de boel niet te snappen: bij een vlak wordt het punt wel geselecteerd als het op een segment ligt.
afbeelding

Is er nog verschil tussen ‘kruisen met’ en ‘kruisen’? De Engelse termen zijn ‘Intersect’ en ‘Cross’.

Ja, heerlijk die vertalingen. vooral omdat de documentatie intersect heeft vertaald met Kruisen en Cross ook. Gelukkig staat het in de tool wel anders.

Ik heb mooit iets kunnen maken van Cross of Kruisen:
Cross
Returns 1 (true) if the supplied geometries have some, but not all, interior points in common and the actual crossing is of a lower dimension than the highest supplied geometry. For example, a line crossing a polygon will cross as a line (selected). Two lines crossing will cross as a point (selected). Two polygons cross as a polygon (not selected).

Soms denk ik dat ik wat wiskundige achtergrond mis.
Waar kruisen met het punt op de rand van de rechthoek selecteert, doet kruisen dat niet
afbeelding

Sorry, afrondingsfout had ik niet als term moeten gebruiken. Ik bedoel dat computers raar kunnen rekenen met doubles. Als ik bijvoorbeeld 48.7-48.6 uitreken, dan krijg ik als werkelijke waarde 0.99999999785. Die zie je in je UI nooit terug omdat daar alles wordt afgerond met een paar decimalen, maar voor een functie om te kijken of een punt op een lijn ligt kan het net teveel zijn.

In ArcGis kan er een workaround zijn toegepast die kijkt of de afstand binnen een fuzz afstand ligt. Dat weet ik niet. Misschien dat QGIS gewoon niet sterk is in Points en intersections.

En dat hoort ook zo, dat is Tolerantie. Elke punt in een GIS vertegenwoordigt iets IRL, en heeft dus een standaardafwijking, betrouwbaarheid en precisie. DIe moeten dus meegenomen worden in vergelijkingen. Als twee punten een 10e millimeter van elkaar liggen, zijn ze IRL gelijk - maar als je coordinaten als pure wiskundige getallen gaat beschouwen, zouden ze dat niet zijn. En dus zou elk GIS dit soort operaties met een tolerantie moeten uitvoeren.

Dat zou kunnen, het gaat vooral mis bij punten selecteren. Maar als ik een spatial query maak in de DB-manager (de lagen zitten in een geopackage) dan krijg ik hetzelfde gedrag.
Hmm, het zal toch niet aan gpkg liggen? Nou ga ik even wat experimenteren met postgis en shapefiles, wat een gek gedoe!


Helaas, ik heb de lijn geknipt, op knippunt een punt geplaatst. dan wordt het punt geselecteerd. Logisch, dat was eerder ook.
Lijn gemerged, er staat dan een vertex op de voormalige knipplaats waar ik een punt heb gezet. Punt wordt geselecteerd want ligt op een vertex.
Vertex van lijn verwijderd, locatie lijn en punt zodoende ongewijzigd, alleen ligt punt nu op segment ipv vertex. En wordt dus niet geselecteerd.

Dus geen afrondingsfouten. Zou ook flauw zijn omdat ik de tekentool met snappen heb gebruikt. Anders zou daarin iets niet kloppen of extra ingesteld motene worden, maar het snappen lijkt verder prima te werken. Dus geen muteerfout.

De tool doet dus iets anders dan ik verwacht. Maar waarom? En wat dan wel?

ALs je het mij vraagt is dit een bug in QGis. Ik heb (in 3.10.7) dit gedrag kunnen reproduceren, en het klopt niet. Ik ga altijd uit van het nine-intersection model voor ruimtelijke relaties, en volgens dat model zouden de punten die op de lijnsegmenten liggen een relatie moeten hebben met het interior van die lijnsegmenten. En dus geselecteerd moeten worden, maar dat gebeurt dus niet. Als je disjoint kiest, dan zie je ook dat de omgekeerde selectie word gemaakt, dus QGis beschouwt punten die op een lijnsegment liggen duidelijk als disjoint van de lijn. IMHO is dat niet correct.

1 like

Of een punt op een lijn ligt of niet hangt ook nog van de projectie af. Wat recht is in de ene projectie is krom in een andere projectie. Een punt kan daardoor afhankelijk van de projectie zelfs links of juist rechts van een lijn liggen.

Als oplossing zou ik nooit vertrouwen op de tolerantie van je GIS-pakket, maar altijd zelf een tolerantie kiezen door een buffer te gebruiken.

Daarnaast is het belangrijk nooit lange lijnstukken te gebruiken in GIS-bestanden, door tussenpunten toe te voegen (en goed na te denken in welke projectie je die wil berekenen). Ik heb hierover een notitie geschreven: Langelijnenadvies.pdf. Daarin staat de volgende tabel met, afhankelijk van welke afwijking je nog acceptabel vindt, de geadviseerde maximale lengte voor lijnsegmenten:

Acceptabele afwijking	Advies lijnlengte
1 mm	                200 m
1 cm                    500 m
1 dm                    2 km
1 m                     5 km
10 m                    20 km
100 m                   50 km
2 likes

Klopt, daarom heb ik het ook bewust gereproduceerd in EPSG:28992.

Andersom kun je ook stellen dat een goed GIS de gespecificeerde toleranties van de gebruikte coordinatensystemen automatisch gebruiken (of in ieder geval als default opnemen). Maar ik ben het met je eens dat je het het beste zelf in de hand kan houden, omdat ook de inwinningswijze een grote rol speelt.

Interessant! Heb het even diagonaal doorgenomen, maar ga dat vanmiddag nog eens echt goed lezen. Dankjewel voor het delen :slight_smile:

1 like

Hoi Jonna,

QGIS kijkt heel precies of een punt op een lijn ligt, en bij een schuine lijn is dat dus (bijna) nooit het geval. Zoals door anderen aangegeven zou je met een tolerantie kunnen werken maar dat doet QGIS niet automatisch. Ik zou gewoon een buffer maken van je lijn met de door jouw gewenste tolerantie en dat de punten selecteren die er binnen vallen. Dan weet je precies wat je krijgt.

Oja, bij jouw polygoon-voorbeeld gaat het wel goed omdat de lijn precies vertikaal loopt, of omdat je punt toevallig een heeeeel klein beetje links van je lijn ligt, dus IN de polygoon.

Erik heeft een keer dit overzicht gemaakt van de ruimtelijke relaties in QGIS. Ergens in het commentaar heb ik de Nederlandse termen toegevoegd.

https://qgis.nl/2019/08/25/select-by-location-hoe-zit-dat-met-die-opties/?lang=en

Ook in de RD-projectie (EPSG:28992) is een rechte lijn in werkelijkheid (om precies te zijn: een geodetische lijn) licht krom in de kaart (zie tabel 1 van mijn notitie), maar het is in ieder geval al heel veel beter dan de plate carrĂ©e-projectie die QGIS gebruikt voor ongeprojecteerde geografische coördinaten. Wie dat verzonnen heeft 
 :triumph:! Het zou beter zijn om deze coördinaten op een bol af te beelden (een steeds op het view point aangepaste orthogonale projectie) zoals Google Earth dat doet.

Ik vind dit toch een raar geval. Je kunt nl geen tolerantie opgeven. Daarnaast is alles in RD.

Ik heb de punten geplaatst met snapping aan. Als ik met snapping op de lijn een vertex zet dan wordt het punt wel geselecteerd. Dus in mijn beleving kijkt de tool alleen naar overeenkomende vertexen en niet naar vertex (puntobject) en segment. Dat klopt niet, toch?

Oja, bij jouw polygoon-voorbeeld gaat het wel goed omdat de lijn precies vertikaal loopt, of omdat je punt toevallig een heeeeel klein beetje links van je lijn ligt, dus IN de polygoon.

Oneens, want ik heb ook een verticale lijn met een punt en die selecteert ook niet:
afbeelding

Erik heeft een keer dit overzicht gemaakt van de ruimtelijke relaties in QGIS. Ergens in het commentaar heb ik de Nederlandse termen toegevoegd.

Ja, dat weet ik. Maar het punt (
) is dat het goed gaat met vlak selecteert vlak, zoals de voorbeelden van Erik en ook op de QGIS documentatie. Maar andere combinaties, zeker met punten, kloppen niet.
Ik probeer nu een overzicht te maken van wat allemaal wel en niet klopt, ook omdat ik het gewoon niet meer snap


Je moet het je als volgt voorstellen. Elke waarde in een computer heeft een eindige nauwkeurigheid. Het laatste bitje van je komma-getal is 0 of 1, en dus niets daartussen. Dat betekent dat je een soort ruitennet krijgt waarop je coordinaten altijd op de kruispuntjes moeten liggen. Dat gaat dan bijvoorbeeld wel om micrometers of picometers oid, afhankelijk van het datatype dat je hebt gekozen.

Stel je nu voor je hebt een ruitjespapier (type wiskundeschrift van vroeger) en je tekent twee punten op willekeurige ruitkruisjes. Nu trek je een rechte lijn tussen die 2 punten. De kans dat deze lijn precies over andere kruisjes loopt is heel klein.

Dat is ook de kans dat een willekeurig punt in jouw dataset precies op een schuine lijn valt. Zelfs als je tekent met “snapping” dan moet het opgeslagen digitale coordinaat op je ruitjes vallen en dus meestal net naast de lijn. Op zicht is dit prima (want micrometers) maar de “intersect” analyse gebruikt de exacte waarden en vindt dus geen match.
Vandaar ook dat de vertikale lijn in jouw test het wel doet, want die raakt precies alle ruitkruisjes waar ie langs loopt.

Ik begrijp je verbazing, en een slimme tolerantie-optie zou mooi zijn. Maar definieer die om te beginnen maar eens (Welke afstand? Wat te doen met graden en andere units? Wat te doen met projecties?) en zie het dan nog maar eens te implementeren ook. Ik denk dat de buffer-oplossing best makkelijk is en je weet precies wat je doet. Want jij weet in welke projectie je werkt, wat de nauwkeurigheid van je data is etc.

1 like

image

Gaat bij mij wel goed. Het noordelijkste puntje heb ik getekend met snapping op de lijn, de andere 3 door coordinaten in te voeren. (Oeps ik zie nu dat het 4e puntje nog niet in mijn screenshot zat, maar zit wel in de gpkg)

test_intersect.gpkg (116 KB)

Hier ook een gpkg met mijn lijnen en punten. Kun je die eens proberen? Als het echt niet werkt bij jou maak dan een issue aan en stuur een bestand mee waarmee je het kunt reproduceren.

Hoi Raymond,

Dank voor je duidelijke uitleg. Waarschijnlijk heeft het wel met zoiets te maken. Al snap ik dan weer niet dat het punt dat ik met snappen op de cirkelrand heb getekend wel wordt geselecteerd. Toeval?

afbeelding

Verder geprobeerd met jouw pakketje - het bevat wel alleen punten. Maar ik heb een tijdelijke laag gemaakt, snap op eerste punt en dan lange rechte horizonztale en zelfde met de verticale lijn.
Zowel qgis 3.10 als 3.16 selecteert alle 4 punten, dus ook die op segment liggen. Dus met jouw data heb ik de gewenste resultaten!

Kortom toch iets met een buffer uitproberen om op die manier toch tolerantie mee te geven. Maar ja, hoe dan om de juiste instelling te krijgen. Ik ga zeker het documentje van @Jochem eens bekijken.

Stel, je hebt 3000 stuwen in je gebied en je wilt de stuwen weten die niet op een waterloop liggen (ja, topologie, maar als je even een aantal moet geven voor iemand
) hoe weet je dan of het klopt, met welke buffert?

Nog even extra testje gedaan, ook toch en wihin doen wat ik verwacht met jouw data.

Heel veel bedankt allemaal! fijn om te weten dat: ik de methode dus toch snapte, dat de tool wel goed werkt en dat het probleem dus in de tolerantie zit, dat je daar vooraf iets mee moet met een buffer.

Mijn notitie gaat je niet het antwoord geven op je vraag hoe groot je buffer moet zijn. Die moet je kiezen op basis van de precisie van je data.

Mijn notitie geeft je vervolgens een advies over de maximale lijnlengte die je bij die precisie van je data moet gebruiken, als je niet wil dat de projectie invloed heeft op de resultaten van analyses.