На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

Создание объекта внутри другого

Поиск  Пользователи  Правила  Войти
Форум » Настольные приложения » GIS ToolKit, GIS ToolKit Active, ГИС Конструктор для Windows
Страницы: 1
RSS
Создание объекта внутри другого
 
Здравствуйте, имеется следующая задача - создать новый объект по контуру другого (родительского объекта) с заданным отступом. Наглядно: http://prntscr.com/8e10cj , где черным - начальный объект, а красным - искомый. Затем у полученной копии изменить описание/имя на другое. В моём случае внутри объекта "болото" нужно создать объект "участок болота" (имеет штриховку), чтобы вышло так: http://prntscr.com/8e12my - справа то, что должно получиться. Сделал следующим образом, но оно не работает:
Код
   HOBJ copy_info = mapCreateCopyObject(hMap, info);
   long int result = mapInsideZoneObjectEx(-3, copy_info, 0, 0, 0.001, 3.);
   mapDescribeObject(copy_info, 79758000);
   mapCommitObjectAsNew(copy_info);

, где 79758000 - код объекта "участок болот" в классификаторе.
Спасибо
 
Здравствуйте!
Что конкретно не работает?
copy_info точно содержит метрику до выполнения построения зоны?
Чему у Вас равен result после выполнения функции?
Что возвращает mapDescribeObject?

Попробуйте построить зону с параметрами:
form = 1 - закругленный
arcdist = 0.2 - расстояние между точками по дуге (в метрах на местности) рекомендуется radius / 15

Не забывайте про mapFreeObject(copy_info).
 
Цитата
Роман Твердов пишет:
Что конкретно не работает?
Роман, данная функция не работает при следующих входных условиях:
1. петли в объекте (повторяющаяся метрика поверх существующей)
2. повторяющиеся точки в метрике
3. пересекающиеся сегменты
-----
Автору
перед тем как строить буфер(зону) вокруг объекта, очистите всю некорректную метрику функциями
mapDeleteLoop и подобными. Более подробно в MapApi
Не тот глуп кто не знает, а тот, кто не знает где искать.
 
Цитата
Роман Твердов пишет:
Здравствуйте!
Что конкретно не работает?
Цитата
KFF пишет:
перед тем как строить буфер(зону) вокруг объекта, очистите всю некорректную метрику функциями
mapDeleteLoop и подобными.
Да, что-то я действительно ничего не описал.
Код сейчас имеет следующий вид:
Код
   HOBJ copy_info = mapCreateCopyObject(hMap, info);
   long int result_count = mapPointCount(copy_info, 0);

   mapDeleteLoop(copy_info, (double)1e-3);
   mapDeleteEqualPoint(copy_info, (double)1e-3, 0);
   long int result_zone = mapInsideZoneObjectEx(-3, copy_info, 0, 1, 0.001 * mapGetMapScale(hMap), 3.);
   long int result_describe = mapDescribeObject(copy_info, 79758000);
   long int result_commit = mapCommitObjectAsNew(copy_info);

   mapFreeObject(copy_info);

 По коду, mapDeleteLoop, mapDeleteEqualPoint и mapInsideZoneObjectEx возвращают единицу. В result_describe оказывается 79758000. В result_commit передаётся общее число объектов на карте.
 ----------------------
 Как оказалось, новый объект оно создаёт, даже верный контур. А не увидел я его потому, что результирующий объект получается линейным и совсем далёким от задаваемого значения. В mapDescribeObject я отправляю код 79758000, что соответствует площадному объекту "участок болот" в классификаторе. Написанный же выше код создаёт линейный объект "значок породы древостоя" с кодом 79719300 в классификаторе. Почему так выходит - это новый вопрос этой темы, первый можно считать устаревшим.
 Появился ещё второй вопрос - начальный объект, по метрике которого мы строим новый содержит порядка ста подобъектов, в то время как полученный их исключает. Как сделать так, чтобы вокруг подобъектов контур тоже строился?
 PS - и еще один, а то забыл. Начальный объект касается границы карты и поэтому отступ искомого объекта происходит в том числе и от границы карты. Можно ли этого избежать? Наглядно: http://prntscr.com/8emp61
Изменено: Денис Бояркин - 10.09.2015 07:52:45
 
Код
Как сделать так, чтобы вокруг подобъектов контур тоже строился? 

Перебором для всех подобъектов меняя subject

Код
Начальный объект касается границы карты и поэтому отступ искомого объекта происходит в том числе и от границы карты. Можно ли этого избежать?

У Вас же по рамке идет контур площадного объекта, для которого Вы строите зону. Готового решения для такой задачи нет. Можете попробовать перед Commit анализировать метрику объекта и при необходимости "притягивать" ее к рамке.
 
