диплом целиком (1218792), страница 7
Текст из файла (страница 7)
Рисунок 23 – Окно добавления нового населенного пункта
Рисунок 24 – Окно работы с отчетом
В окне работы с отчетами используется компонент FlowDocument, который дает возможность разметить структуру отчета прямо в разметке окна в отдельном контейнере. Это позволяет держать элементы, решающие одну задачу, в одном файле и тем самым не усложнять структуру проекта.
Рисунок 25 – Окно ошибки
Вместо системного окна Windows, информирующего об ошибке, было создано окно с расширенной информацией об ошибке, в котором помимо текстового сообщения для пользователя есть техническая информация, содержащая стек вызовов, приведший к ошибке.
3.3 Связь с сайтами
Поскольку для работы с веб-сервисом в интерфейсе IWeatherService определен только один метод GetWeatherData(), класс OpenWeatherService имеет достаточно простую организацию.
public IReadOnlyCollection<WeatherRecord> GetWeatherData(Location location, DateTime from, DateTime to)
{
var request = PrepareRequest(location.SystemName);
var response = _restClient.Execute<dynamic>(request);
if (response.Data.list == null) throw new WeatherServiceException ("Ошибка при загрузке данных с веб-сервиса.");
var forecast = ExtractForecast(response.Data, from, to);
var result = CreateWeatherRecords(location, forecast);
return result.AsReadOnly();
}
Отдельное внимание стоит уделить используемым методам PrepareRequest() и CreateWeatherRecords(). Метод PrepareRequest формирует специальным образом запрос к веб-сервису.
private IRestRequest PrepareRequest(string locationName)
{
var request = new RestRequest("/forecast", Method.GET);
request.AddQueryParameter("q", locationName);
return request;
}
Метод CreateWeathreRecords() проецирует полученный ответ от веб-сервиса в формат, используемый внутри разработанного приложения:
private static List<WeatherRecord> CreateWeatherRecords(Location location, List<dynamic> todayForecast)
{
return todayForecast.Select(weatherData => new WeatherRecord
{
Created = DateTimeHelper
.CreateFromTimestamp(Convert.ToInt32(weatherData.dt)),
Humidity = Convert.ToDecimal(weatherData.main.humidity),
Location = location,
LocationId = location.Id,
Precipitation = Convert.ToDecimal(weatherData.rain == null ? 0 : weatherData.rain["3h"]),
Temperature = Convert.ToDecimal(weatherData.main.temp) - 273
}).ToList();
}
Этот метод необходим, так как формат данных, используемый сервисом OpenWeatherMap, сильно отличается от формата, предусмотренного предметной областью разработанного приложения.
3.4 Связь с базой данных
Так как интерфейсы менеджеров по работе с базой данных одинаковы концептуально, т.е. реализуют операции по получению, сохранению и удалению данных, в данном разделе будет рассмотрен LocationManager, являющийся реализацией программного интерфейса ILocationManager для sqlite базы данных. Данный класс зависит от строки конфигурации, которая передается в конструктор класса.
public LocationManager(string configurationString)
{
_configurationString = configurationString;
}
В строке конфигурации содержится информация о типе базы данных и пути к ней в файловой системе. Формат строки конфигурации определен компанией Microsoft и используется повсеместно.
Метод GetAll() позволяет получить все населенные пункты, хранящиеся в системе.
public IReadOnlyCollection<Location> GetAll()
{
using (var db = new DataConnection(_configurationString))
{
var locations = CreateQuery(db);
return locations.ToArray();
}
}
Метод Get() позволяет получить список населенных пунктов, которые содержат в своем имени подстроку, определяемую в параметре namePart.
public IReadOnlyCollection<Location> Get(string namePart)
{
if (string.IsNullOrWhiteSpace(namePart)) return Enumerable.Empty<Location>().ToArray();
using (var db = new DataConnection(_configurationString))
{
var locations = CreateQuery(db).Where(location => location.Name.Contains(namePart));
return locations.ToArray();
}
}
Закрытый метод CreateQuery() создает запрос-шаблон, который используется при выборке данных
private static IQueryable<Location> CreateQuery(DataConnection db)
{
var locations =
from location in db.GetTable<Location>()
join report in db.GetTable<FireHazardReport>() on location.Id equals report.LocationId into reports
join record in db.GetTable<WeatherRecord>() on location.Id equals record.LocationId into records
select new Location
{
Id = location.Id,
Name = location.Name,
SystemName = location.SystemName,
FireHazardReportsCount = reports.Count(),
WeatherRecordsCount = records.Count()
};
return locations;
}
Выборка данных написана на встроенном в язык C# языке запросов linq.
Метод сохранения населенного пункта сохраняет значение как новую запись в базе данных, если поле Id является неопределенным и обновляет значение, если поле Id уже заполнено.
public void Save(Location location)
{
var exist = Get(location.Name).FirstOrDefault();
if (exist != null) throw new WeatherAnalysisException("Населенный пункт с таким именем уже существует.");
using (var db = new DataConnection(_configurationString))
{
if (location.Id.HasValue)
{
db.Update(location);
}
else
{
location.Id = Convert.ToInt32(db.InsertWithIdentity(location));
}
}
}
Метод удаления просто удаляет передаваемое значение из базы данных.
public void Delete(Location location)
{
using (var db = new DataConnection(_configurationString))
{
db.Delete(location);
}
}
Интерфейс IDbManager описывает возможность управления базой данных, позволяя проверить целостность ее схемы, очистить БД или подготовить базу данных для хранения данных предметной области.
3.5 Связывание программных модулей
Связывание программных модулей происходит в клиентском приложении (WeatherAnalysis.App) при помощи библиотеки NInject. NInject - одна из популярных реализаций шаблона “внедрение зависимостей” с открытым исходном кодом. Данная библиотека позволяет настроить используемые программные модули посредством связывания класса с его интерфейсом и последующей регистрации в контейнере зависимостей. Конфигурация модулей представлена в файле WeatherAnalysis/WeatherAnalysis.App/Configuration/AppModule.cs.
Основными конструкциями являются методы Bind() и To(). Метод Bind() начинает операцию связывания, определяя с каким программным интерфейсом будет связан класс. Метод To() завершает связывание с конкретным классом, реализующим интерфейс, заданный в методе Bind().
Дополнительно используемый метод InSingletonScope() указывает контейнеру, что создать объект нужно всего один раз для всего приложения. Процесс разрешения зависимостей представлен на диаграмме.
Следующий пример иллюстрирует связывание интерфейса IDbManager с его реализацией для sqlite классом DbManager.
Kernel.Bind<IDbManager>()
.To<DbManager>()
.InSingletonScope()
.WithConstructorArgument("configurationString", DbConfigurationName);
Метод WithConstructorArgument() указывает контейнеру, что в конструктор класса DbManager должен передаваться DbConfigurationName как параметр configurationString.
3.6 Реализация отчетов
Подсистема построения отчетов реализована при помощи компонента WPF – FlowDocument. Данный компонент позволяет декларативно описать разметку документа, аналогично языкам разметки HTML и XHTML. Основным элементом документа является параграф.
Следующий пример иллюстрирует как создать параграф и добавить динамически изменяющиеся данные (влажность).
<Paragraph>
Влажность
<Run Text="{Binding SelectedWeatherRecord.Humidity, StringFormat={}{0:0.0}}"/> %
</Paragraph>
Поскольку FlowDocument является частью WPF, а, следовательно, и .net, то необходимый функционал по преобразованию, сохранению и печати уже доступен для данного компонента. Вот так создается страница формата А4:
var document = new FlowDocument
{ ColumnWidth = 21.0*96/2.54,
PageWidth = 21.0*96/2.54,
PageHeight = 29.7*96/2.54,
PagePadding = new Thickness(2*96/2.54, 1.5*96/2.54, 1.5*96/2.54, 96.0/2.54)
};
Единственную задачу, которую необходимо решать прикладному программисту – разбиение документа на страницы. Для этого необходимо явно задать параметры страницы, такие как ширина, длина и отступы от края.
4 Анализ и предупреждение чрезвычайных ситуаций
природного характера по Хабаровскому краю
4.1 Статистика и анализ
Площадь лесного фонда Хабаровского края, составляет 73,7 млн. гектаров (93,5% территории края), из которых на лесные земли приходится 57,9 млн. гектаров (78,6 % лесного фонда), в том числе покрытые лесом земли 51,2 млн. гектаров (69,5 %). Лесистость территории края – 66,5 %. Общий запас древесины в крае превышает 5,1 млрд. куб. м, в том числе в спелых и перестойных насаждениях свыше 3,1 млрд. куб. м, из них хвойных – 2,8 млрд.
На севере края (Охотский, Аяно-Майский и Тугуро-Чумиканский районы) в среднем и верхнем поясах гор растительность представлена в основном стланиковыми формами лесов (кедровый и ольховый стланики, кустарниковая береза), лесотундрами и редколесьями. Для защиты окружающей природной среды эти формы растительности имеют бесценное значение.
По долинам рек и в нижнем поясе гор в этой местности произрастают леса стволовой формы, в основном лиственичники, реже темнохвойные леса с примесью тополя, березы и других древесных пород.
Средняя и южная части края, начинается на севере Николаевским районом и оканчивается на юге Бикинским районом, находятся в качественно лучшем природном положении, несмотря на тот же горный рельеф и близость Тихого океана. На западе этой части края стволовые формы растительности представлены в основном лиственничниками, реже ельниками и лиственными лесами. В районе Нижнего Амура ельники составляют крупные массивы. В средней части края также встречаются стланиковые формы растительности в виде кедрового и ольхового стланика, кустарниковой березы.
При продвижении на юг таежные типы растительности постепенно замещаются хвойно-широколиственными лесами, которые занимают южную часть края, где обретают максимальную продуктивность и биологическое разнообразие. В этом районе наряду с лиственничными и темнохвойными лесами представлены леса с преобладанием кедра корейского, дуба монгольского, березы желтой, липы и других представителей хвойно-широко-лиственных лесов.
На юге Хабаровского края хвойно-широколиственные леса имеют наиболее сложный состав древесных и кустарниковых пород. В бассейне реки Хор и ее притоков (муниципальный район им. Лазо) леса с преобладание кедра корейского и кедровые типы условий произрастания занимают около 40 % площади лесного фонда, с преобладанием ели – около 30 %, по 10 % площади лесного фонда приходится на леса с преобладанием пихтарников, желтоберезников и липняков. Здесь же присутствуют многочисленные сопутствующие древесные и кустарниковые породы, характерные для данной лесной формации [42].
За период с 1995 по 2014 годы в лесном фонде Хабаровского края возникло 11724 пожара на общей площади 3591,9 тыс. га. Среднегодовое количество пожаров и среднегодовая их площадь за 17-летний период составили, соответственно, 615 и 205,8 тыс. га. Средняя площадь одного пожара 334,4 га.
Максимальные ее значения приходятся на 1996, 1998, 1999, 2003, 2005, 2007 годы. В эти годы зарегистрировано 5226 пожаров или 53,1 %, площадь пожаров составила 2568,9 тыс. га или 84,2 % от пройденной огнем площади за 15 лет. Цикличность засушливости повторяется в среднем каждые 2-3 года.
В 2014 году в Хабаровском крае возникло 3587 лесных пожаров, при которых погибло 213 человек.
Относительная горимость по количеству пожаров в целом по краю (11 пожаров на 1 млн га) – «ниже средней», по площади пожаров (3,5 га на 1000 га лесных земель) – «чрезвычайная», кроме Охотского лесопожарного округа, где горимость на 1000 га – «выше средней».
Анализ причин возникновения лесных пожаров показал, что примерно 70% всех загораний на территории края происходит от антропогенных источников огня, в основном по вине местного населения. Кроме того, около 30% всех лесных пожаров на территории края возникли от гроз, преимущественно в горах в его северной части. При этом за последние 5 лет до 41% всех загораний на территории края возникли по невыясненным причинам.
Наибольшее число лесных пожаров в крае случается весной и осенью. На эти периоды приходится до 63% общего количества случаев пожаров за пожароопасный сезон. Все они возникают по вине человека, поскольку в эти периоды (весной до облиствения древесных пород, осенью после опадения листвы и усыхания зеленого травостоя) грозовых разрядов (молний) практически не бывает. Летом массовое возникновение лесных пожаров (37%) происходит в период длительных засух, т.е. при ясной и устойчивой сухой погоде, когда также не наблюдается грозовых разрядов.
Пожароопасный сезон в крае обычно начинается в третьей декаде апреля и заканчивается в первой декаде ноября.
















