Рефераты - Афоризмы - Словари
Русские, белорусские и английские сочинения
Русские и белорусские изложения

Разработка информационной системы для деканата высшего учебного заведения

Работа из раздела: «Программирование, компьютеры и кибернетика»

/

Введение

Изучение особенностей рельефа морского дна является одной из важнейших задач морской геологии и геофизики, картографии и навигации. Батиметрия - изучение рельефа морского дна, получение данных о глубинах в зоне исследования. Также данный термин может использоваться как совокупность данных о глубинах водного объекта, результат батиметрической съёмки. Подстроение батиметрии применяется для решения множества задач:

Создание подробной карты глубин прибрежной зоны позволяет упростить и обезопасить навигацию морских судов.

Многократные батиметрические съемки позволяют производить исследования динамики рельефа морского дна. Если для обследуемой акватории дополнительно проводить регистрацию параметров волнения и течений, то появляется возможность проследить литодинамику и причины размытия прибрежных участков, а также предсказать тенденцию изменений в будущем. Это может существенно сказаться на экономике региона, если разрушению подвергаются стратегически важные объекты, такие как прибрежные авто и железные дороги или пристани.

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

Батиметрическая сетка необходима для расчёта периодов Сейш и тягуна: длинноволновых колебаний в бухтах и заливах. Данная работа производится обеспечения безопасности судохождения в портах.

Глобальное исследование глубин океанского дна позволяет сформировать полное представление о рельефе земли.

Целью данной работы является проектирование и разработка программного комплекса, направленного на решение задач автоматизации чтения и подготовки исходных батиметрических и вспомогательных данных, построения батиметрических карт, исследования динамики рельефа, экспорта данных для дальнейшей обработки в различные форматы. Основными пользователями системы являются техники и научные сотрудники лабораторий, занимающихся исследованием цунами, волновой динамики и прибрежных течений, также программа может использоваться работниками портов.

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

Импорт батиметрическиз данных из исходных треков, получаемых с картплоттера-эхолота, береговых линий из GPS-навигатора а также загрузка сторонних искусственно созданных данных.

Совмещение, компоновка и редактирование данных, исправление ошибок.

Подготовка данных к отображению и обработке: вычитание высоты прилива и сезонных колебаний уровня моря.

Построение и импорт батиметрических карт.

Построение карт сравнения динамики рельефа.

Экспорт данных в различные форматы.

Создаваемое программное обеспечение опирается на анализ предметной области по методике объектно-ориентированного подхода с использованием рационального унифицированного процесса, предложенного авторами языка UML - американской фирмой Rational [6]. На основе результатов анализа должен быть разработан проект программного обеспечения для компьютеризации перечисленных выше функций обработки батиметрических данных.

Итоговый требуемый результат выполнения работы программный косплекс для автоматизации обработки и визуализации батиметрических данных. Спецификация разделов работы дана в таблице 1.

Таблица 1 - Спецификация разделов работы

Обозначение

Наименование

Приме-чание

4217.02067988.09 - 2599 12

Текст программы

4217.02067988.09 - 2599 13

Описание программы

4217.02067988.09 - 2599 33

Руководство программиста

4217.02067988.09 - 2599 34

Руководство оператора

4217.02067988.09 - 2599 51

Программа и методика испытаний

4217.02067988.09 - 2599 90

Техническое задание

4217.02067988.09 - 2599 92

Организационно - экономическая часть

1. ТЕХНИЧЕСКОЕ ЗАДАНИЕ

1.1. Общие сведения

1.1.1 Полное наименование программного обеспечения и его условное обозначение

Полное наименование - Разработка программного косплекса обработки, визуализации и анализа батиметрических данных.

Условное обозначение - ПО «СОКО».

1.1.2 Шифр темы

Шифр темы - код 4217.02067988.09 - 2599, «Дипломная работа».

1.1.3 Сведения о разработчике и заказчике

Разработчик - студент группы ВТ-51 ГОУВПО «КнАГТУ» Филипп Андреевич Плеханов.

Заказчик - ИМГИГ ДВО РАН, лаборатория Волновой динамики и прибрежных течений, в лице заведующего лабораторией Петра Дмитриевича Ковалёва.

программа модуль сообщение эксплуатация

1.1.4 Перечень документов, на основании которых создается программное обеспечение

Перечень документов, на основании которых создается программное обеспечение:

задание на дипломное проектирование;

техническое задание;

календарный план-график выполнения этапов работы (см. п. 1.5 данного технического задания).

1.1.5 Плановые сроки начала и окончания работы по созданию программного обеспечения

Плановый срок начала работ: 20 февраля 2012 г.

Плановый срок окончания работ: 10 июня 2012 г.

1.1.6 Сведения об источниках и порядке финансирования работ

Данная работа выполняется в рамках дипломного проектирования, финансирование не производится.

1.1.7 Порядок оформления и предъявления заказчику результатов работы по созданию программного обеспечения

При оформлении и предъявлении заказчику результата работы следует придерживаться следующего порядка действий:

После подписания технического задания создается рабочий вариант программного обеспечения.

Работа осуществляется в соответствии с графиком (см. п. 1.5 данного технического задания). По окончании работ программное обеспечение тестируется и передается заказчику для эксплуатации.

Также заказчику передается комплект технической документации, оформленный в соответствии с ГОСТ 34.201 и ЕСПД.

1.2. Назначение и цели создания программного обеспечения

1.2.1 Назначение программного обеспечения

Разрабатываемая система предназначена для автоматизации обработки, визуализации и анализа батиметрических данных.

1.2.2 Цели создания программного обеспечения

Целями разрабатываемой системы являются:

Ускорение, упрощение и автоматизация чтения и подготовки исходных данных из различных форматов.

Построение двумерных и трёхмерных батиметрических карт для анализа и обработки в научных лабораториях и для навигационных служб портов.

Быстрое построение батиметрической карты в процессе её съемки на основе имеющихся данных

Экспорт данных в различные графические, текстовые и двоичные форматы.

1.3. Характеристики предметной области

1.3.1 Краткие сведения о предметной области

Объектом автоматизации является процесс подготовки, визуализации и анализа батиметрических данных.

Проектируемое программное обеспечение используется для автоматизации следующих объектов:

процесс подготовки батиметрических данных, выбора необходимых треков, исправления ошибок, сведения в единое целое;

процесс построения батиметрических карт в различных вариантах;

процесс получения результатов в графическом, анимированном, текстовом или бинарном формате;

Форматы выходных данных определяются стандартами фирм-производителей оборудования, такими как Garmin и Lowrance, а форматы исходных определяются стандартами на батиметрические карты, принятыми в РАН, а также форматами входных данных других программных комплексов, предназначенных для обработки батиметрических данных, таких как ANI. К основным данным предметной области относятся батиметрические треки, треки-пути, полученные с помощью GPS-навигатора, коэффициенты приливных гармоники и гармоник сезонных изменений уровня моря исследуемых областей.

Структура деятельности процессов обработки батиметрических данных изображена на диаграммах объектно-ориентированной модели данной предметной области, выполненных в нотации языка UML (см. приложение 1, рисунки 1.1-1.5) [2,6,9].

1.3.2 Сведения об условиях эксплуатации объекта автоматизации характеристик окружающей среды

Разрабатываемая система предназначена для использования на персональных IBM-совместимых компьютерах с центральным Intel-совместимом процессором с частотой работы не менее 1ГГц, оперативным запоминающим устройством объёмом не менее 512 Мб, свободным дисковым пространством не менее 25 Мб для хранения программного обеспечения и произвольным, но желательно не менее 500 мб объёмом для хранения промежуточных результатов работы. Обязательным условием является наличие манипулятора типа «мышь», SVGA-адаптера, совместимого со стандартом OpenGL, и монитора с разрешением не менее 1024х768 [7].

1.4. Требования к программному обеспечению

1.4.1 Требования к программному обеспечению в целом

Требования к структуре и функционированию программного обеспечения

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

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

К основным входным данным создаваемой системы можно отнести следующие:

батиметрические треки, получаемые посредством съёмки с помощью картплоттера-эхолота;

береговые треки, получаемые с помощью GPS-навигатора;

название региона и его координаты для определения уровня прилива и сезонных изменений уровня моря;

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

Выходными данными разрабатываемой системы являются:

батиметрические карты и карты разницы для выбранных участков в чёрно-белом и цветом варианте;

изображения трёхмерных срезов батиметрических данных, показанные с определённого ракурса;

видео-файлы, представляющие собой съёмку трёхмерной батиметрической карты с различных ракурсов;

батиметрические треки и сетки, готовые для отображения в программе Google Earth;

батиметрические сетки в формате.inf для обработки в программном комплексе ANI.

Требования к численности и квалификации персонала

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

Требования к надежности

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

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

Требования к эргономике и технической эстетике

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

Требования к эксплуатации и техническому обслуживанию

Условия и режим эксплуатации ПО определяются условиями эксплуатации использующихся технических средств. Техническое обслуживание ПО не требуется.

Требования к допустимым площадям для размещения персонала и технических средств ПО, к параметрам сети энергоснабжения определяются требованиями использующегося аппаратного обеспечения.

Требования к защите информации от несанкционированного доступа

Защита информации от несанкционированного доступа не предусмотрена.

Требования по сохранности информации при авариях

Сохранность данных при авариях не гарантируется в случае непредвиденного прерывания работы программы.

Программное обеспечение должно оставаться работоспособным при восстановлении системы после аварий (за исключением случаев, не зависящих от программного обеспечения: повреждение дисковой подсистемы, повреждение файловой структуры).

Требования к защите от влияния внешних воздействий

ПО должно быть устойчивой к наличию и параллельной с ней работе на той же ЭВМ другого программного обеспечения. Разрабатываемая программа должна позволять работать с системой любой рабочей станции, которая подключена к локальной сети предприятия и является частью домена.

Требования к защите от физических внешних воздействий определяются аналогичными требованиями, предъявляемыми к используемому аппаратному обеспечению.

Требования к стандартизации и унификации

ПО должно предоставлять пользователю стандартный графический интерфейс операционной системы Microsoft Windows. Сопутствующая программная документация, поставляемая с программным обеспечением, должна быть оформлена в соответствии со стандартом ЕСПД.

1.4.2 Требования к функциям, выполняемым системой

Разрабатываемое приложение должно обеспечивать выполнение следующих основных функций:

Импорт батиметрическиз данных из исходных треков, получаемых с картплоттера-эхолота, береговых линий из GPS-навигатора а также загрузка сторонних искусственно созданных данных.

Совмещение, компоновка и редактирование данных, исправление ошибок.

Подготовка данных к отображению и обработке: вычитание высоты прилива и сезонных колебаний уровня моря.

Построение и импорт батиметрических карт.

Построение карт сравнения динамики рельефа.

Экспорт данных в различные форматы.

1.4.3 Требования к видам обеспечения

Требования к математическому обеспечению

В основе разрабатываемого программного обеспечения должна находиться корректная математическая модель обработки данных: алгоритмы триангуляции, размытия, вычисления приливов и сезонных изменений уровня должны корректно преобразовывать данные. В случае наличия аппроксимации данных диапазон отклонения должен быть не выше уровня, допустимого стандартами Российской Академии Наук.

Требования к информационному обеспечению

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

Требования к лингвистическому обеспечению

Программное обеспечение и интерфейс пользователя в среде разработки приложений Borland C++ Builder 6 [11, 12]. В своей работе программное обеспечение не требует установки никаких сторонних библиотек, отсутствующих в стандарте Microsoft Windows.

Языком ввода-вывода данных, манипулирования данными, способа организации диалога с пользователем является русский язык.

Требования к программному обеспечению

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

операционная система Microsoft Windows версии не ниже 98;

редактор диаграмм и блок-схем Microsoft Visio;

среда разработки приложений Borland C++ Builder 6;

Raize Components - набор визуальных компонентов для Delphi / C++Builder версии не ниже 4.3.2;

приложение для предвычисления приливов wxtide версии не ниже 4.7;

Требования к техническому обеспечению

Для создания данного программного обеспечения необходимы:

персональный компьютер совместимый с IBM PC с тактовой частотой процессора не ниже 1000 МГц, оперативная память 1024 Мб и более;

накопитель данных со свободным объёмом не менее 3 Гб;

видеокарта и монитор, поддерживающие разрешение 1024*768 точек и выше, с частотой обновления не менее 60 Гц, а также поддерживающие стандарт OpenGL;

устройства ввода клавиатура и манипулятор «мышь» (стандартные);

1.5 Состав и содержание работ по созданию программного обеспечения

Этапы выполнения работ по созданию «Регистрация компьютерной техники» приведены в таблице 1.1.

Таблица 1.1 - Этапы выполнения работ

Этап

Дата

начала

Срок окончания

Минимальный

Максимальный

Разработка и утверждение технического задания

09.02.12

18.02.12

23.02.12

Проектирование системы

21.02.12

11.03.12

14.03.12

Программная реализация

14.03.12

21.04.12

25.04.12

Оформление технической документации (Техническое задание)

25.04.12

02.05.12

03.05.12

Оформление технической документации (Описание программы)

03.05.12

07.05.12

08.05.12

Оформление технической документации (Теоретическое описание)

08.05.12

10.05.12

11.05.12

Оформление технической документации (Текст программы)

11.05.12

13.05.12

14.05.12

Оформление технической документации (Руководство программиста)

14.05.12

16.05.12

17.05.12

Оформление технической документации (Руководство пользователя)

17.05.12

21.05.12

22.05.12

Оформление технической документации (Программа и методика испытаний)

22.05.12

24.05.12

25.05.12

Оформление технической документации (Организационно-экономическая часть)

27.05.12

28.05.12

10.06.12

1.6 Порядок контроля и приемки программного обеспечения

При приёмке системы проводится её тестирование. Порядок и методики тестирования определяются в соответствии с ГОСТ 34.301-89. После завершения тестов и исправления недоработок система сдаётся в опытную эксплуатацию программы.

1.7 Требования к документации

Пояснительная записка оформляется в соответствии с ГОСТ 19.106-78 от 01.01.80 «Требования к программным документам, выполненным печатным способом», ГОСТ 19.101-77 от 01.01.80 «Виды программ и программных документов», ГОСТ 2.301-68 от 01.01.71 «Форматы ЕСКД», ЕСПД ГОСТ 19.001-77 от 1.01.80.

2. ОПИСАНИЕ ПРОГРАММЫ

2.1 Описание программы в целом

2.1.1 Общие сведения

Модель предметной области, использованная для разработки программного обеспечения в нотации UML дана в приложении (см. приложение 1, рисунок 1.1 - 1.5). Схемы выполнения основных функций программы приведены в приложении 1 на рисунках 1.6 - 1.9.

Разработанный программный продукт называется «СОКО». Система функционирует в операционных системах Microsoft Windows любых версий, начиная с Windows 98.

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

Программное обеспечение создано в среде разработки приложений Borland C++ Builder 6 на языке программирования C++. Для исполнения двоичных модулей программного обеспечения не требуется установки дополнительных библиотек.

Главный исполняемый двоичный файл называется Soko.exe.

2.1.2 Функциональное назначение

Созданная система реализует следующие основные функции:

Импорт батиметрическиз данных из исходных треков, получаемых с картплоттера-эхолота;

Импорт береговых линий из GPS-навигатора;

Импорт данных, искусственно созданных с помощью приложения Google Maps;

Наглядное совмещение, компоновка и редактирование данных, исправление ошибок;

Подготовка данных к отображению и обработке: вычитание высоты прилива и сезонных колебаний уровня моря;

Выбор необходимого участка для расчёта посредством введения географических координат прямоугольника, либо в графическом режиме;

Настройка параметров отображения будущей карты: коэффициента пропорциональности высоты, частоты изолиний и других;

Построение и батиметрических карт;

Построение карт сравнения динамики рельефа;

Сохранение готовых карт в виде изображений любого размера;

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

Экспорт данных в различные форматы;

Сохранение текущего состояния системы для дальнейшей обработки.

2.1.3 Описание логической структуры

Программа включает в себя 74 файла кода на языке программирования C++ (модулей) и 35 форм рабочих окон и вспомогательных диалоговых окон.

Перечень модулей и их назначение указаны далее в таблице 2.1.

Таблица 2.1 - Перечень модулей проекта

Название модуля

Назначение модуля

soko.cpp

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

soko_code.cpp

soko_code.h

soko_code.dfm

Основной модуль класса окна, сожержит основные методы, управляющие интерфейсом приложения и связывающие его с другими объектами. Также ссылки на остальные модули.

cursor.cpp

cursor.h

Класс курсора. Сожержит методы получения координат курсора на экране, преобразования их в проекцию OpenGL и обратно.

camera.cpp

camera.h

Класс камеры. Содержит методы упрощённого управления камерой в проекции OpenGL.

3dcontrol.cpp

3dcontrol.h

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

camerasequence.cpp

camerasequence.h

Класс-массив камер, является наследником класса камеры, применяется для создания видеороликов.

chizu.cpp

chizu.h

Основной класс для расчёта батиметрии. Содержит все функции обработки и анализа данных.

averagelevel.cpp

averagelevel.h

Класс, применяемый для расчёта сезонных изменений уровня моря.

dinmas.cpp

dinmas.h

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

doubletable.cpp

doubletable

Класс, позволяющий читать ascii-файл, представляющий собой таблицу из чисел, разделённых табуляцией и создающий на выходе двумерный массив. Применяется для чтения исходных данных.

geometry.cpp

geometry.h

Модуль, содержащий функции, решающий некоторые геометрические задачи, связанные с триангуляцией.

glWindow.cpp

glWindow.h

Класс API-окна, реализующего вывод OpenGL-графики.

lamp.cpp

lamp.h

Класс, упрощяющий работу с освещением в OpenGL.

lotexture.cpp

lotexture.h

Класс, предназначенный для чтения и записи файлов в формате TGA. Применяется как в качестве контейнера текстуры батиметрической карты, так и для сохранения изображений и видео.

material.cpp

material.h

Класс, упрощающий работу с материалами в OpelGL.

mathadv.cpp

mathadv.h

Модуль, содержащий некоторые дополнительные математические функции.

merkator.cpp

merkator.h

Модуль, содержащий фунцции преобразования географических координат в координаты Меркатора и обратно.

point3d.cpp

point3d.h

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

rastrfont.cpp

rastrfont.h

Класс, упрощающий работу с выводом текста в среде OpenGL.

Коды перечисленных выше модулей приведены в пункте 3 настоящей пояснительной записки. Программное обеспечение опирается файловую на базу данных.

2.1.4 Используемые технические средства

Техническое обеспечение для разработчика:

Персональный компьютер совместимый с IBM PC, тактовой частотой процессора не ниже 1000 МГц с объёмом оперативной памяти 1024 Мб и более, свободным дисковое пространством не менее 50 Мб, видеокартой и монитором, поддерживающие разрешение 1024х768 точек (или выше) и частотой обновления не менее 60 Гц, оборудованный стандартными устройствами ввода и вывода (клавиатура, мышь).

2.1.5 Используемые программные средства

Программное обеспечение для разработчика программной системы:

операционная система - Microsoft Windows 98 или более поздняя;

редактор диаграмм и блок-схем Microsoft Visio;

интегрированная среда разработки программных приложений Borland C++ Builder 6;

приложение для предрасчёта приливов wxtide версии 4,7 или выше;

консольное приложение для расчёта триангуляции qdelaunay из группы библиотек Qhull;

консольное приложение Slg2Txt для преобразования бинарных файлов формата slg в текстовый формат, предоставленной фирмой-производителем картплоттеров-эхолотов Lowrance;

консольное приложение tga2avi для преобразования последовательности изображений tga в видеоряд avi.

2.1.6 Вызов и загрузка

Вызов и загрузка программного обеспечения осуществляется запуском исполняемого файла soko.exe. Исполняемый файл должен находится в одной папке с представленными выше консольными приложениями.

2.1.7 Входные данные

Входными данными приложения являются:

1) батиметрические треки, получаемые посредством съёмки с помощью картплоттера-эхолота;

2) береговые треки, получаемые с помощью GPS-навигатора;

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

4) информация о размере обрабатываемого участка, качестве обработки, пределах глубины, позициях камеры, режимах отображения, количестве изолиний и прочие настройки состояния системы.

2.1.8 Выходные данные

Выходными приложения являются:

1) батиметрические карты и карты разницы для выбранных участков в чёрно-белом и цветом варианте;

2) изображения трёхмерных срезов батиметрических данных, показанные с определённого ракурса;

3) видео-файлы, представляющие собой съёмку трёхмерной батимет-рической карты с различных ракурсов;

4) батиметрические треки и сетки, готовые для отображения в про-грамме Google Earth;

5) батиметрические сетки в формате.inf для обработки в программном комплексе ANI.

3. ТЕКСТ ПРОГРАММЫ

3.1 Модуль soko.cpp

/******************************************************

Автор: Плеханов Ф. А.

Назначение: Входная точка программного приложения, содержит функцию WinMain

и запускает главный исполняемый поток.

*******************************************************/

#include <vcl.h>

#pragma hdrstop

//---------------------------------------------------------------------------

USEFORM('soko_code.cpp', BathWin);

//---------------------------------------------------------------------------

using namespace std;

//Аргументы командной строки

extern AnsiString args;

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR Args, int)