Цитата
Перебором для всех подобъектов меняя subject
Извиняюсь за мою непонятливость. Это единственное, что осталось в моём вопросе, в остальном разобрался.
Итак, код:
Код
  //работа с полученным объектом info
   HOBJ copy_info = mapCreateCopyObject(hMap, info);

   //удаление циклов и совпадающих точек для проведения контура
   mapDeleteLoop(copy_info, (double)1e-3);
   mapDeleteEqualPoint(copy_info, (double)1e-3, 0);

   //получение числа подобъектов + 1
   //long int sub_count = mapPolyCount(copy_info);

   for(long int i=1; i<sub_count; i++){
       построение внутреннего контура
       long int zone = mapInsideZoneObjectEx(-20, copy_info, i, 1, 0.001 * mapGetMapScale(hMap), 3.);
   }

   //изменение типа объекта на участки болот
   mapRegisterObject(copy_info, 79758000, 1);
   //сохранение нового объекта
   mapCommitObjectAsNew(copy_info);
   
   mapFreeObject(info);
   mapFreeObject(copy_info);

 Я не совсем понял какой идентификатор засылать в subject. Если делать как в коде, то новый объект не создаётся. Цикл начинал как с 0, так и с 1. На итерации i=0 и i=1 в zone записывается 1, значит ошибок нет. При i>1 результат zone = 0 у всех подобъектов, а их порядка 90шт. Если заслать без цикла subject = -1, то подобъекты начинают учитываться, но пропадает отступ, а, соответственно, и весь смысл операции.
 Где в моём коде ошибка, что я сделал не так?
 
1. Построить зону для объекта (subject = 0) со значением -20. Записать ее в объект с кодом 79758000.
2. Далее для каждого подобъекта в цикле (subject=1..sub_count)  построить его зону со значением +20. Полученную метрику записать как подобъект в объект полученный в результате шага 1.

Вам нужно всегда иметь метрику исходного объекта, т.к. mapInsideZoneObjectEx записывает метрику построенной зоны в передаваемый hobj.
Изменено: Роман Твердов - 11.09.2015 11:55:46
 
Цитата
Роман Твердов пишет:
Полученную метрику записать как подобъект в объект полученный в результате шага 1.
Я очень извиняюсь за дотошность, я сейчас около получаса втыкал в API, форум и руководство, но не нашёл как правильно добавлять подобъект к объекту. Готовой функции в API я не увидел, есть только догадка насчёт добавления дескриптора в метрику главного объекта
Код
 // Создать дескриптор подобъекта в записи метрики
 // В конец записи добавляется дескриптор подобъекта
 // Выполняется контроль по длине записи и длине буфера
 // Число точек = 0, номер подобъекта = максимальный номер + 1
 // (как правило, записывается порядковый номер подобъекта)
 // info    - идентификатор объекта карты в памяти
 // При ошибке возвращает ноль
_MAPIMP long int _MAPAPI mapCreateSubject(HOBJ info);
, а затем добавлять каждую точку метрики в конец основного объекта с помощью: mapInsertPointGeo();
Собственно, я так и сделал, нужный мне результат получил.

Во время написания возникла некоторая проблема. На форуме я нашёл следующее сообщение:
http://www.gisweb.ru/forum/messages/forum2/topic3428/message21872/#message21872
В сообщении пример создания подобъекта и в этом примере при добавлении точек после mapCreateSubject() четвёртый аргумент (номер подобъекта) в mapAppendPointPlane() не засылался. Когда я сделал аналогично, у меня вся метрика подобъектов записалась в объект, все подобъекты были созданы, но их метрика была пустой. Пришлось добавлять четвёртый аргумент и тогда всё заработало:
Код
   //получение числа подобъектов + 1
   long int sub_count = mapPolyCount(info);
   //цикл добавления подобъектов
   for(long int i=1; i<sub_count; i++){
       //копирование начального объекта в temp для получения очередного подобъекта
       HOBJ temp_info = mapCreateCopyObject(hMap, info);
       //построение внешнего контура для подобъекта i
       long int result_zone = mapInsideZoneObjectEx(step, temp_info, i, 1,
           0.001 * mapGetMapScale(hMap), 3.);

       //если зона построена успешно
       if (result_zone>0){
           //создаём новый подобъект для искомого объекта
           mapCreateSubject(new_info);
           //все точки темпового объекта переносим в подобъект
           long int point_count = mapPointCount(temp_info, 0);
           long int new_sub_count = mapPolyCount(new_info);

           for(long int i=1; i<point_count; i++){
               double point_x = mapXPlane(temp_info, i, 0);
               double point_y = mapYPlane(temp_info, i, 0);
               mapAppendPointPlane(new_info, point_x, point_y, new_sub_count-1);
           }
       }
       mapFreeObject(temp_info);
   }
На основании этого и вопрос, это я чего упустил или пример в том сообщении был неверный?
Спасибо за помощь.
Изменено: Денис Бояркин - 12.09.2015 09:51:50
Страницы: 1
Читают тему (гостей: 1)



© КБ Панорама, 1991-2024

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности