Разработка прикладных задач для ГИС "Панорама"

Урок 3. Реализация режимов, не требующих создания обработчика задач, на примере решения задачи поиска/выделения мультиполигонов

Автор: Дарья Лунченко

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

В таких режимах, зачастую, используется последовательный вызов функций MAPAPI для обработки данных карты.

Для реализации такого режима необходимо:

1) в классе прикладной задачи, производном от TPanTask (MultiPoligonTask.cpp), создать новую функцию для задачи;

2) в методе для подключения обработчика GetAction, с помощью команды CheckCommand, связать определённую ранее функцию и кнопку режима.

В данном уроке будет рассмотрено:

1) реализация режима поиска/выделения мультиполигонов;

2) добавление справки и подсказок для кнопок в прикладную задачу.

1. Режим поиска/выделения объектов-мультиполигонов

Рассмотрим режим поиска и выделения мультиполигонов, отвечающих заданным пользователем условиям. Данный режим предусматривает, что после запуска режима открывается диалог настройки условий поиска/выделения, в котором пользователь выбирает параметры поиска/выделения. Следовательно взаимодействие с пользователем осуществляется только посредством элементов диалога (рис.1). В этом случае реализация режима не требует создания отдельного обработчика задач.

Рисунок 1 - Диалог поиска и выделения мультиполигонов

Режим предназначен для предварительной обработки карты, содержащей объекты-мультиполигоны, если затем предполагается выполнение операций по генерализации карты.

Чтобы выделить мультиполигоны на всех открытых картах, необходимо в переключателе "Поиск среди" выбрать опцию "Все объекты". Чтобы настроить выбор объектов на конкретной карте, выбрать опцию "Отдельные объекты", а затем установить критерии отбора в появившемся стандартном диалоге поиска ГИС "Панорама".

Для анализа контуров мультиполигона, реализованы следующие ряд фильтров: "Внешние", "Внешние с учётом подобъектов", "Любые". При выборе опции "Внешние" при поиске анализируется площадь и периметр объекта без вычитания площади и периметра внутренних контуров; "Внешние с учётом подобъектов"- анализ с вычитанием внутренних контуров; "Любые" - анализируются все внешние и внутренние контура объекта. Фильтры позволяют находить и выделять объекты, у которых в ходе генерализации карты требуется удалить слишком мелкие для требуемого масштаба внутренние или внешние контура.

Переключатель "Условия отбора" позволяет находить и выделять объекты, которые в ходе генерализации должны быть удалены полностью и те, у которых следует удалить только отдельные контура. При выбранной опции "Все", мультиполигон входит в список поиска/выделения, если все контура объекта удовлетворяют условиям поиска. При выбранной опции "Отдельные", мультиполигон входит в список поиска/выделения, если заданным условиям удовлетворяет хотя бы один из его контуров.

Реализация алгоритма:

1) добавим в класс прикладной задачи CMultiPoligonTask функцию fFindSelectMultipolygons;

2) свяжем функцию fFindSelectMultipolygons с кнопкой режима поиска/выделения в функции GetAction;

3) создадим структуру FINDSELECTPARAM для хранения параметров поиска/выделения;

4) создаём диалог поиска/выделения объектов и вызываем его, передавая структуру параметров FINDSELECTPARAM, идентификатор карты HMAP, текущий язык приложения, структуру параметров прикладной задачи TASKPARMEX, идентификатор главного окна приложения HWND;

5) в классе диалога CFindSelectMDlg.cpp, при выборе пункта "Поиск среди" -> "Отдельные объекты", вызываем selSetFilter - диалог установки фильтра объектов, получаем контекст условий поиска/отображения hSelect, а с помощью mapGetSiteIdentForSelect - идентификатор карты, для которой заполнен данный контекст;

6) возвращаемся в функцию fFindSelectMultipolygons, по контексту условий/поиска, который был заполнен при вызове диалога , определяем номер карты для которой он был создан, если пользователь выбрал условие "Поиск среди" -> "Все объекты", контекст условий равен 0;

7) с помощью mapSetTotalSeekViewRule, устанавливаем правило осуществления поиска среди отображаемых объектов карты, если поиск объектов осуществляется среди всех карт, с помощью mapSetTotalSeekMapRule выделяем объекты на всех картах, и создаем контекст условий поиска/отображения hSelectMain;

8) определяем количество открытых карт - mapGetSiteCount, далее в цикле проходим по картам, и узнаем кол-во листов карты - mapGetSiteListCount, затем количество объектов листа карты - mapGetSiteObjectCountInList, перебираем объекты листа карты с помощью mapReadObjectByNumberEx, находим среди них мультиполигоны - mapIsMultiPolygon, и проверяем подходит ли они под условия поиска/выделения, указанные пользователем в диалоге - fAnanlyzeFindSelectParam;

9) с помощью функции mapSetSiteSeekSelect, устанавливаем условия поиска объектов, таким образом выделяя объекты на карте;

10) для того, чтобы выделить объекты на отдельной карте определяем номер карты mapGetSiteNumber, проводим перебор среди отображаемых объектов карты - mapSeekSiteViewObject, и проверяем подходит ли они под условия поиска/выделения - fAnanlyzeFindSelectParam;

11) устанавливаем поиск объектов для заданной карты - mapSetTotalSeekMapRule, и признак выделения объектов на карте - mapSetTotalSelectFlag;

12) теперь рассмотрим вариант, когда пользователь нажал кнопку "Найти";

13) вызываем функцию formSeekObject с контекстом условий поиска hSelectMain, созданным нами ранее при выделении объектов;

2. Добавление справки в прикладную задачу

Любая программа удобна, если в ней уже содержится необходимая справочная информация. В нашем случае необходимо добавить следующие возможности: появление названия кнопок панели задач, при наведении на них мыши, показ справки по нажатию на соответствующую кнопку на панели задач, а также при вызове режима ГИС "Панорама" "Что это?" , отображать соответствующие разделы справки.

Для того чтобы добавить название подсказок при наведении курсора на кнопки, необходимо в функции класса прикладной программы EnableAction, использовать метод SetText, передавая в качестве параметра имя кнопки:

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

1) переопределить виртуальную функцию ViewHelp;

2) вызвать функцию с соответствующим идентификатором раздела справки в методе, связанном с кнопкой панели задач "Справка".

Для реагирования на нажатие кнопки в режиме "Что это?", в методе добавления обработчиков GetAction, необходимо использовать макросы CheckCommandUn и CheckActionUn, передавая в качестве параметров: идентификатор команды, имя обработчика, имя справки, и раздел справки, соответствующий текущей кнопке.

Следующий урок будет посвящён созданию потоковых прикладных задач, не требующих интерактивной работы пользователя.