ops.snap not functioning as expected.
See original GitHub issueI believe I found a bug in ops.snap; I’ve made a post on StackExchange GIS but no one has really responded. I will try to replicate that post here.
Expected behavior and actual behavior.
ops.snap does not snap two geometries when using a tolerance that is greater than their distance apart. Specifically, the endpoints of two polylines are 0.0006 apart, but ops.snap with a tolerance of 0.001 does not snap the geometries together. A tolerance of 0.003 does snap them together, however.
Steps to reproduce the problem.
I have two polylines whose endpoints are near to each other, but do not overlap. I’ve put them into this shapefile. I want to use shapely’s ops.snap() to snap their endpoints, but it’s not working as expected.
from shapely import ops
import geopandas as gpd
wontsnap = gpd.read_file(path_to_wontsnap)
g1 = wontsnap.geometry.values[0]
g2 = wontsnap.geometry.values[1]
If I check the distance between the geometries, I get
g1.distance(g2)
Out[661]: 0.0006421029901831172
This agrees (roughly) with the measure tool in QGIS:
Now if I try to snap the two geometries with a tolerance that is greater than the distance between their endpoints:
snapped = ops.snap(g1, g2, 0.001)
The snapped object contains only the g1 geometry. I.e., they don’t snap.
If I increase the tolerance by 10x:
snapped = ops.snap(g1, g2, 0.01)
The snapped object includes both geometries, snapped correctly.
If I trim the g1 and g2 geometries to the last and first 10 points, respectively, snapping works as expected.
I have tried various tolerances between 0.001 and 0.01–the geometries will snap at 0.003 but not 0.002. g1.is_valid and g2.is_valid both return True.
Operating system
Windows 10
Shapely version and provenance
1.6.3 via conda install shapely
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
@erihe251 yes, I think maximum is more true than mimimum. It’s curious that JTS, GEOS, and PostGIS avoid using either minimum or maximum in their documentation of this feature. Maybe maximum isn’t exactly correct.
I too am surprised that your point doesn’t snap to (1, 0).
I agree that the behaviour is not what I would expect from reading the documentation.
gives
Shouldn’t it snap to (1,0) at some point?
In the documentation the tolerance is also described as:
The tolerance argument specifies the minimum distance between vertices for them to be snapped.
Shouldn’t it be maximum distance?