I'm having a lot of trouble with getting shapely points to actually snap on linestrings. This is really important to be able to construct a network graph from geospatial data for example. I would like to avoid using shapely.ops.snap
as according to the docs this seems only to snap to line vertices. Instead I would like to use the linear referencing technique proposed in this question. For a simple point-in-linestring situation (see TEST2 below) this seems to work fine, and the within
assertion evaluates to true. However, I can't seem to get it to work for a more complex linestring, even though matplotlib clearly shows the point to lie somewhere along the linestring.
from shapely.wkt import loads
from shapely.geometry import LineString, Point
import matplotlib.pyplot as plt
import geopandas
class Test:
def __init__(self, point, line):
self.point = point
self.line = line
def snap(self, point, line):
snapped_point = line.interpolate(line.project(point))
return snapped_point
def test(self):
snapped_point = self.snap(self.point, self.line)
plt.close()
fig = plt.figure()
ax = plt.gca()
geopandas.GeoDataFrame(geometry=[snapped_point]).plot(ax=ax)
geopandas.GeoDataFrame(geometry=[ls]).plot(ax=ax)
return snapped_point.within(self.line)
def show(self):
plt.show()
### TEST 1
point = loads('POINT (141508.3132070995 445104.7256057188)')
ls = loads('LINESTRING (141408.7699052179 445535.6376462562, 141420.9609999987 445491.5920000025, 141444.1930000001 445394.7640000023, 141465.3480000009 445299.004, 141486.3999999985 445202.0350000015, 141508.3209999985 445104.6910000004, 141529.2399999978 445006.3560000034, 141550.8399999999 444909.6550000002, 141572.6389999985 444811.9950000045, 141594.0459999999 444713.4210000001, 141614.9339999997 444616.2859999968)')
test1 = Test(point, ls)
print(test1.test())
test1.show()
### TEST 2
point = Point((0.5, 0.46))
ls = LineString([(0,0), (1,1), (2,2)])
test2 = Test(point, ls)
print(test2.test())
test2.show()
Why does the second linestring check evaluate to False? Shouldn't the interpolate
and project
methods be geometry independent?