Разработка клиентских приложений (плагинов) в среде ГИС «Геопроект 5»
РУКОВОДСТВО РАЗРАБОТЧИКА

Вступление

Геоинформационная система «Геопроект 5» (ГИС) сама по себе является достаточно мощной и многофункциональной средой, позволяющей решать очень широкий спектр задач, возложенных на предприятия геодезического, геофизического, геокадастрового и прочих направлений. Однако не существует таких программ, которые бы в полной мере могли удовлетворить абсолютно все запросы их пользователей и это вполне нормально и естественно, ведь каждый отдельный пользователь, каждое отдельное предприятие проводит свою профессиональную деятельность со своим уникальным «акцентом», т.е. своими собственными наработками, технологиями, требованиями.

Для расширения базовой функциональности ГИС «Геопроект 5», в состав системы был внедрён механизм, позволяющий сторонним разработчикам, да и просто «продвинутым» пользователям самостоятельно дорабатывать среду, создавая новые уникальные функции и целые независимые модули.

Для этой цели ГИС предоставляет набор процедур и функций API (Application Programming Interfaces), благодаря которому внешние модули могут функционировать совместно с ГИС, а также интегрироваться в общий пользовательский интерфейс среды.

Термины и сокращения

Плагин (plugin) или модуль - собственно то, о чём и будет описано в этом документе - отдельный модуль, созданный сторонним разработчиком и содержащий в себе определённый разработчиком набор функций. Модулем является динамически подключаемая библиотека (dll - файл) с определённой структурой, согласно представленной ниже спецификации.

ГИС - основная среда или ядро, к которому будут подключаться созданные сторонними разработчиками плагины. В нашем случае таким ядром будет сама система ГИС «Геопроект 5».

API - встроенный в ГИС интерфейс взаимодействия самой ГИС и подключенных к ней плагинов. Данный интерфейс включает в себя функции по регистрации плагина в системе, созданию кнопок и пунктов меню, использованию стандартных средств ГИС по созданию и редактированию объектов на плане и т.д.

Программная среда - язык программирования на котором разработчик будет писать плагины. Поскольку сама ГИС написана на языке Delphi, то и представленные в этом документе описания структур, функций API и примеры так же будут на языке Delphi. Однако стоит отметить, что плагины могут быть написаны и на любом другом языке программирования, поддерживающем написание dll-библиотек, например "C++". Главное, чтобы разработчик точно передал описания структур и типов, используемых в API.

Данный документ не научит вас основам программирования, не расскажет о теории и практике написания приложений в среде Delphi, и уж тем более не раскрывает тонкости работы с dll-приложениями. Подразумевается что тот, кто будет использовать это «Руководство разработчика» является более-менее опытным программистом, понимающим суть выражений «Debug», «Trace» и «Access Violation». Если вам не особо понятен последний термин - не беспокойтесь, скорее всего вы с ним будете очень часто сталкиваться, особенно вначале. Может быть даже он вам будет сниться.

brain not found

Начало работы

Создайте новый dll-проект. В среде BDS 2006 это делается очень просто. Пройдя меню «File ⇒ New ⇒ Other», в открывшемся окошке выберите пункт «DLL Wizard».

API new dll

В результате вы получите минимальный код - заготовку для вашего первого плагина:

library Project1;

uses
  SysUtils,
  Classes;

{$R *.res}

begin
end.

Сохраните проект. Дайте ему осмысленное название, отражающее суть работы плагина, дабы потом не запутаться. По сути, это уже полноценная библиотека. Если вы прошли этот шаг - то вас уже можно поздравить.

Для того чтобы посмотреть работу вашего плагина необходимо скомпилировать библиотеку и полученный в процессе компиляции dll-файл скопировать в специальную папку для плагинов. Это папка «Plugins», которая находится в основном каталоге ГИС. При этом сама ГИС должна быть закрыта, поскольку иначе вы никаких изменений не увидите. Все плагины из папки «Plugins» загружаются в процессе запуска ГИС и выгружаются в процессе завершения работы ГИС.

Наверняка вы уже попытались скомпилировать ваш первый плагин и даже скопировали его в общую папку плагинов. Вы запустили ГИС и не увидели никаких изменений? Естественно! Ведь наш плагин совсем пустой и ещё ничего не делает. Далее, в примерах мы будем постепенно устранять этот недостаток.

Подключение ГИС-API

Для начала необходимо внести в код плагина описание типов и структур, которые мы сможем вдальнейшем использовать. Но что самое главное - нам необходимо внести описание класса API-интерфейса. Дабы не вдаваться в лишние подробности и не загрязнять код плагина, просто подключите к вашему проекту модуль (unit) в котором содержатся все необходимые для работы описания типов структур и API-интерфейса.

