Пересечение полигонов с линией / Python Shapely

Я пытался использовать shapely, чтобы найти пересечение линии и многоугольника, но у меня возникли проблемы с некоторыми числами с плавающей запятой.

пример кода:

polygon = [(4.0, -2.0), (5.0, -2.0), (4.0, -3.0), (3.0, -3.0), (4.0, -2.0)]
shapely_poly = shapely.geometry.Polygon(polygon)

line = [(4.0, -2.0000000000000004), (2.0, -1.1102230246251565e-15)]
shapely_line = shapely.geometry.LineString(line)

intersection_line = list(shapely_poly.intersection(shapely_line).coords)
print intersection_line

то, что я ожидал-это список из двух вершин.

Point 1: точка, которая будет внутри многоугольника, или (4.0, -2.0000000000000004) в этом случае.

точка 2: точка, которая является пересечением [(4.0, -2.0000000000000004), (2.0, -1.1102230246251565 e-15)] и [(3.0, -3.0), (4.0, -2.0)].

тем не менее, результат, который я получаю:

[(4.0, -2.0000000000000004)]

Я также проверил, есть ли вообще пересечение с краем, на которое я смотрю:

>>> edge = shapely.geometry.LineString([(3.0, -3.0), (4.0, -2.0)])
>>> edge.intersects(shapely_line)
False

Если я заменю (4.0, -2.0000000000000004) на (4.0, -2.000000000000000), то пересечение ребер будет равно True.

есть ли у кого-нибудь идеи о том, что происходит или чего мне не хватает? Спасибо!

enter image description here

Edit:

Я тестировал с помощью shapely версии 1.12 и geos 3.3.1, 3.3.5, 3.3.6, 3.3.7.

в случае, если кому-то интересно, как я обновил версию geos в Windows:

скачал geos-[версия].деготь.bz2 с веб-сайта GEOS. Извлек файлы и запустил CMake на нем, используя генератор Visual Studio 10 Win64. Открыл .sln файл и строили потом он перевел автоматически geos_c.dll и наклеил его туда, где geos_c.dll был установлен shapely в каталоге Python.

1 ответов


Shapely построен поверх оболочки C вокруг библиотеки C++ GEOS. Где-то!--1-->глубоко внутри этой библиотеки C++ сидеть классы точности, которые обрабатывают ошибки округления. Я думаю, мы можем заключить, что ваша версия Shapely и библиотеки geos обрабатывают этот случай по-разному. К сожалению, код, который обращается к прецизионной модели, недоступен в api C и, следовательно, ни в Shapely. Видеть http://lists.gispython.org/pipermail/community/2011-February/002898.html

переход на более высокую версию geos может решить вашу проблему. Он отлично работает на моей машине с shapely 1.2.16 и libgeos 3.3.5-CAPI-1.7.5.