Как программным путем разрезать объект
Как программным путем разрезать объект
Добрый день. Подскажите, пожалуйста, как программным путем выбрать изменяемый объект, а затем разрезать его полигоном, удалив внешнюю часть?
Не могу найти необходимые операторы или функции в справке. Да и в примерах плагинов тоже...
Не могу найти необходимые операторы или функции в справке. Да и в примерах плагинов тоже...
Re: Как программным путем разрезать объект
Здравствуйте!
Насколько мы понимаем Вашу задачу, то Вам необходимо использовать функцию пересечения двух объектов.
Это будет выглядеть примерно вот так:
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() # Сохраняем
Объект также можно взять и из выборки.
Для проведения этой операции Вам не требуется работа с Изменяемыми объектами. Изменяемые объекты применяются для того чтобы в интерфейсе визуально можно было отметить объекты для последующих операций.
Насколько мы понимаем Вашу задачу, то Вам необходимо использовать функцию пересечения двух объектов.
Это будет выглядеть примерно вот так:
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() # Сохраняем
Объект также можно взять и из выборки.
Для проведения этой операции Вам не требуется работа с Изменяемыми объектами. Изменяемые объекты применяются для того чтобы в интерфейсе визуально можно было отметить объекты для последующих операций.
Re: Как программным путем разрезать объект
Дмитрий, спасибо. Буду разбираться. Пока не совсем понятно.
На самом деле ситуация должна выглядеть следующим образом:
Есть карта с некоторым количеством слоев. Каждый слой может содержать как линейные, так и площадные объекты. Есть также слой, в котором вручную выбирается площадной объект, а затем запускается плагин, который в каждом слое отрезает все, что выходит за границы выбранного объекта и результат записывает на диск в виде новых таблиц.
На самом деле ситуация должна выглядеть следующим образом:
Есть карта с некоторым количеством слоев. Каждый слой может содержать как линейные, так и площадные объекты. Есть также слой, в котором вручную выбирается площадной объект, а затем запускается плагин, который в каждом слое отрезает все, что выходит за границы выбранного объекта и результат записывает на диск в виде новых таблиц.
Re: Как программным путем разрезать объект
Добавлю: вручную вся эта процедура выполняется как раз с помощью "Выбрать все", затем "Выбрать изменяемый объект" и "Удалить внешнюю часть" для каждого слоя.
Может есть возможность программно имитировать нажатие этих кнопок?
Может есть возможность программно имитировать нажатие этих кнопок?
Re: Как программным путем разрезать объект
В аксиоме выборка доступна через 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() #сохраняем ее
Re: Как программным путем разрезать объект
Рисунок
- Вложения
-
- Untitled.png (63.21 КБ) 10570 просмотров
Re: Как программным путем разрезать объект
Дмитрий, спасибо, все понятно, но не могу повторить, опять есть "затык":
"В аксиоме выборка доступна через data_manager.selection", а в какой библиотеке этот data_manager? Может это в версии 3.5.0? (у меня 3.0.2)
"В аксиоме выборка доступна через data_manager.selection", а в какой библиотеке этот data_manager? Может это в версии 3.5.0? (у меня 3.0.2)
Re: Как программным путем разрезать объект
Да, мы переименовали службы для приведения их однотипному виду. Для 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() #сохраняем ее
Re: Как программным путем разрезать объект
Отлично, Дмитрий! Теперь все работает. Осталось встроить все это в свой модуль. Но с этим, надеюсь, я справлюсь сам.
Огромное спасибо!
Огромное спасибо!