{

args=Args;

try

{

Application->Initialize();

Application->CreateForm(__classid(TBathWin), &BathWin);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

catch (...)

{

try

{

throw Exception('');

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

}

return 0;

}

//---------------------------------------------------------------------------

3.2 Модуль dinmas.cpp (выборочно)

/******************************************************

Автор: Плеханов Ф.А.

Назначение: Модуль контейнерных классов

Входные данные: размер контейнера

Выходные данные: готовый к использванию динамический массив

*******************************************************/

#ifndef DINMAS_CPP

#define DINMAS_CPP

#include <vcl>

#include <fstream>

#include <ComCtrls.hpp>

#define SIZETYPE long

//Обычный одномерный динамический массив

export template<typename type>

class dinmas

{

protected: public:

type* data;

public:

SIZETYPE siz;

dinmas();

dinmas(SIZETYPE);

~dinmas();

bool make(SIZETYPE);

void clear();

type& operator[](SIZETYPE);

int bytes();

void insert(type &, int);

void erase(int);

push(type &);

pop();

type& top();

bool SaveToFile(AnsiString);

bool LoadFromFile(AnsiString);

SIZETYPE& size();

#ifndef NOCOPY

operator=(dinmas<type> &);

#endif

};

//Обычный двумерный динамический массив

template<typename type>

class dinmas2d

{

public:

type** data;

SIZETYPE n,m;

bool exists;

dinmas2d();

dinmas2d(SIZETYPE, SIZETYPE);

~dinmas2d();

bool make(SIZETYPE, SIZETYPE);

void clear();

type* operator[](SIZETYPE);

int bytes();

#ifndef NOCOPY

operator=(dinmas2d<type> &);

#endif

};

//Одномерный динамический массив с двойной адресацией, может содержать в себе

//другие динамические массивы

template<typename type>

class smartcont

{

private:

type** graphs;

int _size;

int selected;

public:

smartcont(int);

smartcont();

make(int n);

int &size();

void clear();

type& operator[](int);

type& operator()();

~smartcont();

insert(type &value);

insert();

void copy();

void erase(int);

void erase();

bool select(int);

int SelectedItem();

void MoveUp();

void MoveDown();

};

using namespace std;

template<typename type>dinmas<type>::dinmas()

{

siz=0;

}

template<typename type>dinmas<type>::dinmas(SIZETYPE Size)

{

Beep(2500,100);

siz=0;

make(Size);

}

template<typename type>dinmas<type>::~dinmas()

{

clear();

}

template<typename type> bool dinmas<type>::make(SIZETYPE Size)

{

if(siz>0) clear();

siz=Size;

data=new type[siz];

return 1;

}

template<typename type> void dinmas<type>::clear()

{

if(siz<=0) return;

delete[] data;

siz=0;

}

template<typename type> type& dinmas<type>::operator[](SIZETYPE i)

{

return data[i];

}

template<typename type> int dinmas<type>::bytes()

{

return siz*sizeof(type);

}

template<typename type> void dinmas<type>::insert(type &variable, int position)

{

if(siz==0)

{

make(1);

data[0]=variable;

return;

}

if(position<0) position=0;

if(position>siz) position=siz;

type *buff1, *buff2;

buff1=new type[position];

for(int i=0;i<position;i++)

{

buff1[i]=data[i];

}

buff2=new type[siz-position];

for(int i=0;i<siz-position;i++)

{

buff2[i]=data[position+i];

}

siz++;

make(siz);

for(int i=0;i<position;i++)

{

data[i]=buff1[i];

}

data[position]=variable;

for(int i=0;i<siz-1-position;i++)

{

data[position+1+i]=buff2[i];

}

delete[] buff1;

delete[] buff2;

}

template<typename type> void dinmas<type>::erase(int position)

{

if(position<0) position=0;

if(position>siz-1) position=siz-1;

if(siz==0) return;

type *buff1, *buff2;

buff1=new type[position];

for(int i=0;i<position;i++)

{

buff1[i]=data[i];

}

buff2=new type[siz-position-1];

for(int i=0;i<siz-position-1;i++)

{

buff2[i]=data[position+1+i];

}

siz--;

make(siz);

for(int i=0;i<position;i++)

{

data[i]=buff1[i];

}

for(int i=0;i<siz-position;i++)

{

data[position+i]=buff2[i];

}

delete[] buff1;

delete[] buff2;

}

template<typename type> dinmas<type>::push(type &variable)

{

insert(variable, 0);

}

template<typename type> dinmas<type>::pop()

{

erase(0);

}

template<typename type> type& dinmas<type>::top()

{

return data[0];

}

template<typename type> bool dinmas<type>::SaveToFile(AnsiString FileName)

{

ofstream file(FileName.c_str(), ios::binary);

file.write((char*)&siz,sizeof(siz));

for(int i=0;i<siz;i++)

{

file.write((char*)&data[i],sizeof(type));

}

file.close();

return 1;

}

template<typename type> bool dinmas<type>::LoadFromFile(AnsiString FileName)

{

ifstream file(FileName.c_str(), ios::binary);

file.read((char*)&siz,sizeof(siz));

make(siz);

for(int i=0;i<siz;i++)

{

file.read((char*)&data[i],sizeof(type));

}

file.close();

return 1;

}

template<typename type> SIZETYPE& dinmas<type>::size()

{

return siz;

}

#ifndef NOCOPY

template<typename type> dinmas<type>::operator=(dinmas<type> &object)

{

if(object.size()>0)

{

make(object.size());

for(int i=0;i<size();i++)

{

data[i]=object.data[i];

}

}

}

#endif

template<typename type> dinmas2d<type>::dinmas2d()

{

exists=0;

n=m=0;

}

template<typename type> dinmas2d<type>::dinmas2d(SIZETYPE N, SIZETYPE M)

{

exists=0;

n=m=0;

make(N,M);

}

template<typename type> dinmas2d<type>::~dinmas2d()

{

clear();

}

template<typename type> bool dinmas2d<type>::make(SIZETYPE N, SIZETYPE M)

{

if(N==0 || M==0) return 0;

clear();

n=N; m=M;

data=new type*[n];

for(int i=0;i<n;i++)

{

data[i]=new type[m];

}

exists=1;

return 1;

}

template<typename type> void dinmas2d<type>::clear()

{

if(!exists) return;

for(int i=0;i<n;i++)

{

delete data[i];

}

delete[] data;

exists=0;

}

template<typename type> type* dinmas2d<type>::operator[](SIZETYPE i)

{

return data[i];

}

template<typename type> int bytes()

{

return n*m*sizeof(type);

}

#ifndef NOCOPY

template<typename type> dinmas2d<type>::operator=(dinmas2d<type> &object)

{

if(object.exists)

{

make(object.n,object.m);

for(int i=0;i<n;i++)

{

for(int j=0;j<m;j++)

{

data[i][j]=object.data[i][j];

}

}

exists=1;

}

}

#endif

template<typename type> smartcont<type>::smartcont(int n)

{

_size=selected=0;

make(n);

}

template<typename type> smartcont<type>::smartcont()

{

_size=selected=0;

make(0);

}

template<typename type> smartcont<type>::make(int n)

{

if(_size>0) clear();

_size=n;

if(_size!=0)

{

graphs = new type*[n];

for(int i=0;i<n;i++)

{

graphs[i] = new type[1];

}

}

}

template<typename type> int & smartcont<type>::size()

{

return _size;

}

template<typename type> void smartcont<type>::clear()

{

if(_size<=0) return;

for(int i=0;i<_size;i++)

{

delete[] graphs[i];

}

delete[] graphs;

_size=0;

}

template<typename type> type& smartcont<type>::operator[](int n)

{

if(_size>0 && n<_size)

return *graphs[n];

else

{

MessageBox(NULL,'Ошибка массива','Ошибка',MB_OK|MB_ICONERROR);

}

}

template<typename type> type& smartcont<type>::operator()()

{

if(_size>0 && selected<_size)

return *graphs[selected];

else

{

MessageBox(NULL,'Ошибка массива','Ошибка',MB_OK|MB_ICONERROR);

}

}

template<typename type> smartcont<type>::~smartcont()

{

clear();

}

template<typename type> smartcont<type>::insert(type &value)

{

insert();

graphs[selected]=value;

}

template<typename type> smartcont<type>::insert()

{

if(_size!=0)

{

selected++;

type** buff;

buff = new type*[_size];

for(int i=0;i<_size;i++)

{

buff[i]=graphs[i];

}

_size++;

graphs = new type*[_size];

for(int i=0;i<selected;i++)

{

graphs[i]=buff[i];

}

graphs[selected] = new type[1];

for(int i=selected+1;i<_size;i++)

{

graphs[i]=buff[i-1];

}

delete[] buff;

select(selected);

}

else

{

make(1);

selected=0;

select(selected);

}

}

template<typename type> void smartcont<type>::copy()

{

insert();

*graphs[selected]=*graphs[selected-1];

select(selected);

}

template<typename type> void smartcont<type>::erase(int n)

{

int buff=selected;

select(n);

erase();

select(selected);

}

template<typename type> void smartcont<type>::erase()

{

if(_size==0) return;

delete[] graphs[selected];

type** buff;

buff = new type*[_size];

for(int i=0;i<_size;i++)

{

buff[i]=graphs[i];

}

_size--;

graphs = new type*[_size];

for(int i=0;i<selected;i++)

{

graphs[i]=buff[i];

}

for(int i=selected;i<_size;i++)

{

graphs[i]=buff[i+1];

}

delete[] buff;

if(selected>0)

select(selected-1);

}

template<typename type> bool smartcont<type>::select(int item)

{

if(_size==0) return 0;

selected=item;

return 1;

}

template<typename type> int smartcont<type>::SelectedItem()

{

return selected;

}

template<typename type> void smartcont<type>::MoveUp()

{

if(selected<1) return;

type* buff;

buff=graphs[selected-1];

graphs[selected-1]=graphs[selected];

graphs[selected]=buff;

selected--;

}

template<typename type> void smartcont<type>::MoveDown()

{

if(selected>_size-1) return;

type* buff;

buff=graphs[selected+1];

graphs[selected+1]=graphs[selected];

graphs[selected]=buff;

selected++;

}

#endif

3.3 Модуль lotexture

/******************************************************

Автор: Плеханов Ф.А.

Назначение: Класс для чтения файлов изображений в формате TGA и преобразования

в готовые для использования в среде OpenGL текстуры, также позволяет сохранять

изображения в формате TGA.

Входные данные: файл TGA, настройки чтения

Выходные данные: ID текстуры в OpenGL

*******************************************************/

3.3.1 Заголовочный файл lotexture.h

#ifndef LOTEXTURE_H

#define LOTEXTURE_H

#include <vcl.h>

#include <windowsx.h>

#include <winuser.h>

#include <gl>

#include <glu>

#include 'mathadv.h'

#include 'dinmas.cpp'

#define LT_IGNORE_ERROR 1

using namespace std;

#pragma pack (push, 1)

//Заголовок TGA-файла

struct TgaHeader

{

byte idLength;

byte colormapType;

byte imageType;

unsigned __int16 colormapIndex;

unsigned __int16 colormapLength;

byte colormapEntrySize;

unsigned __int16 xOrigin;

unsigned __int16 yOrigin;

unsigned __int16 width;

unsigned __int16 height;

byte pixelSize;

byte imageDesc;

};

#pragma pack (pop)

//Структуры точнек в формате TGA

struct RGBApixel

{

GLubyte r,g,b,a;

RGBApixel(GLubyte, GLubyte, GLubyte, GLubyte);

RGBApixel();

void GetPixel(GLubyte &, GLubyte &, GLubyte &, GLubyte &);

RGBApixel ToBGRA();

};

struct RGBpixel

{

GLubyte r,g,b;

RGBpixel(GLubyte, GLubyte, GLubyte);

GBpixel();

void GetPixel(GLubyte &, GLubyte &, GLubyte &);

RGBpixel ToBGR();

RGBApixel ToBGRA();

};

//Основной класс текстуры

class texture

{

protected:

bool exsist; //суествует

bool binded; //уже применяется

int width; //ширина

int height; //высота

int RealWidth; //ширина, приближённая к степени двойки

int RealHeight; //высота, приближённая к степени двойки

int PixelsQnt; //количество точек

int ID; //идентификационный номер текстуры в OpelGL

float hcoeff; //отношение height к RealHeight

float wcoeff; //отношение width к RealWidth

public:

//поля

dinmas<RGBApixel> imageData; //массив точек

//методы

//исправление целочисленного цвета,

//если он выходит из диапазона 0-255

GLubyte correct(float);

//копировать текстуру

void operator=(texture &);

//задать одну точку целыми числами

void SetPixel(int, int, GLubyte, GLubyte, GLubyte, GLubyte);

//задать одну точку числами с плавающей точкой

void SetPixelf(int, int, float, float, float, float);

//получить одну точку

void GetPixel(int, int, GLubyte &, GLubyte &, GLubyte &, GLubyte &);

texture(); //конструктор

//выделение памяти c проверкой на степень двойки

bool MakeArray(int, int);

//выделение памяти в обход проверки на степень двойки

bool MakeArraySimple(unsigned int, unsigned int);

//применение текстуры

bool BindTexture(unsigned int, bool, bool);

//сохранение в TGA

bool SaveToTGA(AnsiString);

//чтение из TGA

bool LoadFromTGA(AnsiString, unsigned int, bool, bool);

~texture(); //деструктор

void DeleteArray(); //очистить массив

void UnBind(); //отменить текстуру

//Методы получения величин

unsigned int GetWidth();

unsigned int GetHeight();

unsigned int GetRealWidth();

unsigned int GetRealHeight();

unsigned int GetPixelsQnt();

unsigned int GetID();

bool GetExsist();

bool GetBinded();

float GetWCoeff();

float GetHCoeff();

float GetWCoeffF();

float GetHCoeffF();

//Методы установки величин

void PutWidth(unsigned int);

void PutHeight(unsigned int);

void PutRealWidth(unsigned int);

void PutRealHeight(unsigned int);

void PutPixelsQnt(unsigned int);

void PutID(unsigned int);

void PutExsist(bool);

void PutBinded(bool);

void PutWCoeff(float);

void PutHCoeff(float);

};

#endif

3.3.2 Реализация lotexture.cpp

#ifndef LOTEXTURE_CPP

#define LOTEXTURE_CPP

#include 'lotexture.h'

using namespace std;

RGBApixel::RGBApixel(GLubyte R, GLubyte G, GLubyte B, GLubyte A)

{

r=R; g=G; b=B; a=A;

}

RGBApixel::RGBApixel()

{

r=0; g=0; b=0; a=255;

}

void RGBApixel::GetPixel(GLubyte &R, GLubyte &G, GLubyte &B, GLubyte &A)

{

R=r; G=g; B=b; A=a;

}

RGBApixel RGBApixel::ToBGRA()

{

return RGBApixel(b,g,r,a);

}

RGBpixel::RGBpixel(GLubyte R, GLubyte G, GLubyte B)

{

r=R; g=G; b=B;

}

RGBpixel::RGBpixel()

{

r=0; g=0; b=0;

}

void RGBpixel::GetPixel(GLubyte &R, GLubyte &G, GLubyte &B)

{

R=r; G=g; B=b;

}

RGBpixel RGBpixel::ToBGR()

{

return RGBpixel(b,g,r);

}

RGBApixel RGBpixel::ToBGRA()

{

return RGBApixel(b,g,r,255);

}

GLubyte texture::correct(float x)

{

if(x<=0) return 0;

if(x>=1) return 255;

return floor(255*x);

}

void texture::operator=(texture &object)

{

exsist=object.exsist;

}

void texture::SetPixel(int Col, int Row, GLubyte r, GLubyte g, GLubyte b, GLubyte a)

{

int i=Row*RealWidth+Col;

if(i<PixelsQnt) imageData[i]=RGBApixel(r,g,b,a);

}

void texture::SetPixelf(int Col, int Row, float r, float g, float b, float a)

{

int i=Row*RealWidth+Col;

if(i<PixelsQnt) imageData[i]=RGBApixel(correct(r),correct(g),correct(b),correct(a));

}

void texture::GetPixel(int Col, int Row, GLubyte &r, GLubyte &g, GLubyte &b, GLubyte &a)

{

int i=Row*RealWidth+Col;

if(i<PixelsQnt)

{

imageData[i].GetPixel(r,g,b,a);

}

}

texture::texture()

{

exsist=0; binded=0;

}

bool texture::MakeArray(int w, int h)

{

if(w==0 || h==0) return 0;

width=w; height=h;

#ifdef LT_IGNORE_ERROR

{

RealWidth =NearestPow2(w);

RealHeight=NearestPow2(h);

wcoeff=1-1.*(RealWidth -width )/RealWidth ;

hcoeff=1-1.*(RealHeight-height)/RealHeight;

}

#else

{

RealWidth=width;

RealHeight=height;

hcoeff=wcoeff=1;

}

#endif

PixelsQnt=RealWidth*RealHeight;

if(imageData.make(PixelsQnt))

{

exsist=1;

return 1;

}

else

{

ShowMessage('Ошибка');

return 0;

}

}

bool texture::MakeArraySimple(unsigned int w, unsigned int h)

{

if(w==0 || h==0) return 0;

width=w; height=h;

RealWidth=width;

RealHeight=height;

hcoeff=wcoeff=1;

PixelsQnt=RealWidth*RealHeight;

if(imageData.make(PixelsQnt))

{

exsist=1;

return 1;

}

else

{

ShowMessage('Ошибка');

return 0;

}

}

bool texture::BindTexture(unsigned int TexID, bool Interpolation, bool Multiply)

{

if(!exsist) return 0;

ID=TexID;

glBindTexture(GL_TEXTURE_2D, TexID);

if (Interpolation)

{

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

}

else

{

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

}

if (Multiply)

{

glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);

}

else

{

glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP);

glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP);

}

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, RealWidth, RealHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData.data);

binded=1;

return 1;

}

bool texture::SaveToTGA(AnsiString fileName)

{

if(!exsist) return 0;

TgaHeader hdr;

memset ( &hdr, ' ', sizeof ( hdr ) );

hdr.imageType = 2; // unencoded image

hdr.width = width;

hdr.height = height;

hdr.pixelSize = 32;

FILE *pFile;

pFile=fopen(fileName.c_str(), 'wb');

fwrite(&hdr, sizeof(hdr),1,pFile);

int WritedPxlQnt=width*height;

RGBApixel *temp = new RGBApixel[WritedPxlQnt];

int i=0;

for(int row=0;row<height;row++)

{

for(int col=0;col<width;col++)

{

temp[i]=imageData[row*RealWidth+col].ToBGRA();

i++;

}

}

fwrite(temp, WritedPxlQnt*4, 1, pFile);

fclose(pFile);

free ( temp );

return 1;

}

bool texture::LoadFromTGA(AnsiString fileName, unsigned int TexID, bool Interpolation, bool Multiply)

{

TgaHeader hdr;

FILE *pFile;

pFile=fopen(fileName.c_str(), 'rb');

if(pFile==NULL) return 0;

fread(&hdr, sizeof(hdr),1,pFile);

if(!(hdr.pixelSize==32 || hdr.pixelSize==24) || hdr.imageType!=2) return 0;

MakeArray(hdr.width,hdr.height);

int ReadPxlQnt=hdr.width*hdr.height;

if(hdr.pixelSize==32)

{

RGBApixel *temp = new RGBApixel[ReadPxlQnt];

fread(temp, ReadPxlQnt*4, 1, pFile);

int i=0;

for(int row=0;row<height;row++)

{

for(int col=0;col<width;col++)

{

imageData[row*RealWidth+col]=temp[i].ToBGRA();

i++;

}

}

free(temp);

}

if(hdr.pixelSize==24)

{

RGBpixel *temp = new RGBpixel[ReadPxlQnt];

fread(temp, ReadPxlQnt*3, 1, pFile);

int i=0;

for(int row=0;row<height;row++)

{

for(int col=0;col<width;col++)

{

imageData[row*RealWidth+col]=temp[i].ToBGRA();

i++;

}

}

free(temp);

}

fclose(pFile);

BindTexture(TexID,Interpolation,Multiply);

return 1;

}

texture::~texture()

{

DeleteArray();

}

void texture::DeleteArray()

{

if(!exsist) return;

imageData.clear();

exsist=0;

}

void texture::UnBind()

{

if(!binded) return;

glBindTexture(GL_TEXTURE_2D, ID);

char data[4]='1111';

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

binded=0;

}

unsigned int texture::GetWidth()

{

return width;

}

unsigned int texture::GetHeight()

{

return height;

}

unsigned int texture::GetRealWidth()

{

return RealWidth;

}

unsigned int texture::GetRealHeight()

{

return RealHeight;

}

unsigned int texture::GetPixelsQnt()

{

return PixelsQnt;

}

unsigned int texture::GetID()

{

return ID;

}

bool texture::GetExsist()

{

return exsist;

}

bool texture::GetBinded()

{

return binded;

}

float texture::GetWCoeff()

{

return wcoeff;

}

float texture::GetHCoeff()

{

return hcoeff;

}

float texture::GetWCoeffF()

{

return 1-1.*(RealWidth-width-2)/RealWidth;

}

float texture::GetHCoeffF()

{

return 1-1.*(RealHeight-height-2)/RealHeight;

}

void texture::PutWidth(unsigned int w)

{

width=w;

}

void texture::PutHeight(unsigned int h)

{

height=h;

}

void texture::PutRealWidth(unsigned int rw)

{

RealWidth=rw;

}

void texture::PutRealHeight(unsigned int rh)

{

RealHeight=rh;

}

void texture::PutPixelsQnt(unsigned int pq)

{

PixelsQnt=pq;

}

void texture::PutID(unsigned int id)

{

ID=id;

}

void texture::PutExsist(bool ex)

{

exsist=ex;

}

void texture::PutBinded(bool bd)

{

binded=bd;

}

void texture::PutWCoeff(float wc)

{

wcoeff=wc;

}

void texture::PutHCoeff(float hc)

{

hcoeff=hc;

}

#endif

3.4 Модуль chizu

/******************************************************

Автор: Плеханов Ф.А.

Назначение: Класс батиметрии. Производит всю обработку батиметрических данных

и построение батиметрической сетки.

Входные данные: исходные треки, множество настроек, таких как частота изолиний

Выходные данные: трёхмерная батиметрическая карта с изолиниями и подписями

*******************************************************/

3.4.1 Заголовочный файл chizu.h

#ifndef CHIZU_H

#define CHIZU_H

#include <vector>

#include <map>

#include <list>

//Пользовательские модули

#include 'merkator.h'

#include 'doubletable.h'

#include 'spline.h'

#include 'lotexture.h'

#include 'material.h'

#include 'geometry.h'

#include 'mathadv.h'

using namespace std;

//Константы максимума и минимума

#define MAX 9999999999

#define MIN -9999999999

//Цветовые константы

#define COLOR_RED 0

#define COLOR_GREEN 1

#define COLOR_BLUE 2

//Стандартизация исходных

AnsiString ReplaceComma(AnsiString);

//Получение строки из числа

AnsiString PointDouble(double);

//Получние строки с градусами и минутами из градусов с нецелой частью

AnsiString DegToDegMin(double);

//Получение строки с градусами,

//минутами и секундами из градусов с нецелой частью

AnsiString DegToCoord(double);

//Получение строки из градусов с нецелой частью, добавляет букву E или N

AnsiString DegToDegMinI(double, bool);

//Получние строки с градусами и минутами из градусов с нецелой частью,

//добавляет букву E или N

AnsiString DegToDegMinSecI(double, bool);

//Получение градусов с нецелой частью из градусов, минут и секунд

double DegMinSecToDouble(double, double, double);

//Установка заголовка окна, виртуальная функция, реализуемая

//в модуле, где расположено окно

void SetTitle(AnsiString msg);

//Функуция для тестирования

void Debag(AnsiString msg);

//Структура 'трёхмерная точка'

struct point3D

{

double x,y,z; //координаты

bool ataru(point3D &); //проверка на совпадение с другой

};

//Структура 'узел батиметрии', основанная на трёхмерной точке

struct vertex:point3D

{

double nx,ny,nz; //нормали

double b; //буфер для размытия

bool e; //существует ли

};

//Попадает ли трёхмерная точка в треугольник

bool InTriangle(point3D &, point3D &, point3D &, point3D &);

//Существует ли такой треугольник

bool CorrectTria(point3D &, point3D &, point3D &, double);

//Универсальная функция расчёта цвета по глубине

double countColor(double, double, double, unsigned __int8, bool, bool);

//Точка батиметрического трека

struct BathPoint

{

point3D r,m; //Точка в географических и нормализованных к 1 координатах

unsigned int t; //Сколько миллисекунд прошло с начала трека

double tide; //Высота прилива в данной точке

BathPoint(); //Конструктор

};

//Изолиния

struct isoline

{

point3D a,b; //начало и конец

bool zero; //не показывать

isoline(); //конструктор

void put(double &, double &, double &, //задать

double &, double &, double &, bool &);

void view(int &); //показать

};

//цифра-подпись

struct figure:public point3D

{

bool exists; //показывать

double length; //размер

isoline *line; //к какой изолинии привязана

char str[8]; //что отображать

int strl; //длина строки

double angle; //угол разворота

void activate(double, double); //'прилепить' к изолинии

void view(int); //показать

};

//Структура треугольника для триангуляции

struct OneTri

{

//порядковые номера точек в качестве вершин

unsigned int a,b,c;

};

//основной класс батиметрии

class bath:public texture

{

private:

//поля

double f; //уровень для расчёта изолиний

bool zero; //являетмя ли уровень текущей изолинии нулевым

float material_color[4]; //массив цвета материала

dinmas<OneTri> tri; //набор треугольников для триангуляции

//буферная изолиния для работы функции расчёта изолиний

isoline line;

//методы

bool triangulation();

public:

//поля

dinmas<BathPoint> q; //батиметрический трек

dinmas2d<vertex> p; //батиметрическая сетка

dinmas2d<double> blurBuff; //буфферный массив для размытия

TDateTime startDate; //дата начала съёмки

TDateTime endDate; //дата конца съёмки

vector<isoline> iso; //вектор изолиний

dinmas2d<figure> figures; //массив цифр

dinmas<double> *isolist; //список уровней изолиний

double d; //шаг сетки

double sclxy; //коэффициент нормализации долготы и широты

double sclz; //коэффициент нормализации высоты

double cfx; //коэффициент нормализации долготы

double cfy; //коэффициент нормализации широты

//суммарное математическое отклонение данных от исходных в

//результате сглаживания и расчёта равномерной сетки

double dev;

double tmpz; //нормализованная высота для расчёта цвета

double isoHaba; //частота изолиний

double isolineSize; //толщина изолинии

point3D min; //минимум, нормализованный к 1

point3D max; //максимум, нормализованный к 1

point3D rmn; //минимум в географических координатах

point3D rmx; //максимум в географических координатах

//число строк в текстуре для доступа к ячейке одномерной

//текстуры по двум координатам

int k;

int blurCount; //количество проходов размытия

int texNum; //ID текстуры в среде OpenGL

int fighaba; //Расстояние между подписями

int diffBlur; //количество проходов размытия для сравнения батиметрий

int step; //пропуск кратных узлов сетки для ускорения отображения

AnsiString Filename; //имя файла

bool tex; //отображение текстуры средставми OpenGL

bool varIso; //переменный список изолиний

bool lighting; //освещение включено

bool rt; //режим отображения без пропусков

bool viewPoints; //отображать треки

bool net; //отображать сетку

bool counted; //сетка уже расчитана

bool isolines; //отображать изолинии

bool viewRelief; //отображать рельеф

bool visible; //отображать сетку

bool hideFar; //скрыть удалённые участки

//скрыть участки, выходящие за границу минимума и максимума

bool hideUpLimit;

bool needRecount; //требуется перерасчёт

bool difference; //является разницей между двумя батиметриями

bool blackAndWhite; //отображать в чёрнобелых тонах

bool slg; //является прочитанным slg-файлом

bool hasTide; //прилив вычтен

//методы

//Конструктор

bath();

//Чтение точек из ASCII-файла

bool LoadPoints(AnsiString, bool, bool);

//Чтение трека из slg-файла

bool LoadSlg(DoubleTable &, AnsiString);

//Очистить батиметрию

bool MakeEmpty(int);

//Расчёт прилива

void CountTide(cubic_spline &);

//Вычисление минимума и максимума

void ReCountMinMax();

//Вычисление только минимума

double ReCountMin();

//Расчёт батиметрической сетки

bool CountNet(int, point3D, point3D, double, double, double, double,

double, int, double, double, int, int, int, dinmas<double> *, bool);

//размытие

void blur(int);

//расчёт отклонения

void deviation();

//Расчёт цвета для выбранного узла сетки

inline __fastcall void CountColor(int &, int &);

//Перерасчёт цвета

void ReCountColor();

//Вычисление нормалей

inline __fastcall void CountNorm(int &, int &);

//Конструктор (в виде вызываемой функции)

void DefConstr();

//Вывод одного узла сетки на экран

void OneVertex(int &, int &);

//Вывод всей батиметрии

void view();

//Вывот треков

void ViewPoints();

//Линейная интерполяция

double cf(double &, double &, double &, bool);

//Создание одной изолинии

void makeLine(int &, int &);

//Отображение цифр-подписей

void ViewFigures(int);

//Расчёт одного слоя изолиний

void countOneIso(double);

//Расчёт всех изолиний

void countIso(double, dinmas<double> *, bool);

//Расчёт цифр-подписей

void CountFigures(int);

//Отображение изолиний

void viewIso();

//Удаление расчитанной батиметрической сетки

void EraseNet();

//Вычисление разницы между двумя батиметриями

bool GetDiffer(bath &, bath &, int, double, int);

//Вычисление

bool GetDifferPoints(bath &, double);

//Наложение текстуры

bool ReBindTexture();

//Сохранение сетки в ASCII-формате

bool SaveNet(AnsiString);

//Сохранение данных в формате.inf и.dat для программы ANI

bool SaveANI(AnsiString, double);

//Сохранение набора точек для отображения в прорамме Google Chrome

bool SavePointsGoogle(AnsiString);

//Сохранение трека для отображения в прорамме Google Chrome

bool SaveTrack(AnsiString);

//Сохранение набора точек в ASCII-формате в географических коордиантах

bool SavePoints(AnsiString);

//Сохранение набора точек в ASCII-формате в координатах меркатора

bool SavePointsMer(AnsiString);

//Сохранение батиметрической карты для отображения в прорамме Google Chrome

bool SaveNetGoogle(AnsiString, int);

//Получение всех статических переменных батиметрии из другой

void setConstantPreset(bath &);

//Полное копирование батиметрии из другой

operator=(bath &);

};

//Точка данных нивелирования

struct LevelPoint

{

double l; //расстояние от берега

double h; //высота над уровнем моря

//Координаты начальной точки

double x;

double y;

double z;

};

//Класс для работы с нивелированием

struct Levelling

{

dinmas<LevelPoint> levelPoint; //массив точек местности

};

#endif

3.4.2 Реализация chizu.cpp

#ifndef CHIZU_CPP

#define CHIZU_CPP

#include 'chizu.h'

using namespace std;

//Константы малентких чисел

#define SM 0.00000001

#define SM2 0.1

//Смещение изолинии вверх

#define UE 0.001

//Коэффициенты для раскрашивания шкалы

#define RC 4.3

#define GC 1.8

#define BC 1.2

#define RD 0.0

#define GD 0.0

#define BD 0.0

//Эпсилон отклонения

#define EPS 0.0001

AnsiString ReplaceComma(AnsiString str)

{

for(int i=1;i<=str.Length();i++)

{

if(str[i]==',')

str[i]='.';

}

return str;

}

AnsiString PointDouble(double x)

{

return AnsiString(x);

}

AnsiString DegToDegMin(double x)

{

int deg=floor(x);

double min=(x-deg)*60;

return AnsiString(deg)+'° '+PointDouble(min)+''';

}

AnsiString DegToCoord(double x)

{

int deg=floor(x);

int min=floor(fabs(x-deg)*60);

nt sec=floor(fabs((fabs(x-deg)*60)-min)*60);

int ms=floor(100*((fabs(fabs(fabs(x-deg)*60)-min)*60)-sec));

if(ms==99)

{

ms=0;

sec++;

if(sec==59 || sec==60)

{

sec=0;

min++;

if(min==59 || min==60)

{

min=0;

deg++;

}

}

}

if(min==0 && sec==0 && ms==0)

{

return AnsiString(deg)+':';

}

if(min!=0 && sec==0 && ms==0)

{

return AnsiString(deg)+':'+AnsiString(min)+''';

}

if(min!=0 && sec!=0 && ms==0)

{

return AnsiString(deg)+':'+

AnsiString(min)+'''+AnsiString(sec)+''';

}

return AnsiString(deg)+':'+AnsiString(min)+

'''+AnsiString(sec)+'''+AnsiString(ms);

}

AnsiString DegToDegMinI(double x, bool E)

{

int deg=floor(x);

int min=round((x-deg)*60);

return AnsiString(deg)+'° '+AnsiString(min)+'' '+((E)?'E':'N');

}

AnsiString DegToDegMinSecI(double x, bool E)

{

int deg=floor(x);

int min=floor((x-deg)*60);

int sec=floor((((x-deg)*60)-min)*60);

AnsiString secs=AnsiString(sec)+'' ';

return AnsiString(deg)+'° '+AnsiString(min)+

'' '+((sec!=0)?(secs):AnsiString(''))+((E)?'E':'N');

}

double DegMinSecToDouble(double deg, double min, double sec)

{

return deg+(min/60.)+(sec/3600.);

}

bool point3D::ataru(point3D &p)

{

return (fabs(p.x-x)<EPS) && (fabs(p.y-y)<EPS) && (fabs(p.z-z)<EPS);

}

bool InTriangle(point3D &a, point3D &b, point3D &c, point3D &p)

{

double pl1, pl2, pl3;

pl1 = (a.x - p.x)*(b.y - a.y)-(b.x - a.x)*(a.y - p.y);

pl2 = (b.x - p.x)*(c.y - b.y)-(c.x - b.x)*(b.y - p.y);

pl3 = (c.x - p.x)*(a.y - c.y)-(a.x - c.x)*(c.y - p.y);

if ((pl1 >= 0 && pl2 >= 0 && pl3 >= 0) ||

(pl1 <= 0 && pl2 <= 0 && pl3 <= 0))

{

return true;

}

return false;

}

bool CorrectTria(point3D &a, point3D &b, point3D &c, double max)

{

if (sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))>max)

{

return 0;

}

else

{

if (sqrt(sqr(a.x-c.x)+sqr(a.y-c.y))>max)

{

return 0;

}

else

{

if (sqrt(sqr(b.x-c.x)+sqr(b.y-c.y))>max)

{

return 0;

}

else

{

return 1;

}

}

}

}

double countColor(double z, double A, double B,

unsigned __int8 color, bool difference, bool blackAndWhite)

{

if(!difference)

{

if(!blackAndWhite)

if(B<=A) return 0;

switch(color)

{

case COLOR_RED:

if(z<0)

return exp(-sqr((z)*(4.3/(-A))));

else

return exp(-sqr((z+B*(-1))*(2/(((1.6)*(B))))));

break;

case COLOR_GREEN:

if(z<0)

return exp(-sqr((z)*(1.8/(-A))));

else

return exp(-sqr((z+B*(-0.42))*(2/(((0.85)*(B))))));

break;

case COLOR_BLUE:

if(z<0)

return exp(-sqr((z)*(1.2/(-A))));

else

return exp(-sqr((z+B*(1.2))*(2/(((1.9)*(B))))));

break;

}

}

else

{

double ret=1-(z-A)/(B-A);

if(ret<0) return 0;

if(ret>1) return 1;

return ret;

}

}

else

{

if(!blackAndWhite)

{

switch(color)

{

case COLOR_RED:

return exp(-pow((z-A-(B-A)*2)*(2./(((3.3)*(B-A)))),10));

break;

case COLOR_GREEN:

return exp(-pow((z-A-(B-A)*0)*(2./(((5)*(B-A)))),4));

break;

case COLOR_BLUE:

return exp(-pow((z-A-(B-A)*(-2))*(2./(((3.5)*(B-A)))),8));

break;

}

}

else

{

double ret=z/((B-A)/8)+B;

if(ret<0) return 0;

if(ret>1) return 1;

return ret;

}

}

}

BathPoint::BathPoint()

{

t=0;

tide=0;

}

isoline::isoline(){};

void isoline::put(double &x1, double &y1, double &z1,

double &x2, double &y2, double &z2, bool &Zero)

{

a.x=x1;

a.y=y1;

a.z=z1;

b.x=x2;

b.y=y2;

b.z=z2;

zero=Zero;

}

void isoline::view(int &isolineSize)

{

if(zero)

{

glLineWidth(2*isolineSize);

glColor4d(0,0,0,1);

}

else

{

glLineWidth(1*isolineSize);

glColor4d(0,0,0,0.5);

}

glBegin(GL_LINES);

glVertex3d(a.x,a.y,a.z+UE);

glVertex3d(b.x,b.y,b.z+UE);

glEnd();

}

void figure::activate(double figh, double h)

{

if(length<figh)

{

x=line->a.x;

y=line->a.y;

z=line->a.z;

double r;

polar(line->b.x-line->a.x, line->b.y-line->a.y, r, angle);

angle=deg(angle);

exists=1;

AnsiString s=FormatFloat('0.00',h);

if(s[s.Length()]=='0')s=s.SubString(1,s.Length()-1);

if(s[s.Length()]=='0')s=s.SubString(1,s.Length()-2);

int i;

for(i=0;i<s.Length()&&i<8;i++)

{

str[i]=s[i+1];

}

strl=i;

}

else

{

exists=0;

}

}

void figure::view(int size)

{

glEnd();

if(!exists) return;

glEnable(GL_TEXTURE_2D);

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

glBindTexture(GL_TEXTURE_2D,0);

PutMaterial(1,1,1,0,0,0,0,0,0,0,120);

glColor3f(1,1,1);

double figsize=size*0.001875;

#define FIGCF 1.0

#define FIGDS 0.5

#define FIGSM 0.0005

double k=0;

glPushMatrix();

glTranslatef(x,y,z);

glRotatef(angle,0,0,1);

for(int i=0;i<strl;i++)

{

if(str[i]>='0' && str[i]<='9') k=str[i]-'0';

if(str[i]=='.' || str[i]==',') k=10;

if(str[i]=='-') k=11;

glBegin(GL_QUADS);

glTexCoord2f(k/16.0,0);

glVertex3d(-figsize*0.5+figsize*FIGDS*i,-figsize*0.5*FIGCF,i*FIGSM);

glTexCoord2f(k/16.0,1);

glVertex3d(-figsize*0.5+figsize*FIGDS*i,figsize*0.5*FIGCF,i*FIGSM);

glTexCoord2f((k+1)/16.0,1);

glVertex3d(figsize*0.5+figsize*FIGDS*i,figsize*0.5*FIGCF,i*FIGSM);

glTexCoord2f((k+1)/16.0,0);

glVertex3d(figsize*0.5+figsize*FIGDS*i,-figsize*0.5*FIGCF,i*FIGSM);

glEnd();

}

glDisable(GL_TEXTURE_2D);

glDisable(GL_BLEND);

glPopMatrix();

}

bool bath::triangulation()

{

ofstream file('input.txt');

if(!file.is_open()) return 0;

file<<'2 RBOX s 4 W0 c D2n';

file<<q.size()<<'n';

char buffer [50];

SetTitle('СОКО - сохранение точек');

for(int i=0;i<q.size();i++)

{

sprintf(buffer, '%.19f %.19fn', q[i].m.x, q[i].m.y);

file<<buffer;

}

file.close();

SetTitle('СОКО - расчёт триангуляции');

system(AnsiString('qdelaunay TI input.txt s i Qt TO output.txt').c_str());

//ShowMessage('');

SetTitle('СОКО - чтение треугольников');

ifstream file2('output.txt');

//if(!file2.is_open()) return 0;

unsigned int n=0,x;

file2>>n;

tri.make(n);

for(int i=0;i<n;i++)

{

file2>>x;

tri[i].a=x;

file2>>x;

tri[i].b=x;

file2>>x;

tri[i].c=x;

}

SetTitle('СОКО - треугольники прочитаны');

file2.close();

remove('input.txt');

remove('output.txt');

SetTitle('СОКО - временные файлы удалены');

return 1;

}

bath::bath()

{

DefConstr();

}

bool bath::LoadPoints(AnsiString FileName, bool merkator, bool minus)

{

DefConstr();

fstream file0(AnsiString(FileName+'.dat').c_str());

file0.close();

ifstream file(FileName.c_str());

char tmp[30];

double val;

int size=0;

if(!file.is_open()) return 0;

char name[32];

_splitpath(FileName.c_str(),NULL,NULL,name,NULL);

Filename=name;

SetTitle('СОКО - Чтение ASCII');

vector<double> buff;

while (!file.eof())

{

file>>val;

buff.push_back(val);

size++;

}

q.make(size/3);

file.close();

int i=0, coord=0;

for (int j=0;j<size-1;j++)

{

switch(coord)

{

case 0:

q[i].r.x=buff[j];

coord=1;

break;

case 1:

q[i].r.y=buff[j];

coord=2;

if(merkator) MerToGeo(q[i].r.x,q[i].r.y);

break;

case 2:

q[i].r.z=(-minus*2+1)*buff[j];

coord=0;

if(q[i].r.x<min.x) min.x=q[i].r.x;

if(q[i].r.x>max.x) max.x=q[i].r.x;

if(q[i].r.y<min.y) min.y=q[i].r.y;

if(q[i].r.y>max.y) max.y=q[i].r.y;

if(q[i].r.z<min.z) min.z=q[i].r.z;

if(q[i].r.z>max.z) max.z=q[i].r.z;

i++;

break;

}

}

SetTitle('СОКО');

return 1;

}

bool bath::LoadSlg(DoubleTable &table, AnsiString name)

{

#define FEET_TO_M 0.3048

int c=0,n=1,num;

double depth=0;

SetTitle('СОКО - Чтение slg');

for(int i=1;i<table.d.m;i++)

{

if(table.d[13][i]!=0) c++;

}

if(c>=table.d.m) return 0;

q.make(c);

c=0;

int i;

for(i=1;i<table.d.m;i++)

{

if(table.d[13][i]!=0)

{

if(c>0)

{

q[c-1].r.z=-(depth/n)*FEET_TO_M;

if(q[c-1].r.x<min.x) min.x=q[c-1].r.x;

if(q[c-1].r.x>max.x) max.x=q[c-1].r.x;

if(q[c-1].r.y<min.y) min.y=q[c-1].r.y;

if(q[c-1].r.y>max.y) max.y=q[c-1].r.y;

if(q[c-1].r.z<min.z) min.z=q[c-1].r.z;

if(q[c-1].r.z>max.z) max.z=q[c-1].r.z;

}

q[c].r.x=table.d[13][i];

q[c].r.y=table.d[14][i];

q[c].t=table.d[21][i];

MerToGeo(q[c].r.x,q[c].r.y);

depth=table.d[3][i];

n=1;

c++;

}

else

{

n++;

depth+=table.d[3][i];

}

}

q[c-1].r.z=-(depth/n)*FEET_TO_M;

if(q[c-1].r.x<min.x) min.x=q[c-1].r.x;

if(q[c-1].r.x>max.x) max.x=q[c-1].r.x;

if(q[c-1].r.y<min.y) min.y=q[c-1].r.y;

if(q[c-1].r.y>max.y) max.y=q[c-1].r.y;

if(q[c-1].r.z<min.z) min.z=q[c-1].r.z;

if(q[c-1].r.z>max.z) max.z=q[c-1].r.z;

Filename=name;

SetTitle('СОКО');

slg=1;

return 1;

}

bool bath::MakeEmpty(int length)

{

q.make(length);

return 1;

}

void bath::CountTide(cubic_spline &spl)

{

if(slg)

{

if((double)startDate==0.0) return;

for(int i=0;i<q.size();i++)

{

if(hasTide)

q[i].tide=spl.f(startDate+q[i].t/86400000.0);

else

q[i].tide=0;

}

}

else

{

if((double)startDate==0.0 || (double)endDate==0.0) return;

TDateTime current;

for(int i=0;i<q.size();i++)

{

if(hasTide)

q[i].tide=spl.f((double)startDate+((double)endDate-

(double)startDate)*(i/(double)q.size()));

else

q[i].tide=0;

}

}

}

void bath::ReCountMinMax()

{

min.x=MAX;

max.x=MIN;

min.y=MAX;

max.y=MIN;

min.z=MAX;

max.z=MIN;

for(int i=0;i<q.size();i++)

{

if(q[i].r.x<min.x) min.x=q[i].r.x;

if(q[i].r.x>max.x) max.x=q[i].r.x;

if(q[i].r.y<min.y) min.y=q[i].r.y;

if(q[i].r.y>max.y) max.y=q[i].r.y;

if(q[i].r.z<min.z) min.z=q[i].r.z;

if(q[i].r.z>max.z) max.z=q[i].r.z;

}

needRecount=0;

}

double bath::ReCountMin()

{

double min=MAX;

for(int i=0;i<q.size();i++)

{

if(q[i].r.z<min) min=q[i].r.z;

}

return min;

}

bool bath::CountNet(int TexNum, point3D Min, point3D Max, double Sclxy,

double Sclz, double Cfx, double Cfy, double D, int N, double rad,

double isoHABA, int maskBlurCount, int FigHaba, int IsolineSize,

dinmas<double> *Isolist, bool VarIso)

{

fighaba=FigHaba;

sclxy=Sclxy;

sclz=Sclz;

min=Min;

max=Max;

d=D;

texNum=TexNum;

isoHaba=isoHABA;

isolineSize=IsolineSize;

isolist=Isolist;

varIso=VarIso;

height=cfy*N;

width=cfx*N;

for(int i=0;i<q.size();i++)

{

q[i].m.x=sclxy*(q[i].r.x-min.x-(max.x-min.x)/2);

q[i].m.y=sclxy*(q[i].r.y-min.y-(max.y-min.y)/2);

q[i].m.z=sclz*(q[i].r.z+q[i].tide*(hasTide)-min.z-(max.z-min.z)/2);

}

rmn.z=sclz*(min.z-min.z-(max.z-min.z)/2);

rmx.z=sclz*(max.z-min.z-(max.z-min.z)/2);

SetTitle('СОКО - триангуляция');

triangulation();

SetTitle('СОКО - триангуляция завершена');

counted=0;

if(!p.make(width,height)) return 0;

SetTitle('СОКО - создана сетка');

if(!blurBuff.make(width,height))

{

SetTitle('СОКО - не создана буферная сетка');

return 0;

}

else

{

SetTitle('СОКО - создана буферная сетка');

}

if(!MakeArray(height,width)) return 0;

SetTitle('СОКО - создана текстура');

double ls,hs,ls2,l,mn,lm;

if(max.y-min.y>max.x-min.x)

lm=SphereLenght(min.x, min.y, min.x, max.y);

else

lm=SphereLenght(min.x, min.y, max.x, min.y);

int km=0;

SetTitle('СОКО - обнуление сетки');

for(int j=0;j<width;j++)

{

for(int i=0;i<height;i++)

{

p[i][j].x=-cfx/2+d*i;

p[i][j].y=-cfy/2+d*j;

p[i][j].z=0;

p[i][j].b=p[i][j].z;

blurBuff[i][j]=p[i][j].z;

p[i][j].e=0;

}

}

int ia,ib,ja,jb;

double ta=0,tb=0,tc=1,td=0;

SetTitle('СОКО - расчёт треугольников');

for(int k=0;k<tri.size();k++)

{

ia=floor((MinFrom3(q[tri[k].a].m.x,

q[tri[k].b].m.x,q[tri[k].c].m.x)+cfx/2)/d);

ib=ceil((MaxFrom3(q[tri[k].a].m.x,

q[tri[k].b].m.x,q[tri[k].c].m.x)+cfx/2)/d);

ja=floor((MinFrom3(q[tri[k].a].m.y,

q[tri[k].b].m.y,q[tri[k].c].m.y)+cfy/2)/d);

jb=ceil((MaxFrom3(q[tri[k].a].m.y,

q[tri[k].b].m.y,q[tri[k].c].m.y)+cfy/2)/d);

if(ia<0 || ja<0 || ib>height || jb>width) continue;

if(!CorrectTria(q[tri[k].a].m,

q[tri[k].b].m,q[tri[k].c].m,rad/lm)) continue;

planeSet(

q[tri[k].a].m.x,q[tri[k].b].m.x,q[tri[k].c].m.x,

q[tri[k].a].m.y,q[tri[k].b].m.y,q[tri[k].c].m.y,

q[tri[k].a].m.z,q[tri[k].b].m.z,q[tri[k].c].m.z,

ta,tb,tc,td);

for(int j=ja;j<jb;j++)

{

for(int i=ia;i<ib;i++)

{

if(InTriangle(q[tri[k].a].m,

q[tri[k].b].m,q[tri[k].c].m,p[i][j])

&& tri[k].a>=0 && tri[k].a<q.size()

&& tri[k].b>=0 && tri[k].b<q.size()

&& tri[k].b>=0 && tri[k].c<q.size()

)

{

p[i][j].z=(-ta*p[i][j].x-tb*p[i][j].y-td)/tc;

p[i][j].b=p[i][j].z;

blurBuff[i][j]=p[i][j].z;

p[i][j].e=1;

}

}

}

}

if(maskBlurCount==0)

{

SetTitle('СОКО - расчёт цвета и нормалей');

for(int j=0;j<width;j++)

{

for(int i=0;i<height;i++)

{

if(p[i][j].e)

{

CountColor(i,j);

CountNorm(i,j);

}

}

}

}

else

{

blur(maskBlurCount);

}

exsist=1;

counted=1;

SetTitle('СОКО - наложение текстуры');

BindTexture(texNum,1,0);

if(maskBlurCount==0)

{

countIso(isoHaba,isolist,varIso);

deviation();

}

SetTitle('СОКО');

return 1;

}

void bath::blur(int times)

{

for(int k=0;k<times;k++)

{

for(int j=1;j<width-1;j++)

{

for(int i=1;i<height-1;i++)

{

if(

p[i-1][j+1].e && p[i ][j+1].e && p[i+1][j+1].e &&

p[i-1][j ].e && p[i ][j ].e && p[i+1][j ].e &&

p[i-1][j-1].e && p[i ][j-1].e && p[i+1][j-1].e

)

{

blurBuff[i][j]=(

(0.0625)*p[i-1][j+1].z+(0.125)*

p[i ][j+1].z+(0.0625)*p[i+1][j+1].z+

(0.125 )*p[i-1][j ].z+(0.25 )*

p[i ][j ].z+(0.125 )*p[i+1][j ].z+

(0.0625)*p[i-1][j-1].z+(0.125)*

p[i ][j-1].z+(0.0625)*p[i+1][j-1].z

);

}

else

{

blurBuff[i][j]=p[i][j].z;

}

}

}

for(int j=1;j<width-1;j++)

{

for(int i=1;i<height-1;i++)

{

if(

p[i-1][j+1].e && p[i ][j+1].e && p[i+1][j+1].e &&

p[i-1][j ].e && p[i ][j ].e && p[i+1][j ].e &&

p[i-1][j-1].e && p[i ][j-1].e && p[i+1][j-1].e

)

{

p[i][j].z=blurBuff[i][j];

(

(0.0625)*blurBuff[i-1][j+1]+(0.125 )*

blurBuff[i ][j+1]+(0.0625)*blurBuff[i+1][j+1]+

(0.125 )*blurBuff[i-1][j ]+(0.25 )*

blurBuff[i ][j ]+(0.125 )*blurBuff[i+1][j ]+

(0.0625)*blurBuff[i-1][j-1]+(0.125 )*

blurBuff[i ][j-1]+(0.0625)*blurBuff[i+1][j-1]

);

}

else

{

p[i][j].z=blurBuff[i][j];

}

if(k==times-1)

{

CountColor(i,j);

CountNorm(i,j);

}

}

SetTitle('СОКО - размытие '+

AnsiString(FormatFloat(100*(double(k+1)/double(times)),2))+'%');

}

SetTitle('СОКО');

}

exsist=1;

BindTexture(texNum,1,0);

blurCount+=times;

countIso(isoHaba,isolist,varIso);

deviation();

SetTitle('СОКО');

}

void bath::deviation()

{

return;

SetTitle('СОКО - расчёт ошибки');

double sz=0, srz=0, z;

int nx,ny;

for(int i=0;i<q.size();i++)

{

nx=floor((q[i].m.x+cfx/2)/d);

ny=floor((q[i].m.y+cfy/2)/d);

if(nx>=height-2 || ny>=width-2) continue;

if(!p[nx][ny].e || !p[nx][ny+1].e ||

!p[nx+1][ny+1].e || !p[nx+1][ny].e) continue;

z=bilinear(p[nx][ny].z,p[nx][ny+1].z,

p[nx+1][ny].z,p[nx+1][ny+1].z,p[nx][ny].x,

p[nx+1][ny].x,p[nx][ny].y,p[nx][ny+1].y,

q[i].m.x,q[i].m.y);

sz+=fabs(q[i].m.z);

srz+=fabs(z);

}

dev=100*fabs(sz-srz)/srz;

}

inline __fastcall void bath::CountColor(int &i, int &j)

{

tmpz=p[i][j].z/sclz+min.z+(max.z-min.z)/2;

if(difference)

{

imageData[i*RealWidth+j].r=

255*countColor(tmpz,-2,2,0,1,blackAndWhite);

imageData[i*RealWidth+j].g=

255*countColor(tmpz,-2,2,1,1,blackAndWhite);

imageData[i*RealWidth+j].b=

255*countColor(tmpz,-2,2,2,1,blackAndWhite);

}

else

{

imageData[i*RealWidth+j].r=

255*countColor(tmpz,min.z,max.z,0,0,blackAndWhite);

imageData[i*RealWidth+j].g=

255*countColor(tmpz,min.z,max.z,1,0,blackAndWhite);

imageData[i*RealWidth+j].b=

255*countColor(tmpz,min.z,max.z,2,0,blackAndWhite);

}

}

void bath::ReCountColor()

{

SetTitle('СОКО - расчёт цвета');

for(int j=1;j<width-1;j++)

{

for(int i=1;i<height-1;i++)

{

if(p[i][j].e) CountColor(i,j);

}

}

exsist=1;

SetTitle('СОКО - наложение текстуры');

BindTexture(texNum,1,0);

SetTitle('СОКО');

}

inline __fastcall void bath::CountNorm(int &i, int &j)

{

if(i>0 && j>0)

{

VecNormD(

p[i][j].x, p[i][j].y, p[i][j].z,

p[i][j-1].x, p[i][j-1].y, p[i][j-1].z,

p[i-1][j-1].x, p[i-1][j-1].y, p[i-1][j-1].z,

p[i][j].nx, p[i][j].ny, p[i][j].nz, 0) ;

}

}

void bath::DefConstr()

{

//rt=1;

width=1;

height=1;

counted=0;

tex=1;

viewPoints=1;

net=0;

//fb=0;

step=1;

PixelsQnt=0;

isolines=1;

dev=0;

//dif=0;

viewRelief=1;

min.x=MAX; max.x=MIN; min.y=MAX; max.y=MIN; min.z=MAX; max.z=MIN;

visible=1;

hideFar=1;

hideUpLimit=0;

needRecount=0;

difference=0;

blackAndWhite=0;

slg=0;

hasTide=1;

startDate=0;

endDate=0;

lighting=1;

}

void bath::OneVertex(int &i, int &j)

{

//glColor3d(1,1,1);

//material1.view(1,1,1,0,1,1,1,0,0,0,60);

if(tex)

{

glTexCoord2f(((1.*j/width))*wcoeff,((1.*i/height))*hcoeff);

}

else

{

k=i*RealWidth+j;

material_color[0]=imageData[k].r/255.0;

material_color[1]=imageData[k].g/255.0;

material_color[2]=imageData[k].b/255.0;

glColor3fv(material_color);

glMaterialfv(GL_FRONT_AND_BACK,

GL_AMBIENT_AND_DIFFUSE, material_color);

}

glNormal3d(p[i][j].nx,p[i][j].ny,p[i][j].nz);

glVertex3d(p[i][j].x,p[i][j].y,p[i][j].z);

}

void bath::view()

{

if(!counted) return;

if(viewRelief)

{

exsist=0;

if(tex)

{

glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D,texNum);

PutMaterial(1,1,1,0,0,0,0,0,0,0,120);

}

int tc=0;

int stepBuff;

if(!rt)

{

stepBuff=step;

step=1;

}

glColor3d(1,1,1);

PutMaterial(1,1,1,0,0.5,0.5,0.5,0,0,0,60);

if(lighting) glEnable(GL_LIGHTING);

if(step<height && step<width)

{

for(int i=1;i<height-step;i+=step)

{

for(int j=1;j<width-step;j+=step)

{

if(

((hideFar && p[i][j].e && p[i][j+step].e &&

p[i+step][j+step].e && p[i+step][j].e) || !hideFar )

&&

((hideUpLimit && p[i][j].z<rmx.z && p[i][j].z>rmn.z) ||

!hideUpLimit || difference )

)

{

if(!net) glBegin(GL_QUADS); else glBegin(GL_LINE_LOOP);

OneVertex(i,j);

OneVertex(i,j+step);

OneVertex(i+step,j+step);

OneVertex(i+step,j);

glEnd();

}

}

}

}

if(lighting) glDisable(GL_LIGHTING);

glColor3d(0,0,0);

if(!rt)

{

step=stepBuff;

}

if(tex)

{

glDisable(GL_TEXTURE_2D);

}

}

if(isolines) viewIso();

}

void bath::ViewPoints()

{

if(viewPoints)

{

glPointSize(1);

glBegin(GL_POINTS);

for(int i=0;i<q.size();i++)

{

glVertex3d(q[i].r.x,q[i].r.y,q[i].r.z+q[i].tide*(hasTide));

}

glEnd();

}

}

double bath::cf(double &s, double &e, double &f, bool revert)

{

return fabs((revert)-((f-s)/(e-s)));

}

void bath::makeLine(int &i, int &j)

{

if(

(p[i][j].z< f && p[i][j+1].z>=f && p[i+1][j+1].z>=f && p[i+1][j].z>=f)||

(p[i][j].z>=f && p[i][j+1].z< f && p[i+1][j+1].z< f && p[i+1][j].z< f))

{

line.put(p[i][j].x,p[i][j].y+d*cf(p[i][j].z,p[i][j+1].z,f,0),f

,p[i][j].x+d*cf(p[i][j].z,p[i+1][j].z,f,0),p[i][j].y,f,zero);

iso.push_back(line);

//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));

return;

}

if(

(p[i][j].z>=f && p[i][j+1].z< f && p[i+1][j+1].z>=f && p[i+1][j].z>=f)||

(p[i][j].z< f && p[i][j+1].z>=f && p[i+1][j+1].z< f && p[i+1][j].z< f))

{

line.put(p[i][j].x,p[i][j].y+d*cf(p[i][j].z,p[i][j+1].z,f,0),f

,p[i][j].x+d*cf(p[i][j+1].z,p[i+1][j+1].z,f,0),p[i][j].y+d,f,zero);

iso.push_back(line);

//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));

return;

}

if(

(p[i][j].z>=f && p[i][j+1].z>=f && p[i+1][j+1].z< f && p[i+1][j].z>=f)||

(p[i][j].z< f && p[i][j+1].z< f && p[i+1][j+1].z>=f && p[i+1][j].z< f))

{

line.put(p[i][j].x+d*cf(p[i+1][j+1].z,p[i][j+1].z,f,1),p[i][j].y+d,f

,p[i][j].x+d,p[i][j].y+d*cf(p[i+1][j+1].z,p[i+1][j].z,f,1),f,zero);

iso.push_back(line);

//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));

return;

}

if(

(p[i][j].z>=f && p[i][j+1].z>=f && p[i+1][j+1].z>=f && p[i+1][j].z< f)||

(p[i][j].z< f && p[i][j+1].z< f && p[i+1][j+1].z< f && p[i+1][j].z>=f))

{

line.put(p[i][j].x+d*cf(p[i][j].z,p[i+1][j].z,f,0),p[i][j].y,f

,p[i][j].x+d,p[i][j].y+d*cf(p[i+1][j].z,p[i+1][j+1].z,f,0),f,zero);

iso.push_back(line);

//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));

return;

}

if(

(p[i][j].z< f && p[i][j+1].z< f && p[i+1][j+1].z>=f && p[i+1][j].z>=f)||

(p[i][j].z>=f && p[i][j+1].z>=f && p[i+1][j+1].z< f && p[i+1][j].z< f))

{

line.put(p[i][j].x+d*cf(p[i][j].z,p[i+1][j].z,f,0),p[i][j].y,f

,p[i][j].x+d*cf(p[i][j+1].z,p[i+1][j+1].z,f,0),p[i][j].y+d,f,zero);

iso.push_back(line);

//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));

return;

}

if(

(p[i][j].z< f && p[i][j+1].z>=f && p[i+1][j+1].z>=f && p[i+1][j].z< f)||

(p[i][j].z>=f && p[i][j+1].z< f && p[i+1][j+1].z< f && p[i+1][j].z>=f))

{

line.put(p[i][j].x,p[i][j].y+d*cf(p[i][j].z,p[i][j+1].z,f,0),f

,p[i][j].x+d,p[i][j].y+d*cf(p[i+1][j].z,p[i+1][j+1].z,f,0),f,zero);

iso.push_back(line);

//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));

return;

}

if(

(p[i][j].z>=f && p[i][j+1].z< f && p[i+1][j+1].z>=f && p[i+1][j].z< f)||

(p[i][j].z< f && p[i][j+1].z>=f && p[i+1][j+1].z< f && p[i+1][j].z>=f))

{

line.put(p[i][j].x,p[i][j].y+d*cf(p[i][j].z,p[i][j+1].z,f,0),f

,p[i][j].x+d*cf(p[i][j].z,p[i+1][j].z,f,0),p[i][j].y,f,zero);

iso.push_back(line);

//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));

line.put(p[i][j].x+d*cf(p[i+1][j+1].z,p[i][j+1].z,f,1),p[i][j].y+d,f

,p[i][j].x+d,p[i][j].y+d*cf(p[i+1][j+1].z,p[i+1][j].z,f,1),f,zero);

iso.push_back(line);

//isom.insert(pair<pair<int,int>,isoline>(pair<int,int>(i,j),line));

return;

}

}

void bath::ViewFigures(int size)

{

//ViewValue('-125.4',0,0,0.05,270);

if(!figures.exists) return;

glBegin(GL_LINES);

for(int i=0;i<fighaba;i++)

{

for(int j=0;j<fighaba;j++)

{

figures[i][j].view(size);

}

}

glEnd();

}

void bath::countOneIso(double k)

f=sclz*(k-min.z-(max.z-min.z)/2);

for(int i=1;i<height-1;i++)

{

for(int j=1;j<width-1;j++)

{

if(

(p[i][j].e && p[i][j+1].e && p[i+1][j+1].e && p[i+1][j].e)

&&

((hideUpLimit && p[i][j].z<rmx.z && p[i][j].z>rmn.z)

|| !hideUpLimit)

)

makeLine(i,j);

}

}

}

void bath::countIso(double IsoHaba, dinmas<double> *Isolist, bool VarIso)

{

isoHaba=IsoHaba;

varIso=VarIso;

isolist=Isolist;

if(p.n==0) return;

double k;

iso.clear();

SetTitle('СОКО - расчёт изолиний');

zero=1;

if(!difference)

{

double min=ReCountMin();

if(varIso)

{

for(k=0;k>min;k-=isoHaba)

{

countOneIso(k);

zero=0;

}

for(k=isoHaba;k<max.z;k+=isoHaba)

{

countOneIso(k);

}

}

else

{

for(int i=0;i<isolist->size();i++)

{

zero=(isolist->operator [](i)==0);

countOneIso(isolist->operator [](i));

}

}

}

else

{

for(k=0;k>-4;k-=isoHaba)

{

countOneIso(k);

zero=0;

}

for(k=isoHaba;k<4;k+=isoHaba)

{

countOneIso(k);

}

}

CountFigures(fighaba);

}

void bath::CountFigures(int figh)

{

//return;

if(p.n==0 || iso.size()==0) return;

SetTitle('СОКО - расчёт цифр');

fighaba=figh;

figures.make(fighaba,fighaba);

double l;

for(int i=0;i<fighaba;i++)

{ //0.86602540378443864676372317075294

for(int j=0;j<fighaba;j++)

{

if(cfx<cfy)

{

figures[i][j].x=-cfx/2+(cfx*i/fighaba);

if(i%2!=0)

figures[i][j].y=-cfy/2+(cfy*j/fighaba);

else

figures[i][j].y=-cfy/2+0.5*cfy/fighaba+(cfy*j/fighaba);

}

else

{

figures[i][j].y=-cfy/2+(cfy*j/fighaba);

if(j%2!=0)

figures[i][j].x=-cfx/2+(cfx*i/fighaba);

else

figures[i][j].x=-cfx/2+0.5*cfx/fighaba+(cfx*i/fighaba);

}

figures[i][j].length=MAX;

for(int k=0;k<iso.size();k++)

{

l=sqrt(sqr(iso[k].a.x-figures[i][j].x)+

sqr(iso[k].a.y-figures[i][j].y));

if(l<figures[i][j].length)

{

figures[i][j].length=l;

figures[i][j].line=&iso[k];

}

}

figures[i][j].activate(

((cfx>cfy)?(cfy/fighaba):(cfx/fighaba))/2,-

(figures[i][j].line->a.z/sclz+min.z+

(max.z-min.z)/2)*(difference?-1:1));

}

}

SetTitle('СОКО');

}

void bath::viewIso()

{

//glEnable(GL_BLEND);

for(int i=0;i<iso.size();i++)

{

iso[i].view(isolineSize);

}

//glDisable(GL_BLEND);

}

void bath::EraseNet()

{

if(!counted) return;

counted=0;

}

bool bath::GetDiffer(bath &src, bath &dst,

int TexNum, double isoHABA, int DiffBlur)

