Расширение функциональности MapInfo на основе SmartPanels: различия между версиями
Wasposa (обсуждение | вклад) |
Wasposa (обсуждение | вклад) Нет описания правки |
||
(не показано 15 промежуточных версий 2 участников) | |||
Строка 1: | Строка 1: | ||
{{Статья| | {{Статья|Опубликована|mapinfo-smartpanels}} | ||
{{Аннотация|В данной статье речь пойдет об утилите SmartPanels для MapInfo, позволяющей достаточно просто интегрировать в MapInfo пользовательские специализированные приложения или приложения, расширяющие функциональность MapInfo.}} | {{Аннотация|В данной статье речь пойдет об утилите SmartPanels для MapInfo, позволяющей достаточно просто интегрировать в MapInfo пользовательские специализированные приложения или приложения, расширяющие функциональность MapInfo.}} | ||
==Описание== | ==Описание== | ||
В данной статье речь пойдет об утилите SmartPanels для MapInfo, позволяющей достаточно просто интегрировать в MapInfo пользовательские специализированные приложения или приложения, расширяющие функциональность MapInfo. | В данной статье речь пойдет об утилите SmartPanels для MapInfo, позволяющей достаточно просто интегрировать в MapInfo пользовательские специализированные приложения или приложения, расширяющие функциональность MapInfo. | ||
MapInfo имеет штатный язык программирования MapBasic, который позволяет автоматизировать практически все операции MapInfo. Всем хорош MapBasic, пока дело не доходит до создания с его помощью достаточно развитого пользовательского интерфейса. Тут возникает сразу несколько проблем: | MapInfo имеет штатный язык программирования MapBasic, который позволяет автоматизировать практически все операции MapInfo. Всем хорош MapBasic, пока дело не доходит до создания с его помощью достаточно развитого пользовательского интерфейса. Тут возникает сразу несколько проблем: | ||
Строка 9: | Строка 10: | ||
* ограниченный набор элементов управления состоящий всего из 15 элементов. | * ограниченный набор элементов управления состоящий всего из 15 элементов. | ||
С другой стороны, существует достаточно широкий класс задач, где развитой пользовательский интерфейс просто необходим. В качестве характерного примера можно привести тот же кадастровый учет, в котором необходимо отображать большое количество разнообразной информации, привязанной к одному участку. | |||
С другой стороны, существует достаточно широкий класс задач, где развитой пользовательский интерфейс просто необходим. В качестве характерного примера можно привести тот же кадастровый учет, в котором необходимо отображать большое количество разнообразной информации, привязанной к одному участку. | |||
Разработчиками предпринимались различные попытки обойти ограничения MapBasic. К ним можно отнести создание визуальных редакторов диалогов (своеобразные IDE), реализация функционала MapInfo в среде MSAccess с использованием MapX, динамическое связывание MapInfo и MSAccess посредством механизма DDE и т.п. Но какого-то универсального инструмента не существовало. Точнее он был. Однако для его использования необходимо было быть специалистом в C++, а точнее хорошо разбираться в тонкостях создания библиотек DLL (разработка, подключение их в MapBasic, вызов из них внешних подпрограммы и пр.) что, согласитесь, для прикладного программиста MapBasic не является характерным. | |||
Ситуация изменилась коренным образом с выходом утилиты SmartPanels, разработанной специалистами компании ЭСТИ МАП.<ref> Официальный дистрибьютер MapInfo в России и СНГ</ref> Разработка данной утилиты стала возможной, благодаря переходу MapInfo начиная с версии 9.5 на платформу Microsoft .NET. С помощью этой утилиты стало возможным быстро подключать (регистрировать) к MapInfo пользовательские приложения, созданные на любом из языков семейства .NET. Утилита является, как бы, посредником между MapInfo и внешним приложением. При этом для разработки прикладного решения не требуется установленного компилятора MapBasic. Все что нужно–это установленная утилита SmartPanel и среда разработки MSVisualStudio. | |||
====Примечания==== | ====Примечания==== | ||
<references/> | <references/> | ||
Строка 21: | Строка 21: | ||
<p style="text-align:justify">Для наглядного представления о том, что представляет из себя SmartPanels, приведем примеры четырех плагинов. Первые два поставляются в качестве примеров вместе со SmartPanels и представляет собой плагины общего назначения, т.е. расширяющие стандартные возможности MapInfo. Первый из них - «Вкладки» вносит полезное дополнение к пользовательскому интерфейсу MapInfo. Так при развернутых окнах, в верхней части окон появляются вкладки с именами документов и переключения между ними становится намного удобнее.<ref>в MapInfo 16 версии это уже штатный функционал, но и режим отображения окон документов только один – "во все окно".</ref> Вторым дополнением к пользовательскому интерфейсу <ref>Данная возможность обеспечивается непосредственно SmartPanels</ref> является возможность «прикреплять» панели к одной из сторон окна MapInfo с помощью соответствующих инструментов, отображающихся при перемещении панелей. Если ко одной стороне будет прикреплено несколько панелей, то они также будут отображаться в виде вкладок.</p> | <p style="text-align:justify">Для наглядного представления о том, что представляет из себя SmartPanels, приведем примеры четырех плагинов. Первые два поставляются в качестве примеров вместе со SmartPanels и представляет собой плагины общего назначения, т.е. расширяющие стандартные возможности MapInfo. Первый из них - «Вкладки» вносит полезное дополнение к пользовательскому интерфейсу MapInfo. Так при развернутых окнах, в верхней части окон появляются вкладки с именами документов и переключения между ними становится намного удобнее.<ref>в MapInfo 16 версии это уже штатный функционал, но и режим отображения окон документов только один – "во все окно".</ref> Вторым дополнением к пользовательскому интерфейсу <ref>Данная возможность обеспечивается непосредственно SmartPanels</ref> является возможность «прикреплять» панели к одной из сторон окна MapInfo с помощью соответствующих инструментов, отображающихся при перемещении панелей. Если ко одной стороне будет прикреплено несколько панелей, то они также будут отображаться в виде вкладок.</p> | ||
[[ | [[Изображение:SmartPanels_img1.png|800px|center|frame|Вкладки документов и прикрепляемые панели.]] | ||
Второй плагин – «Информация». Его задачей является отображение и редактирование информации по выбранному объекту в настраиваемой пользователем форме. При первом запуске он ничем не отличается от стандартного окна информации MapInfo. | Второй плагин – «Информация». Его задачей является отображение и редактирование информации по выбранному объекту в настраиваемой пользователем форме. При первом запуске он ничем не отличается от стандартного окна информации MapInfo. | ||
[[ | [[Изображение:SmartPanels_img2.png|800px|center|frame|Вид окна "Информация" SmaprtPanels.]] | ||
Но вызвав с помощью правой клавиши мыши контекстное меню, можно открыть визуальный редактор экранной формы и настроить представление информации в соответствии со своими потребностями. | |||
Кроме этого он позволяет определять для полей списки предопределенных значений, т.е. определять словари. Причем эти списки можно создавать как непосредственно в дизайнере форм, так и в обычных таблицах MapInfo или таблицах базы данных, указывая при этом ссылку на них в дизайнере форм. Это значительно ускоряет ввод и редактирование данных, помогая избежать многих ошибок. | Кроме этого он позволяет определять для полей списки предопределенных значений, т.е. определять словари. Причем эти списки можно создавать как непосредственно в дизайнере форм, так и в обычных таблицах MapInfo или таблицах базы данных, указывая при этом ссылку на них в дизайнере форм. Это значительно ускоряет ввод и редактирование данных, помогая избежать многих ошибок. | ||
[[ | [[Изображение:SmartPanels_img3.png|800px|center|frame|Настройка окна "Информация"]] | ||
Задача состояла в представлении данных переписи населения в различных разрезах. В MapInfo имелся слой с населенными пунктами и имелась база данных с результатами переписи. Плагин выполняет две основные задачи: | Остальные два плагина были созданы под конкретные проекты. Первый из них предназначен для отображения данных переписи населения. | ||
Задача состояла в представлении данных переписи населения в различных разрезах. В MapInfo имелся слой с населенными пунктами и имелась база данных с результатами переписи. Плагин выполняет две основные задачи: | |||
*получает от MapInfo уникальный код населенного пункта (код ОКАТО), осуществлял выборку данных из БД их интерпретацию и представление. | *получает от MapInfo уникальный код населенного пункта (код ОКАТО), осуществлял выборку данных из БД их интерпретацию и представление. | ||
*передает MapInfo команду на позиционирование окна карты в центре с выбранным пользователем в иерархическом списке населенным пунктом. | *передает MapInfo команду на позиционирование окна карты в центре с выбранным пользователем в иерархическом списке населенным пунктом. | ||
[[ | [[Изображение:SmartPanels_img4.png|800px|center|frame|Выбранный населенный пункт (ОКАТО) в центре карты.]] | ||
При использовании специального инструмента «Информация» при выборе населенного пункта на карте происходит отображение информации в различных разрезах | При использовании специального инструмента «Информация» при выборе населенного пункта на карте происходит отображение информации в различных разрезах | ||
[[ | [[Изображение:SmartPanels_img5.png|800px|center|frame|Представление результатов переписи населения в иерархическом списке.]] | ||
[[ | [[Изображение:SmartPanels_img6.png|800px|center|frame|Представление результатов переписи населения в виде круговой диаграммы.]] | ||
[[ | [[Изображение:SmartPanels_img7.png|800px|center|frame|Представление результатов переписи населения в виде столбчатой диаграммы.]] | ||
И еще один пример. В данном случае был разработан плагин для отображения панорам Yandex и Google при выборе точки на карте и использования поискового сервиса Yandex. | И еще один пример. В данном случае был разработан плагин для отображения панорам Yandex и Google при выборе точки на карте и использования поискового сервиса Yandex. | ||
[[ | [[Изображение:SmartPanels_img8.png|800px|center|frame|Использование панорамы Yandex.]] | ||
[[Изображение:SmartPanels_img9.png|800px|center|frame|Использование панорамы Google.]] | |||
===Примечания=== | ===Примечания=== | ||
<references/> | <references/> | ||
==Пример создания плагина для SmartPanel== | ==Пример создания плагина для SmartPanel== | ||
Особый интерес, конечно же, представляет возможность создания собственных плагинов. В качестве примера рассмотрим создание приложения, которое будет не просто приветствовать этот мир, но реализовать полезную функцию – клонировать окно отчета. В стандартном MapIinfo такая возможность отсутствует, в отличие от окна карты. | <p style="text-align:justify">Особый интерес, конечно же, представляет возможность создания собственных плагинов. В качестве примера рассмотрим создание приложения, которое будет не просто приветствовать этот мир, но реализовать полезную функцию – клонировать окно отчета. В стандартном MapIinfo такая возможность отсутствует, в отличие от окна карты. | ||
Для начала необходимо скачать и установить SmartPanel. Утилита является абсолютно бесплатной и скачать ее можно по ссылке [ | Для начала необходимо скачать и установить SmartPanel. Утилита является абсолютно бесплатной и скачать ее можно по ссылке [[Медиа:SPInstaller32.zip]] для 32 разрядной версии и [[Медиа:SPInstaller64.zip]] для 64 разрядной. В терминах SmartPanel все подключаемые пользовательские приложения носят названия плагинов. В качестве примеров вместе с самой утилитой распространяются также бесплатные плагины – «Вкладки» и «Расширенная панель информации». Подробное описание этих плагинов можно найти по той же ссылке. | ||
После установки в основном меню MapInfo появится новый пункт – SmartPanel. Данный пункт содержит два элемента: Настройки и Панели. Пункт «Настройки» предназначен для основных действий с плагинами | После установки в основном меню MapInfo появится новый пункт – SmartPanel. Данный пункт содержит два элемента: Настройки и Панели. Пункт «Настройки» предназначен для основных действий с плагинами по их настройке, удалению и добавлению в SmartPanels. Второй пункт отвечает за отображение списка всех зарегистрированных панелей, позволяет их показывать или скрывать. </p> | ||
[[Image:SmartPanels_img10a.png|450px|center|Меню SmartPanels в Mapinfo до 16 версии]] | |||
[[Image:SmartPanels_img10b.png|450px|center|Меню SmartPanels в Mapinfo в 16 версии]] | |||
Вполне подойдет и бесплатная версия этой IDE – Community [https://www.visualstudio.com/ru/downloads]. После запуска загрузчика рекомендуется выбрать пункт «Разработка классических приложений .NET» | Теперь все готово для добавления своего собственного плагина. Для его создания необходимо установить MS Visual Studio. Вполне подойдет и бесплатная версия этой IDE – Community [https://www.visualstudio.com/ru/downloads]. После запуска загрузчика рекомендуется выбрать пункт «Разработка классических приложений .NET» | ||
[[ | [[Image:SmartPanels_img11.png|center|frame|Настройка загрузчика MSVisualStudio]] | ||
После установки MS VisualStudio можно приступать непосредственно к созданию нашего проекта: Файл – Проект – Cоздать – Библиотека классов (.NET Framework) | После установки MS VisualStudio можно приступать непосредственно к созданию нашего проекта:'' Файл – Проект – Cоздать – Библиотека классов (.NET Framework)'' | ||
[[ | [[Image:SmartPanels_img12.png|center|frame|Общий вид меню «Создание проекта».]] | ||
В созданном проекте нужно указать ссылку на библиотеку SmarPanels.dll. Данная библиотека находится в корневом каталоге установки SmartPanel. Если при установке утилиты были использованы настройки по умолчанию, то эта библиотека будет находится в каталоге C:\Program Files\ESTI MAP\SmartPanels. Для создания ссылки необходимо в панели «Обозреватель решения» вызвать диалог добавления ссылки путем нажатия правой клавиши мыши на пункте «Ссылки» и далее «Добавить ссылку…». После инициализации проекта был создан класс по умолчанию Class1. Название класса можно оставить без изменений, а можно переименовать, но в любом случае этот класс должен реализовывать интерфейс SPNet.IMiPlugin. Это и есть предопределенный шаблон плагина. В контексте этого интерфейса наш класс должен реализовывать пять свойств и три метода. | <p style="text-align:justify">В созданном проекте нужно указать ссылку на библиотеку SmarPanels.dll. Данная библиотека находится в корневом каталоге установки SmartPanel. Если при установке утилиты были использованы настройки по умолчанию, то эта библиотека будет находится в каталоге C:\Program Files\ESTI MAP\SmartPanels. Для создания ссылки необходимо в панели «Обозреватель решения» вызвать диалог добавления ссылки путем нажатия правой клавиши мыши на пункте «Ссылки» и далее «Добавить ссылку…». После инициализации проекта был создан класс по умолчанию Class1. Название класса можно оставить без изменений, а можно переименовать, но в любом случае этот класс должен реализовывать интерфейс SPNet.IMiPlugin. Это и есть предопределенный шаблон плагина. В контексте этого интерфейса наш класс должен реализовывать пять свойств и три метода.</p> | ||
Свойства: | |||
*PluginName - название плагина, которое будет отображаться в списке установленных плагинов. | *PluginName - название плагина, которое будет отображаться в списке установленных плагинов. | ||
*PluginDescription - описание плагина. | *PluginDescription - описание плагина. | ||
*PluginUID – глобально уникальный идентификатор плагина. | *PluginUID – глобально уникальный идентификатор плагина. | ||
*PluginVersion - версия плагина. | *PluginVersion - версия плагина. | ||
*RestoredPanels - список панелей, местоположение которых SmartPanels будет автоматически | *RestoredPanels - список панелей, местоположение которых SmartPanels будет автоматически сохранять и восстанавливать при запуске. | ||
Методы: | |||
*Init - производит инициализацию плагина. | *Init - производит инициализацию плагина. | ||
*LoadPluginSettings - загружает состояние плагина. | *LoadPluginSettings - загружает состояние плагина. | ||
*Dispose - освобождение используемых ресурсов при завершении приложения. | *Dispose - освобождение используемых ресурсов при завершении приложения. | ||
Для краткости не будем здесь приводить подробное описание этих свойств и методов. В состав дистрибутива SamrtPanel входит полная документация разработчика, где все подробно описано. Для генерации PluginUID можно воспользоваться соответствующим пунктом меню VisualStudio:'' Средства - Создать GUID ''. В конечном итоге проект должен выглядеть аналогично снимку ниже. | Для краткости не будем здесь приводить подробное описание этих свойств и методов. В состав дистрибутива SamrtPanel входит полная документация разработчика, где все подробно описано. Для генерации PluginUID можно воспользоваться соответствующим пунктом меню VisualStudio:'' Средства - Создать GUID ''. В конечном итоге проект должен выглядеть аналогично снимку ниже. | ||
[[ | [[Image:SmartPanels_img13.png|center|frame|Класс CloneLayout.]] | ||
На данном этапе плагин создан и готов к добавлению в SmartPanels, но он еще не имеет визуального представления. Добавим в проект панель для размещения на ней элементов управления:'' Проект – Добавить пользовательский элемент управления… ''. В качестве имени задайте LayoutControl.cs. На созданном элементе управления разместите группирующую панель (Panel в разделе Контейнеры панели Элементы управления), элемент управления «ListBox» и | <p style="text-align:justify">На данном этапе плагин создан и готов к добавлению в SmartPanels, но он еще не имеет визуального представления. Добавим в проект панель для размещения на ней элементов управления:'' Проект – Добавить пользовательский элемент управления… ''. В качестве имени задайте LayoutControl.cs. На созданном элементе управления разместите группирующую панель (Panel в разделе Контейнеры панели Элементы управления), элемент управления «ListBox» и одну кнопку. (раздел Стандартные элементы управления). Новый элемент управления должен выглядеть примерно следующим образом:</p> | ||
[[ | [[Image:SmartPanels_img15.png|center|frame|Пользовательские элементы управления.]] | ||
Экранная форма плагина создана. Теперь надо сообщить об этом SmartPanels. В классе CloneLayout.cs необходимо добавить следующий код: | Экранная форма плагина создана. Теперь надо сообщить об этом SmartPanels. В классе CloneLayout.cs необходимо добавить следующий код: | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
//Создаем новый объект – панель SmartPanels и его идентификатор | //Создаем новый объект – панель SmartPanels и его идентификатор | ||
Строка 137: | Строка 140: | ||
После сделанных изменения класс CloneLayout.cs должен выглядеть следующим образом: | После сделанных изменения класс CloneLayout.cs должен выглядеть следующим образом: | ||
[[ | [[Image:SmartPanels_img16.png|center|frame|Измененный класс CloneLayout.]] | ||
На этом основная работа по созданию и регистрации нового плагина выполнена. На этом этапе возможно посмотреть, как будет выглядеть плагин в MapInfo. Для этого необходимо собрать решение:''Сборка – Собрать решение F6'' и дождаться окончания сборки. По умолчанию готовая сборка в виде файла CloneLayout.dll будет находится в каталоге \bin\Debug корневого каталога проекта. Далее необходимо его загрузить в SmartPanels в Mapinfo: меню ''SmartPanels – Настройки – вкладка Плагины - кнопка Добавить'' | <p style="text-align:justify">На этом основная работа по созданию и регистрации нового плагина выполнена. На этом этапе возможно посмотреть, как будет выглядеть плагин в MapInfo. Для этого необходимо собрать решение:''Сборка – Собрать решение F6'' и дождаться окончания сборки. По умолчанию готовая сборка в виде файла CloneLayout.dll будет находится в каталоге \bin\Debug корневого каталога проекта. Далее необходимо его загрузить в SmartPanels в Mapinfo: меню ''SmartPanels – Настройки – вкладка Плагины - кнопка Добавить''</p> | ||
[[ | [[Image:SmartPanels_img17.png|750px|center|Добавление созданного плагина]] | ||
К сожалению, существует особенность, при которой необходимо перезагружать MapInfo (или SamrtPanels) после установки нового плагина. После перезагрузки в списке установленных плагинов появится новый плагин. | <p style="text-align:justify">К сожалению, существует особенность, при которой необходимо перезагружать MapInfo (или SamrtPanels) после установки нового плагина. После перезагрузки в списке установленных плагинов появится новый плагин.</p> | ||
[[ | [[Image:SmartPanels_img18.png|center|frame|Новый плагин в MapInfo]] | ||
Теперь реализуем взаимодействие с MapInfo. В класс LayoutControl.cs добавим реализацию метода, который будет опрашивать MapInfo на предмет открытых окон и их типа. Если тип окна «Отчет», то имя окна и его ID будет добавляться в список формы. Для этого будем использовать метод <code>MiHost.MB.GetWindows</code>, возвращающий коллекцию всех открытых в MapInfo окон. Этот метод может получать в качестве параметра фильтр <code>MbCommands.MiWindowInfo.WindowTypeFilter</code>, который будет указывать SmartPanels возвращать окна только определенного типа. | <p style="text-align:justify">Теперь реализуем взаимодействие с MapInfo. В класс LayoutControl.cs добавим реализацию метода, который будет опрашивать MapInfo на предмет открытых окон и их типа. Если тип окна «Отчет», то имя окна и его ID будет добавляться в список формы. Для этого будем использовать метод <code>MiHost.MB.GetWindows</code>, возвращающий коллекцию всех открытых в MapInfo окон. Этот метод может получать в качестве параметра фильтр <code>MbCommands.MiWindowInfo.WindowTypeFilter</code>, который будет указывать SmartPanels возвращать окна только определенного типа.</p> | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
private void fillList() { | private void fillList() { | ||
Строка 160: | Строка 163: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Хотя SmartPanels и имеет развитый программный интерфейс (API), в большинстве случаев, можно обойтись всего двумя командами - <code>MiHost.MB.EvalCommand</code> и <code>MiHost.MB.EvalCommandX</code>, где X обозначает тип возвращаемого значения (EvalCommandS – для String, EvalCommandI – для Integer и т.п.), первая команда просто выполняет команду, а вторая еще и возвращает полученное значение. На следующем шаге создадим метод, вызываемый при нажатии на кнопку «Клонировать». Данный метод будет определять активный элемент списка и засылать в MapInfo команду на дублирование этого окна. | <p style="text-align:justify">Хотя SmartPanels и имеет развитый программный интерфейс (API), в большинстве случаев, можно обойтись всего двумя командами - <code>MiHost.MB.EvalCommand</code> и <code>MiHost.MB.EvalCommandX</code>, где X обозначает тип возвращаемого значения (EvalCommandS – для String, EvalCommandI – для Integer и т.п.), первая команда просто выполняет команду, а вторая еще и возвращает полученное значение. На следующем шаге создадим метод, вызываемый при нажатии на кнопку «Клонировать». Данный метод будет определять активный элемент списка и засылать в MapInfo команду на дублирование этого окна.</p> | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
private void btnClone_Click(object sender, EventArgs e) | private void btnClone_Click(object sender, EventArgs e) | ||
Строка 173: | Строка 176: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Осталось только определить, как будет обновляться список отчетов. Для этого попросим MapInfo присылать сообщение при открытии или закрытии окон. При получении такого сообщения будем обновлять список отчетов. | <p style="text-align:justify">Осталось только определить, как будет обновляться список отчетов. Для этого попросим MapInfo присылать сообщение при открытии или закрытии окон. При получении такого сообщения будем обновлять список отчетов.</p> | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
public LayoutControl() | public LayoutControl() | ||
Строка 193: | Строка 196: | ||
После внесенных изменений класс должен выглядеть следующим образом: | После внесенных изменений класс должен выглядеть следующим образом: | ||
[[ | [[Image:SmartPanels_img19.png|center|frame|Измененный класс LayoutControl]] | ||
После сборки решения открываем MapInfo и проверяем результат. | После сборки решения открываем MapInfo и проверяем результат. | ||
[[ | [[Image:SmartPanels_img20.png|center|frame|Плагин в действии]] | ||
==Заключение== | ==Заключение== | ||
SmartPanels существенно облегчает жизнь разработчикам приложений MapInfo и позволяет осуществлять проекты любой сложности. Это могут быть как проекты, реализующие конкретные прикладные задачи, так и проекты, расширяющие функциональные возможности MapInfo. В качестве примера последнего можно привести разрабатываемый в настоящий момент плагин, который является аналогом Редактора моделей анализа в QGIS и ModelBuidler в ArcGIS. | <p style="text-align:justify">SmartPanels существенно облегчает жизнь разработчикам приложений MapInfo и позволяет осуществлять проекты любой сложности. Это могут быть как проекты, реализующие конкретные прикладные задачи, так и проекты, расширяющие функциональные возможности MapInfo. В качестве примера последнего можно привести разрабатываемый в настоящий момент плагин, который является аналогом Редактора моделей анализа в QGIS и ModelBuidler в ArcGIS.</p> |
Текущая версия от 10:18, 9 апреля 2018
по адресу http://gis-lab.info/qa/mapinfo-smartpanels.html
В данной статье речь пойдет об утилите SmartPanels для MapInfo, позволяющей достаточно просто интегрировать в MapInfo пользовательские специализированные приложения или приложения, расширяющие функциональность MapInfo.
Описание
В данной статье речь пойдет об утилите SmartPanels для MapInfo, позволяющей достаточно просто интегрировать в MapInfo пользовательские специализированные приложения или приложения, расширяющие функциональность MapInfo.
MapInfo имеет штатный язык программирования MapBasic, который позволяет автоматизировать практически все операции MapInfo. Всем хорош MapBasic, пока дело не доходит до создания с его помощью достаточно развитого пользовательского интерфейса. Тут возникает сразу несколько проблем:
- большая трудоемкость при создании и размещении элементов управления.[1]
- невозможность создавать немодальные окна;
- ограниченный набор элементов управления состоящий всего из 15 элементов.
С другой стороны, существует достаточно широкий класс задач, где развитой пользовательский интерфейс просто необходим. В качестве характерного примера можно привести тот же кадастровый учет, в котором необходимо отображать большое количество разнообразной информации, привязанной к одному участку.
Разработчиками предпринимались различные попытки обойти ограничения MapBasic. К ним можно отнести создание визуальных редакторов диалогов (своеобразные IDE), реализация функционала MapInfo в среде MSAccess с использованием MapX, динамическое связывание MapInfo и MSAccess посредством механизма DDE и т.п. Но какого-то универсального инструмента не существовало. Точнее он был. Однако для его использования необходимо было быть специалистом в C++, а точнее хорошо разбираться в тонкостях создания библиотек DLL (разработка, подключение их в MapBasic, вызов из них внешних подпрограммы и пр.) что, согласитесь, для прикладного программиста MapBasic не является характерным.
Ситуация изменилась коренным образом с выходом утилиты SmartPanels, разработанной специалистами компании ЭСТИ МАП.[2] Разработка данной утилиты стала возможной, благодаря переходу MapInfo начиная с версии 9.5 на платформу Microsoft .NET. С помощью этой утилиты стало возможным быстро подключать (регистрировать) к MapInfo пользовательские приложения, созданные на любом из языков семейства .NET. Утилита является, как бы, посредником между MapInfo и внешним приложением. При этом для разработки прикладного решения не требуется установленного компилятора MapBasic. Все что нужно–это установленная утилита SmartPanel и среда разработки MSVisualStudio.
Примечания
Примеры реализации
Для наглядного представления о том, что представляет из себя SmartPanels, приведем примеры четырех плагинов. Первые два поставляются в качестве примеров вместе со SmartPanels и представляет собой плагины общего назначения, т.е. расширяющие стандартные возможности MapInfo. Первый из них - «Вкладки» вносит полезное дополнение к пользовательскому интерфейсу MapInfo. Так при развернутых окнах, в верхней части окон появляются вкладки с именами документов и переключения между ними становится намного удобнее.[1] Вторым дополнением к пользовательскому интерфейсу [2] является возможность «прикреплять» панели к одной из сторон окна MapInfo с помощью соответствующих инструментов, отображающихся при перемещении панелей. Если ко одной стороне будет прикреплено несколько панелей, то они также будут отображаться в виде вкладок.
Второй плагин – «Информация». Его задачей является отображение и редактирование информации по выбранному объекту в настраиваемой пользователем форме. При первом запуске он ничем не отличается от стандартного окна информации MapInfo.
Но вызвав с помощью правой клавиши мыши контекстное меню, можно открыть визуальный редактор экранной формы и настроить представление информации в соответствии со своими потребностями. Кроме этого он позволяет определять для полей списки предопределенных значений, т.е. определять словари. Причем эти списки можно создавать как непосредственно в дизайнере форм, так и в обычных таблицах MapInfo или таблицах базы данных, указывая при этом ссылку на них в дизайнере форм. Это значительно ускоряет ввод и редактирование данных, помогая избежать многих ошибок.
Остальные два плагина были созданы под конкретные проекты. Первый из них предназначен для отображения данных переписи населения. Задача состояла в представлении данных переписи населения в различных разрезах. В MapInfo имелся слой с населенными пунктами и имелась база данных с результатами переписи. Плагин выполняет две основные задачи:
- получает от MapInfo уникальный код населенного пункта (код ОКАТО), осуществлял выборку данных из БД их интерпретацию и представление.
- передает MapInfo команду на позиционирование окна карты в центре с выбранным пользователем в иерархическом списке населенным пунктом.
При использовании специального инструмента «Информация» при выборе населенного пункта на карте происходит отображение информации в различных разрезах
И еще один пример. В данном случае был разработан плагин для отображения панорам Yandex и Google при выборе точки на карте и использования поискового сервиса Yandex.
Примечания
Пример создания плагина для SmartPanel
Особый интерес, конечно же, представляет возможность создания собственных плагинов. В качестве примера рассмотрим создание приложения, которое будет не просто приветствовать этот мир, но реализовать полезную функцию – клонировать окно отчета. В стандартном MapIinfo такая возможность отсутствует, в отличие от окна карты. Для начала необходимо скачать и установить SmartPanel. Утилита является абсолютно бесплатной и скачать ее можно по ссылке Медиа:SPInstaller32.zip для 32 разрядной версии и Медиа:SPInstaller64.zip для 64 разрядной. В терминах SmartPanel все подключаемые пользовательские приложения носят названия плагинов. В качестве примеров вместе с самой утилитой распространяются также бесплатные плагины – «Вкладки» и «Расширенная панель информации». Подробное описание этих плагинов можно найти по той же ссылке. После установки в основном меню MapInfo появится новый пункт – SmartPanel. Данный пункт содержит два элемента: Настройки и Панели. Пункт «Настройки» предназначен для основных действий с плагинами по их настройке, удалению и добавлению в SmartPanels. Второй пункт отвечает за отображение списка всех зарегистрированных панелей, позволяет их показывать или скрывать.
Теперь все готово для добавления своего собственного плагина. Для его создания необходимо установить MS Visual Studio. Вполне подойдет и бесплатная версия этой IDE – Community [1]. После запуска загрузчика рекомендуется выбрать пункт «Разработка классических приложений .NET»
После установки MS VisualStudio можно приступать непосредственно к созданию нашего проекта: Файл – Проект – Cоздать – Библиотека классов (.NET Framework)
В созданном проекте нужно указать ссылку на библиотеку SmarPanels.dll. Данная библиотека находится в корневом каталоге установки SmartPanel. Если при установке утилиты были использованы настройки по умолчанию, то эта библиотека будет находится в каталоге C:\Program Files\ESTI MAP\SmartPanels. Для создания ссылки необходимо в панели «Обозреватель решения» вызвать диалог добавления ссылки путем нажатия правой клавиши мыши на пункте «Ссылки» и далее «Добавить ссылку…». После инициализации проекта был создан класс по умолчанию Class1. Название класса можно оставить без изменений, а можно переименовать, но в любом случае этот класс должен реализовывать интерфейс SPNet.IMiPlugin. Это и есть предопределенный шаблон плагина. В контексте этого интерфейса наш класс должен реализовывать пять свойств и три метода.
Свойства:
- PluginName - название плагина, которое будет отображаться в списке установленных плагинов.
- PluginDescription - описание плагина.
- PluginUID – глобально уникальный идентификатор плагина.
- PluginVersion - версия плагина.
- RestoredPanels - список панелей, местоположение которых SmartPanels будет автоматически сохранять и восстанавливать при запуске.
Методы:
- Init - производит инициализацию плагина.
- LoadPluginSettings - загружает состояние плагина.
- Dispose - освобождение используемых ресурсов при завершении приложения.
Для краткости не будем здесь приводить подробное описание этих свойств и методов. В состав дистрибутива SamrtPanel входит полная документация разработчика, где все подробно описано. Для генерации PluginUID можно воспользоваться соответствующим пунктом меню VisualStudio: Средства - Создать GUID . В конечном итоге проект должен выглядеть аналогично снимку ниже.
На данном этапе плагин создан и готов к добавлению в SmartPanels, но он еще не имеет визуального представления. Добавим в проект панель для размещения на ней элементов управления: Проект – Добавить пользовательский элемент управления… . В качестве имени задайте LayoutControl.cs. На созданном элементе управления разместите группирующую панель (Panel в разделе Контейнеры панели Элементы управления), элемент управления «ListBox» и одну кнопку. (раздел Стандартные элементы управления). Новый элемент управления должен выглядеть примерно следующим образом:
Экранная форма плагина создана. Теперь надо сообщить об этом SmartPanels. В классе CloneLayout.cs необходимо добавить следующий код:
//Создаем новый объект – панель SmartPanels и его идентификатор
// Guid необходимо сформировать с помощью меню Средства-Создать GUID
MiDockPanel pnl = null;
Guid pnlID = new Guid("{77BCA491-65DA-4C40-A1AE-B792C77DFDAC}");
//Заменияем public List<Guid> RestoredPanels{get{return null;}} на
public List<Guid> RestoredPanels
{
get
{List<Guid> l = new List<Guid>();
l.Add(pnlID);
return l;}
}
//Реализовываем метод Init(), который вызывается при инициализации плагина
public void Init()
{
//Событие MiHost.Inited вызывается после инициализации всех плагинов.
MiHost.Inited += MiHost_Inited;
//Добавляем панель
pnl = MiHost.AddDockPanel("Клонирование отчета", pnlID);
//Создаем экземпляр нашего элемента управления
LayoutControl ctrl = new LayoutControl();
ctrl.Dock = DockStyle.Fill;
//Созданная панель должна иметь вид нашего элемента управления
pnl.Controls.Add(ctrl);
}
//Добавляем метод Init(), который будет выполняться при инициализации плагина
//Подробное описание команд см. Документацию
void MiHost_Inited(object sender, EventArgs e)
{try
{
MiHost.AddPanelToMenu("Клонирование отчета",SPNet.MbCommands.MenuItemShortcut
.CreateShortcut(SPNet.MbCommands.MenuItemShortcut.ModifierKey.Ctrl,(byte)'T'), "Клонирование отчета",pnl);
}
catch (Exception except)
{ MessageBox.Show(MiHost.MainHandle,
"Произошла ошибка при инициализации плагина:" + except.Message,
"Клонирование отчета",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
После сделанных изменения класс CloneLayout.cs должен выглядеть следующим образом:
На этом основная работа по созданию и регистрации нового плагина выполнена. На этом этапе возможно посмотреть, как будет выглядеть плагин в MapInfo. Для этого необходимо собрать решение:Сборка – Собрать решение F6 и дождаться окончания сборки. По умолчанию готовая сборка в виде файла CloneLayout.dll будет находится в каталоге \bin\Debug корневого каталога проекта. Далее необходимо его загрузить в SmartPanels в Mapinfo: меню SmartPanels – Настройки – вкладка Плагины - кнопка Добавить
К сожалению, существует особенность, при которой необходимо перезагружать MapInfo (или SamrtPanels) после установки нового плагина. После перезагрузки в списке установленных плагинов появится новый плагин.
Теперь реализуем взаимодействие с MapInfo. В класс LayoutControl.cs добавим реализацию метода, который будет опрашивать MapInfo на предмет открытых окон и их типа. Если тип окна «Отчет», то имя окна и его ID будет добавляться в список формы. Для этого будем использовать метод MiHost.MB.GetWindows
, возвращающий коллекцию всех открытых в MapInfo окон. Этот метод может получать в качестве параметра фильтр MbCommands.MiWindowInfo.WindowTypeFilter
, который будет указывать SmartPanels возвращать окна только определенного типа.
private void fillList() {
listLayout.Items.Clear();
foreach (var lw in MiHost.MB.GetWindows(MbCommands.MiWindowInfo.WindowTypeFilter.WIN_LAYOUT)) {
listLayout.Items.Add(string.Format("{0}#{1}", lw.WindowID, lw.WindowName));
}
//Пусть последний элемент списка всегда будет выделенным
if (listLayout.Items.Count>0) {
listLayout.SelectedIndex = listLayout.Items.Count - 1;
}
}
Хотя SmartPanels и имеет развитый программный интерфейс (API), в большинстве случаев, можно обойтись всего двумя командами - MiHost.MB.EvalCommand
и MiHost.MB.EvalCommandX
, где X обозначает тип возвращаемого значения (EvalCommandS – для String, EvalCommandI – для Integer и т.п.), первая команда просто выполняет команду, а вторая еще и возвращает полученное значение. На следующем шаге создадим метод, вызываемый при нажатии на кнопку «Клонировать». Данный метод будет определять активный элемент списка и засылать в MapInfo команду на дублирование этого окна.
private void btnClone_Click(object sender, EventArgs e)
{
if (listLayout.SelectedItem != null)
{
string item = listLayout.SelectedItem.ToString();
string idWin = item.Substring(item.IndexOf("#")+1);
//Засылаем в MI команду на клонирование окна
MiHost.MB.EvalCommand("Run Command WindowInfo("+idWin+", 15)");
}
}
Осталось только определить, как будет обновляться список отчетов. Для этого попросим MapInfo присылать сообщение при открытии или закрытии окон. При получении такого сообщения будем обновлять список отчетов.
public LayoutControl()
{
InitializeComponent();
//Будем следить за новыми окнами в MI
MiHost.AddDocumentWindow += MI_NewWin;
//и за закрытыми окнами в MI
MiHost.RemoveDocumentWindow+= MI_RemoveWin;
}
void MI_NewWin(object sender, EventArgs e) {
fillList();
}
void MI_ RemoveWin(object sender, EventArgs e)
{
fillList();
}
После внесенных изменений класс должен выглядеть следующим образом:
После сборки решения открываем MapInfo и проверяем результат.
Заключение
SmartPanels существенно облегчает жизнь разработчикам приложений MapInfo и позволяет осуществлять проекты любой сложности. Это могут быть как проекты, реализующие конкретные прикладные задачи, так и проекты, расширяющие функциональные возможности MapInfo. В качестве примера последнего можно привести разрабатываемый в настоящий момент плагин, который является аналогом Редактора моделей анализа в QGIS и ModelBuidler в ArcGIS.