Shapely Python: найдите, где соприкасаются линии и многоугольник

Я использую shapely для работы с геометрией. Мне не удается найти точку, в которой LineString касается внешней части многоугольника. Пользуюсь функцией "прикосновения", но вроде работает не всегда.

Согласно руководству пользователя Shapely:

object.touches (другое)

Возвращает True, если у объектов есть хотя бы одна общая точка, и их внутренняя часть не пересекается ни с одной частью другой.

Для справки рассмотрим следующие два примера. Один работает, другой - нет.

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()

Результат примера кода ниже. Почему "касания" возвращают True, например 1, но False, например, 2? Разве они не должны быть такими же?

#################### Example 2 ####################
False
POINT (336.925 332.075)
#################### Example 1 ####################
True
POINT (1 0)

Вот получившиеся изображения:

введите здесь описание изображения  введите описание изображения здесь


person Luke Stuemke    schedule 20.09.2018    source источник


Ответы (1)


Думаю, ответ в определении:

object.touches (другое)

Возвращает True, если у объектов есть хотя бы одна общая точка, и их внутренняя часть не пересекается ни с одной частью другой.

Я подозреваю, что при более внимательном рассмотрении вы обнаружите, что ваша строка line_string перекрывается с вашим многоугольником, а не просто касается его. Это привело бы к сбою второго предложения оператора and в определении, поскольку несколько точек на линии неявно пересекаются с многоугольником.

person 4xle    schedule 05.12.2018