Применение геоинформационных систем в геоэкологических исследованиях |
Страница 45 из 49
Основы программирования на Avenue Когда пользователь вызывает различные опции с помощью интерфейса пользователя, на самом деле он запускает на исполнение системные программы ArcView 3.2, которые написаны на языке Avenue. Как мы уже убедились, пользователь имеет возможность сам писать программы в окне Редактора скриптов и сохранять эти программы во внешних файлах с расширением «ave». Он может также внедрить эти программы в состав системных, хотя это совершенно необязательно: чтобы программу можно было запускать на исполнение необходимо её наличие в списке документов проекта. Разумеется, программа должна быть откомпилирована. Текст программы хранится в проекте, соответственно записывается в файл проекта с расширением «apr», и, как указано выше, может сохраняться в файле с расширением «ave», что не является обязательным. Алгоритмический язык Avenue создан на принципах объектно-ориентированного программирования. Немного обсудим эти принципы. Для этого необходимо вкратце коснуться истории программирования. После изобретения первых цифровых электронно-вычислительных машин первое время программы представляли собой последовательности команд в двоичном коде, что требовало глубоких специальных знаний и больших затрат времени при их разработке. Затем был изобретён язык Assembler, на котором команды для ЭВМ записывались в мнемоническом коде. Эту программу с помощью программы транслятора Ассемблера необходимо перевести в последовательность исполняемых машинных кодов. Ассемблер требует от программиста определить, в каких областях памяти машины держать ту или иную информацию. Поэтому Ассемблер называется языком низкого уровня: он ближе всего к уровню компьютера. Это делает программу очень громоздкой при написании, но зато обеспечивает максимум быстродействия и экономии ресурсов памяти ЭВМ. Затем были изобретены языки высокого уровня, в которых задача распределения информации в памяти машины была «переложена на плечи» самого компьютера. Это сильно упростило написание программ и объём их текстов, но увеличило затраты памяти и снизило быстродействие машины. Если сравнить программиста с главнокомандующим, а программу ЭВМ с выполнением боевой задачи его армией, то в Ассемблере главнокомандующему приходится отдавать приказ каждому рядовому. На языках высокого уровня «приказы отдаются генералам и офицерам»: одна команда на этом языке на уровне компьютера превращается в десятки и сотни команд в исполняемых машинных кодах. Языки высокого уровня подразделяются на языки интерпретирующего и компилирующего типов. В первом случае отдельная команда языка переводится в исполняемый машинный код в памяти машины и выполняется. Таким образом, программа выполняется по отдельным шагам: загрузка команды, перевод в машинный код и исполнение, загрузка следующей команды и т.д. Программа запускается на выполнение из программного пакета, для которого этот язык разработан. Файл последовательностей исполняемых машинных кодов с расширением «exe» в данном случае не образуется. В случае языка компилирующего типа вся программа переводится в последовательность исполняемых машинных кодов, которая записывается в большинстве случаев в файл с расширением «exe». Для запуска этой программы необходимо только наличие операционной системы, а в ряде случаев – ещё и файлов динамически подключаемых библиотек с расширением «dll». Можно привести такой пример. Допустим, Вам необходимо выступить с докладом на научной конференции, рабочий язык которой нам не известен. Можно произнести доклад по-русски, а переводчик-синхронист будет переводить Ваш доклад фразу за фразой. А можно перевести свой доклад ещё дома и произнести его на иностранном языке самому (разумеется, необходимо доеобходимо дбиться маол-мальски (разумеется, знести выступить с докладом на научной конференции, рабочий язык которой нам не избиться мало-мальски приемлемого произношения). Первый случай иллюстрирует работы программы на языке интерпретирующего типа, второй – компилирующего. Сначала языки высокого уровня разрабатывались на принципах структурного программирования. В этом случае идентификаторы сущностей (переменных) и действия программы (операторы, команды, функции) отделены друг от друга. Однако ещё в языках структурного типа (например, в Паскале) появился тип переменных запись, в которой одна сущность может включать в себя свои разнотипные параметры. Например, имя, отчество, фамилию, год рождения человека и т.д. Когда в состав параметров сущности включили методы её обработки, то появился объектно-ориентированный подход программирования. Стандарт объектно-ориентированного программирования зиждется на «трёх китах»: инкапсуляции, наследовании и полиморфизме. Инкапсуляция означает соединение в объекте программы сущности (например, координат и мерности пространственного объекта) и методов её обработки. Наследование означает, что объект программы может порождать объекты-потомки, которые наследуют характеристики объекта-родителя. Так, при запуске на компьютере программного пакета ArcView 3.2 в памяти компьютера создаётся объект приложение ArcView, которое на языке Avenue обозначается av. Этот универсальный объект содержит в себе все объекты интерфейса пользователя и текущего проекта. Обращаясь к нему и его потомкам, можно «добраться» до любых используемых в проекте документов и данных. Разумеется, если программа должна работать с пространственными данными, то её можно строить от обращения к активной теме открытого Вида, однако наиболее универсальным является построение программы Avenue от обращения к объекту av, возвращающего открытый проект ArcView 3.2 (вспомним, что открыт может быть только один проект и мы не можем работать в ArcView 3.2 вне проекта): theProject=av.GetProject. Здесь мы видим инкапсуляцию: объект av содержит в себе методы обработки, в данном случае метод GetProject, возвращающий текущий проект в объект theProject. Последний наследует часть характеристик объекта av, касающуюся документов открытого проекта. Полиморфизм означает, что благодаря применению к одному и тому же объекту различных методов мы будем получать представление объекта в разных формах, отражающих его различные характеристики. Затем в программе следует получить список DocList всех документов проекта: DocList=theProject.GetDocs. Объект типа список (List) представляет собой упорядоченную последовательность каких-либо объектов, возможно, совершенно разнотипных. Чтобы получить необходимый элемент списка, нужно указать его порядковый номер. Номер первого элемента списка – 0! Поскольку нам неизвестно, в каком порядке компьютер расположил в списке DocList документы проекта, то нам придётся в поиске нужных организовать перебор всех. Для этого нам необходимо узнать количество элементов списка NDoc с помощью метода Count: NDoc=DocList.Count. Мы можем работать с документами различных типов: видами, таблицами, диаграммами, компоновками, скриптами (программами), диалогами. Предположим, нам необходимо работать с определённым векторным слоем (темой) электронной карты (вида). В этом случае сначала нам следует выбрать этот вид. Для этого создадим пустой список, в который затем добавим все виды проекта: ViewList=List.Make. Далее организуем цикл по всем элементам списка документов проекта. Цикл начинается с оператора for each, а заканчивается словом end. Между этими двумя операторами расположено «тело цикла», содержащее повторяющиеся операции: for each dok in 0..(NDoc-1) Переменная dok принимает целочисленные значения от 0 до величины NDoc-1, поскольку если общее число элементов списка равно NDoc, а номер первого элемента – 0, то номер последнего будет на единицу меньше общего количества. В переменную (объект) tekdoc на каждом шаге цикла поступает текущий элемент списка документов проекта. Затем необходимо определить тип этого документа. Однако названия конкретных документов не отражают тип документа. Здесь нам поможет то обстоятельство, что при открытии документов различных типов интерфейс пользователя принимает соответствующий характерный вид. Метод GetGUI, применённый к любому документу проекта возвращает строковый объект, в котором записано, какому типу документов проекта соответствует графический интерфейс пользователя (Grapher User Interface), связанный с данным документом проекта. Возможные типы ответов: «View», «Table», «Chart», «Layout», «Scripts», «Dialog». Оператор условного перехода «if» выполняет набор операторов между строкой «if (выражение) then» и строкой «end» только в том случае, если выражение является истинным. В данном случае если графический интерфейс пользователя имеет тип «View», то текущий документ добавляется в список видов. Теперь нам необходимо выбрать из списка видов нужный. Современные интегрированные среды разработки приложений имеют инструмент для визуального конструирования экранных форм. ArcView 3.2 лишён этой возможности, она появляется в ArcGIS. Вместо этого в Avenue имеются объекты для создания готовых диалоговых окон, в частности MsgBox. Применение к нему метода List позволяет пользователю выбрать элемент списка. У этого оператора следующий синтаксис: в скобках сначала помещается идентификатор списка, затем – маска для выбора объектов (например, если в списке слоёв необходимо выбирать только шейпфайлы, то маска будет "*.shp"), если маска не нужна, то ставится "", затем – титул, т.е. название вверху окна диалога (тоже не обязательно). В нашем случае: theView=MsgBox.List(ViewList, "", "Выберите Вид"). Теперь объект theView содержит тот Вид, в котором содержится интересующий нас слой (Тема). Следовательно, необходимо получить эту Тему. Сначала получаем список всех слоёв (тем) Вида (электронной карты): list_of_themes=theView.getThemes. Далее с помощью стандартного диалога выбираем слой: theTheme = MsgBox.List(list_of_themes, "*.shp", "Выберите векторную тему"). До любых данных векторных слоёв можно добраться только через таблицу атрибутов темы Ftab. Это подкласс виртуальных таблиц Vtab. Виртуальными таблицы называются потому, что они формируются из различных файловых источников в памяти машины и их невозможно записать в отдельный файл стандартного формата баз данных. Между ними следующая разница: Ftab содержит, а Vtab – не содержит поле Shape пространственных данных. При работе с Ftab ГИС обращается к данным, содержащимся в файле с расширением «shp» или к файлам покрытия ArcInfo. Разумеется, ГИС обращается также и к файлам, содержащим семантические данные, и к файлам, обеспечивающим взаимосвязь пространственной и семантической информации (для шейпфайлов это файлы с расширением shx). Таблица Vtab формируется только из файлов, содержащих семантическую информацию в реляционных таблицах. Синтаксис работы с обоими типами виртуальных таблиц практически одинаков, есть различия в создании таблиц. Если мы работаем с таблицей типа Ftab, то для получения существующей таблицы следует применить метод GetFtab к векторному слою (теме): theFtab = theTheme.GetFtab. Для возможности получения интересующих данных из записей таблицы сначала нужно создать объект – значение определённого поля в конкретной записи. Например, создание идентификатора поля Shape выполняется так: theShapeField = theFtab.FindField("Shape"). Мы можем работать с уже существующей таблицей типа Ftab, при этом сделать её редактируемой и создать в ней новые семантические поля для записи результатов. Чтобы сделать таблицу редактируемой, следует ввести в программу следующий оператор: «Идентификатор данной таблицы типа Ftab».SetEditable(true). Далее следует создать пустой список новых полей, например: fields = List.Make, последовательно добавить в него вновь создаваемые поля в соответствии со следующим синтаксисом: fields.Add(Field.Make("Название поля", Тип поля, Общая ширина поля в знаках, Число знаков после запятой)). Для нечисловых полей число знаков после запятой всегда равно нулю. Например: fields.Add(Field.Make("Rasst_km", #FIELD_DECIMAL , 8, 2)). Далее следует добавить вновь созданные поля в таблицу: «Идентификатор данной таблицы типа Ftab».AddFields(«Идентификатор списка полей») и создать идентификаторы для новых полей таблицы. Если Вам необходимо поработать с данными какого-либо векторного слоя проекта, то объект типа Ftab создаётся, как показано выше, путём запроса GetFtab к соответствующей теме. В принципе возможен случай, когда Вам нужно обработать данные каких-либо шейпфайлов или покрытий, которые не образуют тем проекта, но Вам точно известно их местоположение и Вы не хотите добавлять их в качестве слоев в Виды проекта. Такая ситуация может иметь место при обработке большого количества однотипных шейпфайлов или покрытий. В этом случае объект типа Ftab создаётся с помощью метода Make: «Идентификатор создаваемой таблицы Ftab». Make(«Идентификатор Источника данных – объекта типа SrcName»). Последний создаётся в соответствии следующим образом: «Идентификатор объекта типа SrcName» = SrcName.Make («Объект типа строка (String), указывающий полный путь к источнику данных, начиная от диска»). Часто приходится создавать совершенно новый слой. В этом случае объект типа Ftab создаётся с помощью метода MakeNew. Применение этого метода к уже существующей таблице уничтожает все данные, он применяется исключительно для создания новых таблиц: «Идентификатор новой таблицы FTab» = FTab.MakeNew («Идентификатор объекта типа FileName», «Класс пространственных объектов создаваемой таблицы»). Объект типа FileName – это представление имени создаваемого шейпфайла. Он может быть создан с помощью метода Make: «Идентификатор объекта типа FileName». Make («Идентификатор объекта типа FileString»). В свою очередь идентификатор объекта типа FileString представляет собой имя создаваемого файла с полным путём к нему. Другой способ создания объекта типа FileName – с помощью метода AsFileName, который преобразует строку в этот объект. Пространственные объекты могут быть следующих классов: Point, PolyLine, Polygon или MultiPoint. Иногда есть необходимость создания таблицы типа Vtab – просто реляционной таблицы формата dBASE или текстового, в которую будут записаны результаты анализа векторных слоёв Вида. Создание новой таблицы типа Vtab производится методом MakeNew: «Идентификатор создаваемого объекта типа Vtab». MakeNew («Название нового файла типа FileName», «Тип файла создаваемой таблицы»). Тип создаваемого файла может быть dBASE, INFO (формат ArcInfo), или DText (текстовой файл). Рассмотрим ключевые части кода ещё нескольких весьма полезных программ. Часто возникает необходимость создания слоя типа PolyLine по последовательности точечных объектов. Вообще данная программа была создана одним из авторов данного пособия (В.Ю. Третьяковым) для возможности визуализации результатов специальных ледовых наблюдений, но точно такая же ситуация наблюдается при обработке полевых маршрутов. При выполнении маршрута фиксируются точки поворота и точки смены условий (ландшафтных, биогеографических, почвенных таксонов и т.п.). Координаты точек определяются с помощью систем спутниковой навигации. Далее по ним создаётся тема событий, каждая точка которой является отдельным объектом, семантические характеристики которой отражают условия до следующей точки. |