{

SetTitle('СОКО - расчёт разницы');

//DefConstr();

setConstantPreset(src);

difference=1;

Filename=src.Filename+'-'+dst.Filename;

//dif=1;

sclxy=src.sclxy;

sclz=src.sclz;

cfx=src.cfx;

cfy=src.cfy;

min=src.min;

max=src.max;

rmn=src.rmn;

rmx=src.rmx;

diffBlur=DiffBlur;

d=src.d;

texNum=TexNum;

height=src.width;

width=src.height;

isoHaba=isoHABA;

counted=0;

p.make(width,height);

blurBuff.make(width,height);

MakeArray(height,width);

for(int j=0;j<width;j++)

{

for(int i=0;i<height;i++)

{

p[i][j].x=src.p[i][j].x;

p[i][j].y=src.p[i][j].y;

p[i][j].z=

sclz*(

((src.p[i][j].z/src.sclz+src.min.z+(src.max.z-src.min.z)/2)-

(dst.p[i][j].z/dst.sclz+dst.min.z+(dst.max.z-dst.min.z)/2))

-src.min.z-(src.max.z-src.min.z)/2);

p[i][j].b=p[i][j].z;

blurBuff[i][j]=p[i][j].z;

//p[i][j].s=(src.p[i][j].s+dst.p[i][j].s)/2.;

p[i][j].e=src.p[i][j].e&&dst.p[i][j].e;

if(diffBlur==0)

{

CountColor(i,j);

CountNorm(i,j);

}

}

}

exsist=1;

counted=1;

blur(diffBlur);

BindTexture(texNum,1,0);

countIso(isoHaba,isolist,varIso);

return 1;

bool bath::GetDifferPoints(bath &dst, double Range)

{

SetTitle('СОКО - расчёт разницы');

double rx=Range*(max.x-min.x)/SphereLenght(min.x, min.y, max.x, min.y);

double ry=Range*(max.y-min.y)/SphereLenght(min.x, min.y, min.x, max.y);

vector<BathPoint> q1;

for(int i=0;i<q.size();i++)

{

for(int j=0;j<dst.q.size();j++)

{

if((fabs(q[i].r.x-dst.q[j].r.x)<=rx) &&

(fabs(q[i].r.y-dst.q[j].r.y)<=ry))

{

q1.push_back(q[i]);

goto kk;

}

}

kk:

if(i%1000==0)

SetTitle('СОКО - расчёт разницы для ''+Filename+'' '+

AnsiString(FormatFloat(100*(double(i+1)/double(q.size())),2))+'%');

}

q.make(q1.size());

for(int i=0;i<q1.size();i++)

{

q[i]=q1[i];

}

SetTitle('СОКО');

return 1;

}

bool bath::ReBindTexture()

{

if(counted) exsist=1;

return BindTexture(texNum,1,0);

}

bool bath::SaveNet(AnsiString FileName)

{

ofstream file(FileName.c_str());

if(!file.is_open()) return 0;

SetTitle('СОКО - сохранение сетки');

char buffer [10];

int n;

file<<'0 ';

for(int i=0;i<height;i++)

{

sprintf(buffer, '%.13f', p[i][0].x/sclxy+min.x+(max.x-min.x)/2);

file<<buffer<<' ';

}

file<<'n';

for(int j=0;j<width;j++)

{

sprintf(buffer, '%.13f', p[0][j].y/sclxy+min.y+(max.y-min.y)/2);

file<<buffer<<' ';

for(int i=0;i<height;i++)

{

sprintf(buffer, '%.13f', p[i][j].z/sclz+min.z+(max.z-min.z)/2);

file<<buffer<<' ';

}

file<<'n';

}

file.close();

return 1;

}

bool bath::SaveANI(AnsiString FileName, double minutesStep)

{

SetTitle('СОКО - сохранение сетки');

FILE *pFile;

pFile=fopen(AnsiString(FileName.SubString(

1,FileName.Length()-4)+'.dat').c_str(), 'wb');

if(pFile==0) return 0;

float value;

for(int j=0;j<width;j++)

{

for(int i=0;i<height;i++)

{

if(p[i][j].e)

{

value=-p[i][j].z/sclz+min.z+(max.z-min.z)/2;

}

else

{

value=10001;

}

fwrite(&value, sizeof(float), 1, pFile);

}

}

fclose(pFile);

char buff[256];

char drive[3],direc[256],name[128],ext[8];

_splitpath(FileName.c_str(),drive,direc,name,ext);

ofstream file(FileName.c_str());

CharToOem(Filename.c_str(),buff);

file<<buff<<'n';

file<<'Created by SOKOn';

CharToOem(name,buff);

file<<buff<<'.datn4n2n';

file<<width<<' '<<height<<'n';

file<<'0 0 0 0n';

file<<ReplaceComma(FormatFloat('0.000000',min.z)).c_str()<<

' '<<ReplaceComma(FormatFloat('0.000000',max.z)).c_str()<<' mn';

file<<ReplaceComma(minutesStep).c_str()<<' '<<

ReplaceComma(minutesStep).c_str()<<' ' 0n';

file<<'0 '<<DegToCoord(min.y).c_str()<<' '<<DegToCoord(min.x).c_str();

file<<'n0n';

file.close();

return 1;

}

bool bath::SavePointsGoogle(AnsiString FileName)

{

ofstream file(FileName.c_str());

if(!file.is_open()) return 0;

SetTitle('СОКО - сохранение точек');

char buffer [20];

file<< AnsiString(

'<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://www.opengis.net/kml/2.2' xmlns:gx='http://www.google.com/kml/ext/2.2' xmlns:kml='http://www.opengis.net/kml/2.2' xmlns:atom='http://www.w3.org/2005/Atom'><Document><name>'+

Filename+'.kml</name>n'+

'<StyleMap id='msn_shaded_dot'><Pair><key>normal</key><styleUrl>#sn_shaded_dot</styleUrl></Pair><Pair><key>highlight</key><styleUrl>#sh_shaded_dot</styleUrl></Pair></StyleMap><Style id='sn_shaded_dot'><IconStyle><scale>0.2</scale><Icon><href>http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png</href></Icon></IconStyle><ListStyle></ListStyle></Style><Style id='sh_shaded_dot'><IconStyle><scale>0.236364</scale><Icon><href>http://maps.google.com/mapfiles/kml/shapes/shaded_dot.png</href></Icon></IconStyle><ListStyle></ListStyle></Style>'+

'<Folder><name>'+Filename+'</name><open>1</open>n').c_str();

for(int i=0;i<q.size();i++)

{

file<<'<Placemark><styleUrl>#msn_shaded_dot</styleUrl><Point><altitudeMode>relativeToGround</altitudeMode><coordinates>';

sprintf(buffer, '%.13f', q[i].r.x);

file<<buffer<<',';

sprintf(buffer, '%.13f', q[i].r.y);

file<<buffer<<',';

sprintf(buffer, '%.13f', q[i].r.z+q[i].tide*(hasTide));

file<<buffer<<'n';

file<<'n</coordinates></Point></Placemark>';

}

file<<'</Folder></Document></kml>';

file.close();

return 1;

}

bool bath::SaveTrack(AnsiString FileName)

{

ofstream file(FileName.c_str());

if(!file.is_open()) return 0;

SetTitle('СОКО - сохранение трека');

char buffer [20];

file<<'<?xml version='1.0' encoding='UTF-8'?>n<kml xmlns='http://www.opengis.net/kml/2.2' xmlns:gx='http://www.google.com/kml/ext/2.2' xmlns:kml='http://www.opengis.net/kml/2.2' xmlns:atom='http://www.w3.org/2005/Atom'>n<Document>n<name>';

file<<'track';

file<<'</name>n<Style id='sn_ylw-pushpin'>n<IconStyle>n<scale>n1.1</scale>n<Icon>n<href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>n</Icon>n<hotSpot x='20' y='2' xunits='pixels' yunits='pixels'/>n</IconStyle>n</Style>n<StyleMap id='msn_ylw-pushpin'>n<Pair>n<key>normal</key>n<styleUrl>#sn_ylw-pushpin</styleUrl>n</Pair>n<Pair>n<key>highlight</key>n<styleUrl>#sh_ylw-pushpin</styleUrl>n</Pair>n</StyleMap>n<Style id='sh_ylw-pushpin'>n<IconStyle>n<scale>n1.3</scale>n<Icon>n<href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>n</Icon>n<hotSpot x='20' y='2' xunits='pixels' yunits='pixels'/>n</IconStyle>n</Style>n<Placemark>n<name>';

file<<'track';

file<<'</name>n<styleUrl>#msn_ylw-pushpin</styleUrl>n<LineString>n<tessellate>1</tessellate>n<coordinates>n';

for(int i=0;i<q.size();i++)

{

sprintf(buffer, '%.13f', q[i].r.x);

file<<buffer<<',';

sprintf(buffer, '%.13f', q[i].r.y);

file<<buffer<<',0 ';

}

file<<'</coordinates>n</LineString>n</Placemark>n</Document>n</kml>n';

file.close();

return 1;

}

bool bath::SavePoints(AnsiString FileName)

{

ofstream file(FileName.c_str());

if(!file.is_open()) return 0;

SetTitle('СОКО - сохранение точек');

char buffer [20];

for(int i=0;i<q.size();i++)

{

sprintf(buffer, '%.13f', q[i].r.x);

file<<buffer<<' ';

sprintf(buffer, '%.13f', q[i].r.y);

file<<buffer<<' ';

sprintf(buffer, '%.13f', -q[i].r.z-q[i].tide*(hasTide));

file<<buffer<<'n';

}

file.close();

return 1;

}

bool bath::SavePointsMer(AnsiString FileName)

{

ofstream file(FileName.c_str());

if(!file.is_open()) return 0;

SetTitle('СОКО - сохранение точек');

char buffer [20];

double x,y;

for(int i=0;i<q.size();i++)

{

x=q[i].r.x;

y=q[i].r.y;

GeoToMer(x,y);

sprintf(buffer, '%i', (int)x);

file<<buffer<<' ';

sprintf(buffer, '%i', (int)y);

file<<buffer<<' ';

sprintf(buffer, '%.13f', -q[i].r.z-q[i].tide*(hasTide));

file<<buffer<<'n';

}

file.close();

return 1;

}

bool bath::SaveNetGoogle(AnsiString FileName, int ScaleZ)

{

ofstream file(FileName.c_str());

if(!file.is_open()) return 0;

SetTitle('СОКО - сохранение сетки');

char buffer [20];

int k;

file<< AnsiString(

<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://www.opengis.net/kml/2.2'><Document><name>'+

Filename+'</name>n<Style id='line'><LineStyle><color>'+((viewRelief)?'4d000000':'ffffffff')+'</color><width>1</width></LineStyle><PolyStyle><color>'+((viewRelief)?'4d000000':'ffffffff')+'</color></PolyStyle></Style>n').c_str();

if(viewRelief)

{

for(int i=1;i<height-step;i+=step)

{

for(int j=1;j<width-step;j+=step)

{

if(

((hideFar && p[i][j].e && p[i][j+step].e &&

p[i+step][j+step].e && p[i+step][j].e) || !hideFar )

&&

((hideUpLimit && p[i][j].z<rmx.z && p[i][j].z>rmn.z &&

p[i+step][j+step].e && p[i+step][j].e) ||

!hideUpLimit || difference )

)

{

file<<'<Placemark><visibility>1</visibility><Style id='transBluePoly'><LineStyle><width>0</width></LineStyle><PolyStyle><color>n';

k=i*RealWidth+j;;

sprintf(buffer, 'ff%0*x%0*x%0*x',2,imageData[k].b,2,imageData[k].g,2,imageData[k].r);

file<<buffer<<'n';

file<<'</color></PolyStyle></Style><Polygon><altitudeMode>absolute</altitudeMode><outerBoundaryIs><LinearRing><coordinates>n';

sprintf(buffer, '%.13f',p[i][j].x/sclxy+

min.x+(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',p[i][j].y/sclxy+

min.y+(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*(p[i][j].z/sclz+min.z+

(max.z-min.z)/2-min.z));

file<<buffer<<'n';

sprintf(buffer, '%.13f',p[i+step][j].x/sclxy+min.x+

(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',p[i+step][j].y/sclxy+min.y+

(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*(p[i+step][j].z/sclz+min.z+

(max.z-min.z)/2-min.z));

file<<buffer<<'n';

sprintf(buffer, '%.13f',p[i+step][j+step].x/sclxy+min.x+

(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',p[i+step][j+step].y/sclxy+min.y+

(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*

(p[i+step][j+step].z/sclz+min.z+(max.z-min.z)/2-min.z));

file<<buffer<<'n';

sprintf(buffer, '%.13f',p[i][j].x/sclxy+min.x+

(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',p[i][j].y/sclxy+min.y+

(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*(p[i][j].z/sclz+min.z+

(max.z-min.z)/2-min.z));

file<<buffer<<'n';

file<<'</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark>n';

file<<'<Placemark><visibility>1</visibility><Style id='transBluePoly'><LineStyle><width>0</width></LineStyle><PolyStyle><color>n';

k=i*RealWidth+j;;

sprintf(buffer, 'ff%0*x%0*x%0*x',2,imageData[k].b,2,

imageData[k].g,2,imageData[k].r);

file<<buffer<<'n';

file<<'</color></PolyStyle></Style><Polygon><altitudeMode>absolute</altitudeMode><outerBoundaryIs><LinearRing><coordinates>n';

sprintf(buffer, '%.13f',p[i+step][j+step].x/

sclxy+min.x+(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',p[i+step][j+step].y/

sclxy+min.y+(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*(p[i+step][j+step].z/

sclz+min.z+(max.z-min.z)/2-min.z));

file<<buffer<<'n';

sprintf(buffer, '%.13f',p[i][j+step].x/

sclxy+min.x+(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',p[i][j+step].y/

sclxy+min.y+(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*(p[i][j+step].z/

sclz+min.z+(max.z-min.z)/2-min.z));

file<<buffer<<'n';

sprintf(buffer, '%.13f',p[i][j].x/

sclxy+min.x+(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',p[i][j].y/

sclxy+min.y+(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*(p[i][j].z/

sclz+min.z+(max.z-min.z)/2-min.z));

file<<buffer<<'n';

sprintf(buffer, '%.13f',p[i+step][j+step].x/

sclxy+min.x+(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',p[i+step][j+step].y/

sclxy+min.y+(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*(p[i+step][j+step].z/

sclz+min.z+(max.z-min.z)/2-min.z));

file<<buffer<<'n';

file<<'</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark>n';

}

}

}

}

if(isolines)

{

for(int i=0;i<iso.size();i++)

{

file<<'<Placemark><name>Absolute</name><visibility>1</visibility><styleUrl>#line</styleUrl><LineString><tessellate>1</tessellate><altitudeMode>absolute</altitudeMode><coordinates>n';

sprintf(buffer, '%.13f',iso[i].a.x/sclxy+min.x+(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',iso[i].a.y/sclxy+min.y+(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*(iso[i].a.z/sclz+min.z+

(max.z-min.z)/2-min.z));

file<<buffer<<'n';

sprintf(buffer, '%.13f',iso[i].b.x/sclxy+min.x+(max.x-min.x)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',iso[i].b.y/sclxy+min.y+(max.y-min.y)/2);

file<<buffer<<',';

sprintf(buffer, '%.13f',ScaleZ*(iso[i].b.z/sclz+min.z+

(max.z-min.z)/2-min.z));

file<<buffer<<'n';

file<<'</coordinates></LineString></Placemark>n';

}

}

file<<'</Document></kml>';

file.close();

return 1;

}

void bath::setConstantPreset(bath &src)

{

f=src.f;

zero=src.zero;

startDate=src.startDate;

endDate=src.startDate;

d=src.d;

sclxy=src.sclxy;

sclz=src.sclz;

cfx=src.cfx;

cfy=src.cfy;

dev=src.dev;

tmpz=src.tmpz;

isoHaba=src.isoHaba;

min=src.min;

max=src.max;

rmn=src.rmn;

rmx=src.rmx;

k=src.k;

blurCount=src.blurCount;

texNum=src.texNum+1;

Filename=src.Filename;

tex=src.tex;

step=src.step;

rt=src.rt;

viewPoints=src.viewPoints;

net=src.net;

counted=src.counted;

isolines=src.isolines;

viewRelief=src.viewRelief;

visible=src.visible;

hideFar=src.hideFar;

hideUpLimit=src.hideUpLimit;

needRecount=src.needRecount;

difference=src.difference;

blackAndWhite=src.blackAndWhite;

slg=src.slg;

hasTide=src.hasTide;

exsist=src.exsist;

binded=src.binded;

width=src.width;

height=src.height;

RealWidth=src.RealWidth;

RealHeight=src.RealHeight;

PixelsQnt=src.PixelsQnt,

hcoeff=src.hcoeff;

wcoeff=src.wcoeff;

ID=src.ID;

fighaba=src.fighaba;

isolineSize=src.isolineSize;

}

bath::operator=(bath &src)

{

setConstantPreset(src);

if(src.q.size()>0)

{

q.make(src.q.size());

for(int i=0;i<src.q.size();i++)

{

q[i]=src.q[i];

}

}

if(src.iso.size()>0)

{

for(int i=0;i<src.iso.size();i++)

{

iso.push_back(src.iso[i]);

}

}

if(src.imageData.size()>0)

{

imageData.make(src.imageData.size());

for(int i=0;i<src.imageData.size();i++)

{

imageData[i]=src.imageData[i];

}

}

if(src.p.n>0)

{

p.make(src.p.n,src.p.m);

blurBuff.make(src.p.n,src.p.m);

for(int i=0;i<src.p.n;i++)

{

for(int j=0;j<src.p.m;j++)

{

p[i][j]=src.p[i][j];

blurBuff[i][j]=src.blurBuff[i][j];

}

}

exsist=1;

BindTexture(texNum,1,0);

}

}

#endif

4. РУКОВОДСТВО ПРОГРАММИСТА

4.1 Руководство программиста для программы в целом

4.1.1 Назначение и условия применения программного обеспечения

SOKO обеспечивает выполнение следующих основных функций:

Импорт батиметрическиз данных из исходных треков, получаемых с картплоттера-эхолота;

Импорт береговых линий из GPS-навигатора;

Импорт данных, искусственно созданных с помощью приложения Google Maps;

Наглядное совмещение, компоновка и редактирование данных, исправление ошибок;

Подготовка данных к отображению и обработке: вычитание высоты прилива и сезонных колебаний уровня моря;

Выбор необходимого участка для расчёта посредством введения географических координат прямоугольника, либо в графическом режиме;

Настройка параметров отображения будущей карты: коэффициента пропорциональности высоты, частоты изолиний и других;

Построение и батиметрических карт;

Построение карт сравнения динамики рельефа;

Сохранение готовых карт в виде изображений любого размера;

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

Экспорт данных в различные форматы;

Сохранение текущего состояния системы для дальнейшей обработки.

Для работы с данным программным обеспечением необходимо перечисленное далее аппаратное и программное обеспечение.

Техническое обеспечение:

персональный компьютер совместимый с IBM PC с тактовой частотой процессора не ниже 1000 МГц;

оперативная память 1024 Мб и более;

накопитель данных со свободным объёмом не менее 3 Гб;

видеокарта и монитор, поддерживающие разрешение 1024*768 точек и выше, с частотой обновления не менее 60 Гц;

устройства ввода клавиатура и манипулятор «мышь» (стандартные);

Программное обеспечение:

операционная система - Microsoft Windows 98 или более поздняя;

интегрированная среда разработки приложений Borland C+ Builder 6

Raize Components - набор визуальных компонентов для Delphi / C++Builder версии не ниже 4.3.2;

приложение для предвычисления приливов wxtide версии не ниже 4.7;

Microsoft Office Excel 2003 или выше;

распространяемый дистрибутив приложения с пакетом дополнительных консольных программ и исполняемым файлом программы «Soko.exe» (схема зависимостей компонентов приложения показана на рисунке 1.10 в приложении №1).

4.1.2 Характеристика программного обеспечения

Программа включает в себя 74 заголовочных файла языке программирования C++, 10 файлов реализации функций, и один файл формы soko_code.dfm, где дана спецификация графического интерфейса.

Графический интерфейс приложения создан в среде разработки приложений Borland C++ Builder на основе компонентов библиотек классов VCL и библиотеки Raize.

Приложение опирается на стандартную библиотеку классов C++, библиотеку VCL, предоставляемую фирмой Borland, библиотеку OpenGL, а также на несколько консольных приложений, необходимых для преобразования данных.

При разработке программного обеспечения в проекте используются модули стандартной библиотеки C++, библиотек VCL, Raize и OpenGL, перечисленные далее в таблицах 4.1-4.3.

Таблица 4.1 - Использованные в программе заголовочные файлы стандартной библиотеки

Заголовочный файл

Назначение в проекте программы

windows.h

Реализует доступ к API-функциям операционной системы Microsoft Windows

iostream.h

Работа с потоками и консолью операционной системы, используется для связи с консольными модулями.

fstream.h

Чтение и запись файлов

stdio.h

Стандартный ввод и вывод

map

Реализует шаблоны классов контейнеров std::map и std::multimap - Ассоциативный массив и мультиотображение.

vector

Реализует шаблон класса контейнеров std::vector - динамический массив.

math

Основные математческие операции, такие как косинус или возведение в степень

stdarg.h

Средства для перебора аргументов функции, количество и типы которых заранее не известны.

ctime

Типы и функции для работы с датой и временем.

cstdlib

Функции, занимающиеся выделением памяти, контроль процесса выполнения программы, преобразования типов и другие.

limits

Определения характеристик общих типов переменных.

Таблица 4.2 - Использованные в программе классы стандартной библиотеки (выборочно)

Название класса

Назначение в проекте программы

vector

Универсальный контейнер, используется редко: для хранения изолиний и уровней изолиний. В остальных случаях заменяется пользовательскими контейнерами семейства dinmas.

map

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

ifstream

Чтение файлов

ofstream

Запись файлов

Таблица 4.3 - Использованные в программе заголовочные файлы VCL

Заголовочный файл

Назначение в проекте программы

Classes.hpp

Стандартные классы VCL

StdCtrls.hpp

Стандартные элементы управления

Forms.hpp

Форма - окно настроек в программе

Menus.hpp

Главное меню

Dialogs.hpp

Диалоговые окна

msxmldom.hpp

XMLDoc.hpp

xmldom.hpp

XMLIntf.hpp

Классы для работы с XMLёиспользуются для чтения файлов в формате kml (Google Earth), а также xml-файлы треков GPS-навигатора Garmin.

Таблица 4.4 - Использованные в программе классы VCL

Название класса

Назначение в проекте программы

AnsiString

Основной строковый класс программы, используется повсеместно.

TDateTime

Класс для работы с датой и временем.

FileInfo

Операции управления файловой структурой.

DirectoryInfo

Получение сведений о файлах и каталогах.

TMainMenu

Главное меню

TTimer

Таймер

TOpenDialog

Диалог открытия файлов

TSaveDialog

Диалог сохранения файлов

TPopupMenu

Контекстное меню

TMenuItem

Класс элемента главного меню

TXMLDocument

Класс для работы с XML

TForm

Рабочее окно программы

Таблица 4.5 - Использованные в программе программе заголовочные файлы Raize

Заголовочный файл

Назначение в проекте программы

RzEdit.hpp

Поля ввода

RzSpnEdt.hpp

Поля числового ввода, позволяющие изменять значение с помощью колёсика мыши

RzPanel.hpp

Панели, объединяющие несколько элементов

RzTabs.hpp

Панели управления страницами

RzButton.hpp

Кнопки

RzChkLst.hpp

Списки с выбором элеметов

RzLstBox.hpp

Списки

RzCmboBx.hpp

Выпадающие списки

RzRadGrp.hpp

Группы, позволяющие выбрать один параметр

RzRadChk.hpp

Группы, позволяющие выбрать несколько параметров

RzLabel.hpp

Текстовая строка

RzTrkBar.hpp

Информационная панель внизу

RzGroupBar.hpp

Вертикальные панели, содержащие сворачиваемые группы элементов управления

Таблица 4.6 - Использованные в программе программе заголовочные файлы Raize

Название компонента

Описание

TRzToolbar

Панель инструментов

TRzToolbarButton

Кнопка на панели инструментов

TRzPanel

Панель, объединяющая другие компоненты

TRzSplitter

Бегунок, разделяющий две панели

TRzListBox

Список

TRzGroupBar

Вертикальная панель со сворачиваемыми группами

TRzLabel

Текстовая подпись

TRzSpinEdit

Элемент числового ввода, позволяющий изменять значение с помощью колёсика мыи

TRzStatusBar

Строка состояния

TRzSpacer

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

TRzBitBtn

Кнопка с изображением

TRzComboBox

Всплывающий список

TRzCheckBox

Группа с выбором нескольких элементов

TRzRadioGroup

Группа с выбором одного элемента

TRzColorEdit

Элемент управления цветом

TRzCheckList

Список в выбором элементов

TRzEdit

Компонент текстового ввода

TRzDateTimeEdit

Элемент отображения и задания времени и даты

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

Далее в таблице 4.4 представлены названия основных таких классов, а в таблицах 4.5 и 4.6 дано описание их структуры.

Также следует отметить, что каждый модуль реализован в виде одного или нескольких классов, реализующих функциональность, возложенную на данный модуль.

Таблица 4.7 - Главные структуры данных пользователя, использованные в программе

Название класса

Назначение в проекте программы

point2d

Структура «двумерная точка», используется как предок класса «трёхмерная точка»

point3d

Структура «трёхмерная точка», используется как предок классов Vertex и BathPoint, и поле в классах Camera, Cursor, Isoline, Figure, Lamp.

camera

Класс камеры. Содержит методы упрощённого управления камерой в проекции OpenGL. Является предком класса control3d.

cursor

Класс курсора. Сожержит методы получения координат курсора на экране, преобразования их в проекцию OpenGL и обратно. Является предком класса control3d

coltrol3d

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

AverageLevel

Класс, применяемый для расчёта сезонных изменений уровня моря.

CamItem

Элемент последовательности камер, входит в качестве поля в класс CameraSequence.

CameraSequence

Класс-массив камер, является наследником класса Camera, применяется для создания видеороликов.

dinmas

Одномерный простой динамический массив. Используется в качестве массива для большинства типов данных.

dinmas2d

Двумерный простой динамический массив. Используется в качестве массива для батиметрической карты и её текстуры.

smartcont

Одномерный динамический массив с двойной адресацией. Используется для хранения объектов, содержащих поля типа dinmas и dinmas2d, в частности для списка батиметрических треков и списка камер.

TgaHeader

Заголовок TGA-файла.

RGBApixel

Структура точки в формате TGA

texture

Класс, предназначенный для чтения и записи файлов в формате TGA. Применяется как в качестве контейнера текстуры батиметрической карты, так и для сохранения изображений и видео. Является предком класса bath.

DoubleTable

Класс, позволяющий читать ascii-файл, представляющий собой таблицу из чисел, разделённых табуляцией и создающий на выходе двумерный массив. Применяется для чтения исходных данных.

vertex

Структура 'узел батиметрии', основанная на трёхмерной точке.

BathPoint

Точка батиметрического трека.

isoline

Класс одного отрезка изолинии.

figure

Класс цифры-подписи.

OneTri

Структура треугольника для триангуляции.

bath

Основной класс для расчёта батиметрии. Содержит все функции обработки и анализа данных.

glWindow

Класс API-окна, реализующего вывод OpenGL-графики.

lamp

Класс, упрощяющий работу с освещением в OpenGL.

RastrFont

Класс, упрощающий работу с выводом текста в среде OpenGL.

WorkArea

Класс, предназначенный для чтения параметров текущего экрана.

Таблица 4.8 - Структура point2d

Вид члена

Описание

Назначение

поле

double x

Абсцисса

поле

double y

Ордината

метод

point2d()

Пустой конструктор

метод

point2d(double, double)

Конструктор

метод

bool equal(point2d&)

Проверка на равенство

метод

void mix(point2d&)

Вычислить среднюю точку

метод

double angto(point2d&)

Получить ориентацию точки

Вид члена

Описание

Назначение

поле

double z

Аппликата

метод

point3d()

Пустой конструктор

метод

point3d(double, double, double)

Конструктор

метод

bool equal(point3d&)

Проверка на равенство

метод

void mix(point3d&)

Вычислить среднюю точку

метод

bool ataru(point3d&)

Попадает ли в точку с радиусом EPS

метод

double z

Аппликата

Вид члена

Описание

Назначение

поле

point3d pos

Позиция

метод

point3d startpos

Начальная позиция

метод

point3d ang

Вектор угла поворота

метод

point3d startang

Начальный вектор угла поворота

метод

camera()

Пустой конструктор

метод

camera(float, float, float, float, float, float)

Конструктор

метод

void view()

Применить камеру

Вид члена

Описание

Назначение

поле

float x

Абсцисса в среде OpenGL

поле

float y

Ордината в среде OpenGL

поле

float dx

Текущая скорость по оси абсцисс в среде OpenGL

поле

float dy

Текущая скорость по оси ординат в среде OpenGL

поле

float size

Размер курсора

поле

float oldX

Предыдущая абсцисса в среде OpenGL

поле

float oldY

Предыдущая ордината в среде OpenGL

поле

int WinX

Абсцисса в оконных координатах

поле

int WinY

Ордината в оконных координатах

поле

int OldWinX

Предыдущая абсцисса в среде OpenGL

поле

int OldWinY

Предыдущая абсцисса в среде OpenGL

поле

bool RMB

Нажата правая кнопка

поле

bool LMB

Нажата левая кнопка

поле

bool MMB

Нажата средняя кнопка

метод

cursor()

Пустой конструктор

метод

void check(int &, int &, int, int)

Получить координаты курсора

метод

void putold()

Запомнить предыдущие значения

метод

void view()

Отобразить курсор

метод

void PutState(bool, bool, bool)

Установить состояние кнопок мыши

метод

void PutState(bool, bool, bool, bool)

Установить состояние кнопок мыши с проверкой

Таблица 4.9 - Структура класса coltrol3d, потомок классов camera и cursor

Вид члена

Описание

Назначение

метод

coltrol3d()

Пустой конструктор

метод

coltrol3d(float, float, float, float, float, float)

Конструктор

метод

void view(bool)

Установить камеру на текущую позицию в соответствии с курсором

метод

void gets(int, int, int, int, bool)

Получить координаты курсора

метод

wheel(bool, float)

Получить сообщение прокрутки мыши, отдалив камеру

метод

coltrol3d middle(coltrol3d, double)

Установить позицию камеры посередине между двумя позициями

Таблица 4.10 - Структура класса AverageLevel

Вид члена

Описание

Назначение

поле

TDateTime date

Текущая дата

поле

double ya

Годовая амплитуда

поле

double yf

Годовая частота

поле

double hya

Полугодовая амплитуда

поле

double hyf

Полугодовая частота

поле

double tya

Третьгодовая амплитуда

поле

double tyf

Третьгодовая частота

поле

unsigned short y

Текущий год

поле

unsigned short m

Текущий месяц

поле

unsigned short d

Текущий день

метод

void put(AnsiString)

Задать данные из файла

метод

double get(TDateTime)

Получить уровень для выбранной даты

Таблица 4.11 - Структура класса dinmas

Вид члена

Описание

Назначение

поле

type* data

Указатель на массив данных

поле

long siz

Размер массива

метод

dinmas()

Пустой конструктор

метод

dinmas(long)

Конструктор

метод

~dinmas()

Десруктор

метод

bool make(long)

Управляемый конструктор (выделить память)

метод

void clear()

Управляемый декструктор (очистить память)

метод

type& operator[](long)

Доступ к элементу массива

метод

int bytes()

Вывести занимаемую память

метод

void insert(type &, int)

Вставить элемент

метод

void erase(int)

Вырезать элемент

метод

push(type &)

Вставить элемент в конец

метод

pop()

Удалить последний элемент

метод

type& top()

Получить последний элемент

метод

bool SaveToFile(AnsiString)

Сохранить содержимое в файл

метод

bool LoadFromFile(AnsiString)

Загрузить содержимое из файла

метод

long& size()

Получить размер массива

метод

operator=(dinmas<type> &)

Скопировать массив

Таблица 4.12 - Структура класса dinmas2d

Вид члена

Описание

Назначение

поле

type** data

Указатель на массив данных

поле

long n

Размер по первому измерению

поле

long m

Размер по второму измерению

поле

bool exists

Массив создан

метод

dinmas2d()

Пустой конструктор

метод

dinmas2d(long, long)

Конструктор

метод

~dinmas2d()

Деструктор

метод

bool make(long, long)

Управляемый конструктор (выделить память)

метод

void clear()

Управляемый декструктор (очистить память)

метод

type* operator[](long)

Доступ к элементу массива

метод

int bytes()

Вывести занимаемую память

метод

operator=(dinmas2d<type> &)

Скопировать массив

Таблица 4.13 - Структура класса smartcont

Вид члена

Описание

Назначение

поле

type** graphs

Указатель на массив данных

поле

int _size

Размер массива

поле

int selected

Индекс выбранного элемента

метод

smartcont(int)

Конструктор

метод

smartcont()

Пустой конструктор

метод

make(int n)

Управляемый конструктор (выделить память)

метод

int &size()

Получить размер массива

метод

void clear()

Управляемый деструктор (очистить память)

метод

type& operator[](int)

Получить элемент по индексу

метод

type& operator()()

Получить выбранный элемент

метод

~smartcont()

Деструктор

метод

insert(type &value)

Вставить элемент по индексу

метод

insert()

Вставить элемент в выбранное место

метод

void copy()

Создать дубликат рядом с выбранным элементом

метод

void erase(int)

Удалить элемент по индексу

метод

void erase()

Удалить выбранный элемент

метод

bool select(int)

Выбрать элемент

метод

int SelectedItem()

Получить индекс выбранного элемента

метод

void MoveUp()

Переместить элемент вверх

метод

void MoveDown()

Переместить элемент вниз

Таблица 4.14 - Структура класса CamItem

Вид члена

Описание

Назначение

поле

coltrol3d ctrl

Позиция камеры

поле

int secs

Занимает секунд

метод

CamItem(coltrol3d, int)

Конструктор

метод

CamItem()

Пустой конструктор

Таблица 4.15 - Структура класса CameraSequence

Вид члена

Описание

Назначение

поле

coltrol3d ctrl

Позиция камеры

поле

int secs

Занимает секунд

метод

CamItem(coltrol3d, int)

Конструктор

метод

CamItem()

Пустой конструктор

Вид члена

Описание

Назначение

поле

int selected

Выбранный элемент

поле

int secs

Всего секунд

поле

int shots

Всего кадров

метод

dinmas<CamItem> ctrl

Массив позиций камеры

метод

dinmas<double> x

Дискретный массив отрезков времени

метод

dinmas<double> y[6]

Дискретный массив позиций и углов поворота камеры

метод

cubic_spline spl[6]

Непрервыный массив (кубический сплайн) позиций и углов поворота камеры

метод

CameraSequence()

Пустой конструктор

метод

void insert(coltrol3d, int)

Вставить новую камеру

метод

void update(coltrol3d, int)

Заменить выбранную камеру

метод

void remove()

Удалить выбранную камеру

метод

coltrol3d selectedCtrl()

Получить выбранную камеру

метод

void countSpline()

Расчитать кубическую интерполяцию

Таблица 4.16 - Структура класса RGBpixel

Вид члена

Описание

Назначение

поле

GLubyte r

Красный канал

поле

GLubyte g

Зелёный канал

поле

GLubyte b

Синий канал

метод

RGBpixel(GLubyte, GLubyte, GLubyte)

Конструктор

метод

RGBpixel()

Пустой конструктор

метод

void GetPixel(GLubyte &, GLubyte &, GLubyte &)

Получить пиксель

метод

RGBpixel ToBGR()

Преобразовать в формат для записи в TGA на 24 бита

метод

RGBApixel ToBGRA()

Преобразовать в формат для записи в TGA на 32 бита

Вид члена

Описание

Назначение

поле

GLubyte a

Альфаканал

метод

RGBApixel(GLubyte, GLubyte, GLubyte, GLubyte)

Конструктор

метод

RGBApixel()

Пустой конструктор

метод

void GetPixel(GLubyte &, GLubyte &, GLubyte &, GLubyte &)

Получить пиксель

метод

RGBApixel ToBGRA()

Преобразовать в формат для записи в TGA на 32 бита

Таблица 4.17 - Структура класса texture

Вид члена

Описание

Назначение

поле

bool exsist

суествует

поле

bool binded

уже применяется

поле

int width

ширина

поле

int height

высота

поле

int RealWidth

ширина, приближённая к степени двойки

поле

int RealHeight

высота, приближённая к степени двойки

поле

int PixelsQnt

количество точек

поле

int ID

идентификационный номер текстуры в OpelGL

поле

float hcoeff

отношение height к RealHeight

поле

float wcoeff

отношение width к RealWidth

поле

dinmas<RGBApixel> imageData

массив точек

метод

GLubyte correct(float)

исправление целочисленного цвета, если он выходит из диапазона 0-255

метод

void operator=(texture &)

копировать текстуру

метод

void SetPixel(int, int, GLubyte, GLubyte, GLubyte, GLubyte)

задать одну точку целыми числами

метод

void SetPixelf(int, int, float, float, float, float)

задать одну точку числами с плавающей точкой

метод

void GetPixel(int, int, GLubyte &, GLubyte &, GLubyte &, GLubyte &)

получить одну точку

метод

texture()

конструктор

метод

bool MakeArray(int, int)

выделение памяти c проверкой на степень двойки

метод

bool MakeArraySimple(unsigned int, unsigned int)

выделение памяти в обход проверки на степень двойки

метод

bool BindTexture(unsigned int, bool, bool)

применение текстуры

метод

bool SaveToTGA(AnsiString)

сохранение в TGA

метод

bool LoadFromTGA(AnsiString, unsigned int, bool, bool)

чтение из TGA

метод

~texture()

деструктор

метод

void DeleteArray()

очистить массив

метод

void UnBind()

отменить текстуру

метод

unsigned int GetWidth()

Получить ширину

метод

unsigned int GetHeight()

Получить высоту

метод

unsigned int GetRealWidth()

Получить ширину, ближайшую к степени двойки

метод

unsigned int GetRealHeight()

Получить высоту, ближайшую к степени двойки

метод

unsigned int GetPixelsQnt()

Получить число пикселей

метод

unsigned int GetID()

Получить ID текстуры

метод

bool GetExsist()

Узнать, существует ли текстура

метод

bool GetBinded()

Узнать, наложена ли текстура

метод

float GetWCoeff()

Получить отношение height к RealHeight

метод

float GetHCoeff()

Получить отношение width к RealWidth

метод

void PutWidth(unsigned int)

Задать ширину

метод

void PutHeight(unsigned int)

Получить высоту

метод

void PutRealWidth(unsigned int)

Получить ширину, ближайшую к степени двойки

метод

void PutRealHeight(unsigned int)

Получить высоту, ближайшую к степени двойки

метод

void PutPixelsQnt(unsigned int)

Получить число пикселей

метод

void PutID(unsigned int)

Получить ID текстуры

метод

void PutExsist(bool)

Узнать, существует ли текстура

метод

void PutBinded(bool)

Узнать, наложена ли текстура

метод

void PutWCoeff(float)

Получить отношение height к RealHeight

метод

void PutHCoeff(float)

Получить отношение width к RealWidth

Таблица 4.18 - Структура класса DoubleTable

Вид члена

Описание

Назначение

поле

dinmas2d<double> d

Выходной массив данных

метод

DoubleTable(AnsiString)

Конструктор

метод

DoubleTable()

Пустой конструктор

метод

bool Load(AnsiString, char)

Прочитать файл, узнав разделитель

метод

double* operator[](unsigned int)

Доступ к элементу

Таблица 4.19 - Структура класса lamp

Вид члена

Описание

Назначение

поле

int light

ID источника света в OpenGL

поле

GLUquadricObj* sun

Указатель на объект-солнце

поле

GLfloat position[4]

Позиция

поле

GLfloat ambient[4]

Внешний свет

поле

GLfloat diffuse[4]

Рассеянный светт

поле

GLfloat specular[4]

Отражащий свет

поле

GLfloat attenuation

Размер блика

поле

bool active

Активен

поле

bool focused

Выбран

метод

lamp()

Пустой конструктор

метод

lamp(int, float, float, float)

Конструктор

метод

make(int, float, float, float)

Задать цвет на позиции

метод

make(int, float, float, float, float, float, float, float, float, float, float, float, float, bool, bool, float);

Задать свет по всем параметрам

метод

void setlight(int)

Установить свет

метод

void put(bool)

Включить свет

метод

void view(bool,bool)

Показать источник света

метод

color(float, float, float, int)

Задать цвет

метод

pos(float, float, float)

Задать позицию

метод

SetInfinity(bool)

Установить, бесконечный ли свет

метод

SetAttenuation(float)

Установить размер бликов

метод

void border()

Показывать рамку на источнике

метод

SetActive(bool)

Активировать

Таблица 4.20 - Структура класса BathPoint

Вид члена

Описание

Назначение

поле

point3d r,m

Точка в географических и нормализованных к 1 координатах

поле

unsigned int t

Сколько миллисекунд прошло с начала трека

поле

double tide

Высота прилива в данной точке

метод

BathPoint()

Конструктор

Вид члена

Описание

Назначение

поле

point3d a

начало

поле

point3d b

конец

поле

bool zero

не показывать

метод

isoline()

конструктор

метод

void put(double &, double &, double &, double &, double &, double &, bool &)

задать

метод

void view(int &)

показать

Таблица 4.21 - Структура класса figure, потомок класса point3d

Вид члена

Описание

Назначение

поле

bool exists

показывать

поле

double length

размер

поле

isoline *line

к какой изолинии привязана

поле

char str[8]

что отображать

поле

int strl

длина строки

поле

double angle

угол разворота

метод

void activate(double, double)

'прилепить' к изолинии

метод

void view(int)

показать

поле

double f

уровень для расчёта изолиний

поле

bool zero

являетмя ли уровень текущей изолинии нулевым

поле

float material_color[4]

массив цвета материала

поле

dinmas<OneTri> tri

набор треугольников для триангуляции

поле

isoline line

буферная изолиния для работы функции расчёта изолиний

поле

bool triangulation()

произвести триангуляцию

поле

dinmas<BathPoint> q

батиметрический трек

поле

dinmas2d<vertex> p

батиметрическая сетка

поле

TDateTime startDate

дата начала съёмки

поле

TDateTime endDate

дата конца съёмки

поле

vector<isoline> iso

вектор изолиний

поле

dinmas2d<figure> figures

массив цифр

поле

dinmas<double> *isolist

список уровней изолиний

поле

double d

шаг сетки

поле

double sclxy

коэффициент нормализации долготы и широты

поле

double sclz

коэффициент нормализации высоты

поле

double cfx

коэффициент нормализации долготы

поле

double cfy

коэффициент нормализации широты

поле

double dev

суммарное математическое отклонение данных от исходных в результате сглаживания и расчёта равномерной сетки

поле

double tmpz

нормализованная высота для расчёта цвета

поле

double isoHaba

частота изолиний

поле

double isolineSize

толщина изолинии

поле

point3d min

минимум, нормализованный к 1

поле

point3d max

максимум, нормализованный к 1

поле

point3d rmn

минимум в географических координатах

поле

point3d rmx

максимум в географических координатах

поле

int k

число строк в текстуре для доступа к ячейке одномерной текстуры по двум координатам

поле

int blurCount

количество проходов размытия

поле

int texNum

ID текстуры в среде OpenGL

поле

int fighaba

Расстояние между подписями

поле

int diffBlur

количество проходов размытия для сравнения батиметрий

поле

int step

пропуск кратных узлов сетки для ускорения отображения

поле

AnsiString Filename

имя файла

поле

bool tex

отображение текстуры средставми OpenGL

поле

bool varIso

переменный список изолиний

поле

bool lighting

освещение включено

поле

bool rt

режим отображения без пропусков

поле

bool viewPoints

отображать треки

поле

bool net

отображать сетку

поле

bool counted

сетка уже расчитана

поле

bool isolines

отображать изолинии

поле

bool viewRelief

отображать рельеф

поле

bool visible

отображать сетку

поле

bool hideFar

скрыть удалённые участки

поле

bool hideUpLimit

скрыть участки, выходящие за границу минимума и максимума

поле

bool needRecount

требуется перерасчёт

поле

bool difference

является разницей между двумя батиметриями

поле

bool blackAndWhite

отображать в чёрнобелых тонах

поле

bool slg

является прочитанным slg-файлом

поле

bool hasTide

прилив вычтен

метод

bath()

Конструктор

метод

bool LoadPoints(AnsiString, bool, bool)

Чтение точек из ASCII-файла

метод

bool LoadSlg(DoubleTable &, AnsiString)

Чтение трека из slg-файла

метод

bool MakeEmpty(int)

Очистить батиметрию

метод

void CountTide(cubic_spline &)

Расчёт прилива

метод

void ReCountMinMax()

Вычисление минимума и максимума

метод

double ReCountMin()

Вычисление только минимума

метод

bool CountNet(int, point3d, point3d, double, double, double, double, double, int, double, double, int, int, int, dinmas<double> *, bool)

Расчёт батиметрической сетки

метод

void blur(int)

размытие

метод

void deviation()

расчёт отклонения

метод

inline __fastcall void CountColor(int &, int &)

Расчёт цвета для выбранного узла сетки

метод

void ReCountColor()

Перерасчёт цвета

метод

inline __fastcall void CountNorm(int &, int &)

Вычисление нормалей

метод

void DefConstr()

Конструктор (в виде вызываемой функции)

метод

void OneVertex(int &, int &)

Вывод одного узла сетки на экран

метод

void view()

Вывод всей батиметрии

метод

void ViewPoints()

Вывот треков

метод

double cf(double &, double &, double &, bool)

Линейная интерполяция

метод

void makeLine(int &, int &)

Создание одной изолинии

метод

void ViewFigures(int)

Отображение цифр-подписей

метод

void countOneIso(double)

Расчёт одного слоя изолиний

метод

void countIso(double, dinmas<double> *, bool)

Расчёт всех изолиний

метод

void CountFigures(int)

Расчёт цифр-подписей

метод

void viewIso()

Отображение изолиний

метод

void EraseNet()

Удаление расчитанной батиметрической сетки

метод

bool GetDiffer(bath &, bath &, int, double, int)

Вычисление разницы между двумя батиметриями

метод

bool GetDifferPoints(bath &, double)

Вычисление

метод

bool ReBindTexture()

Наложение текстуры

метод

bool SaveNet(AnsiString)

Сохранение сетки в ASCII-формате

метод

bool SaveANI(AnsiString, double)

Сохранение данных в формате.inf и.dat для программы ANI

метод

bool SavePointsGoogle(AnsiString)

Сохранение набора точек для отображения в прорамме Google Chrome

метод

bool SaveTrack(AnsiString)

Сохранение трека для отображения в прорамме Google Chrome

метод

bool SavePoints(AnsiString)

Сохранение набора точек в ASCII-формате в географических коордиантах

метод

bool SavePointsMer(AnsiString)

Сохранение набора точек в ASCII-формате в координатах меркатора

метод

bool SaveNetGoogle(AnsiString, int)

Сохранение батиметрической карты для отображения в прорамме Google Chrome

метод

void setConstantPreset(bath &)

Получение всех статических переменных батиметрии из другой

метод

operator=(bath &)

Полное копирование батиметрии из другой

Таблица 4.22 - Структура класса glWindow

Вид члена

Описание

Назначение

метод

LRESULT CALLBACK (*WindProc)(HWND,UINT,WPARAM,LPARAM)

Функция обработки сообщений окна

поле

AnsiString title

Заголовок окна

поле

HINSTANCE hInstance

Содержит экземпляр приложения

поле

GLuint

метод

GLvoid KillGLWindow(GLvoid)

Закрыть окно

метод

BOOL CreateGLWindow(char*, int, int, int, bool)

Создать окно

поле

HDC hDC

Приватный контекст устройства GDI

поле

HWND hWnd

Содержит handle окна типа hWnd

поле

HGLRC hRC

Текущий контекст воспроизведения

поле

HANDLE H

Содержит handle окна типа HANDLE

поле

int winW

Ширина окна

поле

int winH

Высота окна

поле

int winL

Смещение окна слева

поле

int winT

Смещение окна сверху

поле

bool killed

Закрыто ли окно

метод

glWindow()

Пустой конструктор

метод

glWindow(int, int, AnsiString, LRESULT CALLBACK (*wp)(HWND,UINT,WPARAM,LPARAM))

Конструктор

метод

void make(int, int, AnsiString, LRESULT CALLBACK (*wp)(HWND,UINT,WPARAM,LPARAM))

Управляемый конструктор

метод

void __fastcall Execute()

Запуск окна

метод

bool ConnectGlToWindow()

Подключить к окну параметры OpenGL

4.2 Характеристика и структура интерфейса проекта

Интерфейс приложения состоит из двух окон, не считая стандартных всплывающих диалоговых окон и окон сообщений. Окно настроек (по-умолчанию слева) содержит все средства управления программой, кроме настроек положения, угла поворота и масштаба камеры. Данное окно реализовано средствами VCL в среде C++ Builder при помощи стандартных компонентов VCL и (в большей степени) компонетов библиотеки Raize. Окно отображения выводит результаты работы на экран и представляет собой окно, реализованное средствами Windows API, связанной контекстом воспроизведения с OpenGL. Данное окно позволяет вращать и масштабировать сцену.

Модуль «soko_code.cpp» проекта приложения имеет принципиальное значение и реализует базисный функционал системы. В графическом интерфейсе системы данный модуль реализует главное окно настроек приложения.

4.2.1 Главное окно

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

Таблица 4.23 - Состав основных компонентов главного окна

Название компоненты

Тип компоненты

Назначение

TMainMenu

MainMenu

Главное меню. Содержит пункты управления открытием, сохранением, испортом и экспортом данных.

TRzToolbar

MainToolBar

Главная панель инструментов. Повторяет функции главного меню.

TRzSizePanel

ViewPanel

Содержит элементы управления всей сценой.

TRzSizePanel

BathsPanel

Содержит элементы управления списком треков и выбранной батиметрией

TRzListBox

CameraList

Список камер для рендеринга видео

TRzToolbar

CameraListEditToolBar

Панель управления камерами, позволяет добавлять, удалять, заменять камеры

TRzGroupbar

CameraGroupBar

Группа управления камерами

TRzGroupbar

SceneGroupBar

Группа управления сценой

TRzCheckList

PointsList

Список треков

TRzToolbar

TrackListEditToolBar

Панель управления списком треков, позволяет импортировать и экспортировать данные, объединять и разделять треки.

TRzGroupbar

BathsGroupBar

Группа управления выбранной батиметрией

4.2.2 Главное меню

Главное меню содержит пункты управления файлами: окрытия, сохранения, импорта и экспорта. Также имеется возможность выйти из приложения, предварительно сохранив изменения с помощью всплывающего окна.

Таблица 4.24 - Состав компонентов главного меню

Название компоненты

Тип компоненты

Назначение

MainMenu

TMainMenu

Основной объект главного меню

MenuFile

TMenuItem

Пукт «файл», сохранение и открытие батиметрических сцен.

MenuNew

TMenuItem

Создать новую сцену / сбросить все настройки

MenuOpen

TMenuItem

Открыть сцену

MenuSave

TMenuItem

Сохранить текущую сцену

MenuSaveAs

TMenuItem

Сохранить новую сцену

MenuSpacer

TMenuItem

Разделитель

MenuExit

TMenuItem

Выйти из программы

MenuData

TMenuItem

Пункт «дата», управление импортом и экспортом данных.

MenuImport

TMenuItem

Импортировать данные

MenuExport

TMenuItem

Экспортировать данные

4.2.3 Группа «границы»

Данная группа является первой среди групп настроек текущей сцены (левая колонка). Данная группа предназначена для установки границ четырёхугольника, в котором будет производиться расчёт батиметрической сетки. Она содержит настройки переменных, общих для всех рассчитываемых батиметрий, и особенностью её работы является тот факт, что при расчёте хотя бы одной батиметрической сетки доступ к данной группе ограничивается. Это необходимо для того, чтобы вся совокупность батиметрических сеток существовала в единых координатах для удобства их совместной обработки.

Таблица 4.25 - Состав компонентов группы «границы» (выборочно)

Название компоненты

Тип компоненты

Назначение

BordersGroup

TRzGroup

Объект данной группы

Borders

TRzPanel

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

GetFromPoints

TRzBitBtn

Кнопка, позволяющая автоматически получить границы из текущего набора батиметрических треков

PlMinY

TRzSpinEdit

Минимальная широта

PlMaxY

TRzSpinEdit

Максимальная широта

PlMinX

TRzSpinEdit

Минимальная долгота

PlMaxX

TRzSpinEdit

Максимальная долгота

PlMinZ

TRzSpinEdit

Минимальная глубина

PlMaxZ

TRzSpinEdit

Максимальная глубина

PlSclZ

TRzSpinEdit

Масштабирование глубины

PlaceBox

TRzComboBox

Список доступных районов для вычисления прилива и сезонных гармонических колебаний

SeparationType

TRzRadioGroup

Группа, позволяющая выбрать тип задания сетки: с помощью деления выбранного прямоугольника на определённое число узлов сетки, либо задание шага вручную

PlN

TRzSpinEdit

Число узлов сетки по максимальному измерению

Step

TRzSpinEdit

Шаг

StepType

TRzComboBox

Тип задания узлов сетки

BorderLines

TCheckBox

Показывать границы

Lines

TRzCheckBox

Показывать линейки

Measurment

TRzRadioGroup

Отбражать градусную или километровую сетку

С использованием группы «границы» могут быть выполнены следующие основные действия:

Автоматическое задание границ равномерной сетки

Корректировка границ на местности

Установка диапазона глубин

Корректировка масштабирования по высоте

Установка размера и шага батиметрической сетки

Установка названия участка местности для вычисления прилива

Управление внешним видом градусной или киломентровой сетки

4.2.4 Группа «рельеф»

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

Таблица 4.26 - Состав компонентов группы «рельеф» (выборочно)

Название компоненты

Тип компоненты

Назначение

SurfceGroup

TRzGroup

Объект данной группы

HideUpLimit

TCheckBox

Опция, позволяющая скрывать участки рельефа, не вошедшие в диапазон глубин

Net

TCheckBox

Показывать рельеф в виде сетки

PreviewSpin

TRzSpinEdit

Кратный пропуск узлов сетки, используется для ускорения просмотра

Relief

TCheckBox

Опция, позволяющая отображать и скрывать рельеф

ViewPoints

TCheckBox

Опция, позволяющая отображать и скрывать батиметрические треки

4.2.5 Группа «свет и цвет»

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

Таблица 4.27 - Состав компонентов группы «свет и цвет» (выборочно)

Название компоненты

Тип компоненты

Назначение

ColorAndLightGroup

TRzGroup

Объект данной группы

BackColor

TRzColorEdit

Объект редактирования цвета фона

Lighting

TCheckBox

Включить или отключить динамическое освещение

Hotspots

TCheckBox

Включить или отключить блики (режим с бликами требует повышенных ресурсов графической системы)

BlackAndWhite

TCheckBox

Чёрно-белый или цветной режим

LightUV

TRzSpinEdit

Угол поворота источника света

LightW

TRzSpinEdit

Угол наклона источника света

4.2.6 Группа «изолинии»

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

Таблица 4.28 - Состав компонентов группы «изолинии» (выборочно)

Название компоненты

Тип компоненты

Назначение

IsolinesGroup

TRzGroup

Объект данной группы

VarIso

TRzRadioGroup

Опция, задающая режим постоянной или переменной частоты изолиний

Isolines

TCheckBox

Отображать или скрывать изолинии

IsolineSize

TRzSpinEdit

Толщина изолиний

IsolineListOpen

TRzToolbarButton

Кнопка, позвляющая загрузить список уровней изолиний из файла при режиме переменной частоты

IsoHaba

TRzSpinEdit

Частота изолиний при режиме постоянной частоты

IsolineList

TRzComboBox

Список переменных уровней изолиний, получаемый после загрузки из файла

4.2.7 Группа «цифры»

Следующая группа на панели сцены отвечает за настройку цифр-подписей. Имеется возможность задать размер и частоту подписей.

Таблица 4.29 - Состав компонентов группы «цифры» (выборочно)

Название компоненты

Тип компоненты

Назначение

FiguresGroup

TRzGroup

Объект данной группы

FiguresSize

TRzSpinEdit

Видимый размер цифр-подписей

FiguresFreq

TRzSpinEdit

Частота расположения цифр-подписей на батиметрической сетке

FiguresCheck

TRzCheckBox

Отображать или скрывать цифры-подписи

4.2.8 Группа «общие настройки»

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

Таблица 4.30 - Состав компонентов группы «общие настройки» (выборочно)

Название компоненты

Тип компоненты

Назначение

MainOptionsGroup

TRzGroup

Объект данной группы

PlaceWindow

TRzCheckBox

Опция, позволяющая выбрать, привязывать ли окно отображения к окну настроек

ScaleFigureSize

TRzSpinEdit

Размер цифр шкалы глубин справа в пикселах

4.2.9 Группа «правка трека»

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

Таблица 4.31 - Состав компонентов группы «правка трека» (выборочно)

Название компоненты

Тип компоненты

Назначение

TrackEditGoup

TRzGroup

Объект данной группы

PointInd

TRzSpinEdit

Номер выбранной точки

ViewOnePoint

TCheckBox

Выделять на экране выбранную точку

PointsCount

TRzEdit

Поле, отображающее общее число точек

PointX

TRzSpinEdit

Поле для изменения текущей широты точки

PointY

TRzSpinEdit

Поле для изменения текущей долготы точки

PointDepth

TRzSpinEdit

Поле для изменения текущей глубины точки

PointDepthFin

TRzSpinEdit

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

Absolute

TRzCheckBox

Режим смещения в абсолютных или относительных координатах

Replace

TRzBitBtn

Произвести смещение всего трека

4.2.10 Группа «прилив»

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

Таблица 4.32 - Состав компонентов группы «прилив» (выборочно)

Название компоненты

Тип компоненты

Назначение

TideGroup

TRzGroup

Объект данной группы

HasTide

TRzCheckBox

Опция, включающая режим вычитания прилива

TideCount

TRzBitBtn

Произвести перерасчёт прилива

StartDate

TRzDateTimeEdit

Управление датой начала съёмки

StartTime

TRzDateTimeEdit

Управление временем начала съёмки

EndDate

TRzDateTimeEdit

Управление датой конца съёмки

EndTime

TRzDateTimeEdit

Управление временем конца съёмки

4.2.11 Группа «расчёт»

Третья группа на панели батиметрий отвечает за расчёт батиметрической сетки. Имеется возможность установить максимальный радиус для смежных областей, что должно соответствовать частоте галсов во время батиметрической съёмки. Участки, расстояние между которыми превышает данный радиус, показаны не будут, так как полагается, что данных недостаточно. Также имеется возможность настроить число проходов размытия готовой сетки.

Таблица 4.33 - Состав компонентов группы «расчёт» (выборочно)

Название компоненты

Тип компоненты

Назначение

CountGroup

TRzGroup

Объект данной группы

CountBtn

TRzBitBtn

Кнопка расчёта батиметрической сетки

DeleteNet

TRzBitBtn

Кнопка удаления сетки из объекта трека

MaxRad

TRzSpinEdit

Максимальный радиус, при котором между смежными данными будет построена сетка

MaskBlurCount

TRzSpinEdit

Число проходов размытия сетки

4.2.12 Группа «разность»

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

Таблица 4.34 - Состав компонентов группы «разность» (выборочно)

Название компоненты

Тип компоненты

Назначение

DifferenceGroup

TRzGroup

Объект данной группы

DiffList

TRzComboBox

Список батиметрий для сравнения

DiffBtn

TRzBitBtn

Кнопка расчёта разности

DiffRange

TRzSpinEdit

Поле задания радиуса обрезания участков, находящихся вне пересечений треков двух выбранных батиметрий

Nokosu

TRzBitBtn

Кнопка, выполняющая обрезание вышеназванных участков

DiffBlur

TRzSpinEdit

Число проходов размытия сетки

4.2.13 Список треков

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

Таблица 4.35 - Состав компонентов списка треков и кнопки управления им

Название компоненты

Тип компоненты

Назначение

PointsList

TRzCheckList

Список треков. Позволяет отметить опцией любой трек, что отображает либо скрывает его.

TrackListEditToolBar

TRzToolbar

Список батиметрий для сравнения

PointsOpen

TRzToolbarButton

Импорт треков

PointsDelete

TRzToolbarButton

Удаление выбранного трека

CopyButton

TRzToolbarButton

Копирование трека

Export

TRzToolbarButton

Экспорт выбранного трека

ConnectVisible

TRzToolbarButton

Объединить отмеченные треки в один

Separate

TRzToolbarButton

Разделить треки на точке, отмеченной как «текущая» в группе «правка трека»

RenameButton

TRzToolbarButton

Переименовать трек

BathUp

TRzToolbarButton

Переместить трек вверх

BathDown

TRzToolbarButton

Переместить трек вниз

4.2.14 Камеры

В верхней части панели сцены расположен список камер и панель управления треками. Расположенные на панели кнопки позволяют производить все основные операции с камерами: добавление, обновление, удаление, перемещение, копирование, предваритеьный просмотр видеоролика. Находящаяся под панелью группа камер позволяет задавать свойства видеоряда: продолжительность нахождения на экране в милисекундах, частоту кадров, разрешение видео. Также имеется возможность выбирать между плавным и резким перемещением видео, а также между режимами перспективной и ортогональной проекиций.

Таблица 4.36 - Состав компонентов списка треков и кнопки управления им

Название компоненты

Тип компоненты

Назначение

CameraList

TRzListBox

Список камер

CameraAdd

TRzToolbarButton

Добавить камеру

CameraDelete

TRzToolbarButton

Удалить выбранную камеру

CameraUpdate

TRzToolbarButton

Обновить выбранную камеру на текущую

CameraReload

TRzToolbarButton

Установить текущую камеру как выбранную

CameraPlay

TRzToolbarButton

Предварительный просмотр видео

ResetCamera

TRzToolbarButton

Обнулить текущую камеру

ShotButton

TRzToolbarButton

Сохранить изображение

SaveVideo

TRzToolbarButton

Сохранить видео

CameraGroupBar

TRzGroupBar

Панель групп для камеры

CameraGroup

TRzGroup

Группа камер

Perspective

TCheckBox

Установить перспективную или ортогональную проекцию

CameraSmooth

TCheckBox

Сглаживание движения камеры

ShotWidth

TRzSpinEdit

Ширина экрана для сохранения

ShotHeight

TRzSpinEdit

Высота экрана для сохранения

CameraFrameRate

TRzSpinEdit

Частота кадров в секунду

CameraSecs

TRzSpinEdit

Количество миллисекунд, за которые будет показана выбранная позиция камеры в видео

CameraStat

TRzStatusBar

Панель для вывода сообщений о размере видео и общем количестве кадров

4.2.15 Обращение к программе

Вызов и загрузка программы осуществляется запуском исполняемого файла Soko.exe. Исполняемый файл должен находится в одной папке с набором дополнительных консольных приложений и директорий, содержащих файловую базу данных к ней (в соответствии со схемой программы, приведённой в приложении 1 на рисунке 1.10).

Входные данные

Входными данными приложения являются:

1) батиметрические треки, получаемые посредством съёмки с помощью картплоттера-эхолота;

2) береговые треки, получаемые с помощью GPS-навигатора;

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

4) информация о размере обрабатываемого участка, качестве обработки, пределах глубины, позициях камеры, режимах отображения, количестве изолиний и прочие настройки состояния системы.

Выходные данные

Выходными приложения являются:

1) батиметрические карты и карты разницы для выбранных участков в чёрно-белом и цветом варианте;

2) изображения трёхмерных срезов батиметрических данных, показанные с определённого ракурса;

3) видео-файлы, представляющие собой съёмку трёхмерной батимет-рической карты с различных ракурсов;

4) батиметрические треки и сетки, готовые для отображения в про-грамме Google Earth;

5) батиметрические сетки в формате.inf для обработки в программном комплексе ANI.

4.3 Сообщения, выдаваемые программисту

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

'Сохранить изменения в файле <имя файла> перед закрытием?';

'Ошибка чтения файла';

'Ошибка чтения таблицы';

'Файл не может быть открыт';

'Файл не содержит корректных данных';

'Сетка не рассчитана';

'Ошибка записи';

'Ошибка чтения';

'Ошибка массива';

'Невозмоно создать контекст устройства OpenGL';

'Не найден подходящий формат пиксела';

'Невозможно установить формат пиксела';

'Невозможно создать контекст воспроизведения OpenGL';

'Контекст воспроизведения OpenGL не может быть активирован';

'Ошибка создания текстуры'.

'Ошибка выделения памяти'

'Дата начала больше даты конца'

5. РУКОВОДСТВО ОПЕРАТОРА

5.1 Назначение

Система обеспечивает выполнение следующих основных функций:

Импорт батиметрическиз данных из исходных треков, получаемых с картплоттера-эхолота, береговых линий из GPS-навигатора а также загрузка сторонних искусственно созданных данных.

Совмещение, компоновка и редактирование данных, исправление ошибок.

Подготовка данных к отображению и обработке: вычитание высоты прилива и сезонных колебаний уровня моря.

Построение и импорт батиметрических карт.

Построение карт сравнения динамики рельефа.

Экспорт данных в различные форматы.

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

5.2 Условия эксплуатации

Разрабатываемая система предназначена для использования на персональных IBM-совместимых компьютерах с центральным Intel-совместимом процессором с частотой работы не менее 1ГГц, оперативным запоминающим устройством объёмом не менее 512 Мб, свободным дисковым пространством не менее 25 Мб для хранения программного обеспечения и 500 Мб для хранения промежуточных данных. Обязательным условием является наличие манипулятора типа «мышь», SVGA-адаптера, совместимого с библиотекой OpenGL и монитора с разрешением не менее 1024х768.

5.3 Выполнение программы

Схема компонентов программы приведена на рисунке 1.10 в приложении 1. Для запуска программы необходимо наличие в каталоге указанных на данной схеме консольных приложений.

После запуска программы открывается два окна - окно настроек слева и окно отображения справа (см. приложение 1, рисунок 3.1).

Окно насроек предоставляет интерфейс ко всем функциональным возможностям программы, кроме управления текущей камерой, которое осуществляется в окне отображения. Окно разделено на несколько логических блоков. Любой элемент интерфейса окна настроек можно масштабировать и сворачивать. Имеется строка меню, панель инструментов и две сворачиваемые панели - панель сцены и панель батиметрии. Панель сцены состоит из двух частей: верхняя часть содержит элементы управления камерами, нижняя - группы настроек текущей сцены. Панель батиметрии также состоит из двух частей: верхняя часть содержит список батиметрических треков и панель управления ими, нижняя - группы настроек выбранного трека. Особенностью интерфейся приложения являются группы - сворачиваемые наборы настроек, объединённые общим назначением. Список доступных групп перечислен в таблице 99.

Таблица 5.1 - Группы интерфейса

Название

Назначение

Расположение

Границы

Постоянные настройки батиме трической сетки, границы, частота сетки, местность

Левая панель

Рельеф

Внешний вид рельефа батиметрической карты

Левая панель

Свет и цвет

Настройка освещения и цветов в программе

Левая панель

Изолинии

Настройка изолиний: расположения, частоты, толщин

Левая панель

Цифры

Настройка цифр-подписей на карте: размера, частоты

Левая панель

Общие настройки

Общие настройки приложения

Левая панель

Правка трека

Правка отдельных точек, смещение всего трека

Правая панель

Прилив

Вычисление и исправление приливов

Правая панель

Расчёт

Расчёт батиметрической сетки

Правая панель

Разность

Вычисление разностей батиметрий

Правая панель

Камера

Создание одиночных изображений и динамических

Левая панель (сверху)

После запуска программы следует нажать первую кнопку с изображением папки в самом верху панели «батиметрии». Это откроет диалоговое окно импорта исходных данных.

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

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

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

Если исходные данные не были загружены в момент запуска, следует импортировать батиметрические данные. Для этого можно выбрать пункт меню Файл>Импорт, либо нажать на изображение папки в правой панели под пустым списком треков - откроется диалоговое окно импорта исходных данных.

В списке возможных форматов находятся описанные ранее варианты загрузки данных. ASCII-координаты могут быть с глубиной, записанной отрицательными либо положительными числами, а координаты могут быть географическими или Меркатора. Также имеется возможность открывать треки необработанных исходных данных, или преобразованных в текст. Полный список форматов импорта показан в таблице 99.

Таблица 5.2 - Форматы импорта

Название формата

Расширения

ASCII координаты эхолота, глубина положительная

*.txt;*.dat

ASCII координаты эхолота, глубина отрицательная

*.txt;*.dat

ASCII координаты в градусах, глубина положительная

*.txt;*.dat

ASCII координаты в градусах, глубина отрицательная

*.txt;*.dat

Lowrance SLG

*.slg

Lowrance SLG преобразованный

*.txt

GPS eXchange

*.gpx

Трек пути из Google

*.kml

Промеры пляжа

*.csv

Предположим, импортируются исходные треки в формате slg. После их загрузки на экране появится изображение. Иногда приборы могут выдать ошибочные данные, что можно легко заметить по резкому перепаду высот. Чтобы устранить ошибки, в группе «правка трека» следует установить флажок «показать», тогда будет выделена выбранная точка (см. рисунок 12). Следует изменить высоту всех ошибочных точек, если таковые имеются.

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

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

После нажатия кнопки «расчёт» следует подождать некоторое время. Отключится часть группы «границы», а к видимым трекам добавится рассчитанная сетка.

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

Экспорт производится аналогично импорту нажатием кнопки экспорта, которая находится справа от кнопок импорта и удаления. Полный список форматов экспорта показан в таблице 99.

Таблица 5.3 - Форматы импорта

Название формата

Расширения

Матрица высот для MathCad

*.grd

Матрица высот для Google

*.kml

Набор точек в географических координатах с положительной глубиной

*.txt

Набор точек для Google

*.kml

Набор точек в координатах меркатора с отрицательной глубиной

*.txt

Трек пути для Google

*.kml

Матрица для ANI

*.inf

Следует обратить особое внимание на внешний вид сцены: при экспорте равномерной сетки в формат kml изображение будет соответствовать текущему изображению на экране, включая скрываемые области, наличие изолиний и остальные настройки.

Для сохранения и загрузки всего состояния системы, сдедует использовать пункты меню «открыть» и «сохранить как…». Данные сохраняются в формате.soko, разработанном специально для данного приложения.

Для сохранения результатов в графическом виде, следует воспользоваться группой «камеры». Установив требуемую ширину и высоту изображения следует нажать на кнопку «сохранить изображение».

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

5.4 Сообщения, выдаваемые оператору

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

'СОКО - сохранение точек';

'СОКО - расчёт триангуляции';

'СОКО - чтение треугольников';

'СОКО - треугольники прочитаны';

'СОКО - временные файлы удалены';

'СОКО - Чтение ASCII';

'СОКО - Чтение slg';

'СОКО - триангуляция';

'СОКО - триангуляция завершена';

'СОКО - создана сетка';

'СОКО - не создана буферная сетка';

'СОКО - создана буферная сетка';

'СОКО - создана текстура';

'СОКО - обнуление сетки';

'СОКО - расчёт треугольников';

'СОКО - расчёт цвета и нормалей';

'СОКО - наложение текстуры';

'СОКО - размытие <номер трека>';

'СОКО - расчёт ошибки';

'СОКО - расчёт цвета';

6. ПРОГРАММА И МЕТОДИКА ИСПЫТАНИЙ

6.1. Объект испытаний

6.1.1 Наименование системы

Наименование системы - Приложение «SOKO».

6.1.2 Назначение системы

Система обеспечивает выполнение следующих основных функций:

Ускорение, упрощение и автоматизация чтения и подготовки исходных данных из различных форматов.

Построение двумерных и трёхмерных батиметрических карт для анализа и обработки в научных лабораториях и для навигационных служб портов.

Быстрое построение батиметрической карты в процессе её съемки на основе имеющихся данных

Экспорт данных в различные графические, текстовые и двоичные форматы.

6.2 Цель испытаний

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

6.3 Требования к программе

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

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

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

6.4 Требования к программной документации

При испытании системы использовались следующие документы:

техническое задание;

руководство оператора;

руководство программиста.

6.5 Состав и порядок испытаний

6.5.1 Технические средства, используемые во время испытаний

Тестирование проводилось на рабочих станциях локальной компьютерной сети предприятия. Компьютеры, используемые для тестирования, соответствуют следующей спецификации: IBM PC совместимый персональный компьютер, оснащённый процессором с тактовой частотой не менее 2,7 ГГц, оперативной памятью не менее 8 Гб, графической подсистемой с памятью не менее 2 Гб, устройствами ввода (клавиатура и манипулятор мышь).

6.5.2 Программные средства, используемые во время испытаний

Во время испытаний использовалось программное обеспечение:

операционная система Microsoft Windows XP (32-битная), Windows 7 (32-битная), Windows 7 (64-битная);

среда разработки Borland C++ Builder.

6.5.3 Порядок испытаний

Испытания программы проводились в следующем порядке:

испытание на корректность (адекватно ли программа реагирует на ввод-вывод информации);

испытание на правильность (соответствуют ли полученные результаты ожидаемым);

испытание на надежность (процент отказов и сбоев системы).

6.6 Методы испытаний

6.6.1 Проверка на корректность

После запуска исполняемого файла Soko.exe на экране появляются окно отображения и настройки (рисунок 3.1). В окне настроек предлагается произвести импорт исходных данных. В случае открытия неподходящего файла, пользователь получает соответственное сообщение (рисунок 3.2) и может продолжить работу с программой.

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

Пользователь имеет возможность задать любой размер рассчитываемой сетки. Если память, необходимая для выделения в программе превысит ресурсы системы, пользователь получает соответственное сообщение (рисунок 3.3) и может продолжить работу с программой.

Проверки на корректность входных данных и результата осуществляются в ходе работы пользователя на всех этапах его деятельности с использованием данной системы.

Возможные ошибочные ситуации во время работы программы и реакция на них системы приведены в таблице 5.1.

Следует отметить, что в целом интерфейс пользователя и порядок реализации функций программы спроектированы таким образом, чтобы избежать ошибочных ситуаций из-за неграмотных действий оператора. Тем не менее, иногда такие случаи возможны, ввиду того, что программа полагается при выполнении вычислений на пользовательские настройки.

Таблица 6.1 - Проверка на корректность

Проверка

Рабочая операция

Причина ошибочной ситуации

Способ устранения

Корректность обработки заданного размера сетки (рис. 3.6, рис. 3.7)

Расчёт батиметрической сетки

введено слишком большое число

Ввести меньшее число, такое, чтобы программа смогла ввыделить соответствующий участок памяти

Корректность вычисления прилива

Вычисление прилива

Дата начала больше даты конца трека

Установить дату начала меньше даты конца трека

Корректность октрытия файла

Открытие импорт файлов

Файл повреждён или имеет неверные данные

Открыть другой файл

6.6.2 Проверка на правильность

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

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

При проверке на правильность результат построяния батиметрических карт не отличается от ожидаемого, поэтому можно утверждать, что программа работает правильно.

6.6.3 Проверка на надежность

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

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

7. ОРГАНИЗАЦИОННО-ЭКОНОМИЧЕСКАЯ ЧАСТЬ

7.1 Расчет трудоемкости разработки программного обеспечения

В качестве объекта расчета взят вариант создания программного обеспечения, разработанного с использованием среды программирования Borland C++ Builder 6.

Проведем расчёт затрат времени на выполнение работ по созданию программного обеспечения, в котором выделим два этапа:

составление необходимого перечня работ и их кодирование;

установление оценок времени продолжительности работ.

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

, (7.1)

где tmin - оптимистическая оценка, при наиболее благоприятных условиях, tmax - пессимистическая оценка, при неблагоприятных условиях.

Рассчитаем трудоемкость разработки программного обеспечения.

Расчёт трудоемкости приведен в таблице 7.1. В результате предполагаемая продолжительность работы составляет 101 человеко-день.

Таблица 7.1 - Расчет трудоемкости программного обеспечения и оптимизация на основе экспертных оценок

Формулировка работы

Вероятностные оценки

tmin

tmax

tож

Постановка задачи

2

4

3

Сбор данных о предметной области

20

30

25

Оформление ТЗ

2

4

2,8

Разработка метода реализации задачи

30

40

35

Формирование структуры программного обеспечения

5

7

5,8

Разработка структуры файловой базы данных

1

2

1,2

Разработка графических модулей для работы с OpenGL (освещение, камера, текстуры и прочие)

12

15

13,5

Разработка контейнерных типов данных

4

8

6

Разработка ядра системы - модуля работы с батиметрией

15

20

13,5

Разработка интерфейса пользователя

10

15

12

Комплексное тестирование и отладка системы

6

10

7

Документирование системы

5

10

7

Итого

88

127

101

7.2 Определение себестоимости разработки программы

Стоимость разработки программы состоит в общем виде из затрат на разработку модулей информационной системы. Себестоимость разработки включает в себя следующие статьи расходов:

материальные затраты;

затраты на оплату труда разработчику;

отчисления во внебюджетные фонды;

налог на имущество;

затраты на электроэнергию;

расходы по эксплуатации оборудования;

общехозяйственные расходы;

прочие расходы.

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

Затраты на оплату труда разработчиков программы рассчитываются на основе данных о тарифных ставках, трудоемкости подготовки программного обеспечения и совокупности доплат и надбавок работникам. Трудоемкость разработки программного обеспечения рассчитывается в человеко-часах и определяется на базе скорректированных отчётных данных по аналогичным работам.

Норматив отчислений на страхование для бюджетных организаций производится в размере 34% от общего фонда заработной платы.

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

Общехозяйственные расходы составляют 75% от затрат на оплату труда разработчиков, прочие расходы - 10%.

7.2.1 Расчёт материальных затрат

В таблице 7.2. представлены данные о материалах, используемых для решения поставленной задачи.

Таблица 7.2 - Материальные затраты

Наименование материала

Количество комплектов, шт.

Цена комплекта, р.

Сумма затрат, р.

Картридж для принтера

1

1 200

1 200

Бумага для принтера

1

180

180

Итого

1 380

7.2.2 Затраты на оплату труда разработчика и налоговые отчисления

Месячная зарплата программиста - 21000 р.

Дневная зарплата программиста (21 рабочий день в месяце) - 1 000 р.

Тогда при трудоемкости 101 человеко-день оплата труда программиста по разработке системы составляет 101 000 р.

Отчисления во внебюджетные фонды при трудоемкости 104 ч/дн составляют 34% от зарплаты программиста (в рублях): 0,34?101000 = 34340.

7.2.3 Расходы на эксплуатации оборудования

Затраты на электроэнергию

Основным оборудованием, используемым при разработке системы, являются персональный компьютер (потребляемая мощность данного устройства составляет около 0,5 кВт), печатающее устройство (принтер), потребляемая мощность которого составляет 0,02 кВт.

Средняя стоимость 1 кВт/час для предприятий составляет 3,72 р.

При трудоемкости 101 ч/дн компьютеры использовались 808 часа, принтер эксплуатировался около 19 часов.

В итоге затраты на оплату электропитания составили:

для компьютера: 0,5?808?3,72 = 1502,88,

принтера: 0,02*19*3,72 = 1,41.

Амортизационные отчисления

При годовой амортизации в 12,5%, дневная амортизация оборудования равна 12,5/365 = 0,034%.

Стоимость компьютера с установленным системным программным обеспечением составляет 40 000 р. При указанной выше дневной амортизации и при условии использования серверного компьютера в течение 101 ч/дня, суммарная амортизация за период разработки системы составила 101?40000?0,00034 = 1373,6.

Стоимость принтера Hewlett Packard HP LaserJet 1010 составляет 3000 рублей. При указанной выше дневной амортизации и при условии использования этого устройства в течение 19 ч. (0,79 дня), суммарная амортизация за период разработки системы составила 0,79*3000*0,00034 = 0,80.

Обобщение расходов на эксплуатацию оборудования дано в таблице 7.3.

Таблица 7.3 - Расходы по эксплуатации оборудования при трудоёмкости 104 человека-дня

Вид оборудования

Время использования, дн.

Электроэнергия, р.

Амортизационные отчисления, р.

Суммарные затраты, р.

Клиентский IBM PC

101

1502,9

1373,6

2977,5

Лазерный принтер HP LaserJet 1010

0,79

1,41

0,8

3

Итого

1504,3

1374,4

2980,5

7.2.4 Общехозяйственные и прочие расходы

Общехозяйственные расходы составляют 75% от затрат на оплату труда разработчика. Таким образом, при трудоемкости разработки в 104 ч/дня данная статья расходов будет равна 101000 ? 0,75 = 75 750.

Прочие расходы составляют 10% от затрат на оплату труда разработчика, и равны 101000*0,10 = 10 100.

7.2.5 Расчет общей себестоимости разработки

Общие затраты на разработку комплекса сведены в таблицу 7.4.

Таблица 7.4 - Общие затраты на разработку комплекса

Наименование статьи расхода

Сумма, р.

Материальные затраты

1 380,00

Затраты на оплату труда разработчика

101 000,00

Единый социальный налог

34340,00

Расходы по эксплуатации оборудования

2 980,5

Общехозяйственные расходы

75 750,00

Прочие расходы

10 100,00

Итого

225 550,50

7.3 Капитальные вложения по внедрению системы

Для внедрения системы необходимо закупить более мощный компьютер, чем до него. Стоимость аппаратного обеспечения вместе с установленной на каждый из компьютеров операционной системой Microsoft Windows XP составляет 57 000 р.

Ремонт и обслуживание составляют 2% от стоимости оборудования и оцениваются в 57000 ? 0,02 = 1140.

Рассчитаем затраты на электроэнергию при внедрении системы.

Мощность компьютера составляет 0,5 кВт. Стоимость 1 кВт/час - 3,72 р. Представим, что обработка батиметрических данных необходима лаборатории каждый день. Тогда для создания одной батиметрической карты в день потребуется не более 30 минут = 0,5 часа в день.

3,72 ? 0,5 ? 0,5 ? 500 = 465 в год на один компьютер.

Рассчитаем зарплату персонала. Работой с системой занимается 1 техник. Годовая заработная плата техника составляет 12 ? 18 000 = 216000. Согласно должностной инструкции время, потраченное на работу с системой, составляет 5% от общего фонда времени. Значит, стоимость обслуживания системы за год составляет 216000 ? 0,05 = = 10800. Подведем итог в таблице 7.5.

Таблица 7.5 - Суммарные затраты на эксплуатацию системы

Наименование

Стоимость, р.

Расходы на электроэнергию

465

Ремонт и обслуживание

1 140

Оплата персонала

10 800,00

Итого

12 405

7.4 Расчет годовой экономии от эксплуатации

7.4.1 Расчет годовых расходов при неавтоматизированном создании батиметрических карт

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

Оценим затраты на оплату труда. Средняя месячная заработная плата техника лаборатории с требуемой квалификацией составляет 18 000 р. Оплата за 1 год составляет 18 000 ? 12 = 216000.

Оценим затраты на оплату труда. Средняя месячная заработная плата лаборанта кафедры с требуемой квалификацией составляет 18 000 р., младшего научного сотрудника- 25 000 р.

Оплата за 1 год на двух работников составляет 43 000?12 = 516 000.

Отчисления во внебюджетный фонд (34%) составляют 516 000? 0,34 = = 175 440.

Общехозяйственные расходы от затрат на оплату труда (75%) составят 516 000? 0,75 = 387 000.

Прочие расходы от затрат на оплату труда (10%): 516 000 ? 0,1 = = 51 600.

При необходимости печатать одну батиметрическую карту в день при 250 рабочих днях в году, в год требуется 0,5 упаковки бумаги для принтеров в 500 листов стоимостью 180 руб. При стоимости картриджа для цветного принтера в 3290 руб., его ресурс 2200 страниц, тоесть 250/2200=11% запаса картриджа в год.

Таблица 7.6 - Затраченные материальные ресурсы при неавтоматизированном способе управления

Наименование материала

Количество, шт.

Цена комплекта, руб.

Годовые затраты, руб.

Картридж для принтера

0,11

3290

361,9

Бумага для принтера

0,5

180

90

Итого

451,9

7.4.2 Расчет годовых расходов при автоматизированном создании батиметрических карт

Оценим затраты на оплату труда. Средняя месячная заработная плата техника лаборатории с требуемой квалификацией составляет 18 000 р.

Оплата за составляет 18 000 ?12 = 216 000.

Отчисления во внебюджетный фонд (34%) составляют: 216 000?0,34 = =73440.

Общехозяйственные расходы (75%) составят 216 000 ? 0,75 = 162 000. Прочие расходы (10%) составят 216 000 ? 0,1 = 21 600.

При необходимости печатать одну батиметрическую карту в день при 250 рабочих днях в году, в год требуется 0,5 упаковки бумаги для принтеров в 500 листов стоимостью 180 руб. При стоимости картриджа для цветного принтера в 3290 руб., его ресурс 2200 страниц, тоесть 250/2200=11% запаса картриджа в год.

Наименование материала

Количество, шт.

Цена комплекта, руб.

Годовые затраты, руб.

Картридж для принтера

0,11

3290

361,9

Бумага для принтера

0,5

180

90

Итого

451,9

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

Таблица 7.8 - Расчёт расходов при ручном и автоматизированном способах работы с учетом годовой загрузки

Наименование статьи расходов

Неавтоматизированный способ, руб.

Автоматизированный способ, руб.

Материальные затраты

451,9

451,9

Затраты на оплату труда

516 000

216 000

Отчисления во внебюджетные

фонды

175 440

73440

Общехозяйственные расходы

387 000

162 000

Прочие расходы

51 600

21 600

Итого

614 491,9

257 491,9

Приведённый выше расчет годовых эксплуатационных расходов при неавтоматизированном и автоматизированном способах работы показывает, что расходы для первого способа составляют 614 491,9 р., а для второго - 257 491,9 р. Таким образом, годовая экономия для автоматизированного способа работы составляет 357 000р. в год.

7.5 Определение экономической эффективности

К показателям экономической эффективности внедрения новой технологии обработки информации относятся следующие показатели:

годовой экономический коэффициент от внедрения технологии;

коэффициент эффективности капитальных вложений;

срок окупаемости капитальных вложений.

Годовой экономический эффект

Э = ( ЭГ - ЕН · КД ) · КТ, (7.2)где ЭГ - годовая экономия текущих затрат, ЕН - нормативный коэффициент эффективности капвложений - 0,15, КД - дополнительные капитальные вложения; КТ - коэффициент, учитывающий преимущество ускорения обработки информации, равный 1,25;

Э = (357 000- 0,15 · (225 550,50 + 12 405)) · 1,25 = 321306,68.

Расчетный коэффициент экономической эффективности капитальных затрат ЕР представляет собой отношение годовой экономии к капитальным затратам на разработку и внедрение программного обеспечения:

Ер = ЭГ / КД, (7.3)

где ЭГ - годовая экономия текущих затрат, Кд - дополнительные капитальные вложения, Ер = 357 000 / (225 550,50 + 12405) = 1,5.

Срок окупаемости (Т) представляет собой отношение капитальных затрат на разработку и внедрение ИС к годовой экономии составит следующее количество лет:

Т = КД / ЭГ = 1 / Ер, (7.4)

Т = 1 / 1,5 = 0,(6).

Получаем, что затраты на покупку данной программы окупаются за период, равный примерно 8 месяцам.

Заключение

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

Реализация программного комплекса проведена с использованием среды разработки приложений Borland C++ Builder 6 на языке программирования C++.

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

Также был проведена оценка экономической эффективности разработки данного комплекса.

Таким образом, все задачи дипломного проектирования полностью решены.

Список использованных источников

1. Вендров А.М. CASE-технологии. Современные методы и средства проектирования информационных систем. / А.М. Вендров. - М.: Финансы и статистика, 1998. - 176 с.

2. Буч Г. Объектно-ориентированное проектирование с примерами применения / Г. Буч - Киев: Диалектика, 1992. - 800 c.

3. Гуннерсон Э. Введение в C#. Библиотека программиста. / Э. Гуннерсон -СПб.: Питер, 2001. -304 с.

4. Дейт К. Введение в системы баз данных. / К. Дейт М., -СПб., Киев: Издательский дом «Вильямс». 2000. -950 с.: ил.

5. Конноли Т. Базы данных: проектирование, реализация, сопровождение / Т. Конноли, К. Бегг, А. Страчан. - М.: издательский дом «Вильямс», 2000. -1120 с.

6. Кратчен Ф. Введение в Rational Unified Process. / Ф. Кратчен - М.: Вильямс. 2002. - 456 с.

7. Лупин С.А. Архитектура электронных вычислительных машин. / С.А. Лунин - М.: Инфра-М, 2009. -458 с.

8. Мамаев Е. Microsoft SQL Server 2000. / Е. Мамаев -СПб.: БХВ-Петербург, 2002. -1200 с.

9. Мюллер Р. Базы данных и UML проектирование. / Р. Мюллер -М.: Лори, 2002. - 420 с.

10. Нейбург Э. Проектирование баз данных с помощью UML. / Э. Нейбург, Роберт Максимчук -М.: Вильямс, 2002. -288 с.

11. Робинсон С. Язык программирования C# для профессионалов. Том 1. / С. Робинсон - М.: Лори, 2003. - 478 с.

12. Робинсон С. Язык программирования C# для профессионалов. Том 2. / С. Робинсон- М.: Лори, 2003. - 523 с.

13. Троелсен Э. Язык программирования C# / Э. Троелсен -СПб.: Питер, 2002. - 800 с.

14. Хомоненко А.Д. Базы данных. / А.Д. Хомоненко, М.Г. Мальцев, В.М. Цыганков - СПб: КОРОНА принт, 2000. - 345 с.

15. Шилдт Г. C#: учебный курс. / Г. Шилдт - СПб.: Питер, 2002. - 512 с.

ПРИЛОЖЕНИЕ 1

СТРУКТУРНЫЕ СХЕМЫ

Рис. 1.1

Рис. 1.2

Рис. 1.3

Рис. 1.4

Рис. 1.5

Рис. 1.6

Рис. 1.7

Рис. 1.8

Рис. 1.9

Рис. 1.10

ПРИЛОЖЕНИЕ 2

Окна программы

Рис. 2.1

Рис. 2.2

Рис. 2.3

Рис. 2.4

Рис. 2.5

Рис. 2.6

Рис. 2.7

Рис. 2.8

Рис. 2.9

Рис. 2.10

Рис. 2.11

Рис. 2.12

Рис. 2.13

Рис. 2.14

Рис. 2.15

Рис. 2.16

Рис. 2.17

Рис. 2.18

Рис. 2.19

Рис. 2.20

Рис. 2.21

Рис. 2.22

Рис. 2.23

Рис. 2.24

Рис. 2.25

Рис. 2.26

Рис. 2.27

Рис. 2.28

Рис. 2.29

Рис. 2.30

Рис. 2.31

Рис. 2.32

Рис. 2.33

Рис. 2.34

Рис. 2.35

Рис. 2.36

Рис. 2.37

ref.by 2006—2025
contextus@mail.ru