2015-11-24 5 views
2

Salut Je me demande si je pense dans le mauvais sens ou si c'est un bug:Des intersections bien faites et des relations bien faites - inexactes?

J'ai un linestring et un polygone, -je créer des points d'intersection de la ligne et la limite du polygone

enter image description here

Ces points d'intersection devraient croiser (au moins toucher) la limite du polygone, n'est-ce pas?

from shapely import geometry,wkt 
line = geometry.LineString([(13.51039642756912, 52.598912814414675), (13.525173800277184, 52.60620240344557)]) 
poly = geometry.Polygon ([(13.52072838433517, 52.61735554606274), (13.52233276805985, 52.59511541819082), (13.51312087418833, 52.59394589806786),(13.51526963068252, 52.60338701649216),(13.51836560008325 ,52.6009395669487), (13.52072838433517, 52.61735554606274)]) 

ips = line.intersection(poly.boundary) 
for i in ips: 
    print i.touches(poly.boundary)# should touch but it doesnt!!!! 

>>>False 
+0

Depuis que vous imprimez certaines choses à la console, pourriez-vous inclure cette sortie dans votre question s'il vous plaît? –

+0

Beaucoup de choses en chiffres sont inexactes. Cependant, que voulez-vous vraiment faire avec cette information? Ne pouvez-vous pas supposer que les points d'intersection sont très proches de la frontière - puisqu'ils ont été calculés exactement de cette façon? Pas besoin de vérifier ça, ou est-ce qu'il y en a? – Trilarion

Répondre

3

Ce n'est pas un bogue, mais c'est une question fréquente.

Sans un modèle de précision, tous les calculs à virgule flottante sont limités par le machine epsilon. Les points intersectés sont interpolés à partir de chaque géométrie et sont rarement exacts (sauf si vous avez des angles droits). Tous les prédicats DE-9IM comme «touches» nécessitent actuellement un nodule exact ( sauf si nous avons un modèle de précision, ce qui pourrait arriver un jour MISE À JOUR: test avec JTS Topology Suite, les prédicats DE-9IM n'utilisent pas le modèle de précision, donc il est peu probable que le clone GEOS fonctionne différemment).

Une stratégie plus robuste consiste à tester la distance entre les deux, qui devrait être inférieure à la machine epsilon s'ils se croisent. E.g .:

EPS = 1e-15 
for i in ips: 
    print i.distance(poly) < EPS 
+0

À quel point ce calcul de distance peut-il être intensif en calcul? Une implémentation «tactile» incluant un modèle de précision pourrait-elle être un jour beaucoup plus rapide? Quels algorithmes utiliseriez-vous pour cela? (Juste par curiosité.) – Trilarion

+0

Juste vérifié la même chose en postgis (avec GEOS 3.4.2): '' 'CHOISIR st_touches (st_geometryn (st_intersection (l, st_boundary (p)), 1), st_boundary (p)) de ST_GeomFromText ('LINESTRING (13,51039642756912 52,59891281441467, 13,52517380027718 52,60620240344557)', 4326) l, ST_GeomFromText ('polygonal ((13,52072838433517 52,61735554606274, 13,52233276805985 52,59511541819082, 13,51312087418833 52,59394589806786, 13,51526963068252 52,60338701649216, 13,51836560008325 52,6009395669487, 13,52072838433517 52,61735554606274))', 4326) p ; '' 'Même résultat – sal

+0

@Trilarion Je viens de tester si le modèle de précision fonctionne (en utilisant JTS) pour" toucher ", et ça ne marche pas comme je le pensais. Une métrique basée sur la distance pour ce type de prédicat est en fait très courante sous le capot de la plupart des logiciels SIG, et elle est beaucoup moins computationnelle que d'autres opérations comme «tampon». –