note_awardx

advertisement
1
Федеральное агентство по образованию
Государственное образовательное учреждение
высшего профессионального образования
«ИЖЕВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Факультет «Информатика и вычислительная техника»
Кафедра «Программное обеспечение»
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к дипломной работе на тему:
«Автоматизированная система ввода плана эвакуации для разработки паспортов
безопасности учебных заведений РФ»
Дипломник
студент группы 10-19-3
А.А. Яценко
Руководитель
(д.т.н., профессор,
научный рук-ль «ИИПиТК»)
В.М. Колодкин
Консультант по экономической части
(к.э.н., доцент)
И.И. Радыгина
Консультант по безопасности
и экологичности проекта
Н.А. Баранова
Нормоконтроль
В.П. Соболева
Рецензент
(ИТ специалист ООО «ИжИнфоТех»)
А.А.Селиванов
Заведующий кафедрой
«Программное обеспечение»
(к.т.н., доцент)
И.О. Архипов
Ижевск 2009
2
РЕФЕРАТ
Пояснительная
записка
к
дипломной
работе
на
тему
«Разработка
автоматизированной системы для контроля работы команды разработчиков»
оформлена на 126 листах, содержит 23 рисунка, 22 таблицы.
Система разрабатывается в рамках выигранного гранта по теме «Паспорт
безопасности образовательного учреждения как основа управления рисками в
образовательных учреждениях России». Регистрационный номер проекта:
2.2.3.2/936.
1. Краткое описание проекта
Разработка,
опытная
эксплуатация
и
сопровождение
проблемно-
ориентированного Сервиса (технология клиент-сервер) для создания Паспортов
безопасности образовательных учреждений России ("РИСК-АНАЛИТИК ОУ").
2. Цели и задачи проекта
Снижение рисков и уменьшение последствий чрезвычайных и кризисных
ситуаций в системе высшего профессионального образования России.
1. Адаптация методик риск-анализа, адаптация существующих и разработка
новых моделей эвакуации, применительно к условиям образовательных
учреждений (ОУ) России.
2. Разработка инструментария и общих баз данных для создания Паспортов
безопасности ОУ России.
3. Подготовка и переподготовка специалистов ОУ России в области рисканализа с целью приобретения навыков формирования Паспортов безопасности.
4. Отработка технологии формирования Паспорта безопасности в режиме
удаленного доступа (режим тестирования).
3
5. Обеспечение доступа со стороны ОУ России к инструментарию для
формирования Паспорта безопасности на единой методологической основе, на
единой базе данных по частотам аварийных событий.
6. Разработка методологии и инструментария для ранжирования ОУ России
по уровню потенциальной аварийной опасности.
7. Техническая и методическая поддержка работ по паспортизации ОУ
России.
3. Актуальность выполнения проекта
Необходимое условие снижения ущерба от аварий и катастроф в ОУ России–
количественная оценка уровня опасности. То есть необходимо сделать срез
уровня опасности по ОУ России на сегодняшний день, выделить учреждения с
высокими рисками. Тем самым дать возможность работы экономическим,
организационным рычагам управления риска. Срез уровня опасности, сделанный
через определенное время, позволит проверить эффективность мер и, при
необходимости, откорректировать меры для достижения требуемого уровня
риска в условиях существующих финансовых возможностей. На оценку уровня
опасности направлены меры по внедрению в практику технологии оценки рисков
посредством подготовки Паспорта безопасности ОУ. При этом для всех ОУ
России желательно использовать один доступный всем инструментарий,
использовать единые базы данных. Для достижения этих целей предлагается
использовать возможности современных информационных технологий.
4. Предполагаемые пути получения результата
1. Создание Сервиса "РИСК-АНАЛИТИК ОУ" в рамках существующего
электронного ресурса "Безопасность в техносфере", для решения задач, входящих
в Паспорт безопасности образовательного учреждения. Доступ к Сервису
осуществляется через сеть Интернет. Сервис поддерживает открытый банк
4
моделей для прогнозирования и управления рисками, для моделей эвакуации в
условиях ЧС.
2. Разработка электронного ресурса для обучения использования Сервиса при
подготовке Паспорта ОУ (с использованием дистанционных технологий).
3. Отработка технологии построения Паспортов на базе "РИСК-АНАЛИТИК
ОУ" на примере государственных университетов Удмуртии.
4. Обеспечение доступа к Сервису со стороны ОУ России, с целью
формирования Паспорта и одновременного поиска путей снижения рисков.
5. Сопровождение Сервиса, сопровождение доступа к Сервису.
Целью данной работы было создание автоматизированной системы,
позволяющей вводить план эвакуации с последующей передачей его в один из
расчетных модулей (моделирование пожара или эвакуация людей), чтобы учесть
все тонкости каждого модуля, была разработана общая спецификация входных
данных, представляющая из себя структурированный xml (eXtended Markup
Language) файл.
Система является частью расчетного - комплекса «Риск-аналитик». Данный
сервис предоставляет возможность осуществлять расчеты по прогнозированию
последствий аварий различного типа. Для каждого типа аварий (взрыв газа в
помещении, пожар пролива, химические аварии и т.д.) есть отдельный модуль,
позволяющий вводить исходные данные по аварии и отображать результаты
расчетов. Расчеты происходят на удаленном высокопроизводительном сервере. В
качестве канала связи программы и сервера используется сеть интернет.
Для написания соответствующего программного обеспечения были изучены
необходимые нормативные документы.
На сегодняшний день не существует ни единый системы по вводу плана
эвакуации. Хотя многие САПР системы, такие как ArchiCAD, Компас+, MS
5
Visio, позволяют чертить план эвакуации, но ни одна из них не позволяет
учитывать специфику помещения.
6
СОДЕРЖАНИЕ
ВВЕДЕНИЕ .............................................................................................................. 9
1. РАЗРАБОТКА АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ ВВОДА ПЛАНА
ЭВАКУАЦИИ ДЛЯ РАЗРАБОТКИ ПАСПОРТОВ БЕЗОПАСНОСТИ УЧЕБНЫХ
ЗАВЕДЕНИЙ РФ ................................................................................................... 11
1.1. Обоснование целесообразности разработки автоматизированной системы
ввода плана эвакуации для разработки паспортов безопасности учебных
заведений РФ ...................................................................................................... 11
1.1.1. Назначение системы ............................................................................. 11
1.1.2. Характеристика функциональной структуры системы..................... 11
1.1.3. Обоснование цели создания системы ................................................. 13
1.1.4. Обоснование состава автоматизируемых задач................................. 13
1.3. Основные требования к системе ............................................................... 14
1.3.1. Основные цели создания системы и критерии эффективности ее
функционирования ......................................................................................... 14
1.3.2. Функциональное назначение системы................................................ 14
1.3.3. Особенности системы и условия ее эксплуатации ............................ 15
1.3.4. Требования к функциональной структуре ......................................... 15
1.3.5. Требования к техническому обеспечению ......................................... 17
1.3.6. Требования к информационному обеспечению ................................ 17
1.3.7. Требования к программному обеспечению........................................ 17
1.3.8. Перспективность системы, возможность ее развития ...................... 18
1.4. Основные технические решения проекта системы ................................. 18
1.4.1. Решения по комплексу технических средств ..................................... 18
1.4.2. Описание системы программного обеспечения ................................ 19
2. РАЗРАБОТКА ЗАДАЧИ «АВТОМАТИЗИРОВАННАЯ СИСТЕМА ВВОДА
ПЛАНА ЭВАКУАЦИИ ДЛЯ РАЗРАБОТКИ ПАСПАРТОВ БЕЗОПАСНОСТИ
УЧЕБНЫХ ЗАВЕДЕНИЙ РФ» ............................................................................ 20
2.1. Описание постановки задачи ..................................................................... 20
7
2.1.1. Характеристика задачи ......................................................................... 20
2.1.2. Входная информация ............................................................................ 21
2.1.3. Выходная информация ......................................................................... 21
2.2. Описание модуля реализации пользовательского интерфейса .............. 21
2.2.1. Назначение и характеристика модуля ................................................ 21
2.2.2. Требования к контрольному примеру................................................. 22
2.3. Описание модуля рабочей поверхности ................................................... 22
2.3.1. Назначение и характеристика модуля ................................................ 22
2.3.2. Описание алгоритма сохранения…………………………………22
2.4. Описание модуля инструментария .......................................................... 255
2.4.1. Назначение и характеристика модуля ................................................ 25
2.4.2.
Характеристика инструмента «Лифт»……………………………25
2.4.3.
Характеристика инструмента «Помещение»…………………….25
2.4.4.
Характеристика инструмента «Стена»…………………………...28
2.4.5.
Характеристика инструмента «Дверь»…………………………...28
2.4.6.
Характеристика инструмента «Окно»………….….….……...…..28
2.4.7.
Характеристика инструмента «Лестница»……….….…...….…...28
2.4.8.
Описание алгоритма отрисовки…………………………..……....28
2.4.9.
Список условных обозначений…………………………..……….28
2.4.11. Требования к контрольному примеру ........................................ ....322
2.5. Описание программы «Автоматизированная система ввода плана эвакуации
для разработки паспортов безопасности учебных заведений РФ» .............. 32
2.5.1. Описание логики ................................................................................... 33
2.6. Описание контрольного примера .............................................................. 34
2.6.1. Назначение ............................................................................................. 34
2.7. Исходные данные ........................................................................................ 35
2.7.1. Результаты работы задачи.................................................................... 35
2.7.2. Результаты испытания .......................................................................... 36
8
3. ОРГАНИЗАЦИОННО – ЭКОНОМИЧЕСКАЯ ЧАСТЬ. ............................... 38
3.1.Расчет бюджета на разработку НИР ............................................................. 42
3.1.1.Расходы на материалы и амортизацию .................................................. 42
3.2.2.Расходы на оплату труда .......................................................................... 44
3.2.3.Единый социальный налог....................................................................... 46
3.2.4.Накладные расходы .................................................................................. 46
3.2.5.Прочие расходы ........................................................................................ 47
3.3. Бюджет затрат.............................................................................................. 47
4. БЕЗОПАСНОСТЬ И ЭКОЛОГИЧНОСТЬ ПРОЕКТА .................................. 49
4.2. Анализ вредных и опасных факторов ..................................................... 511
4.2.2. Постоянное напряжение глаз ............................................................. 522
4.2.3. Влияние электростатических и электромагнитных полей ............. 522
4.2.4. Длительное неизменное положение тела ......................................... 533
4.2.5. Шум ...................................................................................................... 544
4.3. Пожаробезопасность и электробезопасность......................................... 555
4.4. Расчет требований к рабочему месту инженера-программиста .......... 577
ЗАКЛЮЧЕНИЕ ................................................................................................... 633
СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ ............................................... 644
ПРИЛОЖЕНИЕ 1 КОНТРОЛЬНЫЙ ПРИМЕР ................................................. 67
ПРИЛОЖЕНИЕ 2 КОД ПРОГРАММЫ.............................................................. 72
ПРИЛОЖЕНИЕ 3 РУКОВОДСТВО ОПЕРАТОРА ПО ПРОГРАММЕ
«АВТОМАТИЗИРОВАННАЯ СИСТЕМА ВВОДА ПЛАНА ЭВАКУАЦИИ ДЛЯ
РАЗРАБОТКИ ПАСПОРТОВ БЕЗОПАСНОСТИ УЧЕБНЫХ ЗАВЕДЕНИЙ РФ»
1099
ПРИЛОЖЕНИЕ 4 РУКОВОДСТВО ПРОГРАММИСТА ПО ПРОГРАММЕ
«АВТОМАТИЗИРОВАННАЯ СИСТЕМА ВВОДА ПЛАНА ЭВАКУАЦИИ ДЛЯ
РАЗРАБОТКИ ПАСПОРТОВ БЕЗОПАСНОСТИ УЧЕБНЫХ ЗАВЕДЕНИЙ РФ»
121
9
ВВЕДЕНИЕ
Современный мир находится на грани техногенных катастроф. С каждым
годом катастрофы становятся более масштабными и более опасными.
Человечество ощутило и осознало техногенные опасности и угрозы
значительно позже, чем природные. В ХХ веке, в связи с бурным развитием
техносферы, наряду с повышением комфорта, в жизнь людей вторглись
техногенные бедствия, источником которых являются аварии и техногенные
катастрофы, создавшие в настоящее время угрозу благополучного существования
не только отдельных государств, но и человечество в целом.
Обеспечение безопасности – одна из основных задач, стоящих перед
центральными и местными органами власти России. Особая актуальности
проблематики обеспечения безопасности в настоящее время связана СС
сохраняющейся угрозой террористических действия, а также нарушением в
работе производств и коммунальных служб из-за изношенности основных
фондов.
Существованию
внутренней
напряженности
и
низкого
уровня
безопасности способствуют некоторые нежелательные процессы, идущие в
экономики, политике, социальной, культурной сферах, а также постоянно
растущая загруженности автомобильных трасс,
переполненность остановок
городского транспорта и других мест скопления людей. Статистические данные
по городам и регионам Российской Федерации свидетельствуют о том, что
ситуация по некоторым социально значимым вопросам близка к предельным
допустимым нормам.
В решении этих задач значительную поддержку могут оказать современные
технологии. Уровень их развития в настоящее время позволяет создавать
интеллектуальные
межведомственные
территориально
–
распределенные
системы, способные регистрировать, обрабатывать, хранить и анализировать
значительные объемы разнородной информации. Эти системы позволяют
10
осуществлять достаточно эффективный контроль над обстановкой в регионе и
таким образом влиять на уровень безопасности. Существенным элементом такой
комплексной системы является возможность
особо опасных объектов.
самостоятельной паспортизации
11
1. РАЗРАБОТКА АВТОМАТИЗИРОВАННОЙ СИСТЕМЫ ВВОДА ПЛАНА
ЭВАКУАЦИИ ДЛЯ РАЗРАБОТКИ ПАСПОРТОВ БЕЗОПАСНОСТИ
УЧЕБНЫХ ЗАВЕДЕНИЙ РФ
1.1.
Обоснование целесообразности разработки автоматизированной
системы ввода плана эвакуации для разработки паспортов безопасности
учебных заведений РФ
1.1.1. Назначение системы
Система автоматизированного ввода плана эвакуации для разработки
паспортов
безопасности
учебных
заведений
РФ
предоставляет
простой
графический инструмент для ввода плана эвакуации с учетом таких специфики,
как размеры, материалы и тип помещения (исходя из расчетов пожарной
нагрузки). Выходными данными системы является структурированный xml –
файл, с последующей его передачи в один из расчетных модулей.
В настоящее время не существует ни единого программного комплекса,
который автоматизировал бы ввод плана эвакуации.
1.1.2. Характеристика функциональной структуры
системы
Работа с системой делится на следующие этапы (рис. 1.1):
1) MainWindow – главный модуль программы, реализует пользовательский
интерфейс, и такие вспомогательные функции, как сохранении/загрузка, экспорт,
печать;
2) DiagramScene – модуль управляет элементами без их графического
отображения;
3) DiagramDrawItem – модуль является основным для элементов, реализует
события мыши и перетаскивание;
12
4) DiagramTextItem – модуль для работы с текстом;
Схема системы ввода плана эвакуации для разработки паспортов безопасности
учебных заведений РФ
DiagramScene
DiagramDrawItem
MainWindow
DiagramTextItem
Рис. 1.1
Система автоматизированного ввода плана эвакуации для разработки
паспортов безопасности учебных заведений РФ является неотъемлемой частью
программного комплекса «Риск – аналитик». Схема комплекса в виде блоков
приведена на рис. 1.2.
модуль
Ядро
Карты
Ядро для
модулей
INTD
Рис. 1.2
– блок «INTD» – студия, программный комплекс, который содержит в
себе все расчетные модули. Представляет из себя «Все – в – одном», одна
программа содержит все расчетные модули;
13
– блок «Ядро» – основной модуль, в нем хранятся математические
методы расчетов, наложение сетки;
– блок «Ядро модулей» – содержит все типы расчетных модулей;
– блок «Карты» – некоторые модули используют для расчетов карту;
– блок «Модуль» – расчетный модуль, система автоматизированного
ввода плана эвакуации является этим самым модулем.
1.1.3. Обоснование цели создания системы
Разработка паспортов безопасности - трудоемкая многоплановая работа,
включающая в себя анализ и расчёт риска возникновения аварийных ситуаций и
их последствий. Все
разработкой
паспортов
это предполагает в организациях, занимающихся
безопасности,
наличие
высококвалифицированных
специалистов с опытом работы и новейших программных продуктов.
Автоматизация процессов, связанных с такой деятельностью не только
облегчает работу, но и существенно уменьшает временные затраты на данный
вид работ, и результаты являются более точными.
Целью данной работы является разработка системы автоматизированного
ввода плана эвакуации для разработки паспортов безопасности учебных
заведений РФ, которая была бы проста в использовании и имела дружелюбный
пользовательский интерфейс.
1.1.4. Обоснование состава автоматизируемых задач
Реализация системы автоматизированного ввода плана эвакуации для
разработки паспортов безопасности учебных заведений РФ:
1) инструментарий
для
работы
с
графическими
примитивами,
отображающих реальные физические объекты, каждый со своими
уникальными свойствами и атрибутами;
14
2) расчет пожарной нагрузки, каждого помещения в соответствии НПБ 10503;
3) логическая реализация плана, для каждой двери присваивается те
помещения, которые она соединяет, а для помещения указывается окна.
Необходимо для расчета модели эвакуации и распространение пожара.
1.2.
Аналитический обзор
Как уже было указано выше, не существует ни одной системы по
редактированию плана эвакуации.
1.3.
Основные требования к системе
1.3.1. Основные цели создания системы и критерии эффективности ее
функционирования
Создание автоматизированной
разработки
паспортов
системы
безопасности
ввода плана эвакуации для
учебных
заведений
РФ
позволит
самостоятельное изготовление паспорта безопасности с учетом всех требований
МЧС и пожарных служб.
1.3.2. Функциональное назначение системы
Автоматизация процесса ввода плана эвакуации подразумевает реализацию
в
системе
определенных
средств
и
функций.
Следует
выделить
функциональных особенностей, которыми должна обладать система ввода:
1) поэтажное черчение плана этажа;
2) экспорт готового плана в растровое или векторное изображение;
3) сохранение и загрузка плана в файл-проект;
4) расчет пожарной нагрузки каждого помещения, кабинета;
ряд
15
5) каждый элемент имеет свои уникальные свойства.
1.3.3. Особенности системы и условия ее эксплуатации
Автоматизированная система ввода плана эвакуации для разработки
паспортов безопасности учебных заведений РФ предназначена для ввода плана и
с последующей передачей его в расчетный модуль. Расчетные модули хранятся
на серверах «Института Исследования Природных и Техногенных Катастроф»,
поэтому для работы необходимо действующее подключение к Интернету.
Тем самым данный комплекс относится к новому типу приложений, так
называемому
«приложение + сервис» или “Software + Services (S+S)”.
Приложение – как правило, является пользовательским интерфейсом, а сами
расчету и различные модели выполняются на стороне какого – либо сервера, о
котором пользователь не догадывается. Такие расчеты называются «Облачными
вычислениями» или “Computing Cloud”.
К скорости передачи данных не предъявляется никаких высоких требований.
1.3.4. Требования к функциональной структуре
Построение автоматизированной системы ввода плана эвакуации для
разработки паспортов безопасности учебных заведений РФ подразумевает
модульную структуру. Общий интерфейс и возможность доступа ко всем
модулям в составе системы должна обеспечивать оболочка. Из оболочки системы
вызываются следующие модули:
Модуль MainWindow – основная часть системы, является посредником
между пользователем и остальными подсистемами. Реализует GUI (Graphics User
Interface), пользовательский интерфейс и вспомогательные функции.
Модуль DiagramScene – рабочее полотно. Размещает и управляет объектами
без их графического представления. Позволяет загружать/сохранять план в
16
структурированный xml файл – проект. Обеспечивает доступ к свойствам
объектов. Реализует drag & drop (перетаскивание объектов).
Модуль DiagramDrawItem – инструменты для работы с рабочим полотном.
Отображает физические объект, такие как, двери, окна, стены, помещения,
лестницы, лифты. Отрисовывает их и управляет их масштабируемостью.
Модуль DiagramTextItem – реализует работу с текстом. Поддерживает
следующие функции: добавление, удаление, редактирование и перетаскивание.
Вся система целиком создана с использованием технологии "интервью", или,
как ее еще называют - "модель-представление".
Использование технологии "интервью" дает следующие преимущества:
–
возможность
показа
данных
в
нескольких
представлениях
без
дублирования. То есть, если при работаете с элементно-базированным подходом
и необходимо добавить новые элементы, то при синхронизации отображения с
данными происходит дублирование самих данных. В подходе "модельпредставление" мы работаем с моделью данных, поэтому
дублирования не
происходит;
– возможность внесения изменения с минимумом временных затрат.
Например, в программе полностью изменился способ сохранения данных. Это не
будет помехой, так как связь с данными происходит с помощью интерфейса, и до
тех пор, пока сам интерфейс останется нетронутым, это не повлечет за собой
больших изменений в коде программы;
– удобство программного кода. Так как производится разделение на данные
и представление, то, если появится необходимость что-то дополнить или
исправить, эти изменения коснутся только лишь одной из частей. Остальные
части вашего приложения останутся без изменений;
– удобство тестирования кода. Как только интерфейс задан, можно написать
тест, который может быть использован для любой модели, реализующей этот
интерфейс.
17
1.3.5. Требования к техническому обеспечению
Задачи, решаемые автоматизированной системой ввода плана эвакуации для
разработки паспортов безопасности учебных заведений РФ, связаны с
графической работой. Исходя из этого, сформулированы требования к
техническим характеристикам персонального компьютера на котором будет
функционировать система (см. табл. 1.1).
Таблица 1.1
Технические характеристики персонального компьютера
Наименование
Значение
Частота процесса, МГц
от 1000
Объем оперативной памяти, Мбайт
от 512
Объем жесткого диска, Гбайт
не менее 10
Разрешение экрана монитора SVGA
не ниже 1024х768
1.3.6. Требования к информационному обеспечению
Автоматизированная система ввода плана эвакуации для разработки
паспортов безопасности учебных заведения РФ предназначена для организации
обмена информацией, между пользователем и расчетным модулем.
Основным видом информации, обрабатываемой в системе, является
графическое представление. Пользователю необходимо иметь план эвакуации,
размеры помещений, дверей, окон.
1.3.7. Требования к программному обеспечению
Автоматизированная система ввода плана эвакуации для разработки
паспортов
безопасности
учебных
заведений
РФ
должна
работать
под
18
управлением любой популярной операционной системы, не теряя при этом
функциональность
и
предоставляя
широкий
диапазон
поддерживаемых
операционных систем. Достичь этого позволяет кросс-платформенная открытая
библиотека Nokia Qt.
1.3.8. Перспективность системы, возможность ее развития
Реализовать возможность создания плана эвакуации в трехмерном
измерении. На первом этапе достаточно разработать предпросмотр, на
следующем этапе уже реализовать возможность полноценного трехмерного
проектирования.
Оптимизировать работу системы. Разработать более гибкое проектирование
плана. Добавление дверей и окон только на стены. Отображать графически
температуру горения помещения прямо на плане.
Добавить поддержку открытого формата dxf (Drawing eXchange Format).
Это открытый формат файлов для обмена двумерной графической информацией
между приложениями САПР. Многие учебные заведения и различные
предприятия
заказывают
чертеж
плана
эвакуации
у
организаций,
предоставляющие такие услуги, а они, как правило, используют CAD системы,
такие как AutoCAD или Компас+. Они позволяют сохранять в данный формат.
Что в итоге ускорит процесс разработки паспортов безопасности.
1.4.
Основные технические решения проекта системы
1.4.1. Решения по комплексу технических средств
Как уже отмечалось в п. 1.3.5, для достижения удобного пользователю
режима функционирования системы необходима следующая минимальная
конфигурация персонального компьютера: частота процессора 1000 МГц, объем
19
оперативной памяти от 512 Мбайт, монитор, поддерживающий разрешение
1024х768 точек.
1.4.2. Описание системы программного обеспечения
Для реализации функционирования проекта необходимо общесистемное
программное обеспечение операционной системы Windows или Linux.
Разработка автоматизированной системы ввода плана эвакуации для
разработки паспортов безопасности учебных заведений РФ будет вестись на
языке C++ с открытой кросс-платформенной библиотекой Nokia Qt в среде
разработки Microsoft Visual Studio 2008.[1][2][3] Среда Microsoft Visual Studio 2008
включает в себя инструменты, позволяющие избавить программиста от рутинных
операций по созданию заготовок кода подпрограмм, а также поддерживает
интеллектуальное автодополнение кода с подсветкой синтаксиса.
20
2. РАЗРАБОТКА ЗАДАЧИ «АВТОМАТИЗИРОВАННАЯ СИСТЕМА ВВОДА
ПЛАНА ЭВАКУАЦИИ ДЛЯ РАЗРАБОТКИ ПАСПАРТОВ
БЕЗОПАСНОСТИ УЧЕБНЫХ ЗАВЕДЕНИЙ РФ»
2.1.
Описание постановки задачи
2.1.1. Характеристика задачи
Данная дипломная работа является разработкой автоматизированной
системой ввода плана эвакуации для разработки паспортов безопасности учебных
заведений РФ. Главная задача этой работы – обеспечить корректный ввод данных
для передачи в расчетный модуль.
Сама задача подразделяется на несколько подзадач, которые выполняют
различные
функции.
Выполнение
этих
функций
в
совокупности
дает
осуществление общей задачи.
В задаче можно выделить следующие основные части:
- пользовательский интерфейс.
- сцена.
- инструментарий.
Подзадача «Пользовательский интерфейс» является посредником между
пользователем
и
всеми
внутренними
процессами
системы.
Является
«представлением» (см . П.1.3.4.).
Подзадача «Сцена» является рабочим полотном для черчения плана
эвакуации.
Размещает
и
управляет
объектами
без
их
графического
представления. Является «моделью» (см . П.1.3.4.).
Подзадача «Инструментарий» содержит различные графические примитивы,
служащие для отображения физических объектов, каждый имеет свои
21
уникальные свойства. Под отображением физических объектов понимается
чертеж стены, окна, двери, помещение, лестницы, лифты. Каждый из этих
объектов имеет набор уникальных атрибутов, которые позволяют более детально
произвести расчет и соответствуют всем нормативным документам.
2.1.2. Входная информация
На вход поступает чертеж плана, вводимый пользователем с помощью
инструментов и задавая им свойства. Также может быть загружен файл
содержащий графическим изображение.
2.1.3. Выходная информация
При работе с системой на выходе получается строго структурированный xml
файл, с уникальными полями и атрибутами. Их описание дано в табл. П. 5.1
2.2.
Описание модуля реализации пользовательского интерфейса
2.2.1. Назначение и характеристика модуля
Данная подсистема реализует пользовательский интерфейс, компонует и
размещает все пользовательские формы, обеспечивает взаимосвязь и управление
с
остальными
компонентами
системы.
Также
отвечает
за
ввод/вывод
информации. Экспортирует план эвакуации в файл – изображение. Реализует
следующие вспомогательные функции:
- масштабирует изображение;
- поворот элемента на 90̊ по часовой или против часовой стрелке;
- группировать/разгруппировать выделенные элементы;
- удаление, копирование элементов;
- перемещать элемент на передний или задний план.
22
2.2.2. Требования к контрольному примеру
Контрольный пример должен содержать примеры экранных форм, меню и
инструментария.
2.3.
Описание модуля рабочей поверхности
2.3.1. Назначение и характеристика модуля
Подсистема предназначена для работы с двухмерной графикой и является
рабочим полотном для пользователя. Отправляет на печать текущий план
эвакуации. Служит контейнером для свойств каждого элемента. Предлагает
пользователю следующие функции при работе с файлом:
- сохраняет и загружает текущий проект в xml файл. Функция быстрого
сохранения позволяет при помощи нажатие на сочетание клавиш “ctrl+s”
сохранить файл, но для этого необходимо, чтобы система работала с файлом, т.е.
либо открыть его или сохранить через пункт в меню «Сохранить как»;
-
предоставляет
возможность
загрузки
растрового
или
векторного
изображения.
2.3.2. Описание алгоритма сохранения
Рассмотрим пример сохранения на нескольких объектах, т.к. процесс
одинаковый для всех, лишь с тем отличием, что сохраняются разные свойства
(рис 2.1).
1) получить файл;
2) создать тэг size и записать его атрибуты width и height;
3) закрыть тэг size;
4) для каждого объекта на сцене пройтись по списку всех элементов;
5) создать и записать тэг Item;
6) создать указатель на объект DiagramDraItem;
23
7) если diagItem == 6;
8) Type = ”Room”;
9) создать тэг Property;
10) создать переменные – итераторы для обхода списка;
11) пока переменные – итераторы не равны концу списка в пункт 12,
иначе в 12;
12) если текущий объект найдет в списке в пункт 13, иначе в 11;
13) записать соответствующий атрибут;
Схема алгоритма сохранения
НАЧАЛО
А
Файл
Запись в
файл
Записать в файл размеры
рабочего полотна
Запись в
файл
Создать объект
Обход списка со всеми
объектами на сцене
Инициализация
цикла
Да
Помещение
D
Из стр 24
Нет
Запись в
файл
Приращение
Есть
элементы
Записать в файл тэг <Item>
Да
А
Нет
КОНЕЦ
Рис.2.1
В
К стр 24
24
Следующий
элемент
Из стр. 23
Нет
В
++mH
Ключ
совпадает
Да
Записать
высоту
В1
Записать
площадь
B1
Записать
тип
B2
Записать
ширину
B3
Следующий
элемент
Нет
B
++mS
Ключ
совпадает
Да
Следующий
элемент
Нет
B1
++mID
Ключ
совпадает
Да
Следующий
элемент
Нет
B2
++mW
Ключ
совпадает
Да
Следующий
элемент
K стр. 23
Нет
B3
++mL
Ключ
совпадает
Да
Записать
глубину
Продолжение Рис. 2.1
D
25
2.4.
Описание модуля инструментария
2.4.1. Назначение и характеристика модуля
Подсистема предоставляет пользователю инструменты для отображает
физических объектов на рабочем полотне в виде чертежа. Реализованы такие
инструменты, как лифт, помещение,
стена, окно, лестница, дверь. Каждый
элемент имеет свойства, которые необходимо выбрать или ввести пользователю.
2.4.2. Характеристика инструмента «Лифт»
Предназначен для черчения лифта. Содержит свойства: тип лестницы
(простая или с лестничной площадкой).
2.4.3. Характеристика инструмента «Помещение»
Предназначен
для
черчения
различных
помещений.
Пользователю
необходимо выбрать тип помещения, для того чтобы произвести расчет
пожарной нагрузки (см. таблицу 2.1.). Такой подход к расчету пожарной нагрузки
позволяет снизить ошибки ввода данных пользователем.
Таблица 2.1
Свойства помещения
Тип помещения
Учебные аудитории
Подтип помещения
Лекционная аудитория
Аудитория для практических занятий
Компьютерные классы
Компьютерный класс (15 комп.)
Спортивные помещения
Большой спортивный зал
Вне Университета
Гимнастический зал
Зал аэробики
Раздевалка
Тренажёрный зал
26
Продолжение таб. 2.1
1
Специализированные
аудитории
2
учебные Военная кафедра
Специализированная лаборатория
Специализированная мастерская
Мастерская рисунка, живописи, по
проектированию
Мастерская скульптуры
Мастерская по обработке материалов
(дерево)
Мастерская по обработке материалов
(металл)
Швейная мастерская
Лингафонный кабинет
Телестудия
Учебно-вспомогательные
Актовый зал
помещения
Зал заседаний
Читальный зал
Абонемент
Фонд, архив
Музей
Административные
помещения
(офисные) Кабинет руководителя
Кабинет сотрудника
Общая преподавательская
Помещение структурного
подразделения
27
Продолжение таб. 2.1
1
2
Научно-исследовательские
Аспирантская
помещения
НИЛ (*)
Служебные помещения
АТС
Гараж (бокс)
Гараж (бокс-ремонтный)
Бойлерная
Буфет
Вахта
Венткамера
Гардероб
Касса
Кинопроекторная
Коридор, лестничная клетка, холл
Котельная (дрова, уголь, газ)
Лифт, лифтовая шахта
Медицинский пункт
Подсобное помещение
Подсобное помещение структурного
подразделения
Производственное помещение
Санузел
Серверная
Склад (по типу назначения)
Столовая
Электрощитовая
28
2.4.4. Характеристика инструмента «Стена»
Предназначен для черчения стен. Стены могут быть несущие или
внутренние.
2.4.5. Характеристика инструмента «Дверь»
Предназначен для черчения дверей. Имеет свойства следующие свойства:
- площадь (м2);
- высота (м);
- глубина дверного проема (м);
- внутренняя или внешняя (связывает помещение и выход);
- расстояние z (расстояние от пола предыдущего этажа до пола следующего
этажа).
2.4.6. Характеристика инструмента «Окно»
Предназначен для черчения дверей. Имеет свойства следующие свойства:
- площадь (м2);
- высота (м);
- расстояние от пола до окна (м).
2.4.7. Характеристика инструмента «Лестница»
Предназначен для черчения лестниц. Имеет свойства следующие свойства:
- простая или с лестничной площадкой.
2.4.8. Описание алгоритма отрисовки (рис. 2.2.)
1. создать переменную dx c координатой курсора x2;
2. создать переменную dy c координатой курсора y2;
3. создать объект QPainterPath path;
4. создать объект QPolygonF polygon;
5. если тип объекта лифт то в пункт 6, иначе в 13;
29
6. в path добавить прямую линию с текущей позиции (0,0);
7. в path добавить прямую линию с текущей позиции (dx, 0);
8. в path добавить прямую линию с текущей позиции (dx, dy);
9. в path добавить прямую линию с текущей позиции (0, dy);
10. в path добавить прямую линию с текущей позиции (0, 0);
11. установить цвет для фигуры;
12. конвертировать все линии (path) в многоугольник (polygon) и залить
цветом из п.11, перейти в пункт 40;
13. если тип объекта дверь то в пункт 14, иначе в 18;
14. в path добавить прямую линию с текущей позиции (0,0);
15. в path добавить четырех угольник с координатами (0, 0, dx, 10);
16. установить цвет для фигуры;
17. конвертировать все линии (path) в многоугольник (polygon) и залить
цветом из п.16, перейти в пункт 40;
18. если тип объекта комната то в пункт 19, иначе в 25;
19. в path добавить прямую линию с текущей позиции (0,0);
20. в path добавить прямую линию с текущей позиции (dx, 0);
21. в path добавить прямую линию с текущей позиции (dx, dy);
22. в path добавить прямую линию с текущей позиции (0, dy);
23. в path добавить прямую линию с текущей позиции (0, 0);
24. установить цвет для фигуры;
25. конвертировать все линии (path) в многоугольник (polygon) и залить
цветом из п.24, перейти в пункт 40;
26. если тип объекта лестница то в пункт 27, иначе в 34;
27. в path добавить прямую линию с текущей позиции (0,0);
28. в path добавить прямую линию с текущей позиции (dx, 0);
29. в path добавить прямую линию с текущей позиции (dx, dy);
30. в path добавить прямую линию с текущей позиции (0, dy);
30
31. в path добавить прямую линию с текущей позиции (0, 0);
32. установить цвет для фигуры;
33. конвертировать все линии (path) в многоугольник (polygon) и залить
цветом из п.32, перейти в пункт 40;
34. если тип объекта стена то в пункт 34, иначе в 39;
35. в path добавить прямую линию с текущей позиции (0,0);
36. в path добавить четырех угольник с координатами (0, 0, dx, 10);
37. установить цвет для фигуры;
38. конвертировать все линии в многоугольник и залить цветом из п.16,
перейти в пункт 40;
39. polygon = 0;
40. нарисовать фигуру;
2.4.9. Список условных обозначений.
При
описании
данного
алгоритма
были
использованы
следующие
обозначения:
dx – переменная содержащая текущую координату х курсора;
dy – переменная содержащая текущую координату y курсора;
path – объект библиотечного класса QPainterPath, содержащий операции для
рисования;
polygon – объект библиотечного класса QPolygon, содержит векторный
контейнер для хранения точек.
31
Схема алгоритма отрисовки
НАЧАЛО
qreal dx = myPos2.x();
qreal dy = myPos2.y();
QPainterPath path;
QPolygonF polygon;
тип элемента
0
черчение лифта
1
черчение двери
вернуть polygon
вернуть polygon
2
черчение стены
вернуть polygon
черчение окна
вернуть polygon
черчение
лестницы
вернуть polygon
3
4
5
6
черчение окна
default
вернуть polygon
polygon = 0
Рис 2.2
КОНЕЦ
32
2.4.10. Требования к контрольному примеру
Контрольный пример должен содержать снимки экранных форм с панелью
инструментов и окном для выбора свойств каждого объекта.
2.5.
Описание программы «Автоматизированная система ввода
плана эвакуации для разработки паспортов безопасности учебных заведений
РФ»
Автоматизированная система ввода плана эвакуации для разработки
паспортов безопасности учебных заведений РФ разработана для сотрудников
учебных заведений, для того, чтобы обеспечить всеобщую паспортизацию всех
школ и ВУЗов.
Программа имеет идентификатор dep.exe и применяется сотрудниками
учебных заведений для самостоятельной паспортизации:
-
управление активными и завершенными задачами;
-
управление циклами разработки;
-
выборка задач по заданным пользователем критериям;
-
построение статистических таблиц заданной пользователем структуры.
Программа реализована на языке C++ в среде разработки Microsoft Visual
Studio 2008 с кросс – платформенной библиотекой Nokia Qt и состоит из
следующих модулей:
-
mainwindow.cpp – основной модуль, в котором происходит вызов других
модулей,
а
также
обеспечивает
управление
над
ними
и
реализует
вспомогательные функции;
-
diagramscene.cpp – обеспечивает размещение элементов на рабочем
полотне и управляет ими без их графического представления, хранит свойства
каждого объекта, реагирует на события манипулятора «мышь»;
33
-
diagramdrawitem.cpp – содержит перечисление все физических объектов
для их графического представления, реагирует на события «мыши» (позволяет
изменять размеры объекта);
-
diagramtextitem.cpp – обеспечивает работу с текстом, позволяет
добавлять, редактировать, перетаскивать и удалять текст с рабочего полотна;
-
doorpropert.cpp – реализует пользовательский интерфейс для работы со
свойствами объекта дверь;
-
liftproperty.cpp – реализует пользовательский интерфейс для работы со
свойствами объекта дверь;
-
propertywindow.cpp – реализует пользовательский интерфейс для работы
со свойствами объекта окна;
-
stairwayproperty.cpp – реализует пользовательский интерфейс для работы
со свойствами объекта лестницы;
-
wallproperty.cpp – реализует пользовательский интерфейс для работы со
свойствами объекта стена;
-
roomproperty.cpp – реализует пользовательский интерфейс для работы со
свойствами объекта помещения;
2.5.1. Описание логики
Логика программы приведена в виде схемы программы, представленной на
рис. 2.3.
34
Схема программы
НАЧАЛО
DiagramDraw
Item
MainWindow
DiagramTextI
tem
DiagramScen
e
КОНЕЦ
Рис. 2.3
MainWindow является основным классом, который управляет остальными.
Для сохранения или загрузки вызывается соответствующая функция из класса
DiagramScene. При добавление объекта на сцену, пользователь нажимает на
кнопку на панели инструментов, затем модель DiagramScene устанавливается в
соответствии с выбранным объектом.
2.6.
Описание контрольного примера
2.6.1. Назначение
Данный контрольный пример служит для проверки корректности работы
автоматизированной системы ввода плана эвакуации для разработки паспортов
безопасности учебных заведений РФ.
35
2.7.
Исходные данные
Пусть на вход поступило изображение с планом эвакуации 3 корпуса УдГУ 1
этаж (рис. 2.5). Для оцифровки и задания свойств каждому объекту может занять
некоторое время.
Рис. 2.5
2.7.1. Результаты работы задачи
После загрузки изображения и ввода чертежа в соответствии с планом и
заданием всех свойств результатом работы будет векторное изображение и
сгенерированный xml файл (см. рис. 2.6). Снимки экранных форм см. в П.1
36
При вводе были учтены все характеристики здания, такие как помещение,
его физические размеры и тип, двери, соединяющие комнаты и коридоры.
При тестирование расчетных модулей пожара и модели эвакуации, были
получены достаточно достоверные данные, что говорит о корректности работы
автоматизированной системе ввода плана эвакуации для разработки паспортов
безопасности учебных заведений РФ.
Рис. 2.6
2.7.2. Результаты испытания
Анализируя результаты рассматриваемой задачи, можно сделать вывод, что
система корректно сохраняет все данные необходимые для расчетов и разработки
паспортов безопасности.
На основании проделанных проверок можно сделать вывод, что система
работает правильно, выполняя поставленные цели и выдавая корректные
результаты.
Все функции системы выполнили свои поставленный задачи без ошибок.
37
Протестирована корректность
отображения рабочей области на различных
мониторах, как стандартного разрешения 4:3, так и на широкоформатных
дисплеях.
Система корректно генерирует выходной xml файл. Также она загружает без
ошибок сгенерированный файл.
38
3. ОРГАНИЗАЦИОННО – ЭКОНОМИЧЕСКАЯ ЧАСТЬ.
Определим этапы разработки НИР и их содержание и составим таблицу. Также
сразу укажем трудоемкость каждого этапа, исполнителей, их число, а также
длительность работы по каждому этапу. Результаты занесем в таблицу 3.1.
Таблица 3.1
Расчет трудоемкости выполнения НИР по теме «Автоматизированная система
ввода плана эвакуации для разработки паспортов безопасности учебных
(специалист,
подразделение)
1
честв
о
испол
нителей
(чел)
2
3
4
5
Программист
21
1
3
- Разработка ТЗ НИР
a. Анализ передовых
достижений
отечественной и
зарубежной науки и
техники
Итого по этапу 1
- Выбор направления
исследования
21
3
(дни)
содержание работ
Коли-
Дли-тельность работы
Исполнитель
ч)
Наименование этапов и
Трудо-емкость работ (н-
заведений РФ»
39
Продолжение табл. 3.1
1
2
3
4
5
Программист
58
1
8
Программист
25
1
4
Программист
16
1
2
Программист
16
1
2
a. Сбор и изучение
научно-технической
литературы,
нормативнотехнической
документации и пр.
b. Составление
аналитического обзора
c. Формулирование
возможных
направлений решения
задач, поставленных в
ТЗ НИР, и
сравнительная оценка
d. Выбор и обоснование
принятого направления
исследований и
способов решения
поставленных задач
Итого по этапу 2
- Теоретические и
экспериментальные
исследования
115
16
40
Продолжение табл.3.1.
1
2
3
4
5
Программист
24
1
3
Программист
48
1
6
Программист
64
1
8
Программист
24
1
3
a. Разработка рабочих
гипотез, построение
моделей объекта
исследований,
обоснование
допущений
b. Разработка методики
экспериментальных
исследований,
подготовка моделей, а
также испытательного
оборудования
c. Проведение
экспериментов,
обработка полученных
данных
d. Составление
промежуточного
отчета и его
рассмотрение
Итого по этапу 3
- Обобщение и оценка
результатов исследования
150
20
41
Продолжение табл. 3.1
1
2
3
4
5
Программист
35
1
5
Программист
36
1
5
a. Обобщение
результатов
предыдущих этапов
работ
b. Составление и
оформление отчета
Итого по этапу 4
Итого:
71
10
257
49
Квалификационный и количественный состав исполнителей приведен в табл. 3.2
Таблица 3.2
Квалификационный и количественный состав исполнителей по теме
«Автоматизированная система ввода плана эвакуации для разработки паспартов
безопасности учебных заведений РФ»
Должность
Категория или
Количество
Месячный
исполнителя
тарифный разряд
исполнителей
должностной
оклад (руб./мес.)
Программист
Итого:
1
5000
5000
42
3.1.
РАСЧЕТ БЮДЖЕТА НА РАЗРАБОТКУ НИР
3.1.1. Расходы на материалы и амортизацию
Материалы, которые были использованы в ходе работы над НИР, приведены
в таблице 3.3.
Таблица 3.3
Расчет затрат на материалы, покупные изделия и полуфабрикаты
Наименование материала,
Единица
Количество
Цена
Стоимость
изделия
измерения
на тему
единицы
на тему
(шт.)
(руб./шт.)
(руб.)
Шт.
2
35
70
Шт.
1
250
250
Шт.
1
400
400
Шт.
1
76
76
КВтЧ
747
2
1500
Ручка шариковая
Бумага для офисной
техники, А4, 500 листов
Тонер для принтера HP
LaserJet 1010
Папка для дипломной
работы
Электроэнергия
Всего
2296
ТЗР (8%)
184
Итого:
2480
МР  К мат  Ц мат (1  К
),
ТЗР
где МР  расходы на материалы;
К мат  количество материала;
Ц мат  цена единицы материала;
К
ТЗР
 коэффициент транспортно  заготовительных расходов ;
43
Так как реализуемых отходов нет, их мы в таблице не учитываем. Расходы на
электроэнергию включаются в список и рассчитываются по следующей формуле:
МР
Э
 МТЦ
1 кВт ч,
 расходы на электоэнергию;
Э
М  мощность установки;
Т  время работы;
Ц
 цена за 1 кВт  ч.
1 кВт ч
где МР
МР
Э
 1,2  257  2  616.8 руб.
Округлим затраты на электроэнергию до 617 руб.
Расходы на амортизацию оборудования указаны в таблице 4. Расчет
производится по следующим формулам:
Н
А

1
Т п. исп
100%,
 норма амортизации;
А
Т п. исп  период полезного использования (ггода)
где Н
Н
1
 100%  20%
А 5
А год 
ОС  Н
где Агод  годовая амортизация;
ОС  стоимость основных средств.
А год 
100
Аг ,
31000  20
 6200 р./год
100
А
Амес  год
12
где Амес  месячная амортизаци я.
44
А мес 
6200
 516,67 р./мес.
12
На период выполнения работы (4 месяца) затраты на амортизацию оборудования
составят 2067 руб., округлим эту сумму до 2070 руб.
Таблица 3.4
Расчет затрат на амортизацию оборудования для научных работ по теме
«Автоматизированная система ввода плана эвакуации для разработки паспартов
безопасности учебных заведений РФ»
Наименование,
Количеств Стоимост
Норма
Время
Сумма
техническая
о на тему
ь
амортизаци
использо-
аморти-
характеристика
(шт)
единицы
и (%)
вания
зации
(мес)
(руб.)
4
2070
, тип
Персональный
компьютер
(р/шт)
1
31000
25
Итого:
2070
3.2.2. Расходы на оплату труда
Расходы на оплату труда исполнителей НИР рассчитываем по следующей
формуле:
ЗПоклад 
Оклад  Т
Тплан
ф


 1  К прем  К пр  1  К з 
45
где ЗПоклад  окладная повременная оплата труда;
Оклад  размер оклада;
Т  время фактического нахождения на работе, ч.;
ф
Т план  плановое рабочее время;
К прем  коэффициент, учитывающий премии из фонда
(0.15  0.30);
К пр  не учтенный коэффициент доплат;
К  коэффициент зональных доплат (0.15).
З
 5000  257
т  4
ЗПпрограммис

оклад

168

 1  0.15  1  0.15  40462 р.

Данные занесем в таблицу 3.5.
Таблица 3.5
Расчет заработной платы исполнителей по теме «Автоматизированная
система ввода плана эвакуации для разработки паспартов безопасности учебных
Итого:
Плановое
факти-
рабочее
ческого
время,
нахождени
ч./мес.
я на
работе,
Сумма
Коэффициент доплат
Время
тарифной
Число месяцев
Программист
оклад, руб.
Исполнитель
Месячный должност-ной
заведений РФ»
4
0
40462
ч./мес.
5 000
257
257
заработной
платы
(руб.)
40462
46
3.2.3. Единый социальный налог
Единый социальный налог составляет 26,2% от заработной платы и
рассчитывается по следующей формуле:
где С
ЗП  К
СЦ
С

СН
100%
 размер социального налога;
СН
ЗП  сумма оплаты труда исполнителя;
К
 процент отчислений на социальные налоги (26%).
СЦ
Спрограммист 
СН
40462  26,2%
 10601.0 р.
100%
Собщ  10601.0 р.
СН
Округлим ЕСН до 10601 руб.
3.2.4. Накладные расходы
Накладные расходы составляют от 100% до 200% общей заработной платы
и вычисляются по следующей формуле:
НР 
ЗП  К
НР ,
100%
где НР  накладные расходы;
ЗП  заработная плата исполнителей;
К
 процент накладных расходов.
НР
Примем процент накладных расходов равный 100%.
НР 
40462 100
 40462 р.
100
Округлим накладные расходы до 40462 руб.
47
3.2.5. Прочие расходы
Прочие расходы составляют 5-10% от основной заработной платы (возьмем
процент прочих расходов 5%) и вычисляются по следующей формуле:
ПР  40462  0,05  2023.1 р.
Округлим прочие расходы до 2023 руб.
3.3. Бюджет затрат
Бюджет затрат на разработку НИР с указанием статей затрат представлен в
таблице 3.6.
Таблица 3.6
Бюджет затрат на выполнение НИР по теме «Автоматизированная система
ввода плана эвакуации для разработки паспартов безопасности учебных
заведений РФ»
Статьи затрат
Сумма затрат
Структура затрат (% к
(руб.)
итогу)
Расходные материалы
2480
3%
Амортизация ВТ
2070
2%
40462
41%
Социальный налог
10601
11%
Накладные расходы
40462
41%
Прочие затраты
2023
2%
Итого:
98098
100%
Расходы на оплату труда
исполнителей
48
Структура затрат на выполнение НИР в виде круговой диаграммы представлена
на рис. 3.1.
• Расходы на материалы (3%)
• Амортизация ВТ (2%)
• Расходы на оплату труда исполнителей (41%)
• Социальный налог (11%)
• Накладные расходы (41%)
• Прочие затраты (2%)
2%
41%
41%
11%
3%
Рис. 3.1.
2%
49
4.
БЕЗОПАСНОСТЬ И ЭКОЛОГИЧНОСТЬ ПРОЕКТА
Охрана труда — система сохранения жизни и здоровья работников в
процессе трудовой деятельности, включающая в себя правовые, социальноэкономические,
организационно-технические,
санитарно-гигиенические,
лечебно-профилактические, реабилитационные и иные мероприятия. Под иными
мероприятиями следует понимать мероприятия, направленные на выполнение
требований пожарной безопасности, промышленной безопасности и т.п. в ходе
трудовой деятельности.
Имеющийся в настоящее время в нашей стране комплекс разработанных
организационных мероприятий и технических средств защиты, накопленный
передовой опыт работы ряда вычислительных центров (ВЦ) показывает, что
имеется возможность добиться больших успехов в деле устранения воздействия
на рабочих опасных и вредных производственных факторов. Однако состояние
условий труда и его безопасности в ряде ВЦ еще не удовлетворяют современным
требованиям. Операторы ЭВМ, операторы подготовки данных, программисты и
другие работники ВЦ еще сталкиваются с воздействием таких физически
опасных и вредных производственных факторов, как повышенный уровень шума,
повышенная температура внешней среды, отсутствие или недостаточная
освещенность рабочей зоны, электрический ток, статическое электричество и
другие.
Многие сотрудники ВЦ связаны с воздействием таких психофизических
факторов, как умственное перенапряжение, перенапряжение зрительных и
слуховых анализаторов, монотонность труда, эмоциональные перегрузки.
Воздействие указанных неблагоприятных факторов приводит к снижению
работоспособности, вызванное развивающимся утомлением. Появление и
50
развитие утомления связано с изменениями, возникающими во время работы в
центральной нервной системе, с тормозными процессами в коре головного мозга.
Например, сильный шум вызывает трудности с распознанием цветовых сигналов,
снижает быстроту восприятия цвета, остроту зрения, зрительную адаптацию,
нарушает восприятие визуальной информации, уменьшает на 5 - 12 %
производительность труда. Длительное воздействие шума с уровнем звукового
давления 90 дБ снижает производительность труда на 30 - 60 % .
Медицинские обследования работников ВЦ показали, что помимо снижения
производительности труда высокие уровни шума приводят к ухудшению слуха.
Длительное нахождение человека в зоне комбинированного воздействия
различных неблагоприятных факторов может привести к профессиональному
заболеванию. Анализ травматизма среди работников ВЦ показывает, что в
основном несчастные случаи происходят от воздействия физически опасных
производственных
факторов
при
заправке
носителя
информации
на
вращающийся барабан при снятом кожухе, при выполнении сотрудниками
несвойственных им работ. На втором месте случаи, связанные с воздействием
электрического тока.
При
взаимодействии
с
ЭВМ
труд
регламентируется
следующими
нормативными документами:
1) Федеральный Закон от 17 июля 1999 г. № 181-ФЗ «Об основах охраны
труда в Российской Федерации» - устанавливает правовые основы регулирования
отношений в области охраны труда между работодателями и работниками и
направлен на создание условий труда, соответствующих требованиям сохранения
жизни
и
здоровья
работников
в
процессе
трудовой
деятельности.
Государственными нормативными требованиями охраны труда, содержащимися
в федеральных законах и иных нормативных правовых актах Российской
51
Федерации и законах и иных нормативных правовых актах субъектов Российской
Федерации об охране труда, устанавливаются правила, процедуры и критерии,
направленные на сохранение жизни и здоровья работников в процессе трудовой
деятельности;
2) ГОСТ 12.1.003–83. ССБТ. Шум. Общие
требования безопасности (с
изменениями по И-1-III-89);
3) ГОСТ 12.1.005–88. ССБТ. Общие санитарно-гигиенические требования к
воздуху рабочей зоны;
4) ГОСТ
12.1.006–84.
ССБТ.
Электромагнитные
поля
радиочастот.
Допустимые уровни на рабочих местах и требования к проведению контроля;
5) СНиП 23-05–95. Естественное и искусственное освещение;
6) СанПиН 2.2.2.542-96. Гигиенические требования к видео-дисплейным
терминалам, персонально-вычислительным машинам и организация работ;
7) ГОСТ
Р
50923-96
Дисплеи.
Рабочее
место
оператора.
Общие
эргономические требования и требования к производственной среде. Методы
измерения;
8) ГОСТ
Р
50948-2001
Средства
отображения
информации
индивидуального пользования. Общие эргономические требования и требования
безопасности;
9) ГОСТ
Р
50949-2001
Средства
отображения
информации
индивидуального пользования. Методы измерений и оценки эргономических
параметров и параметров безопасности.
4.2.
Анализ вредных и опасных факторов
Исследовательская работа в рамках данной дипломной работы заключается в
выполнении многих этапов, практически все из которых проходят в тесном
52
контакте с ЭВМ. Длительная работа инженера-программиста с компьютером
сопряжена с целым рядом вредных и опасных факторов. Рассмотрим некоторые
из них.
4.2.2. Постоянное напряжение глаз
Работа
зрительной
с
компьютером
характеризуется
высокой
напряженностью
работы. В выполняемом исследовании значительный
объем
информации на разных стадиях обработки представлен в графической форме с
большим количеством мелких деталей, что дает серьезную нагрузку на зрение.
Постоянное напряжение глаз может привести к снижению остроты зрения. Экран
видеомонитора должен находиться от глаз пользователя на оптимальном
расстоянии 600…700 мм, но не ближе 500 мм с учетом размеров алфавитноцифровых знаков и символов. Также для снижения утомляемости рекомендуется
делать 15-минутные перерывы в работе за компьютером в течение каждого часа.
4.2.3. Влияние электростатических и электромагнитных полей
Большинство ученых считают, что как кратковременное, так и длительное
воздействие всех видов излучения от экрана монитора не опасно для здоровья
персонала, обслуживающего компьютеры. Однако, исчерпывающих данных
относительно опасности воздействия излучения от мониторов на работающих с
компьютерами
не
существует,
и
исследования
в
этом
направлении
продолжаются.
Допустимые значения параметров неионизирующих электромагнитных
излучений от монитора компьютера представлены в табл. 4.1.
Максимальный уровень рентгеновского излучения на рабочем месте
оператора компьютера обычно не превышает 10
μбэр/ч, а интенсивность
53
ультрафиолетового и инфракрасного излучений от экрана монитора лежит в
пределах 10…100 мВт/м2 .
Для снижения воздействия этих видов излучения рекомендуется применять
мониторы с пониженным уровнем излучения (MPR-II, TCO-92, TCO-99),
устанавливать защитные экраны, а также соблюдать регламентированные режимы труда и отдыха.
Таблица 4.1
Допустимые значения параметров неионизирующих электромагнитных
излучений (в соответствии с СанПиН 2.2.2.542-96)
Наименование параметра
Допустимые
Напряженность электрической составляющей
электромагнитного
Напряженность
магнитной
поля на расстоянии
50 см отсоставляющей
поверхности видеомонитора
электромагнитного
Напряженность
электростатического
полявидеомонитора
не должна
поля на расстоянии
50 см от поверхности
значения
10 В/м
0,3 А/м
превышать:
для взрослых пользователей
20 КВ/м
для детей дошкольных учреждений и учащихся
15 КВ/м
средних специальных и высших учебных заведений
4.2.4. Длительное неизменное положение тела
Работа
напряжением
с
компьютером
и
характеризуется
нервно-эмоциональной
значительным
нагрузкой
умственным
операторов,
высокой
напряженностью зрительной работы и достаточно большой нагрузкой на мышцы
рук при работе с клавиатурой ЭВМ. Большое значение имеет рациональная
конструкция и расположение элементов рабочего места, что важно для
поддержания оптимальной рабочей позы человека-оператора.
54
4.2.5. Шум
Шум ухудшает условия труда, оказывая вредное действие на организм
человека.
Работающие
в
условиях
длительного
шумового
воздействия
испытывают раздражительность, головные боли, головокружение, снижение
памяти, повышенную утомляемость, понижение аппетита, боли в ушах и т. д. В
табл. 2 указаны предельные уровни звука в зависимости от категории тяжести и
напряженности труда, являющиеся безопасными в отношении сохранения
здоровья и работоспособности.
Таблица 2
Предельные уровни звука, дБ, на рабочих местах
Категория тяжести труда
Категория
напряженности труда
I. Мало напряженный
IV. Очень
I. Легкая II. Средняя III. Тяжелая
тяжелая
80
80
75
75
II. Умеренно напряженный 70
70
65
65
III. Напряженный
60
60
–
–
IV. Очень напряженный
50
50
–
–
Уровень шума на рабочем месте инженеров-программистов и операторов
видеоматериалов не должен превышать 50 дБА, а в залах обработки информации
на вычислительных машинах - 65 дБА. Для снижения уровня шума стены и
потолок помещений, где установлены компьютеры, могут быть облицованы
звукопоглощающими
материалами.
Уровень
вибрации
в
помещениях
вычислительных центров может быть снижен путем установки оборудования на
специальные виброизоляторы.
55
4.3.
Пожаробезопасность и электробезопасность
Помещение, в котором установлено рабочее место инженера-программиста,
относится к категории Д по взрыво‐ и пожароопасности, так как не содержит
горючих веществ, но лишь негорючие вещества и материалы в холодном
состоянии.
Пожары в помещении, в котором находится ЭВМ, представляют особую
опасность, так как сопряжены с большими материальными потерями. Площадь
помещения, в котором ведется проектирование, невелика и составляет 12 м 2. Как
известно пожар может возникнуть при взаимодействии горючих веществ,
окисления и источников зажигания. В помещении присутствуют все три
основных фактора, необходимые для возникновения пожара. Горючими
компонентами
являются:
строительные
материалы
для
акустической
и
эстетической отделки помещений, двери, полы, бумага, изоляция кабелей и др.
Противопожарная защита — это комплекс организационных и технических
мероприятий,
направленных
на
обеспечение
безопасности
людей,
на
предотвращение пожара, ограничение его распространения, а также на создание
условий для успешного тушения пожара.
Источниками зажигания в помещении, содержащем ЭВМ, могут быть
электронные схемы от ЭВМ, приборы, применяемые для технического
обслуживания,
устройства
электропитания,
где
в
результате
различных
нарушений образуются перегретые элементы, электрические искры и дуги,
способные вызвать загорания горючих материалов.
В современных ЭВМ очень высока плотность размещения элементов
электронных схем. В непосредственной близости друг от друга располагаются
соединительные провода, кабели. При протекании по ним электрического тока
выделяется значительное количество теплоты. При этом возможно оплавление
56
изоляции. Для отвода избыточной теплоты от ЭВМ служат системы вентиляции и
кондиционирования
воздуха.
При
постоянном
действии
эти
системы
представляют собой дополнительную пожарную опасность.
Одной из наиболее важных задач пожарной защиты является защита
строительных помещений от разрушений и обеспечение их достаточной
прочности в условиях воздействия высоких температур при пожаре. Учитывая
высокую стоимость электронного оборудования, а также категорию его
пожарной опасности, здания, в которых предусмотрено размещение ЭВМ,
должны быть 1 и 2 степени огнестойкости.
К средствам тушения пожара, предназначенным для локализации небольших
возгораний, относятся пожарные стволы, внутренние пожарные водопроводы,
огнетушители, сухой песок, асбестовые одеяла и т. п.
В соответствии с «Типовыми правилами пожарной безопасности для
промышленных
предприятий»
залы
ЭВМ,
помещения
для
внешних
запоминающих устройств, подготовки данных, сервисной аппаратуры, архивов,
копировально-множительного оборудования и т.п. необходимо оборудовать
дымовыми пожарными оповещателями. В этих помещениях в начале пожара при
горении различных пластмассовых, изоляционных материалов и бумажных
изделий выделяется значительное количество дыма и мало теплоты.
Помещение,
в
котором
производится
разработка
данного
проекта,
необходимо оборудовать средствами оповещения о пожаре, а также средствами
для тушения пожара.
Электрические
установки,
к
которым
относится
практически
все
оборудование ЭВМ, представляют для человека большую потенциальную
опасность, так как в процессе эксплуатации или проведении профилактических
работ человек может коснуться частей, находящихся под напряжением.
57
Специфическая опасность электроустановок: токоведущие проводники, корпуса
стоек ЭВМ и прочего оборудования, оказавшегося под напряжением в результате
повреждения (пробоя) изоляции, не подают каких-либо сигналов, которые
предупреждают человека об опасности. Реакция человека на электрический ток
возникает лишь при протекании последнего через тело человека. Разрядные токи
статического электричества чаще всего возникают при прикосновении к любому
из элементов ЭВМ. Такие разряды опасности для человека не представляют, но
кроме неприятных ощущений они могут привести к выходу из строя ЭВМ, что, в
свою очередь, может повлечь за собой потерю рабочего времени и, как результат,
ухудшение конечного результата работы программиста в течение назначенного
на
выполнение
какой-либо
задачи
времени.
Для
снижения
величины
возникающих зарядов статического электричества покрытие технологических
полов
следует
антистатического
выполнить
линолеума,
из
однослойного
обладающего
поливинилхлоридного
низкой
электрической
проводимостью.
4.4.
Расчет требований к рабочему месту инженера-программиста
Разработка данной дипломной работы проводится одним автором на
персональном компьютере в условиях рабочего кабинета. Проведем расчет
параметров
рабочего
места
инженера-программиста
с
точки
зрения
эргономических требований.
В таблице 4.3 приведены параметры стола для занятий с ПЭВМ. Рост автора
данного дипломного проекта в обуви составляет 175 см, что входит в категорию
«161 – 175». Это означает, что согласно эргономическим правилам и нормам
высота поверхности стола над полом должна составлять 700 мм, при этом размер
пространства для ног в столе должен быть не менее 640 мм.
58
Реальная высота стола на рабочем месте автора данного проекта составляет
724 мм. Размер пространства для ног составляет 682 мм. Показатели
соответствуют требованиям к рабочему месту программиста.
Таблица 4.3
Высота одноместного стола для занятий с ПЭВМ
Рост учащихся или студентов
в обуви, см
1
116 – 130
131 – 145
146 – 160
161 – 175
Выше 175
Высота над полом, мм
Пространство для
Поверхность стола
ног, не менее
2
3
520
400
580
520
640
580
700
640
760
700
В таблице 4.4 приведены параметры стула, которым должно быть оснащено
рабочее место инженера-программиста. Рост автора данного дипломного проекта
в обуви составляет 175 см, что входит в категорию «161 – 175». Согласно
эргономическим правилам и нормам, высота сиденья над полом должна
составлять 420 мм; ширина сиденья не менее 340 мм; глубина сиденья 380 мм;
высота нижнего края спинки над сиденьем 170 мм; высота верхнего края спинки
над сиденьем 360 мм; высота линии прогиба спинки не менее 210 мм; радиус
изгиба переднего края сиденья от 20 до 50 мм; угол наклона сиденья от 0 до 4
градусов; угол наклона спинки от 95 до 108 градусов; радиус спинки в плане не
менее 300 мм. Стул, которым оборудовано рабочее место автора данного проекта,
является подъемно-поворотным и обладает возможностью регулирования по
высоте и углам наклона сиденья и спинки, а также расстоянию спинки от
переднего края сиденья. Стул имеет стационарные подлокотники длиной 250 мм
59
и шириной 50 мм. Параметры стула (ширина и глубина сиденья и т.д.)
удовлетворяют допустимым нормам.
Таблица 4.4
Основные размеры стула для учащихся и студентов
Параметры стула
1
Высота сиденья над полом, мм
Ширина сиденья не менее, мм
Глубина сиденья, мм
Высота нижнего края спинки
над сиденьем, мм
Высота верхнего края спинки
над сиденьем, мм
Высота линии прогиба спинки
не менее, мм
Радиус изгиба переднего края
сиденья, мм
Угол наклона сиденья, град.
Угол наклона спинки, град.
Радиус спинки в плане не
менее, мм
Рост учащихся и студентов в обуви, см
116 –
131 –
146 –
161 –
>175
130
145
160
175
2
3
4
5
6
300
270
290
340
290
330
380
320
360
420
340
380
460
360
400
130
150
160
170
190
280
310
330
360
400
170
190
200
210
220
20 - 50
0-4
95-108
300
Рабочее место должно быть оборудовано подставкой для ног, имеющей
ширину не менее 300 мм, глубину не менее 400 мм, регулировку по высоте в
пределах до 150 мм и по углу наклона опорной поверхности подставки до 20
градусов. Поверхность подставки должна быть рифленой и иметь по переднему
краю бортик высотой 10 мм. На рабочем месте автора данного проекта подставка
для ног отсутствует.
60
Исходя из эргономических требований, пространство рабочего места можно
разделить на несколько частей:
Моторное поле — пространство рабочего места, в котором могут
осуществляться двигательные действия человека;
Максимальная зона досягаемости рук — это часть моторного поля рабочего
места, ограниченного дугами, описываемыми максимально вытянутыми руками
при движении их в плечевом суставе;
Оптимальная зона — часть моторного поля рабочего места, ограниченного
дугами, описываемыми предплечьями при движении в локтевых суставах с
опорой в точке локтя и с относительно неподвижным плечом.
Большое значение также придается правильной рабочей позе пользователя.
При неудобной рабочей позе могут появиться боли в мышцах, суставах и
сухожилиях.
Требования
к
рабочей
позе
пользователя
видеотерминала
следующие:
1) голова не должна быть наклонена более чем на 20;
2) плечи должны быть расслаблены;
3) локти - под углом 80…100;
4) предплечья и кисти рук - в горизонтальном положении.
Причина неправильной позы пользователей обусловлена следующими
факторами: нет хорошей подставки для документов, клавиатура находится
слишком высоко, а документы — низко, некуда положить руки и кисти, недостаточно пространство для ног.
В целях преодоления указанных недостатков даются общие рекомендации:
лучше передвижная клавиатура; должны быть предусмотрены специальные
приспособления для регулирования высоты стола, клавиатуры и экрана, а также
подставка для рук.
61
Существенное значение для производительной и качественной работы на
компьютере имеют размеры знаков, плотность их размещения, контраст и
соотношение яркостей символов и фона экрана. Если расстояние от глаз
оператора до экрана дисплея составляет 60…80 см, то высота знака должна быть
не менее 3 мм, оптимальное соотношение ширины и высоты знака составляет 3:4,
а расстояние между знаками – 15…20% их высоты. Соотношение яркости фона
экрана и символов - от 1:2 до 1:15.
Во время пользования компьютером медики советуют устанавливать
монитор на расстоянии 50-60 см от глаз. Специалисты также считают, что верхняя часть видеодисплея должна быть на уровне глаз или чуть ниже. Когда
человек смотрит прямо перед собой, его глаза открываются шире, чем когда он
смотрит вниз. За счет этого площадь обзора значительно увеличивается, вызывая
обезвоживание глаз. К тому же если экран установлен высоко, а глаза широко
открыты, нарушается функция моргания. Это значит, что глаза не закрываются
полностью, не омываются слезной жидкостью, не получают достаточного
увлажнения, что приводит к их быстрой утомляемости.
Рабочее место инженера-программиста в составе данного проекта в целом
соответствует предъявляемым к нему эргономическим требованиям, связанным с
параметрами мебели и размещением предметов труда в рабочих зонах. При этом
можно сформулировать следующие рекомендации: установить на рабочее место
подставку для ног, отодвинуть принтер в зону максимальной досягаемости,
поменяв его местами с рабочей поверхностью стола.
В результате проведения анализа вредных и опасных производственных
факторов, действующих на рабочем месте инженера-программиста, были
выделены следующие: постоянное напряжение глаз, влияние электростатических
и электромагнитных полей, длительное неизменное положение тела, шум. Был
62
проведен
анализ
и
указан
комплекс
мер
по
пожаробезопасности
и
электробезопасности. Проведен расчет эргономических требований к рабочему
месту инженера-программиста. Обозначенные условия должны обеспечивать
комфортную работу. На основании изученной литературы по данной проблеме
были указаны оптимальные размеры рабочего стола и стула, параметры рабочей
поверхности, а также сформулированы предложения по улучшению параметров
рабочего места. Соблюдение условий, определяющих оптимальную организацию
рабочего
места
инженера-программиста,
позволит
сохранить
хорошую
работоспособность в течение всего рабочего дня, повысит как в количественном,
так и в качественном отношениях производительность труда программиста, что,
в свою очередь, будет способствовать более быстрой разработке и отладке
программного продукта.
63
ЗАКЛЮЧЕНИЕ
В результате проделанной работы была создана автоматизированная
система, позволяющая вводить план эвакуации с учетом всех особенностей и
специфик здания, помещения, окон, дверей, лестниц и лифтов; также система
предоставляет возможности определения пожарной нагрузки в соответствии с
нормами
пожарной
безопасности
(НПБ).
Учитывается
географическое
местоположение здания, с указанием сторон полюсов. Система имеет гибкие
функциональные возможности для разработки плана эвакуации. Также система
позволяет редактирование уже имеющегося плана, разработанного данным
программным продуктом.
Система
корректно
генерирует
исходные
данные
и
сохраняет
в
структурированный xml файл, с последующей передачей в один из расчетных
модулей (модель эвакуации и модель пожара).
Так
как
система
является
частью
программного
комплекса
по
прогнозированию последствий ЧС и разработки паспортов безопасности опасных
объектов «Риск - Аналитик», тем самым относится к новому типу программного
обеспечения «Приложение + Сервис», для функционирования которого требуется
подключение к Интернету.
64
СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ
1)
Бланшет Ж, Саммерфилд М.Qt 4: Программирование GUI на C++. –
М.:Кудиц-Пресс, 2008. – 736 с.
2)
Шлее М., Qt4. Профессиональное программирование на C++. –
Спб.:БХВ-Петербург, 2007. – 880с.
3)
Страуструп Б. Язык программирования C++. Специальное издание.
М.:Бином, 2007, 1099 с.
4)
Спольски Д. Джоэл о программировании. – Спб.:Символ-Плюс, 2006,
352 с.
5)
Кнут Д. Искусство программирования для ЭВМ. – М.: Мир, 1976. – Т. 1-
6)
Федеральный Закон от 17 июля 1999 г. № 181-ФЗ «Об основах охраны
3.
труда в Российской Федерации» - устанавливает правовые основы регулирования
отношений в области охраны труда между работодателями и работниками и
направлен на создание условий труда, соответствующих требованиям сохранения
жизни
и
здоровья
работников
в
процессе
трудовой
деятельности.
Государственными нормативными требованиями охраны труда, содержащимися
в федеральных законах и иных нормативных правовых актах Российской
Федерации и законах и иных нормативных правовых актах субъектов Российской
Федерации об охране труда, устанавливаются правила, процедуры и критерии,
направленные на сохранение жизни и здоровья работников в процессе трудовой
деятельности.
7)
ГОСТ 12.1.003–83. ССБТ. Шум. Общие требования безопасности (с
изменениями по И-1-III-89).
65
8)
ГОСТ 12.1.005–88. ССБТ. Общие санитарно-гигиенические требования
к воздуху рабочей зоны.
9)
ГОСТ 12.1.006–84. ССБТ. Электромагнитные поля радиочастот.
Допустимые уровни на рабочих местах и требования к проведению контроля.
10) СНиП 23-05–95. Естественное и искусственное освещение.
11) СанПиН 2.2.2.542-96. Гигиенические требования к видео-дисплейным
терминалам, персонально-вычислительным машинам и организация работ.
12) ГОСТ Р 50923-96 Дисплеи. Рабочее место оператора. Общие
эргономические требования и требования к производственной среде. Методы
измерения.
13) ГОСТ
Р
50948-2001
Средства
отображения
информации
индивидуального пользования. Общие эргономические требования и требования
безопасности.
14) ГОСТ
Р
50949-2001
Средства
отображения
информации
индивидуального пользования. Методы измерений и оценки эргономических
параметров и параметров безопасности.
15) Единая система программной документации [Сборник]: ГОСТ 19.001-77
– ГОСТ 19.604-78. – М.: Издательство стандартов, 1988.
16) ГОСТ 19.701-90. ЕСПД. Схемы алгоритмов, программ, данных и
систем. Условные обозначения и правила выполнения. – М.: Издательство
стандартов, 1991.
17) Методические указания по оформлению курсовых и дипломных работ
для
студентов
специальности
220400
«Программное
обеспечение
вычислительной техники и автоматизированных систем». – Ижевск: ГОУ ВПО
«Ижевский государственный технический университет», 2008.
66
67
ПРИЛОЖЕНИЕ 1
КОНТРОЛЬНЫЙ ПРИМЕР
В данном приложении расположены снимки экранных форм системы.
Главное окно программы
Рис. П.1.1
68
Окно редактирования помещения
Рис. П.1.2
Окно редактирование двери
Рис. П.1.3
69
Работа с текстом
Рис. П.1.4
Меню «Файл»
Рис. П.1.5
70
Меню «Обзор»
Рис. П.1.6
Меню «Обзор»
Рис. П.1.7
71
Контекстное меню
Рис. П.1.8
72
ПРИЛОЖЕНИЕ 2
КОД ПРОГРАММЫ
Файл mainwindow.cpp
#include <QtGui>
#include "mainwindow.h"
#include "character/mwcharacter.h"
const
const
const
const
const
int
int
int
int
int
InsertTextButton = 10;
InsertDrawItemButton = 64;
InsertPathButton = 20;
InsertWallButton = 30;
InsertLineToolButton = 40;
#define NDEBUG
MainWindow::MainWindow()
{
createActions();
createToolBox();
createMenus();
scene = new DiagramScene(itemMenu);
//myGrid = 20;
widthScene = 1000;
heightScene = 1000;
//scene->setGrid(myGrid);
scene->setSceneRect(0, 0, widthScene, heightScene);
connect(scene, SIGNAL(itemInserted(DiagramDrawItem *)),
this, SLOT(itemInserted(DiagramDrawItem *)));
connect(scene, SIGNAL(textInserted(QGraphicsTextItem *)),
this, SLOT(textInserted(QGraphicsTextItem *)));
connect(scene, SIGNAL(itemSelected(QGraphicsItem *)),
this, SLOT(itemSelected(QGraphicsItem *)));
// activate/deactivate shortcuts when text is edited in scene
connect(scene, SIGNAL(editorHasReceivedFocus()),
this, SLOT(deactivateShortcuts()));
connect(scene, SIGNAL(editorHasLostFocus()),
this, SLOT(activateShortcuts()));
connect(scene, SIGNAL(zoomRect(QPointF,QPointF)),
this, SLOT(doZoomRect(QPointF,QPointF)));
connect(scene, SIGNAL(zoom(const qreal)),
this, SLOT(zoom(const qreal)));
createToolbars();
tabWidget = new QTabWidget;
view = new QGraphicsView(scene);
view->setRenderHint(QPainter::Antialiasing, true);
view->setDragMode(QGraphicsView::RubberBandDrag);
view->setCacheMode(QGraphicsView::CacheBackground);
listScene.append(scene);
listView.append(view);
QVBoxLayout *layoutTool = new QVBoxLayout;
73
layoutTool->addWidget(toolBox);
QWidget *widgetTool = new QWidget;
widgetTool->setLayout(layoutTool);
QGridLayout *layoutTab = new QGridLayout;
layoutTab->addWidget(view);
QWidget *widgetTab = new QWidget;
widgetTab->setLayout(layoutTab);
tabWidget->addTab(widgetTab, tr(mwTabWidget));
QGridLayout *layout = new QGridLayout;
layout->addWidget(widgetTool, 0, 0);
layout->addWidget(tabWidget, 0 , 1);
setLayout(layout);
QWidget *widget = new QWidget;
widget->setLayout(layout);
setCentralWidget(widget);
setWindowTitle(tr(mwWinTitle));
toggleGrid(false);
myFileName.clear();
myShowGrid = false;
}
void MainWindow::deleteItem()
{
scene = listScene.at(tabWidget->currentIndex());
foreach (QGraphicsItem *item, scene->selectedItems()) {
scene->removeItem(item);
}
}
void MainWindow::pointerGroupClicked(int id)
{
view = listView.at(tabWidget->currentIndex());
scene = listScene.at(tabWidget->currentIndex());
QList<QAbstractButton *> buttons = pointerTypeGroup->buttons();
foreach (QAbstractButton *button, buttons) {
if (pointerTypeGroup->button(id) != button)
button->setChecked(false);
}
if(pointerTypeGroup->checkedId() != DiagramScene::MoveItem)
view->setDragMode(QGraphicsView::NoDrag);
else
view->setDragMode(QGraphicsView::RubberBandDrag);
scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId()));
}
void MainWindow::bringToFront()
{
if (scene->selectedItems().isEmpty())
return;
else {
QGraphicsItem *selectedItem = scene->selectedItems().first();
QList<QGraphicsItem *> overlapItems = selectedItem->collidingItems();
qreal zValue = 0;
foreach (QGraphicsItem *item, overlapItems)
{
74
if (item->zValue() >= zValue)
zValue = item->zValue() + 0.1;
}
selectedItem->setZValue(zValue);
}
}
void MainWindow::sendToBack()
{
if (scene->selectedItems().isEmpty())
return;
else
{
QGraphicsItem *selectedItem = scene->selectedItems().first();
QList<QGraphicsItem *> overlapItems = selectedItem->collidingItems();
qreal zValue = 0;
foreach (QGraphicsItem *item, overlapItems) {
if (item->zValue() <= zValue)
zValue = item->zValue() - 0.1;
}
selectedItem->setZValue(zValue);
}
}
void MainWindow::rotateRight()
{
if (scene->selectedItems().isEmpty())
return;
else {
QGraphicsItem *selectedItem = scene->selectedItems().first();
selectedItem->rotate(90);
}
}
void MainWindow::rotateLeft()
{
if (scene->selectedItems().isEmpty())
return;
else {
QGraphicsItem *selectedItem = scene->selectedItems().first();
selectedItem->rotate(-90);
}
}
void MainWindow::rotateItem(int i)
{
if (scene->selectedItems().isEmpty())
return;
else {
QGraphicsItem *selectedItem = scene->selectedItems().first();
selectedItem->rotate(i);
}
}
void MainWindow::moveItems()
{
scene->setMode(DiagramScene::MoveItems);
view->setDragMode(QGraphicsView::RubberBandDrag);
}
void MainWindow::abort()
{
scene->abort();
scene->setMode(DiagramScene::MoveItem);
view->setDragMode(QGraphicsView::RubberBandDrag);
}
void MainWindow::copyItems()
{
75
scene->setMode(DiagramScene::CopyItem);
view->setDragMode(QGraphicsView::RubberBandDrag);
}
void MainWindow::groupItems()
{
if (scene->selectedItems().isEmpty())
return;
else {
QGraphicsItemGroup *group = scene->createItemGroup(scene->selectedItems());
group->setFlag(QGraphicsItem::ItemIsMovable, true);
group->setFlag(QGraphicsItem::ItemIsSelectable, true);
}
}
void MainWindow::ungroupItems() {
if (scene->selectedItems().isEmpty())
return;
else {
foreach (QGraphicsItem *item, scene->selectedItems()) {
if (item->type() == 10) {
QGraphicsItemGroup *group = (QGraphicsItemGroup*) item;
scene->destroyItemGroup(group);
}
}
}
}
void MainWindow::textInserted(QGraphicsTextItem *)
{
buttonGroup->button(InsertTextButton)->setChecked(false);
scene->setMode(DiagramScene::MoveItem);
view->setDragMode(QGraphicsView::RubberBandDrag);
pointerTypeGroup->button(DiagramScene::MoveItem)->setChecked(true);
}
void MainWindow::print()
{
//scene = listScene.at(tabWidget->currentIndex());!!!
QPrinter printer;
if (QPrintDialog(&printer).exec() == QDialog::Accepted) {
QPainter painter(&printer);
painter.setRenderHint(QPainter::Antialiasing);
scene->render(&painter);
}
}
void MainWindow::exportImage()
{
QFileDialog::Options options;
options = 0;
QString selectedFilter;
QString fileName = QFileDialog::getSaveFileName(this,
tr(mwExportImage),
".png",
tr("Png (*.png);;Pdf (*.pdf)"),
&selectedFilter,
options);
if (!fileName.isEmpty()){
if((selectedFilter == "Pdf (*.pdf)")) {
QRectF rect = scene->itemsBoundingRect();
QPrinter printer;
printer.setOutputFileName(fileName);
76
QSizeF size = printer.paperSize(QPrinter::Millimeter);
size.setHeight(size.width()*rect.height()/rect.width());
printer.setPaperSize(size,QPrinter::Millimeter);
printer.setPageMargins(0,0,0,0,QPrinter::Millimeter);
QPainter painter(&printer);// generate PDF
painter.setRenderHint(QPainter::Antialiasing);
scene->render(&painter, QRectF(), rect);
}
else {
QPixmap pixmap(1000,1000);
pixmap.fill();
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
QRectF rect=scene->itemsBoundingRect();
scene->render(&painter, QRectF(), rect);
painter.end();
pixmap.save(fileName);
}
}
}
void MainWindow::createToolBox() {
buttonGroup = new QButtonGroup;
buttonGroup->setExclusive(false);
connect(buttonGroup, SIGNAL(buttonClicked(int)),
this, SLOT(buttonGroupClicked(int)));
QGridLayout *layout = new QGridLayout;
layout->addWidget(createCellWidget(tr(mwLblPortal),
DiagramDrawItem::Portal), 0, 1);
layout->addWidget(createCellWidget(tr(mwLblLift),
DiagramDrawItem::Lift), 1, 0);
layout->addWidget(createCellWidget(tr(mwLblRoom),
DiagramDrawItem::Room), 1, 1);
layout->addWidget(createCellWidget(tr(mwLblWall),
DiagramDrawItem::Wall), 2, 0);
layout->addWidget(createCellWidget(tr(mwLblWindow),
DiagramDrawItem::Window), 2, 1);
layout->addWidget(createCellWidget(tr(mwLblStairway),
DiagramDrawItem::Stairway), 3, 0);
layout->addWidget(createCellWidget(tr(mwLblDoor),
DiagramDrawItem::Door), 4, 1);
QToolButton *textButton = new QToolButton;
textButton->setCheckable(true);
buttonGroup->addButton(textButton, InsertTextButton);
textButton->setIcon(QIcon(QPixmap(":/Resources/textpointer.png")
.scaled(30, 30)));
textButton->setIconSize(QSize(30, 30));
QGridLayout *textLayout = new QGridLayout;
textLayout->addWidget(textButton, 0, 0, Qt::AlignHCenter);
textLayout->addWidget(new QLabel(tr(mwLblText)), 1, 0, Qt::AlignCenter);
QWidget *textWidget = new QWidget;
textWidget->setLayout(textLayout);
layout->addWidget(textWidget, 0, 0);
QToolButton *pathButton = new QToolButton;
pathButton->setCheckable(true);
buttonGroup->addButton(pathButton, InsertPathButton);
77
pathButton->setIcon(QIcon(QPixmap(":/Resources/linecolor.png")
.scaled(30, 30)));
pathButton->setIconSize(QSize(30, 30));
QGridLayout *pathLayout = new QGridLayout;
pathLayout->addWidget(pathButton, 0, 0, Qt::AlignHCenter);
pathLayout->addWidget(new QLabel(tr(mwLblPath)), 1, 0, Qt::AlignCenter);
QWidget *pathWidget = new QWidget;
pathWidget->setLayout(pathLayout);
layout->addWidget(pathWidget, 3, 1);
QToolButton *lineButton = new QToolButton;
lineButton->setCheckable(true);
buttonGroup->addButton(lineButton, InsertLineToolButton);
lineButton->setIcon(QIcon(QPixmap(":/Resources/linecolor.png")
.scaled(30, 30)));
lineButton->setIconSize(QSize(30, 30));
QGridLayout *lineLayout = new QGridLayout;
lineLayout->addWidget(lineButton, 0, 0, Qt::AlignHCenter);
lineLayout->addWidget(new QLabel(tr(mwLblLine)), 1, 0, Qt::AlignCenter);
QWidget *lineWidget = new QWidget;
lineWidget->setLayout(lineLayout);
layout->addWidget(lineWidget, 4, 0);
layout->setRowStretch(3, 10);
layout->setColumnStretch(2, 10);
QWidget *itemWidget = new QWidget;
itemWidget->setLayout(layout);
backgroundButtonGroup = new QButtonGroup;
connect(backgroundButtonGroup, SIGNAL(buttonClicked(QAbstractButton *)),
this, SLOT(layerButtonGroupClicked(QAbstractButton *)));
QGridLayout *backgroundLayout = new QGridLayout;
backgroundLayout->addWidget(createLayerCellWidget());
backgroundLayout->setRowStretch(2, 10);
backgroundLayout->setColumnStretch(2, 10);
QWidget *backgroundWidget = new QWidget;
backgroundWidget->setLayout(backgroundLayout);
backgroundLayout->setRowStretch(2, 10);
backgroundLayout->setColumnStretch(2, 10);
QGridLayout *propertyLayout = new QGridLayout;
propertyLayout->addWidget(createPropertyCellWidget());
propertyLayout->setRowStretch(2, 10);
propertyLayout->setColumnStretch(2, 10);
QWidget *propertyWidget = new QWidget;
propertyWidget->setLayout(propertyLayout);
toolBox = new QToolBox;
toolBox->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored));
toolBox->setMinimumWidth(itemWidget->sizeHint().width());
toolBox->addItem(itemWidget, tr(mwWidgetInstrumets));
toolBox->addItem(backgroundWidget, tr(mwWidgetLayer));
toolBox->addItem(propertyWidget, tr(mwWidgetProperty));
}
78
void MainWindow::slotAddLayer() {
DiagramScene *newScene = new DiagramScene(itemMenu);
newScene->setSceneRect(0, 0, 1000, 1000);
toggleGrid(false);
myShowGrid = false;
QGraphicsView *view = new QGraphicsView(newScene);
view->setDragMode(QGraphicsView::RubberBandDrag);
view->setCacheMode(QGraphicsView::CacheBackground);
view->setRenderHint(QPainter::Antialiasing, true);
listScene.append(newScene);
listView.append(view);
scene->lstLayer.append(tabWidget->count()+1);
QGridLayout *layoutTab = new QGridLayout;
layoutTab->addWidget(view);
QWidget *widgetTab = new QWidget;
widgetTab->setLayout(layoutTab);
foreach(QGraphicsItem *item, scene->items())
{
dItem = (DiagramDrawItem *)item;
if(dItem->diagramType() == 5)
{
//Stairway
DiagramDrawItem *newItem = new DiagramDrawItem(dItem->diagramType(),
itemMenu);
newItem->setEnabled(false);
newScene->addItem(newItem);
newScene->setPropertyStairway(newItem, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0);
newItem->setPos(dItem->scenePos());
newItem->setDimension(dItem->getDimension());
newItem->setZValue(dItem->zValue());
newItem->setSelected(false);
}
if(dItem->diagramType() == 4)
{ //Lift
DiagramDrawItem *newItem = new DiagramDrawItem(dItem->diagramType(),
itemMenu);
newItem->setEnabled(false);
newScene->addItem(newItem);
newScene->setPropertyStairway(dItem, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0);
newItem->setPos(dItem->scenePos());
newItem->setDimension(dItem->getDimension());
newItem->setZValue(dItem->zValue());
newItem->setSelected(false);
}
}
tabWidget->addTab(widgetTab, tr(mwWidgetTitleLayer) .arg(tabWidget->count()));
}
void MainWindow::slotDeleteLayer()
{
if(tabWidget->count() > 1) {
tabWidget->removeTab(tabWidget->currentIndex());
listView.removeAt(tabWidget->currentIndex());
listScene.removeAt(tabWidget->currentIndex());
}
}
void MainWindow::slotProperty() {
scene = listScene.at(tabWidget->currentIndex());
LineProperty *lp = new LineProperty(this, lt);
79
if(!scene->selectedItems().isEmpty())
{
QGraphicsItem *item = scene->selectedItems().first();
switch(item->type())
{
case QGraphicsItem::UserType + 9:
lp->spinMeter->setValue(lt->l);
lt = (LineTool*)item;
foreach(QPointF p, lt->myPoints) {
if(lt->myPoints.indexOf(p) == 0) {
x1 = p.x(); y1 = p.y();
}
else if(lt->myPoints.indexOf(p) == 1)
{
x2 = p.x(); y2 = p.y();
}
}
lt->pointList(item->x(), item->y(), x1, y1, x2, y2);
lp->exec();
break;
case QGraphicsItem::UserType+16:
foreach(QGraphicsItem *item, scene->items()){
if(scene->selectedItems().at(0) == item)
dItem = (DiagramDrawItem*)item;
{
///////////////////////////Door/////////////////////////////
if(dItem->diagramType() == 0)
{
propDoor = new DoorProperty(this, item,
scene);
propDoor->show();
}
///////////////////////////////Wall/////////////////////////
else if(dItem->diagramType() == 1)
{
propWall = new WallProperty(this, item,
scene);
propWall->show();
}
///////////////////////////////Window///////////////////////
else if(dItem->diagramType() == 2)
{
propWindow = new PropertyWindow(this, item,
scene);
propWindow->exec();
}
///////////////////////Lift/////////////////////////////////
else if(dItem->diagramType() == 3)
{
propLift = new LiftProperty(this, item,
scene);
propLift->show();
}
/////////////////////////Stairway///////////////////////////
else if(dItem->diagramType() == 4)
{
propStairway = new StairwayProperty(this,
item, scene);
propStairway->exec();
}
//////////////////////Portal////////////////////////////////
else if(dItem->diagramType() == 5)
{
portalProp = new PortalProperty(this, item,
scene);
qDebug() << "Portal\n" << item->scenePos();
80
qDebug() << dItem->getDimension().x() <<
dItem->getDimension().y();
portalProp->exec();
}
///////////////////////////room///////////////////////////
else if(dItem->diagramType() == 6)
{
propRoom = new RoomProperty(this, item,
scene);
propRoom->exec();
}
}
}
break;
default:
break;
}
}
}
void MainWindow::toggleGrid(bool grid)
{
scene = listScene.at(tabWidget->currentIndex());
view = listView.at(tabWidget->currentIndex());
scene->setGridVisible(grid);
view->repaint();
QPointF topLeft
= view->mapToScene( 0, 0 );
QPointF bottomRight = view->mapToScene( view->viewport()->width() - 1,
view->viewport()>height() - 1 );
scene->invalidate(topLeft.x(), topLeft.y(),
bottomRight.x() - topLeft.x(),
bottomRight.y() - topLeft.y());
//scene->update();
//view->update();
}
void MainWindow::setGrid() {
scene = listScene.at(tabWidget->currentIndex());
view = listView.at(tabWidget->currentIndex());
if(scene->isGridVisible()) {
QPointF topLeft
= view->mapToScene(0, 0);
QPointF bottomRight = view->mapToScene( view->viewport()->width() - 1,
view>viewport()->height() - 1 );
qreal width = bottomRight.x() - topLeft.x();
qreal height = bottomRight.y() - topLeft.y();
qreal zw = width;
//std::cout << width << "/" << height << std::endl;
if(zw < height) zw = height;
int n = int(zw)/int(myGrid);
int k = 1;
while(n/k > 50)
k = k*2;
//std::cout << k << std::endl;
scene->setGridScale(k);
scene->update();
}
}
void MainWindow::saveAs() {
//scene = listScene.at(tabWidget->currentIndex());
QFileDialog::Options options;
options = 0;
81
QString selectedFilter;
QString fileName = QFileDialog::getSaveFileName(this,
tr(mwSaveAs),
".rintd",
tr("DesignerRINTD (*.rintd)"),
&selectedFilter,
options);
if (!fileName.isEmpty()){
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QMessageBox::warning(this, tr(mwSaveAsError), file.errorString());
}
else
{
scene->wS = widthScene;
scene->hS = heightScene;
if(scene->save(&file))
myFileName = fileName;
file.close();
if(file.error())
{
QMessageBox::warning(this, tr(mwSaveAsError),
file.errorString());
/*std::cerr << "Error: cannot write file "
<< qPrintable(file.fileName())
<< qPrintable(file.errorString())
<< std::endl ;*/
}
}
}
}
void MainWindow::slotLoadImage() {
QString fileName = QFileDialog::getOpenFileName(this,
tr(mwOpenImage), QDir::currentPath());
if (!fileName.isEmpty()) {
QImage image(fileName);
if (image.isNull()) {
QMessageBox::information(this, tr("DEP"),
tr(mwOpenImageError).arg(fileName));
return;
}
scene = listScene.at(tabWidget->currentIndex());
scene->setSceneRect(0,0, image.width(), image.height());
scene->addPixmap(QPixmap::fromImage(image));
if(image.width() != 0 && image.height() != 0) {
widthScene = image.width();
heightScene = image.height();
} else {
widthScene = heightScene = 1000;
}
view->update();
}
}
void MainWindow::save()
{
if (!myFileName.isEmpty()) {
QFile file(myFileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QMessageBox::warning(this, tr(mwSaveAsError), file.errorString());
}
else
{
scene->wS = widthScene;
scene->hS = heightScene;
scene->save(&file);
}
82
}
}
void MainWindow::load()
{
scene = listScene.at(tabWidget->currentIndex());
QFileDialog::Options options;
options = 0;
QString selectedFilter;
QString fileName = QFileDialog::getOpenFileName(this,
tr(mwLoadPlan),
".rintd",
tr("DesignerRINTD (*.rintd)"),
&selectedFilter,
options);
if (!fileName.isEmpty())
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
QMessageBox::warning(this, tr(mwLoadPlanError), file.errorString());
}
else
{
scene->clear();
scene->load(&file);
myFileName = fileName;
}
}
}
Файл diagramscene.cpp
#include <QtGui>
#include <iostream>
#include "diagramscene.h"
#include "lineproperty.h"
DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent)
: QGraphicsScene(parent)
{
myItemMenu = itemMenu;
myMode = MoveItem;
textItem = 0;
insertedDrawItem = 0;
insertedPathItem = 0;
insertedLineTool = 0;
copiedItems = 0;
hS = wS = 1000;
myDx = 0.0;
myDy = 0.0;
maxZ = 0;
myItemColor = Qt::white;
myTextColor = Qt::black;
myLineColor = Qt::black;
myGrid
= 2.0;
myGridVisible = false;
myGridScale
= 1;
myMoveItems.clear();
}
void DiagramScene::setMode(Mode mode, bool m_abort)
{
if(m_abort)
abort(true);
83
if(myMode == InsertLine)
{
if(insertedPathItem != 0) {
insertedPathItem->remove();
insertedPathItem->setFlag(QGraphicsItem::ItemIsSelectable, true);
insertedPathItem = 0;
}
}
if(myMode == InsertLineTool)
{
if(insertedLineTool != 0) {
insertedLineTool->remove();
insertedLineTool->setFlag(QGraphicsItem::ItemIsSelectable, true);
insertedLineTool = 0;
}
}
myMode = mode;
switch (mode) {
case MoveItem:
enableAllItems(true);
break;
case MoveItems:
enableAllItems(true);
break;
case CopyItem:
enableAllItems(true);
break;
case CopyingItem:
enableAllItems(false);
break;
case Zoom:
enableAllItems(false);
break;
default:
enableAllItems(false);
break;
}
}
void DiagramScene::enableAllItems(bool enable)
{
foreach(QGraphicsItem* item,items()){
item->setEnabled(enable);
}
}
void DiagramScene::setItemType(DiagramDrawItem::ObjectType type)
{
myDrawItemType = type;
}
void DiagramScene::editorLostFocus(DiagramTextItem *item)
{
QTextCursor cursor = item->textCursor();
cursor.clearSelection();
item->setTextCursor(cursor);
if (item->toPlainText().isEmpty()) {
removeItem(item);
item->deleteLater();
}
if((textItem == item) || (textItem == 0)){
textItem = 0;
84
emit editorHasLostFocus();
}
}
void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if (mouseEvent->button() != Qt::LeftButton)
return;
switch (myMode) {
case InsertDrawItem:
if (insertedDrawItem == 0) {
insertedDrawItem = new DiagramDrawItem(myDrawItemType, myItemMenu);
insertedDrawItem->setBrush(myItemColor);
insertedDrawItem->setPen(myLineColor);
insertedDrawItem->setZValue(maxZ);
maxZ += 0.1;
addItem(insertedDrawItem);
switch(insertedDrawItem->diagramType()) {
case 0: //Door
setPropertyDoor(insertedDrawItem, 0.00, 0.00, 0, 0,
0, 0);
insertedDrawItem->setPos(onGrid(mouseEvent>scenePos()));
break;
case 1: //Wall
setPropertyWall(insertedDrawItem);
insertedDrawItem->setPos(onGrid(mouseEvent>scenePos()));
break;
case 2: //Window
setPropertyWindow(insertedDrawItem, 0.00, 0.00);
insertedDrawItem->setPos(onGrid(mouseEvent>scenePos()));
break;
case 3: //Lift
setPropertyLift(insertedDrawItem);
insertedDrawItem->setPos(onGrid(mouseEvent>scenePos()));
break;
case 4: //Stairway
setPropertyStairway(insertedDrawItem, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0);
insertedDrawItem->setPos(onGrid(mouseEvent>scenePos()));
break;
case 5: //Portal
setPropertyPortal(insertedDrawItem, 0.00, 0.00, "",
"", "");
insertedDrawItem->setPos(onGrid(mouseEvent>scenePos()));
break;
case 6: //Room
setPropertyRoom(insertedDrawItem, 0, 0.00, 0.00,
"");
insertedDrawItem->setPos(onGrid(mouseEvent>scenePos()));
break;
default:
break;
}
}
else
{
85
insertedDrawItem->setPos2(onGrid(mouseEvent->scenePos()));
insertedDrawItem->setEnabled(false);
insertedDrawItem = 0;
}
break;
case MoveItems:
{
QPointF point = onGrid(mouseEvent->scenePos());
if(!myMoveItems.isEmpty())
{
qreal dx = point.rx() - myDx;
qreal dy = point.ry() - myDy;
foreach(QGraphicsItem* item, myMoveItems)
{
if(item->parentItem() != 0)
{
if(!item->parentItem()->isSelected())
item->moveBy(-dx, -dy);
}
else
{
item->moveBy(dx, dy);
}
}
myMoveItems.clear();
myMode = MoveItem;
}
else
{
if(!selectedItems().isEmpty())
{
myMoveItems = selectedItems();
foreach(QGraphicsItem* item,myMoveItems)
{
if(item->parentItem())
if(item->parentItem()->isSelected())
{
item->setSelected(false);
myMoveItems.removeOne(item);
}
}
// member pos
myDx = point.rx();
myDy = point.ry();
}
}
break;
}
case InsertLine:
if (insertedPathItem == 0) {
insertedPathItem = new DiagramPathItem(myItemMenu);
insertedPathItem->setPen(myLineColor);
insertedPathItem->setBrush(myLineColor);
insertedPathItem->setZValue(maxZ);
maxZ += 0.1;
addItem(insertedPathItem);
insertedPathItem->setPos(onGrid(mouseEvent->scenePos()));
//insertedPathItem->setFlag(QGraphicsItem::ItemIsSelectable, true);
}
insertedPathItem->append(onGrid(mouseEvent->scenePos()));
break;
case InsertLineTool:
if (insertedLineTool == 0){
insertedLineTool = new LineTool;
insertedLineTool->setPen(myLineColor);
insertedLineTool->setBrush(myLineColor);
insertedLineTool->setZValue(maxZ);
maxZ += 0.1;
addItem(insertedLineTool);
insertedLineTool->setPos(onGrid(mouseEvent->scenePos()));
//insertedPathItem->setFlag(QGraphicsItem::ItemIsSelectable,
true);
86
}
insertedLineTool->append(onGrid(mouseEvent->scenePos()));
break;
case InsertText:
emit editorHasReceivedFocus();
textItem = new DiagramTextItem();
textItem->setFont(myFont);
textItem->setTextInteractionFlags(Qt::TextEditorInteraction);
textItem->setZValue(maxZ);
maxZ += 0.1;
connect(textItem, SIGNAL(lostFocus(DiagramTextItem *)),
this, SLOT(editorLostFocus(DiagramTextItem *)));
connect(textItem, SIGNAL(receivedFocus(DiagramTextItem *)),
this, SLOT(editorReceivedFocus(DiagramTextItem *)));
addItem(textItem);
textItem->setDefaultTextColor(myTextColor);
textItem->setFocus();
textItem->setCenterPoint(onGrid(mouseEvent->scenePos()));
textItem->activateEditor();
emit textInserted(textItem);
mouseEvent->setAccepted(true);
break;
case CopyItem:
if (!selectedItems().empty())
{
copiedItems = new QList<QGraphicsItem*>;
copiedItems->clear();
QList<QGraphicsItem*> myList = selectedItems();
foreach(QGraphicsItem* item, myList)
{
if(item->parentItem())
if(item->parentItem()->isSelected())
{
item->setSelected(false);
myList.removeOne(item);
}
}
// Ready to copy
QGraphicsItem *insItem;
insItem = myList.first();
QPointF point = onGrid(mouseEvent->scenePos());
myDx = insItem->pos().rx() - point.rx();
myDy = insItem->pos().ry() - point.ry();
// copy
foreach(QGraphicsItem* item, myList)
{
insItem = copy(item);
addItem(insItem);
insItem->setPos(item->pos());
copiedItems->append(item);
item->setZValue(maxZ);
maxZ += 0.1;
//check for children
if(item->childItems().count()>0) {
foreach(QGraphicsItem* item_l1, item->childItems())
{
QGraphicsItem* addedItem = copy(item_l1);
addItem(addedItem);
addedItem->setParentItem(insItem);
addedItem->setPos(item_l1->pos());
}
}
//move original to new position
item->setSelected(true);
87
//std::cout<< item->pos().rx()<< ","<<item->pos().ry() <<
std::endl;
}
myMode=CopyingItem;
}
break;
default:
;
break;
}
if(!mouseEvent->isAccepted()) QGraphicsScene::mousePressEvent(mouseEvent);
}
void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
// move cursor
myCursor.setPos(onGrid(mouseEvent->scenePos()));
// shape preview
switch (myMode){
case InsertLine:
if (insertedPathItem != 0) {
insertedPathItem->updateLast(onGrid(mouseEvent->scenePos()));
}
break;
case InsertLineTool:
if (insertedLineTool != 0) {
insertedLineTool->updateLast(onGrid(mouseEvent->scenePos()));
}
break;
case MoveItem:
QGraphicsScene::mouseMoveEvent(mouseEvent);
checkOnGrid();
break;
case MoveItems:
{
QPointF point = onGrid(mouseEvent->scenePos());
qreal dx = point.rx() - myDx;
qreal dy = point.ry() - myDy;
foreach(QGraphicsItem* item, myMoveItems)
{
/*if(item->parentItem() != 0){
if(!item->parentItem()->isSelected())
item->moveBy(dx,dy);
}
else {*/
item->moveBy(dx,dy);
//}
}
myDx = point.rx();
myDy = point.ry();
break;
}
case InsertDrawItem:
if (insertedDrawItem != 0){
insertedDrawItem->setPos2(onGrid(mouseEvent->scenePos()));
}
break;
default:
;
break;
}
}
88
//void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
//{
//
if (myMode == Zoom)
{
//
emit zoomRect(mouseEvent->scenePos(),mouseEvent->lastScenePos());
//
return;
//
}
//
line = 0;
//
//QGraphicsScene::mouseReleaseEvent(mouseEvent);
//}
void DiagramScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
switch (myMode)
{
case InsertLine:
//insertedPathItem->updateLast(onGrid(mouseEvent->scenePos()));
insertedPathItem->remove();
insertedPathItem->setFlag(QGraphicsItem::ItemIsSelectable, true);
insertedPathItem->setEnabled(false);
insertedPathItem = 0;
break;
case InsertLineTool:
//insertedPathItem->updateLast(onGrid(mouseEvent->scenePos()));
insertedLineTool->remove();
insertedLineTool->setFlag(QGraphicsItem::ItemIsSelectable, true);
insertedLineTool->setEnabled(false);
insertedLineTool = 0;
break;
default://Deletete in award
if(!selectedItems().isEmpty())
{
QGraphicsItem *item = selectedItems().first();
if(item)
QGraphicsScene::mouseDoubleClickEvent(mouseEvent);
;
}
break;
}
}
QGraphicsItem* DiagramScene::copy(QGraphicsItem* item)
{
switch(item->type()){
case QGraphicsItem::UserType + 3:
return
qgraphicsitem_cast<QGraphicsItem*>(qgraphicsitem_cast<DiagramTextItem*>(item)->copy());
break;
case QGraphicsItem::UserType + 6:
return
qgraphicsitem_cast<QGraphicsItem*>(qgraphicsitem_cast<DiagramPathItem*>(item)->copy());
break;
default:
DiagramDrawItem* newItem = dynamic_cast<DiagramDrawItem*>(item)>copy();
switch(newItem->diagramType())
{
case 0: //Door
setPropertyDoor(newItem, 0.00, 0.00, 0, 0, 0, 0);
return dynamic_cast<QGraphicsItem*>(newItem);
break;
case 1: //Wall
setPropertyWall(newItem);
return dynamic_cast<QGraphicsItem*>(newItem);
break;
case 2: //Window
setPropertyWindow(newItem, 0.00, 0.00);
return dynamic_cast<QGraphicsItem*>(newItem);
break;
case 3: //Lift
89
setPropertyLift(newItem);
return dynamic_cast<QGraphicsItem*>(newItem);
break;
case 4: //Stairway
setPropertyStairway(newItem, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0);
return dynamic_cast<QGraphicsItem*>(newItem);
break;
case 5: //Portal
setPropertyPortal(newItem, 0.00, 0.00, "", "", "");
return dynamic_cast<QGraphicsItem*>(newItem);
break;
case 6: //Room
setPropertyRoom(newItem, 0, 0.00, 0.00, "");
return dynamic_cast<QGraphicsItem*>(newItem);
break;
default:
break;
}
break;
}
}
bool DiagramScene::save(QFile *file)
{
QXmlStreamWriter xmlWriter(file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeComment("File for DesignerRINTD");
xmlWriter.writeStartElement("doc");
xmlWriter.writeStartElement("size");
xmlWriter.writeAttribute("width", QString::number(wS));
xmlWriter.writeAttribute("height", QString::number(hS));
xmlWriter.writeEndElement();
foreach(QGraphicsItem* item, items())
{
if(item->type() > QGraphicsItem::UserType)
{
xmlWriter.writeStartElement("Item");
DiagramDrawItem* diagItem = (DiagramDrawItem*)item;
if(diagItem->diagramType() == 0) {
xmlWriter.writeAttribute("Type", QString(tr("Door")));
xmlWriter.writeEmptyElement("Property");
QMap<QGraphicsItem*, double>::iterator mH = mapHeight.begin();
QMap<QGraphicsItem*, double>::iterator mS = mapSquare.begin();
QMap<QGraphicsItem*, int>::iterator mIO = mapDoorIO.begin();
QMap<QGraphicsItem*, double>::iterator mW = mapWide.begin();
QMap<QGraphicsItem*, double>::iterator mV = mapVoid.begin();
QMap<QGraphicsItem*, double>::iterator mZ = mapZ.begin();
for(; mH != mapHeight.end(); ++mH){
if(item == mH.key())
xmlWriter.writeAttribute("Height",
QString::number(mH.value()));
}
for(; mS != mapSquare.end(); ++mS){
if(item == mS.key())
xmlWriter.writeAttribute("Square",
QString::number(mS.value()));
}
for(; mIO != mapDoorIO.end(); ++mIO){
if(item == mIO.key())
90
xmlWriter.writeAttribute("IO",
QString::number(mIO.value()));
}
for(; mW != mapWide.end(); ++mW){
if(item == mW.key())
xmlWriter.writeAttribute("Wide",
QString::number(mW.value()));
}
for(; mV != mapVoid.end(); ++mV){
if(item == mV.key())
xmlWriter.writeAttribute("Void",
QString::number(mV.value()));
}
for(; mZ != mapZ.end(); ++mZ){
if(item == mZ.key())
xmlWriter.writeAttribute("Z",
QString::number(mZ.value()));
}
}
else if(diagItem->diagramType() == 1)
{
xmlWriter.writeAttribute("Type", QString(tr("Wall")));
xmlWriter.writeEmptyElement("Property");
QMap<QGraphicsItem*, double>::iterator mH = mapHeight.begin();
QMap<QGraphicsItem*, double>::iterator mS = mapSquare.begin();
for(; mH != mapHeight.end(); ++mH){
if(item == mH.key())
xmlWriter.writeAttribute("Height",
QString::number(mH.value()));
}
for(; mS != mapSquare.end(); ++mS){
if(item == mS.key())
xmlWriter.writeAttribute("Square",
QString::number(mS.value()));
}
}
else if(diagItem->diagramType() == 2){
xmlWriter.writeAttribute("Type", QString(tr("Window")));
xmlWriter.writeEmptyElement("Property");
QMap<QGraphicsItem*, double>::iterator mH = mapHeight.begin();
QMap<QGraphicsItem*, double>::iterator mS = mapSquare.begin();
for(; mH != mapHeight.end(); ++mH){
if(item == mH.key())
xmlWriter.writeAttribute("Height",
QString::number(mH.value()));
}
for(; mS != mapSquare.end(); ++mS){
if(item == mS.key())
xmlWriter.writeAttribute("Square",
QString::number(mS.value()));
}
}
else if(diagItem->diagramType() == 3){
xmlWriter.writeAttribute("Type", QString(tr("Lift")));
xmlWriter.writeEmptyElement("Property");
QMap<QGraphicsItem*, double>::iterator mH = mapHeight.begin();
QMap<QGraphicsItem*, double>::iterator mS = mapSquare.begin();
for(; mH != mapHeight.end(); ++mH){
if(item == mH.key())
91
xmlWriter.writeAttribute("Height",
QString::number(mH.value()));
}
for(; mS != mapSquare.end(); ++mS){
if(item == mS.key())
xmlWriter.writeAttribute("Square",
QString::number(mS.value()));
}
}
else if(diagItem->diagramType() == 4){
xmlWriter.writeAttribute("Type", QString(tr("Stairway")));
xmlWriter.writeEmptyElement("Property");
QMap<QGraphicsItem*, int>::iterator mS = mapStairway.begin();
for(; mS != mapStairway.end(); ++mS){
if(item == mS.key())
xmlWriter.writeAttribute("Simple",
QString::number(mS.value()));
}
QMap<QGraphicsItem *, double>::iterator x1 = mapX.begin();
for(; x1 != mapX.end(); ++x1){
if(item == x1.key())
xmlWriter.writeAttribute("x1",
QString::number(x1.value()));
}
QMap<QGraphicsItem *, double>::iterator y1 = mapY.begin();
for(; y1 != mapY.end(); ++y1){
if(item == x1.key())
xmlWriter.writeAttribute("x1",
QString::number(x1.value()));
}
QMap<QGraphicsItem *, double>::iterator z1 = mapZ.begin();
for(; z1 != mapZ.end(); ++z1){
if(item == x1.key())
xmlWriter.writeAttribute("x1",
QString::number(x1.value()));
}
QMap<QGraphicsItem *, double>::iterator x2 = mapX2.begin();
for(; x2 != mapX2.end(); ++x2){
if(item == x2.key())
xmlWriter.writeAttribute("x2",
QString::number(x2.value()));
}
QMap<QGraphicsItem *, double>::iterator y2 = mapY2.begin();
for(; y2 != mapY2.end(); ++y2){
if(item == y2.key())
xmlWriter.writeAttribute("y2",
QString::number(y2.value()));
}
QMap<QGraphicsItem *, double>::iterator z2 = mapZ2.begin();
for(; z2 != mapZ2.end(); ++z2){
if(item == z2.key())
xmlWriter.writeAttribute("z2",
QString::number(z2.value()));
}
QMap<QGraphicsItem *, double>::iterator x3 = mapX3.begin();
for(; x3 != mapX3.end(); ++x3){
if(item == x3.key())
xmlWriter.writeAttribute("x3",
QString::number(x3.value()));
}
QMap<QGraphicsItem *, double>::iterator y3 = mapY3.begin();
for(; y3 != mapY3.end(); ++y3){
if(item == y3.key())
92
xmlWriter.writeAttribute("y3",
QString::number(y3.value()));
}
QMap<QGraphicsItem *, double>::iterator z3 = mapZ3.begin();
for(; z3 != mapZ3.end(); ++z3){
if(item == z3.key())
xmlWriter.writeAttribute("z3",
QString::number(z3.value()));
}
QMap<QGraphicsItem *, double>::iterator x4 = mapX4.begin();
for(; x4 != mapX4.end(); ++x4){
if(item == x4.key())
xmlWriter.writeAttribute("x4",
QString::number(x4.value()));
}
QMap<QGraphicsItem *, double>::iterator y4 = mapY4.begin();
for(; y4 != mapY4.end(); ++y4){
if(item == y4.key())
xmlWriter.writeAttribute("y4",
QString::number(y4.value()));
}
QMap<QGraphicsItem *, double>::iterator z4 = mapZ4.begin();
for(; z4 != mapZ4.end(); ++z4){
if(item == z4.key())
xmlWriter.writeAttribute("z4",
QString::number(z4.value()));
}
}
else if(diagItem->diagramType() == 5)
{
xmlWriter.writeAttribute("Type", QString(tr("Portal")));
xmlWriter.writeEmptyElement("Property");
QMap<QGraphicsItem*, double>::iterator mH = mapHeight.begin();
QMap<QGraphicsItem*, double>::iterator mS = mapSquare.begin();
QMap<QGraphicsItem *, QString>::iterator m1 =
mapConnectorIdRoom1.begin();
QMap<QGraphicsItem *, QString>::iterator m2 =
mapConnectorIdRoom2.begin();
QMap<QGraphicsItem *, QString>::iterator m =
mapConnectorId.begin();
for(; mH != mapHeight.end(); ++mH){
if(item == mH.key())
xmlWriter.writeAttribute("Height",
QString::number(mH.value()));
}
for(; mS != mapSquare.end(); ++mS){
if(item == mS.key())
xmlWriter.writeAttribute("Square",
QString::number(mS.value()));
}
for(; m1 != mapConnectorIdRoom1.end(); ++m1){
if(item == m1.key())
xmlWriter.writeAttribute("ID_1",
QString(m1.value()));
}
for(; m2 != mapConnectorIdRoom2.end(); ++m2){
if(item == m2.key())
xmlWriter.writeAttribute("ID_2",
QString(m2.value()));
}
for(; m != mapConnectorId.end(); ++m){
if(item == m.key())
xmlWriter.writeAttribute("ID", QString(m.value()));
}
93
}
else if(diagItem->diagramType() == 6)
{
xmlWriter.writeAttribute("Type", QString(tr("Room")));
xmlWriter.writeEmptyElement("Property");
QMap<QGraphicsItem*, double>::iterator mH = mapHeight.begin();
QMap<QGraphicsItem*, double>::iterator mS = mapSquare.begin();
QMap<QGraphicsItem*, int>::iterator mTR = mapTypeRoom.begin();
QMap<QGraphicsItem*, QString>::iterator mId = mapIdRoom.begin();
for(; mH != mapHeight.end(); ++mH){
if(item == mH.key())
xmlWriter.writeAttribute("Height",
QString::number(mH.value()));
}
for(; mS != mapSquare.end(); ++mS){
if(item == mS.key())
xmlWriter.writeAttribute("Square",
QString::number(mS.value()));
}
for(; mTR != mapTypeRoom.end(); ++mTR){
if(item == mTR.key())
xmlWriter.writeAttribute("TypeRoom",
QString::number(mTR.value()));
}
for(; mId != mapIdRoom.end(); ++mId)
{
if(item == mId.key())
xmlWriter.writeAttribute("ID",
QString(mId.value()));
}
}
switch (item->type()) {
case QGraphicsItem::UserType+16: {
DiagramDrawItem* mItem = dynamic_cast<DiagramDrawItem*
>(item);
xmlWriter.writeEmptyElement("Pos");
xmlWriter.writeAttribute("x", QString::number(item>pos().x()));
xmlWriter.writeAttribute("y", QString::number(item>pos().y()));
xmlWriter.writeAttribute("z", QString::number(item>zValue()));
xmlWriter.writeAttribute("width", QString::number(mItem>getDimension().x()));
xmlWriter.writeAttribute("height", QString::number(mItem>getDimension().y()));
}
break;
case QGraphicsItem::UserType+3: {
DiagramTextItem *mItem =
dynamic_cast<DiagramTextItem *>(item);
//xmlWriter.writeEmptyElement("ObjectType");
xmlWriter.writeAttribute("Type", "0");
xmlWriter.writeStartElement("Text");
xmlWriter.writeCharacters(mItem->toHtml());
xmlWriter.writeEndElement();
}
break;
case QGraphicsItem::UserType+6: {
DiagramPathItem *mItem =
dynamic_cast<DiagramPathItem *>(item);
//xmlWriter.writeEmptyElement("ObjectType");
xmlWriter.writeAttribute("Type",
QString::number(QGraphicsItem::UserType+6));
94
foreach(QPointF point, mItem->getPoints()){
xmlWriter.writeEmptyElement("Point");
xmlWriter.writeAttribute("x",QString::number(point.x()));
xmlWriter.writeAttribute("y",QString::number(point.y()));
}
}
break;
case QGraphicsItem::UserType+9: {
LineTool *mItem = dynamic_cast<LineTool *>(item);
//xmlWriter.writeComment("DiagramLineItem");
//xmlWriter.writeEmptyElement("ObjectType");
xmlWriter.writeAttribute("Type",
QString::number(QGraphicsItem::UserType+9));
foreach(QPointF point, mItem->getPoints()){
xmlWriter.writeEmptyElement("Point");
xmlWriter.writeAttribute("x",QString::number(point.x()));
xmlWriter.writeAttribute("y",QString::number(point.y()));
}
}
break;
default:
break;
}
xmlWriter.writeEmptyElement("Transform");
xmlWriter.writeAttribute("m11", QString::number(item>transform().m11()));
xmlWriter.writeAttribute("m12", QString::number(item>transform().m12()));
xmlWriter.writeAttribute("m21", QString::number(item>transform().m21()));
xmlWriter.writeAttribute("m22", QString::number(item>transform().m22()));
xmlWriter.writeAttribute("dx", QString::number(item>transform().dx()));
xmlWriter.writeAttribute("dy", QString::number(item>transform().dy()));
xmlWriter.writeEndElement();
}
}
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
return true;
}
bool DiagramScene::load(QFile *file)
{
QXmlStreamReader xmlReader(file);
int DiaType = 0;
QPointF mPos;
qreal z;
int type, Material, TypeRoom;
double Height, Square;
Height = Square = 0.00;
Material = TypeRoom = 0;
insertedPathItem = 0;
insertedDrawItem = 0;
textItem = 0;
while(!xmlReader.atEnd()) {
xmlReader.readNext();
95
//std::cout << "name: " << DiaType << ":" <<
qPrintable(xmlReader.name().toString()) << std::endl;
if(xmlReader.isStartDocument()) continue;
if(xmlReader.isStartElement()){
if(xmlReader.name() == "doc") continue;
if(xmlReader.name() == "size")
{
setSceneRect(0, 0,
xmlReader.attributes().value("width").toString().toInt(),
xmlReader.attributes().value("height").toString().toInt());
continue;
}
if(!DiaType && (xmlReader.name() == "Item"))
bool ok;
{
QString s = xmlReader.attributes().value("Type").toString();
if(s == "Door" || s == "Wall" || s == "Window" || s == "Lift" ||
s == "Stairway" || s == "Portal" || s == "Room")
DiaType = 65552;
else {
DiaType =
xmlReader.attributes().value("Type").toString().toInt(&ok);
if(!ok)
{
xmlReader.raiseError(tr("DiaType: number conversion
failed"));
continue;
}
}
if(s
else
else
else
else
else
else
== "Door") type = 0;
if(s == "Wall") type = 1;
if(s == "Window") type = 2;
if(s == "Lift") type = 3;
if(s == "Stairway") type = 4;
if(s == "Portal") type = 5;
if(s == "Room") type = 6;
continue;
}
if(DiaType && (xmlReader.name() == "Pos"))
bool ok;
QPointF mPos2;
{
mPos.setX(xmlReader.attributes().value("x").toString().toDouble(&ok));//x1
mPos.setY(xmlReader.attributes().value("y").toString().toDouble(&ok));//y1
z =
xmlReader.attributes().value("z").toString().toDouble(&ok);//z
mPos2.setX(xmlReader.attributes().value("width").toString().toDouble(&ok));//x2
mPos2.setY(xmlReader.attributes().value("height").toString().toDouble(&ok));//y2
qDebug() << mPos;
if(!ok)
{
xmlReader.raiseError(tr("Pos: number conversion
failed"));
continue;
}
switch (DiaType) {
case QGraphicsItem::UserType + 16:
insertedDrawItem->setPos(mPos);
insertedDrawItem->setZValue(z);
insertedDrawItem->setDimension(mPos2);
break;
96
default:
break;
}
continue;
}
if(DiaType && (xmlReader.name() == "Property"))
{
bool ok;
switch (DiaType) {
case QGraphicsItem::UserType+16:
insertedDrawItem = new
DiagramDrawItem(DiagramDrawItem::ObjectType(type), myItemMenu);
addItem(insertedDrawItem);
//std::cout << "DiagramDrawItem" << std::endl;
if(type == 0){//Door
Height =
xmlReader.attributes().value("Height").toString().toDouble(&ok);
Square =
xmlReader.attributes().value("Square").toString().toDouble(&ok);
int io =
xmlReader.attributes().value("IO").toString().toInt(&ok);
double w =
xmlReader.attributes().value("Wide").toString().toDouble(&ok);
double v =
xmlReader.attributes().value("Void").toString().toDouble(&ok);
double z =
xmlReader.attributes().value("Z").toString().toDouble(&ok);;
if(!ok)
{
xmlReader.raiseError(tr("Property:
type number conversion failed"));
continue;
}
setPropertyDoor(insertedDrawItem, Height,
Square, io, w, v, z);
}
else if(type == 1){//Wall
setPropertyWall(insertedDrawItem);
}
else if(type == 2){//Window
Height =
xmlReader.attributes().value("Height").toString().toDouble(&ok);
Square =
xmlReader.attributes().value("Square").toString().toDouble(&ok);
if(!ok)
{
xmlReader.raiseError(tr("Property:
type number conversion failed"));
continue;
}
setPropertyWindow(insertedDrawItem, Height,
Square);
}
else if(type == 3){//Lift
setPropertyLift(insertedDrawItem);
}
else if(type == 4){//Stairway
int s =
xmlReader.attributes().value("Simple").toString().toInt(&ok);
double x1 =
xmlReader.attributes().value("x1").toString().toDouble(&ok);
double y1 =
xmlReader.attributes().value("y1").toString().toDouble(&ok);
double z1 =
xmlReader.attributes().value("z1").toString().toDouble(&ok);
double x2 =
xmlReader.attributes().value("x2").toString().toDouble(&ok);
97
double y2 =
xmlReader.attributes().value("y2").toString().toDouble(&ok);
double z2 =
xmlReader.attributes().value("z2").toString().toDouble(&ok);
double x3 =
xmlReader.attributes().value("x3").toString().toDouble(&ok);
double y3 =
xmlReader.attributes().value("y3").toString().toDouble(&ok);
double z3 =
xmlReader.attributes().value("z3").toString().toDouble(&ok);
double x4 =
xmlReader.attributes().value("x4").toString().toDouble(&ok);
double y4 =
xmlReader.attributes().value("y4").toString().toDouble(&ok);
double z4 =
xmlReader.attributes().value("z4").toString().toDouble(&ok);
if(!ok)
{
xmlReader.raiseError(tr("Property:
type number conversion failed"));
continue;
}
setPropertyStairway(insertedDrawItem, s, x1,
y1, z1, x2, y2, z2
, x3, y3, z3, x4, y4, z4);
}
else if(type == 5){//Portal
Height =
xmlReader.attributes().value("Height").toString().toDouble(&ok);
Square =
xmlReader.attributes().value("Square").toString().toDouble(&ok);
QString id =
xmlReader.attributes().value("ID").toString();
QString id1 =
xmlReader.attributes().value("ID_1").toString();
QString id2 =
xmlReader.attributes().value("ID_2").toString();
if(!ok)
{
xmlReader.raiseError(tr("Property:
type number conversion failed"));
continue;
}
setPropertyPortal(insertedDrawItem, Height,
Square, id, id1, id2);
}
else if(type == 6){//Room
Height =
xmlReader.attributes().value("Height").toString().toDouble(&ok);
Square =
xmlReader.attributes().value("Square").toString().toDouble(&ok);
TypeRoom =
xmlReader.attributes().value("TypeRoom").toString().toInt(&ok);
QString id =
xmlReader.attributes().value("ID").toString();
if(!ok)
{
xmlReader.raiseError(tr("Property:
type number conversion failed"));
continue;
}
setPropertyRoom(insertedDrawItem, TypeRoom,
Height, Square, id);
}
break;
case QGraphicsItem::UserType+6:
insertedPathItem = new DiagramPathItem(myItemMenu);
addItem(insertedPathItem);
98
//std::cout << "DiagramPathItem" << std::endl;
insertedPathItem->setPos(mPos);
insertedPathItem->setZValue(z);
insertedPathItem>setFlag(QGraphicsItem::ItemIsMovable, true);
insertedPathItem>setFlag(QGraphicsItem::ItemIsSelectable, true);
break;
case QGraphicsItem::UserType+3:
textItem = new DiagramTextItem();
textItem>setTextInteractionFlags(Qt::TextEditorInteraction);
textItem->setZValue(z);
connect(textItem, SIGNAL(lostFocus(DiagramTextItem
*)),
this,
SLOT(editorLostFocus(DiagramTextItem *)));
connect(textItem,
SIGNAL(receivedFocus(DiagramTextItem *)),
this,
SLOT(editorReceivedFocus(DiagramTextItem *)));
connect(textItem,
SIGNAL(selectedChange(QGraphicsItem *)),
this,
SIGNAL(itemSelected(QGraphicsItem *)));
addItem(textItem);
textItem->setPos(mPos);
break;
default:
break;
}
continue;
}
if(DiaType && !(insertedDrawItem || textItem || insertedPathItem)){
xmlReader.raiseError(tr("Type definition missing"));
continue;
}
if(DiaType && (xmlReader.name() == "Point")){
QPointF mPos2;
bool ok;
mPos2.setX(xmlReader.attributes().value("x").toString().toDouble(&ok));
mPos2.setY(xmlReader.attributes().value("y").toString().toDouble(&ok));
if(!ok)
{
xmlReader.raiseError(tr("Point: number conversion
failed"));
continue;
}
switch (DiaType) {
case QGraphicsItem::UserType+6:
insertedPathItem->append(mPos2+insertedPathItem>pos());
break;
default:
break;
}
continue;
}
if(DiaType && (xmlReader.name() == "Text"))
{
QString mText;
mText = xmlReader.readElementText();
switch (DiaType) {
99
case QGraphicsItem::UserType+3:
textItem->setHtml(mText);
break;
default:
break;
}
continue;
}//Only for designer
if(DiaType && (xmlReader.name() == "Transform")){
bool ok;
qreal m11 =
xmlReader.attributes().value("m11").toString().toDouble(&ok);
qreal m12 =
xmlReader.attributes().value("m12").toString().toDouble(&ok);
qreal m21 =
xmlReader.attributes().value("m21").toString().toDouble(&ok);
qreal m22 =
xmlReader.attributes().value("m22").toString().toDouble(&ok);
qreal dx =
xmlReader.attributes().value("dx").toString().toDouble(&ok);
qreal dy =
xmlReader.attributes().value("dx").toString().toDouble(&ok);
if(!ok)
{
xmlReader.raiseError(tr("Transform: number conversion
failed"));
continue;
}
QTransform trans = QTransform(m11, m12, m21, m22, dx, dy);
switch (DiaType) {
case QGraphicsItem::UserType+16:
insertedDrawItem->setTransform(trans);
break;
case QGraphicsItem::UserType+6:
insertedPathItem->setTransform(trans);
break;
case QGraphicsItem::UserType+3:
textItem->setTransform(trans);
break;
default:
break;
}
continue;
}
else {
xmlReader.raiseError(tr("unexpected start element"));
continue;
}
}
if(xmlReader.isEndElement()){
if(DiaType && (xmlReader.name() == "Item")){
DiaType = 0;
//insertedItem = 0;
insertedDrawItem = 0;
insertedPathItem = 0;
textItem = 0;
}
}
}
if(xmlReader.hasError()){
std::cerr << "Error in XML Read-in: "
<< qPrintable(xmlReader.errorString())
<< std::endl
100
<< "Line: "
<< xmlReader.lineNumber()
<< std::endl;
}
//insertedItem = 0;
insertedDrawItem = 0;
insertedPathItem = 0;
textItem = 0;
myMode = MoveItem;
return true;
}
Файл diagramdrawitem.cpp
#include <QtGui>
#include <QObject>
#include <iostream>
#include "diagramdrawitem.h"
#include "diagramscene.h"
DiagramDrawItem::DiagramDrawItem(ObjectType
diagramType,
QMenu
*contextMenu,
QGraphicsItem *parent,
QGraphicsScene *scene)
: QGraphicsPolygonItem(parent, scene)
{
myPos2 = pos();
myDiagramType = diagramType;
myContextMenu = contextMenu;
myPolygon = createPath();
setPolygon(myPolygon);
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setAcceptHoverEvents(true);
myHoverPoint = -1;
mySelPoint
= -1;
myHandlerWidth = 5.0;
}
DiagramDrawItem::DiagramDrawItem(const DiagramDrawItem& diagram)
{
myDiagramType = diagram.myDiagramType;
myContextMenu = diagram.myContextMenu;
setBrush(diagram.brush());
setPen(diagram.pen());
setTransform(diagram.transform());
myPos2 = diagram.myPos2;
myPolygon = createPath();
setPolygon(myPolygon);
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setAcceptHoverEvents(true);
101
myHoverPoint
= -1;
mySelPoint
= -1;
myHandlerWidth = 2.0;
}
QPolygonF DiagramDrawItem::createPath()
qreal dx = myPos2.x();
qreal dy = myPos2.y();
{
QPainterPath path;
QPolygonF polygon;
//QPen pen;
switch (myDiagramType) {
case Lift:
path.moveTo(0, 0);
path.lineTo(dx, 0);
path.lineTo(dx, dy);
path.lineTo(0, dy);
path.lineTo(0, 0);
setBrush(QBrush(Qt::darkGreen));
polygon = path.toFillPolygon();
break;
case Door:
path.moveTo(0, 0);
path.addRect(0, 0, dx, 10);
setBrush(QBrush(Qt::white));
polygon = path.toFillPolygon();
break;
case Wall:
path.moveTo(0, 0);
path.addRect(0, 0, dx, 10);
setBrush(QBrush(Qt::black));
polygon = path.toFillPolygon();
break;
case Window:
path.moveTo(0, 0);
path.addRect(0, 0, dx, 10);
setBrush(QBrush(Qt::darkYellow));
polygon = path.toFillPolygon();
break;
case Stairway:
path.moveTo(0, 0);
path.lineTo(dx, 0);
path.lineTo(dx, dy);
path.lineTo(0, dy);
path.lineTo(0, 0);
setBrush(QBrush(Qt::darkMagenta));
polygon = path.toFillPolygon();
break;
case Portal:
path.moveTo(0, 0);
path.addRect(0, 0, dx, 10);
setBrush(QBrush(Qt::darkGreen));
polygon = path.toFillPolygon();
break;
case Room:
path.moveTo(0, 0);
102
path.lineTo(dx, 0);
path.lineTo(dx, dy);
path.lineTo(0, dy);
path.lineTo(0, 0);
//pen.setWidth(10);
//pen.setJoinStyle(Qt::MiterJoin);
//setPen(pen);
setBrush(QBrush(Qt::DiagCrossPattern));
polygon = path.toFillPolygon();
break;
default:
polygon = 0;
break;
}
return polygon;
}
void DiagramDrawItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
scene()->clearSelection();
setSelected(true);
myContextMenu->exec(event->screenPos());
}
QVariant DiagramDrawItem::itemChange(GraphicsItemChange change,//delete from award
const QVariant
&value)
{
if (change == QGraphicsItem::ItemPositionChange) {
;
}
return value;
}
DiagramDrawItem* DiagramDrawItem::copy() {
DiagramDrawItem* newDiagramDrawItem = new DiagramDrawItem(*this);
return dynamic_cast<DiagramDrawItem* >(newDiagramDrawItem);
}
void DiagramDrawItem::setPos2(qreal x,qreal y)
prepareGeometryChange();
myPos2 = mapFromScene(QPointF(x,y));
myPolygon = createPath();
setPolygon(myPolygon);
}
{
void DiagramDrawItem::setPos2(QPointF newPos)
prepareGeometryChange();
myPos2 = mapFromScene(newPos);
myPolygon = createPath();
setPolygon(myPolygon);
}
{
void DiagramDrawItem::setDimension(QPointF newPos)
prepareGeometryChange();
myPos2 = newPos;
myPolygon = createPath();
setPolygon(myPolygon);
{
103
}
QPointF DiagramDrawItem::getDimension()
{
return myPos2;
}
void DiagramDrawItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
QWidget *)
{
painter->setPen(pen());
painter->setBrush(brush());
painter->drawPolygon(polygon());
if(isSelected()) {
QPen selPen = QPen(Qt::DashLine);
selPen.setColor(Qt::black);
QBrush selBrush = QBrush(Qt::NoBrush);
painter->setBrush(selBrush);
painter->setPen(selPen);
painter->drawRect(QRectF(QPointF(0, 0), myPos2));
selBrush = QBrush(Qt::lightGray,Qt::SolidPattern);
selPen = QPen(Qt::lightGray);
painter->setBrush(selBrush);
painter->setPen(selPen);
QPointF point;
if(myDiagramType == 3 || myDiagramType == 4 || myDiagramType == 6)
{
for(int i = 0; i < 8; i++)
{
if(i < 3)
point = QPointF(myPos2.x()/2*i, 0);
if(i == 3)
point = QPointF(myPos2.x(), myPos2.y()/2);
if(i > 3 && i < 7)
point = QPointF(myPos2.x()/2*(i-4), myPos2.y());
if(i == 7)
point=QPointF(0,myPos2.y()/2);
if(i == myHoverPoint)
painter->setBrush(QBrush(Qt::red));
painter->drawRect(QRectF(point - QPointF(4, 4), point +
QPointF(4, 4)));
if(i == myHoverPoint){
painter->setBrush(selBrush);
}
}
}
else if(myDiagramType == 0 || myDiagramType == 1 || myDiagramType == 2
|| myDiagramType == 5) {
for(int i = 0; i < 2; i++)
{
if(i == 0)
point = QPointF(myPos2.x(), myPos2.y()/2);
if(i == 1)
point=QPointF(0,myPos2.y()/2);
if(i == myHoverPoint)
painter->setBrush(QBrush(Qt::red));
104
painter->drawRect(QRectF(point - QPointF(4, 4),
point + QPointF(4, 4)));
if(i == myHoverPoint)
painter->setBrush(selBrush);
}
}
}
}
void DiagramDrawItem::hoverMoveEvent(QGraphicsSceneHoverEvent *e) {
if (isSelected()) {
QPointF hover_point = e->pos();
QPointF point;
if(myDiagramType == 3 || myDiagramType == 4 || myDiagramType == 6)
{
for(myHoverPoint = 0; myHoverPoint < 8; myHoverPoint++)
{
if(myHoverPoint < 3)
point = QPointF(myPos2.x()/2*myHoverPoint,0);
if(myHoverPoint == 3)
point = QPointF(myPos2.x(),myPos2.y()/2);
if(myHoverPoint > 3 && myHoverPoint < 7)
point = QPointF(myPos2.x()/2*(myHoverPoint-4),
myPos2.y());
if(myHoverPoint == 7)
point = QPointF(0,myPos2.y()/2);
if(hasClickedOn(hover_point, point)) break;
}
if(myHoverPoint == 8) myHoverPoint = -1;
else update();
}
else if(myDiagramType == 0 || myDiagramType == 1 || myDiagramType == 2
|| myDiagramType == 5) {
for(myHoverPoint = 0; myHoverPoint < 2; myHoverPoint++)
{
if(myHoverPoint == 0)
point = QPointF(myPos2.x(), myPos2.y()/2);
if(myHoverPoint == 1)
point = QPointF(0, myPos2.y()/2);
if(hasClickedOn(hover_point, point)) break;
}
if(myHoverPoint == 2) myHoverPoint = -1;
else update();
}
}
QGraphicsItem::hoverEnterEvent(e);
}
void DiagramDrawItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *e) {
if (isSelected()) {
if(myHoverPoint > -1)
{
myHoverPoint = -1;
105
update();
}
}
QGraphicsItem::hoverLeaveEvent(e);
}
QPointF DiagramDrawItem::onGrid(QPointF pos)
{
DiagramScene* myScene = dynamic_cast<DiagramScene*>(scene());
QPointF result = myScene->onGrid(pos);
return result;
}
QPainterPath DiagramDrawItem::shape() const {
QPainterPath myPath;
myPath.addPolygon(polygon());
if(isSelected()) {
QPointF point;
if(myDiagramType == 3 || myDiagramType == 4 || myDiagramType == 6)
{
for(int i = 0; i < 8; i++)
{
if(i < 3)
point = QPointF(myPos2.x()/2*i,0);
if(i == 3)
point = QPointF(myPos2.x(),myPos2.y()/2);
if(i > 3 && i < 7)
point = QPointF(myPos2.x()/2*(i-4),myPos2.y());
if(i == 7)
point = QPointF(0,myPos2.y()/2);
// Rect around valid point
myPath.addRect(QRectF(point - QPointF(myHandlerWidth,
myHandlerWidth),
point +
QPointF(myHandlerWidth, myHandlerWidth)) );
}
}
else if(myDiagramType == 0 || myDiagramType == 1 || myDiagramType == 2
|| myDiagramType == 5) {
for(int i = 0; i < 2; i++)
{
if(i == 0)
point = QPointF(myPos2.x(), myPos2.y()/2);
if(i == 1)
point = QPointF(0, myPos2.y()/2);
// Rect around valid point
myPath.addRect(QRectF(point - QPointF(myHandlerWidth,
myHandlerWidth),
point +
QPointF(myHandlerWidth, myHandlerWidth)) );
}
}
}
return myPath;
}
QRectF DiagramDrawItem::boundingRect() const
{
qreal extra = pen().width()+20 / 2.0+myHandlerWidth;
qreal minx = myPos2.x() < 0 ? myPos2.x() : 0;
qreal maxx = myPos2.x() < 0 ? 0 : myPos2.x() ;
106
qreal miny = myPos2.y() < 0 ? myPos2.y() : 0;
qreal maxy = myPos2.y() < 0 ? 0 : myPos2.y() ;
QRectF newRect = QRectF(minx, miny, maxx - minx, maxy - miny)
.adjusted(-extra, -extra, extra, extra);
return newRect;
}
void DiagramDrawItem::mousePressEvent(QGraphicsSceneMouseEvent *e) {
if(isSelected()) {
if (e->buttons() & Qt::LeftButton) {
QPointF mousePoint = e->pos();
QPointF point;
if(myDiagramType == 3 || myDiagramType == 4 || myDiagramType ==
6)
{
for(mySelPoint = 0; mySelPoint < 8; mySelPoint++)
{
if(mySelPoint < 3)
point = QPointF(myPos2.x()/2*mySelPoint,0);
if(mySelPoint==3)
point = QPointF(myPos2.x(),myPos2.y()/2);
if(mySelPoint > 3 && mySelPoint < 7)
point = QPointF(myPos2.x()/2*(mySelPoint-4),
myPos2.y());
if(mySelPoint == 7)
point = QPointF(0,myPos2.y()/2);
if(hasClickedOn(mousePoint, point)) break;
}
if(mySelPoint == 8)
mySelPoint = -1;
else
e->accept();
}
else if(myDiagramType == 0 || myDiagramType == 1 ||
myDiagramType == 2 || myDiagramType == 5) {
for(mySelPoint = 0; mySelPoint < 2; mySelPoint++)
{
if(mySelPoint == 0)
point = QPointF(myPos2.x(),myPos2.y()/2);
if(mySelPoint == 1)
point = QPointF(0, myPos2.y()/2);
if(hasClickedOn(mousePoint, point)) break;
}
if(mySelPoint == 3)
mySelPoint = -1;
else
e->accept();
}
}
}
QGraphicsItem::mousePressEvent(e);
}
void DiagramDrawItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if ((e->buttons() & Qt::LeftButton) && (mySelPoint > -1)) {
QPointF mousePoint = onGrid(e->pos());
prepareGeometryChange();
if(myDiagramType == 3 || myDiagramType == 4 || myDiagramType == 6)
{
107
switch (mySelPoint) {
case 0:
myPos2 = myPos2 - mousePoint;
setPos(mapToScene(mousePoint));
break;
case 1:
setPos(pos().x(), mapToScene(mousePoint).y());
myPos2.setY(myPos2.y() - mousePoint.y());
break;
case 2:
myPos2.setX(mousePoint.x());
setPos(pos().x(), mapToScene(mousePoint).y());
myPos2.setY(myPos2.y() - mousePoint.y());
break;
case 3:
myPos2.setX(mousePoint.x());
break;
case 6:
myPos2.setX(mousePoint.x());
myPos2.setY(mousePoint.y());
break;
case 5:
myPos2.setY(mousePoint.y());
break;
case 4:
myPos2.setY(mousePoint.y());
setPos(mapToScene(mousePoint).x(), pos().y());
myPos2.setX(myPos2.x() - mousePoint.x());
break;
case 7:
setPos(mapToScene(mousePoint).x(), pos().y());
myPos2.setX(myPos2.x() - mousePoint.x());
break;
default:
break;
}
}
else if(myDiagramType == 1 || myDiagramType == 2 || myDiagramType ==
5)
{
switch (mySelPoint) {
case 0:
myPos2.setX(mousePoint.x());
break;
case 1:
setPos(mapToScene(mousePoint).x(), pos().y());
myPos2.setX(myPos2.x() - mousePoint.x());
break;
default:
break;
}
}
else if(myDiagramType == 0)
{
if((e->pos().x() > pItem1.x()) &&( e->pos().x() < pItemSum))
{
qDebug() << e->pos();
switch (mySelPoint) {
case 0:
108
myPos2.setX(mousePoint.x());
break;
case 1:
setPos(mapToScene(mousePoint).x(), pos().y());
myPos2.setX(myPos2.x() - mousePoint.x());
break;
default:
break;
}
}
}
myPolygon = createPath();
setPolygon(myPolygon);
}
else
QGraphicsItem::mouseMoveEvent(e);
}
109
ПРИЛОЖЕНИЕ 3
РУКОВОДСТВО ОПЕРАТОРА ПО ПРОГРАММЕ
«АВТОМАТИЗИРОВАННАЯ СИСТЕМА ВВОДА ПЛАНА ЭВАКУАЦИИ ДЛЯ
РАЗРАБОТКИ ПАСПОРТОВ БЕЗОПАСНОСТИ УЧЕБНЫХ ЗАВЕДЕНИЙ РФ»
П.3.1 Назначение программы
Программа «Автоматизированная система ввода плана эвакуации для
разработки
паспортов
безопасности
учебных
заведений
РФ»
имеет
идентификатор designer.exe и предназначена для поэтажного ввода плана
эвакуации с указанием всех уникальных характеристик помещений в здании.
Для расчета паспорта безопасности необходимо иметь действующее
подключение к Интернету.
В программе предусмотрено выполнение следующих функций:
-
сохранение/загрузка плана в файл;
-
послойная организация черчения плана по этажам;
-
экспорт плана в растровое изображение;
-
вспомогательные инструменты;
-
загрузка изображения с планом эвакуации;
-
печать текущего плана.
П.3.2 Условия выполнения программы
При работе с программой необходимо обеспечить выполнение следующих
требований к комплексу технических средств:
-
персональный компьютер с ОС Windows 2000/XP/Vista/7 или любой
дистрибутив Unix/Linux с предустановленной библиотекой Nokia Qt;
-
цветной монитор;
110
-
накопитель на жестком диске с объемом свободного дискового
пространства не менее 250 Мбайт;
-
оперативная память объемом не менее 512 Мбайт;
Программа реализована на языке C++ в интегрированной среде разработки
Microsoft Visual Studio 2008 с кросс - платформенной открытой библиотекой
Nokia Qt.
П.3.3. Выполнение программы
Программа имеет тип приложения + сервис. Для расчета паспорта
безопасности необходимо иметь рабочее подключение к Интернету, так как все
расчету проходят на серверах «Института Исследования Природных и
Техногенных Катастроф», расчет может занять длительное время.
Чтобы завершить работу приложения, закройте окно или нажмите сочетание
клавиш ctrl+x.
П.3.4. Сообщения оператору
Сообщения, выдаваемые при работе программы и необходимые действия
при их получении приведены в таблице П.3.1.
Таблица П.3.1
Сообщения программы
Сообщение
Невозможно открыть
файл
Невозможно открыть
план
Описание
Системе не удается
открыть файл,
содержащий
изображение
Системе не удается
открыть файл проект
Действия при получении
сообщения
Скопируйте файл с
изображением в папку с
программой
Отправьте файл по
электронной почте нам
111
1
Невозможно сохранить
2
Системе не удается
сохранить план в
файл - проект
Продолжение табл. П.3.1
3
Укажите другой путь для
сохранения файла
П.3.5. Описание главного окна программы
Окно состоит из следующих основных элементов:
1) главное меню;
2) панель инструментов;
3) инструментарий;
4) рабочая область.
112
П.3.5.1. Главное меню
Главное меню содержит основные команды, используемые при работе с
программой. Часто используемые команды так же дублируются кнопками на
панели инструментов. Содержит несколько функциональных разделов меню:
1) «Файл» - служит для работы с файлами, позволяет сохранять или
загружать проект. Экспортировать в файл изображение. (см. табл. П.3.2.)
2) «Обзор» - служит для масштабирования изображения на рабочей
области. (см. табл. П.3.3.)
3) «Элементы» - служит для работы с каждым элементом на рабочей
области. (см. табл. П.3.4.)
Таблица П.3.2
Меню «Файл»
Открыть
Позволяет открыть файл – проект, содержащий
план эвакуации
Позволяет сохранить в файл – проект, содержащий
Сохранить
план эвакуации, без выбора пути сохранения и
имени файла (быстрое сохранение)
Сохранить как
Открыть изображение
Печать
Экспортировать
Выход
Предлагает сохранить текущий план в файл –
проект
Позволяет открыть файл, содержащий изображение
Отправляет на печать текущий план эвакуации
Позволяет экспортировать текущий план эвакуации
в графический файл
Выход из приложения (strl+x)
113
Таблица П.3.3
Меню «Обзор»
Уменьшить
Увеличить
Показать сетку
Уменьшить масштаб изображения
Увеличить масштаб изображения
Показать сетку
Таблица П.3.4
Меню «Элементы»
Удалить
Удаляет один или несколько выбранных объектов
Копировать
Копирует выделенный объект
Переместить
Перемещает один или несколько выбранных
объектов
Вперед
Перемещает текущий объект на передний план
Назад
Перемещает текущий объект на задний план
Налево
Поворачивает объект против часовой стрелке
Направо
Поворачивает объект по часовой стрелке
Группировать
Группирует выделенные объекты
Разгруппировать Разгруппирует выделенные объекты
Свойства
Отображает окно свойств для выбранного объекта
114
П.3.5.2. Инструментарий
Текст
Позволяет работать с текстом
Лифт
Отображает лифт
Комната
Отображает комнату( имеет различные типы)
Стена
Отображает стены
Окно
Отображает окно (каждое окно присваивается той
комнате, в которой оно находится)
Лестница
Отображает лестницы
Линии
Отображает линии (служат для разметки рабочего
полотна)
Линейка
Представляет масштабирование для плана
(пользователь ставит две точки и указывает
физическое расстояние в метрах)
Дверь
Отображает дверь (каждая дверь соединяет две
комнаты)
115
П.3.5.3. Рабочая область
Все пользовательские действия отображаются на рабочем полотне.
Инструмент «Слои»
Предоставляют
поэтажное
проектирование
плана.
подразумевается этаж. Возможно добавление и удаление слоя.
Инструмент «Свойства», реализует свойства каждого объекта.
Пример работы программы
Для примера взят план эвакуации 3 корпуса УдГУ.
1 этаж 3 корпуса УдГУ
Рис. П.3.1
2 этаж 3 корпуса УдГУ
Рис. П.3.2
Под
слоем
116
3 этаж 3 корпуса УдГУ
Рис. П.3.3
Файл с изображением 3 этажа 3 корпуса УдГУ
Рис. П.3.4
117
П 3.5.4. Свойства объектов.
Снимок экрана со свойствами двери
Рис. П.3.5
Снимок экрана со свойствами помещения
Рис. П.3.6
В таблице П.3.5 представлены типы помещений
Таблица П.3.5
Свойства помещения
Тип помещения
Учебные аудитории
Под тип помещения
Лекционная аудитория
Аудитория для практических занятий
118
Продолжение табл. П.3.5
1
2
Компьютерные классы
Компьютерный класс (15 комп.)
Спортивные помещения
Большой спортивный зал
Вне Университета
Гимнастический зал
Зал аэробики
Раздевалка
Тренажёрный зал
Специализированные
аудитории
учебные Военная кафедра
Специализированная лаборатория
Специализированная мастерская
Мастерская рисунка, живописи
проектированию
Мастерская скульптуры
Мастерская по обработке материалов
(дерево)
Мастерская по обработке материалов
(металл)
Швейная мастерская
Лингафонный кабинет
Телестудия
Учебно-вспомогательные
Актовый зал
помещения
Зал заседаний
Читальный зал
Абонемент
Фонд, архив
119
Продолжение табл. П.3.5
1
Административные
2
(офисные) Кабинет руководителя
помещения
Кабинет сотрудника
Общая преподавательская
Помещение структурного
подразделения
Приемная
Научно-исследовательские
Аспирантская
помещения
НИЛ (*)
Служебные помещения
АТС
Гараж (бокс)
Гараж (бокс-ремонтный)
Бойлерная
Буфет
Вахта
Венткамера
Гардероб
Касса
Коридор, лестничная клетка, холл
Котельная (дрова, уголь, газ)
Лифт, лифтовая шахта
Медицинский пункт
Подсобное помещение
Подсобное помещение структурного
подразделения
120
Продолжение табл. П.3.5
1
2
Производственное помещение
Санузел
Серверная
Склад (по типу назначения)
Столовая
Электрощитовая
Снимок экрана со свойствами окна
Рис. П.3.7
121
ПРИЛОЖЕНИЕ 4
РУКОВОДСТВО ПРОГРАММИСТА ПО ПРОГРАММЕ
«АВТОМАТИЗИРОВАННАЯ СИСТЕМА ВВОДА ПЛАНА ЭВАКУАЦИИ ДЛЯ
РАЗРАБОТКИ ПАСПОРТОВ БЕЗОПАСНОСТИ УЧЕБНЫХ ЗАВЕДЕНИЙ РФ»
П.4.1. Назначение программы
Программа «Автоматизированная система ввода плана эвакуации для
разработки
паспортов
безопасности
учебных
заведений
РФ»
имеет
идентификатор designer.exe и предназначена для поэтажного ввода плана
эвакуации с указанием всех уникальных характеристик помещений.
Для расчета паспорта безопасности необходимо иметь действующее
подключение к Интернету.
В программе предусмотрено выполнение следующих функций:
-
сохранение/загрузка плана в файл;
-
послойная организация черчения плана по этажам;
-
экспорт плана в растровое изображение;
-
вспомогательные инструменты;
-
загрузка изображения с планом эвакуации;
-
печать текущего плана.
П.4.2. Условия применения программы
При работе с программой необходимо обеспечить выполнение следующих
требований к комплексу технических средств:
-
персональный компьютер IBM или совместимый с ним;
-
цветной монитор;
-
накопитель на жестком диске с объемом свободного дискового
пространства не менее 250 Мбайт;
-
оперативная память объемом не менее 512 Мбайт;
122
Программа реализована на языке C++ в интегрированной среде разработки
Microsoft Visual Studio 2008 с кросс - платформенной открытой библиотекой
Nokia Qt.
П.4.3. Характеристики программы
Программа может работать в ОС семейства Windows NT или Unix\Linux.
Работу программы можно разделить на несколько этапов:
-
загрузка изображения плана эвакуации (если есть);
-
черчение плана;
-
установка различных свойств, для каждого объекта;
-
сохранение плана в файл - проект;
Программа
выполнена
в
виде
нескольких
программных
модулей,
реализующих различные функции. Список модулей с их кратким описанием
представлен в таблице П.4.1.
Таблица П.4.1
Описание модулей программы
Наименование модуля
1
mainwindow.cpp
diagramscene.cpp
diagramdrawitem.cpp
diagramtextitem.cpp
wallproperty.cpp
stairwayproperty.cpp
Выполняемые функции
2
Основной
модуль,
реализует
пользовательский
интерфейс
и
управляет остальными модулями.
Размещает и управляет элементами без
их
графического
представления,
выполняет роль «рабочего полотна».
Содержит все графические элементы и
отрисовывает их.
Обеспечивает работу с текстом.
Реализует
графическую
настройку
свойств стены.
Реализует
графическую
настройку
свойств лестницы.
123
Продолжение таб. П.4.1
2
Реализует графическую настройку
свойств окна.
Реализует графическую настройку
свойств дверей.
Реализует графическую настройку
свойств лифта.
Реализует графическую настройку
свойств помещения.
1
propertywindow.cpp
doorproperty.cpp
liftproperty.cpp
roomproperty.cpp
П.4.4. Обращение к программе
Программа имеет тип приложение + сервис, поэтому необходимо иметь
рабочее подключение к интернету и имеет идентификатор designer.exe.
П.4.5. Входные и выходные данные
Входными
данными
может
быть
файл,
содержащий
графическое
изображение или графические элементы (чертежи). (см. табл. П.4.2-П.4.5).
Таблица П.4.2
Тэг элемент (Item)
Наименование поля
Описание
1
2
Item
Тип графического элемента
Pos
Координаты на плоскости
Property
Уникальные свойства элемента
124
Таблица П.4.3
Тэг элемент (Item)
Наименование поля
Описание
1
2
Wall
Стена
Door
Дверь
Window
Окно
Lift
Лифт
Stairway
Лестница
Portal
Портал
Room
Помещение
Таблица П.4.4
Тэг координат (Pos)
Наименование поля
Описание
1
2
x
Координата x1
y
Координата y1
z
Координата z
width
Координата x2
height
Координата y2
125
Таблица П.4.5
Тэг свойств (Property)
Наименова
ние поля
Описание
Примечание
Тип
2
3
4
1
Height
Высота помещения
Для всех
double
Square
Площадь помещения
Для всех
double
Z
Расстояние от пола до пола Только
следующего потолка
ID_1
для double
дверей
Идентификационный номер для Только
для int
помещения 1
или
дверей
«порталов»
ID_2
Идентификационный номер для Только
для int
помещения 2
или
дверей
«порталов»
ID
Идентификационный номер
Для всех
InOut
Внутренняя или наружная дверь
Только
int
для bool
дверей
OneTwo
N
Простая ординарная лестница или Только
с лестничной площадкой
лестниц
Количество окон в помещении
Только
помещений
для bool
для Int
126
П.4.6. Сообщения
В процессе работы система выдает сообщения пользователю. Сообщения,
выдаваемые при работе программы и необходимые действия при их получении,
приведены в таблице П.5.6.
Таблица П.4.6
Сообщения программы
Сообщение
Описание
Действия при получении
сообщения
Невозможно открыть
Системе не удается
Скопируйте файл с
файл
открыть файл,
изображением в папку с
содержащий
программой
изображение
Невозможно открыть
Системе не удается
Отправьте файл по
план
открыть файл - проект
электронной почте нам
Невозможно сохранить
Системе не удается
Укажите другой путь для
сохранить план в файл -
сохранения файла
проект
Download