Скачать файл ApiType.pas

Не забудьте объявить новый модуль в разделе uses вашего плагина.

library Project1;

uses
  SysUtils, ApiType;

{$R *.res}

begin
end.

Инициализация и уничтожение

Необходимо позаботиться об обязательных процессах инициализации и уничтожении вашего плагина. В процессе инициализации, ГИС идентифицирует плагин и регистрирует в общем списке действующих плагинов. В это же время плагин имеет возможность «засветиться» в самой ГИС, т.е. создать свои кнопки на панелях инструментов или дополнительные пункты меню. Описывать процесс уничтожения обязательно нужно, чтобы освободить занятые плагином ресурсы, сохранить важные данные и т.д. Для этого в код нужно внести две обязательные процедуры с обязательным объявлением их в разделе экспорта.

  • Процедура InitPlugin - для управления инициализацией;
  • Процедура DestroyPlugin - для управления завершением работы плагина.

Теперь наш код будет выглядеть так:

library Project1;

uses
  SysUtils, ApiType;

{$R *.res}

procedure InitPlugin(PlugClass: TPluginInterface);
begin
end;

procedure DestroyPlugin;
begin
end;

exports
  InitPlugin,
  DestroyPlugin;

begin
end.

Как вы уже успели заметить, процедура InitPlugin возвращает экземпляр класса TPluginInterface, содержащий все доступные функции ГИС-API. Оперируя предоставляемыми этим классом функциями мы сможем напрямую влиять на работу ГИС, заставляя её исполнять наши комманды.

Что писать в процедурах инициализации и уничтожения? Например, в работе плагина вы планируете использовать окно, чтобы вывести какие-то данные, построить график или запросить какую-нибудь информацию от пользователя. В процедуре InitPlugin вы сможете создать это окно, а процедуре DestroyPlugin - уничтожить, чтобы не захламлять системные ресурсы. Кроме того, как уже было сказано выше, только в процедуре InitPlugin целесообразно делать ваш плагин видимым пользователю, т.е. создать необходимые элементы управления в интерфейсной среде ГИС. Ну и конечно же, что самое главное, вам необходимо присвоить значение переменной PlugClass заранее объявленной в вашем плагине глобальной переменной, чтобы вдальнейшем использовать функции API в любом месте плагина.

Регистрация элементов управления

Большинство плагинов создаются с целью дальнейшего взаимодействия с пользователем. Пользователь догадается о существовании вашего модуля лишь в том случае, если увидит его видимое присутствие на панели управления в виде кнопки или набора кнопок, или же в виде соответствующего пункта меню.

Как уже упоминалось выше, регистрация элементов управления плагина производится в процедуре инициализации InitPlugin. Рассмотрим процесс создания кнопок и пунктов меню более подробно.

Создание панели инструментов

Если для работы с функциями плагина вы собираетесь создавать несколько кнопок, то целесообразно было бы создать для этого новую панель инструментов. Как видно из описания класса API-интерфейса, для этой цели служит процедура gisCreateToolBar. Подробное описание функции и передаваемых параметров смотрите ниже, в справочнике по функциям API. Пример создания панели инструментов:

PlugClass.gisCreateToolBar('Новая панель', BarName);

Эта функция создаст в ГИС новую панель инструментов. Пустую, без кнопок, с заголовком «Новая панель». В то же время в переменной BarName ГИС вернёт уникальное системное имя новосозданной панели инструментов. Нам важна эта переменная для последующей регистрации кнопок в этой панели.

Создание кнопки на панели инструментов

Прежде чем создать кнопку или пункт меню, необходимо зарегистрировать «действие», которое будет производить эта кнопка или пункт меню. Для регистрации «действия» предназначена процедура gisCreateAction. В качестве параметров этой процедуры можно указать название, всплывающую подсказку и изображение для будущего элемента управления, а так же ссылку на нужную нам процедуру или функцию в плагине. Пример регистрации «действия»:

PlugClass.gisCreateAction('Открыть файл', 'Открыть файл на диске', GlyphBmp, OpenMyFile, ActName);

В переменной ActName ГИС вернёт уникальное системное имя новосозданного действия. Нам важна эта переменная для последующей регистрации кнопок или пунктов меню.

Для регистрации кнопки на панели инструментов предусмотрена процедура gisCreateToolBtn. Пример использования процедуры:

PlugClass.gisCreateToolBtn(BarName, ActName, BtnName);

Переменные BarName и ActName - системные имена панели инструментов и «действия» соответственно. Эти переменные мы получили в процессе регистрации панели и «действия». В переменной BtnName ГИС вернёт уникальное системное имя новосозданной кнопки.

