Shapely STRtree слишком медленно? - PullRequest
0 голосов
/ 04 апреля 2020

Мне нужно сопоставить несколько сотен тысяч узлов их ближайшим соседям в виде набора из нескольких десятков тысяч других узлов. Естественно, я бы использовал пространственный индекс, чтобы ускорить этот процесс. Ранее я смог это сделать очень быстро, сгенерировав тесселяцию Вороного для меньшего набора узлов и используя пространственные запросы MySQL, чтобы определить, какие узлы в первом наборе попали в область, связанную с узлом второго набора. Это удалось запустить всего за несколько минут. С тех пор я перешел из среды MySQL и хотел сделать весь процесс в python. Я повернулся к популярному пространственному индексу STRtree, предоставленному стройным пакетом. Однако я обнаружил, что этот индекс невероятно медленный. Я пытался использовать как ближайший геометрический запрос с наборами узлов, так и запрос пересечения геометрии с областями Вороного, и получал только 51.787 совпадающих узлов в секунду, что занимало около 4,5 часов для запуска каждого набора узлов, которые я обрабатываю. Почему стройный такой медленный? Или я использую его неправильно?

Некоторые фрагменты кода:

class Network:

    ...

    def load_network(self, planspath):
        log.info('Fetching temperatures.')
        temperatures = self.fetch_temperatures()
        log.info('Fetching centroids.')
        centroids = self.fetch_centroids()
        log.info('Fetching links.')
        links = self.fetch_links()

        Centroid.steps = len(next(iter(temperatures.values())))

        log.info('Building spatial index (strtree) from centroids.')
        points = []
        for centroid in centroids.values():
            uuid = centroid[0]
            self.centroids[uuid] = Centroid(temperatures[centroid[1]])
            point = loads(centroid[2])
            setattr(point, 'id', uuid)
            points.append(point)
        tree = STRtree(points)

        log.info('Mapping links to centroids.')
        for link in links:
            node = loads(link[4])
            point = tree.nearest(node)
            self.links[link[0]] = Link(link[1], link[2], self.centroids[point.id])

        log.info('Loading network routes from output plans file.')
        self.routes = self.fetch_routes(planspath)
...