Как программным путем разрезать объект

Вопросы связанные с работой ГИС Аксиома
Ответить
Аватара пользователя
bgnik
Сообщения: 9
Зарегистрирован: 25 окт 2021, 05:40

Как программным путем разрезать объект

Сообщение bgnik » 15 ноя 2021, 10:21

Добрый день. Подскажите, пожалуйста, как программным путем выбрать изменяемый объект, а затем разрезать его полигоном, удалив внешнюю часть?
Не могу найти необходимые операторы или функции в справке. Да и в примерах плагинов тоже...
Аватара пользователя
Дмитрий
Сообщения: 30
Зарегистрирован: 04 июн 2019, 08:33

Re: Как программным путем разрезать объект

Сообщение Дмитрий » 15 ноя 2021, 12:21

Здравствуйте!

Насколько мы понимаем Вашу задачу, то Вам необходимо использовать функцию пересечения двух объектов.
Это будет выглядеть примерно вот так:

poly1 = Polygon([(0, 0), Pnt(0, 5), Pnt(5, 5), (5, 0), (0, 0)])
poly2 = Polygon([(2, 2), Pnt(2, 7), Pnt(7, 7), (7, 2), (2, 2)])
res = poly1.intersection(poly2)

получить же необходимую для изменения геометрию можно, воспользовавшись методами доступа к таблице:

t = provider_manager.openfile('table.tab')
poly2 = Polygon([(2, 2), Pnt(2, 7), Pnt(7, 7), (7, 2), (2, 2)], t.coordsystem)
f = next(t.itemsByIds([0])) # Получаем первую запись
poly1 = f.geometry
f.geometry = poly1.intersection(poly2) # Производим операцию и присваиваем геометрии результат
t.update(f) # Изменяем
t.commit() # Сохраняем

Объект также можно взять и из выборки.

Для проведения этой операции Вам не требуется работа с Изменяемыми объектами. Изменяемые объекты применяются для того чтобы в интерфейсе визуально можно было отметить объекты для последующих операций.
Аватара пользователя
bgnik
Сообщения: 9
Зарегистрирован: 25 окт 2021, 05:40

Re: Как программным путем разрезать объект

Сообщение bgnik » 15 ноя 2021, 13:36

Дмитрий, спасибо. Буду разбираться. Пока не совсем понятно.
На самом деле ситуация должна выглядеть следующим образом:
Есть карта с некоторым количеством слоев. Каждый слой может содержать как линейные, так и площадные объекты. Есть также слой, в котором вручную выбирается площадной объект, а затем запускается плагин, который в каждом слое отрезает все, что выходит за границы выбранного объекта и результат записывает на диск в виде новых таблиц.
Аватара пользователя
bgnik
Сообщения: 9
Зарегистрирован: 25 окт 2021, 05:40

Re: Как программным путем разрезать объект

Сообщение bgnik » 15 ноя 2021, 13:49

Добавлю: вручную вся эта процедура выполняется как раз с помощью "Выбрать все", затем "Выбрать изменяемый объект" и "Удалить внешнюю часть" для каждого слоя.
Может есть возможность программно имитировать нажатие этих кнопок?
Аватара пользователя
Дмитрий
Сообщения: 30
Зарегистрирован: 04 июн 2019, 08:33

Re: Как программным путем разрезать объект

Сообщение Дмитрий » 15 ноя 2021, 15:49

В аксиоме выборка доступна через data_manager.selection.
Как можно решить Вашу задачу: рисуем на косметическом слое (или открываем готовую таблицу) объект, по которому необходимо произвести обрезку и выделяем его. Допустим, это прямоугольник.
Далее получаем геометрию из этого выделения. Поле этого пробегаемся по слоям текущей карты и обрезаем все объекты по этому прямоугольнику. Сохраняем таблицы.
Это упрощенный пример и редактируется текущая таблица. Разумеется, можно создать новую.
И если выделенный объект находится в списке слоев, то его нжно отключить.
Пример:

Код: Выделить всё


selection_table = data_manager.selection # выборка
updates = []
if selection_table is not None: # Если не пустая
    feature = next(selection_table.items()) # Получаем первую запись выборки
    geom = feature.geometry # Ее геометрию (чем режем прямоугольник на косметическом слое)
#    print(geom)
    if isinstance(view_manager.active, MapView): # если это карта
        for l in view_manager.active.map.layers: # Слои активной карты
            table = l.data_object # Получаем таблицу слоя
            update_list = [] # список на обновление
            for f_lay in table.items(): # пробегаемся по записям
                f_lay.geometry =  geom.intersection(f_lay.geometry) # производим операцию обрезания
                update_list.append(f_lay) # добавляем измененный объект
            table.update(update_list) # обновляем таблицу
            table.commit() #сохраняем ее

Аватара пользователя
Дмитрий
Сообщения: 30
Зарегистрирован: 04 июн 2019, 08:33

Re: Как программным путем разрезать объект

Сообщение Дмитрий » 15 ноя 2021, 16:03

Рисунок
Вложения
Untitled.png
Untitled.png (63.21 КБ) 919 просмотров
Аватара пользователя
bgnik
Сообщения: 9
Зарегистрирован: 25 окт 2021, 05:40

Re: Как программным путем разрезать объект

Сообщение bgnik » 16 ноя 2021, 08:29

Дмитрий, спасибо, все понятно, но не могу повторить, опять есть "затык":
"В аксиоме выборка доступна через data_manager.selection", а в какой библиотеке этот data_manager? Может это в версии 3.5.0? (у меня 3.0.2)
Аватара пользователя
Дмитрий
Сообщения: 30
Зарегистрирован: 04 июн 2019, 08:33

Re: Как программным путем разрезать объект

Сообщение Дмитрий » 16 ноя 2021, 11:52

Да, мы переименовали службы для приведения их однотипному виду. Для 3.0.2 скрипт будет выглядеть так:

Код: Выделить всё

from axipy import *

selection_table = selection_service.table # выборка
if selection_table is not None: # Если не пустая
    feature = next(selection_table.items()) # Получаем первую запись выборки
    geom = feature.geometry # Ее геометрию (чем режем прямоугольник на косметическом слое)
#    print(geom)
    if isinstance(view_service.active, MapView): # если это карта
        for l in view_service.active.map.layers: # Слои активной карты
            table = l.data_object # Получаем таблицу слоя
            update_list = [] # список на обновление
            for f_lay in table.items(): # пробегаемся по записям
                f_lay.geometry =  geom.intersection(f_lay.geometry) # производим операцию обрезания
                update_list.append(f_lay) # добавляем измененный объект
            table.update(update_list) # обновляем таблицу
            table.commit() #сохраняем ее
Аватара пользователя
bgnik
Сообщения: 9
Зарегистрирован: 25 окт 2021, 05:40

Re: Как программным путем разрезать объект

Сообщение bgnik » 16 ноя 2021, 13:12

Отлично, Дмитрий! Теперь все работает. Осталось встроить все это в свой модуль. Но с этим, надеюсь, я справлюсь сам.
Огромное спасибо!
Ответить