Создание пункта меню

Процесс регистрации пункта меню аналогичен процессу регистрации кнопки. Т.е. вначале нужно создать «действие» и только потом, с помощью процедуры gisCreateMenuBtn можно создать пункт меню в любой доступной категории меню. Пункты меню по видам можно условно разделить на три группы: категории, основные пункты меню и второстепенные (вложенные пункты меню).

API menu

Пример создания категории меню:

PlugClass.gisCreateMenuBtn('', ActName, -1, true, CatName);

Первый строковый параметр намеренно указан пустым. Это означает, что мы собираемся создать именно категорию, т.е. пункт в главном меню. Второй параметр - переменная ActName у нас уже есть. Значение этой переменной мы получили когда создавали «действие». Третий параметр указывает на порядок сортировки нашего пункта меню в общем списке. Если это значение меньше 0, то пункт меню будет добавлен в конец списка. Четвёртый параметр определяет, показывать ли изображение рядом с пунктом меню. Это изображение должно быть предварительно передано в процессе регистрации «действия». В переменной CatName ГИС вернёт уникальное системное имя новосозданной категории. Это имя нам понадобится для регистрации основных пунктов меню в категории.

Пример создания основного пункта меню:

PlugClass.gisCreateMenuBtn(CatName, ActName, -1, true, MnuName);

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

Пункт менюСистемное имя
ПроектMenuProject
ПравкаMenuEdit
ВидMenuView
ВычисленияMenuCalc
ПостроенияMenuDraw
НавигацияMenuNav
РастрыMenuRaster
СервисMenuService
ПараметрыMenuParams
МодулиMenuPlugins

Если в переменной ActName вместо имени «действия» передать пустой параметр, то вместо пункта меню будет создана полоса-разделитель.

Создание второстепенного (вложенного) пункта меню производится аналогично созданию основных пунктов меню с одной лишь разницей: перед этим нужно создать пункт SubMenu, т.е. пункт меню, использующийся как переходная точка от основного меню к вложенному. Для создания SubMenu используется процедура gisCreateSubMenu. Пример создания подменю (submenu):

PlugClass.gisCreateSubMenu(CatName, 'Вложенный список', 3, MnuName);

В переменной MnuName ГИС вернёт уникальное системное имя новосозданного SubMenu. Эту переменную можно использовать для дальнейшей регистрации второстепенных пунктов меню. Подробное описание функций и передаваемых параметров смотрите ниже, в справочнике по функциям API.

И напоследок...

Теперь у нас есть всё необходимое для создания действующего плагина. Закрепляя всё вышесказанное, допишем код нашей dll-библиотеки. В процессе инициализации наш плагин создаст новую панель управления и разместит на ней одну кнопку с подсказкой «Нажми меня». Так же плагин создаст пункт меню с аналогичным названием в категории «Проект». Поставим этот пункт меню вторым по списку. По нажатию на кнопку или пункт меню плагин будет выдавать полезное сообщение.

library Test_01;

uses
  Graphics,
  ApiType in 'ApiType.pas',
  WorkUnit in 'WorkUnit.pas';

{$R *.res}
{$R glyphs.res}

{Процедура инициализации}
procedure InitPlugin(PlugClass: TPluginInterface);
var
  GlyphBmp : TBitmap;
  ActName, MnuName, BarName, BtnName : String;
begin
  IPlugin := PlugClass;
  WorkModule := TWorkModule.Create;
  ActName := ''; MnuName:= ''; BarName:= ''; BtnName:= '';

  GlyphBmp := TBitmap.Create;
  try
    GlyphBmp.LoadFromResourceName(hInstance, 'MYGLYPH');
    //Регистрируем действие
    PlugClass.gisCreateAction('Нажми меня', 'Нажми меня', GlyphBmp, WorkModule.ShowTime, ActName);
  finally
  GlyphBmp.Free;
  end;

  if ActName <> '' then
  begin
    //Регистрируем панель инструментов
    PlugClass.gisCreateToolBar('Новая панель', BarName);
    //Регистрируем кнопку на панели
    if BarName <> '' then
    PlugClass.gisCreateToolBtn(BarName, ActName, BtnName);
    //Регистрируем пункт меню
    PlugClass.gisCreateMenuBtn('MenuProject', ActName, 1, true, MnuName);
  end;
end;

{Процедура уничтожения}
procedure DestroyPlugin;
begin
  if Assigned(WorkModule) then WorkModule.Free;
end;

exports
  InitPlugin,
  DestroyPlugin;

begin
end.

Проверить работу плагина на практике вы можете скачав готовый dll-файл или его исходный код.

Скачать готовый плагин Test_01.dll или его исходный код

Наверх
Не случайный отзыв →