Поиск точек каскадного объединения полигонов в питоне

Я пытаюсь найти близко лежащие точки и удалить повторяющиеся точки для некоторых данных формы (координат) в Python. Я называю узлы координат 1,2,3.. и так далее, и я использую пакет shapely и создаю многоугольники вокруг узловых точек 1,2,3.., говоря:

polygons = [Point([nodes[i]).buffer(1) для i в диапазоне(len(nodes))]

и найти каскадные, которые я использую

каскад = каскадное_объединение (многоугольники)

каскад, который возвращается, представляет собой мультиполигон и содержит много перечисленных координат, я хочу точно знать, какие из точек из моих узлов каскадируются (на основе значения буфера, равного 1), чтобы я мог заменить их новым узлом. Откуда я могу это знать??


person user3637176    schedule 02.05.2015    source источник
comment
Насколько я понимаю из документации, каскадное объединение — это объединение всех входных полигонов, поэтому оно будет включать все входные точки. Я что-то упускаю?   -  person daphshez    schedule 05.05.2015


Ответы (1)


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

Вы могли бы сделать что-то вроде этого (не лучшее решение, я объясню почему):

def clean_closely_lying_points(nodes):
    polygons = [Point([nodes[i]).buffer(1) for i in range(len(nodes))]
    for i in range(len(polygons) - 1):
        if polygons[i] is None:
            continue
        for j in range(i + 1, len(polygons)):
            if polygons[j] is None:
                continue
            if polygons[i].intersects(polygons[j]):
                polygons[j] = None
                nodes[j] = None
                # now overwrite 'i' so that it's whatever you want it to be, based on the fact that polygons[i] and polygons[j] intersect
                polygons[i] = 
                nodes[i] = 

Однако в целом я считаю, что создание полигонов занимает много времени и не является необходимым. Также утомительно обновлять список полигонов и список узлов вместе. Вместо этого вы можете просто использовать сами узлы и использовать метод расстояния shapely, чтобы проверить, находятся ли две точки в пределах 2 единиц друг от друга. Это должно быть математически эквивалентно, поскольку пересечение двух окружностей радиусом 1 означает, что их центральные точки находятся на расстоянии не более 2. В этом сценарии ваши циклы for будут иметь аналогичную структуру, за исключением того, что они будут перебирать узлы.

def clean_closely_lying_points(nodes):
    point_nodes = [Point(node) for node in nodes]  # Cast each of the nodes (which I assume are in tuple form like (x,y), to shapely Points)
    for i in range(len(point_nodes) - 1):
        if point_nodes[i] is None:
            continue
        for j in range(i + 1, len(point_nodes)):
            if point_nodes[j] is None:
                continue
            if point_nodes[i].distance(point_nodes[j]) < 2:
                point_nodes[j] = None
                point_nodes[i] = # Whatever you want point_nodes[i] to be now that you know that point_nodes[j] was within a distance of 2 (could remain itself)
     return [node for node in point_nodes if node is not None]

Результатом этого метода будет список фигурных точечных объектов с удаленными близко расположенными точками.

person abali96    schedule 11.09.2015