I'm using shapely to work with geometries. I'm having trouble finding the point where LineString just touches the exterior of a polygon. I have been using the "touches" function, but it does not seem to always work.
According to the Shapely user manual:
object.touches(other)
Returns True if the objects have at least one point in common and their interiors do not intersect with any part of the other.
For reference, consider the following two examples. One works, the other does not.
from shapely.geometry import Polygon
from shapely.speedups._speedups import LineString
from matplotlib import pyplot as plt
examples = {
"Example 1": {
"poly_coords": [(-1, -1), (-1, 1), (1, 1), (1, -1), (-1, -1)],
"line_coords": [(1, 0), (2, 0)]
},
"Example 2": {
"poly_coords": [(336.2, 326.0), (337.65, 338.15), (333.84, 338.8), (333.78, 338.76), (333.14, 338.39),
(331.98, 337.77), (331.25, 337.42), (330.05, 336.91), (329.3, 336.63), (328.09, 336.23),
(327.27, 335.99), (326.02, 335.69), (325.16, 335.54), (323.92, 335.36), (323.03, 335.28),
(321.76, 335.22), (321.19, 335.22), (321.8, 334.9), (322.12, 334.72), (323.64, 333.86),
(323.96, 333.68), (325.53, 332.72), (325.84, 332.51), (327.29, 331.53), (327.61, 331.31),
(329.01, 330.28), (329.33, 330.04), (330.68, 328.96), (331.0, 328.7), (332.27, 327.58),
(332.45, 327.42), (336.2, 326.0)],
"line_coords": [(336.92499999999995, 332.075), (339.80456651646705, 331.731348028899)]
}
}
for example_key, ex in examples.items():
poly = Polygon(ex["poly_coords"])
line = LineString(ex["line_coords"])
print("{1} {0} {1}".format(example_key, "#" * 20))
print(line.touches(poly))
print(line.intersection(poly))
print(line.overlaps(poly))
xpoly, ypoly = poly.exterior.xy
xline, yline = zip(*ex["line_coords"])
plt.figure()
plt.title(example_key)
plt.fill(xpoly, ypoly, alpha=0.5, fc='r')
plt.plot(xline, yline)
plt.show()
The output of the example code is below. Why does "touches" return True for example 1, but False for example 2? Shouldn't they be the same?
#################### Example 2 ####################
False
POINT (336.925 332.075)
#################### Example 1 ####################
True
POINT (1 0)
Here are the resulting images:


I think the answer is in the definition:
I suspect you will find with closer inspection that your line_string overlaps with your polygon instead of merely touching it. This would cause it to fail the second clause of the
andstatement in the definition, as more than one point on the line implicitly intersects with the polygon.