Шифрование данных и аутентификация пользователей в информационной системе "Кадастровые границы Омска" с использованием Visual Studio

Исследование алгоритма взаимодействия пользователя с сервером, на котором находится база данных. Реализация безопасности информационной системы с помощью возможностей программного комплекса Visual Studio. Анализ особенностей интерфейса веб-приложения.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 17.06.2017
Размер файла 1,3 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru

Размещено на http://www.allbest.ru

Введение

Целью курсовой работы является осуществить проектирование базы данных в СУБД MS SQL Server и получить опыт самостоятельной разработки веб-приложения, которое работает под управлением ОС Microsoft Windows с помощью среды разработки приложений Microsoft Visual Studio 2015 на языках программирования C# и JavaScript, используя ASP.NET. Веб-приложение взаимодействует с базой данных и выполняет в ней функции добавления и просмотра данных. Веб-приложение подключается через сеть Интернет к API Яндекс Карт и показывает на карте кадастровые границы участков, которые имеются в базе данных, со всей информацией о них. Также есть возможность отобразить на карте только спорные участки, то есть те, границы которых пересекаются.

Задачи курсовой работы:

- проанализировать предметную область «Кадастровые границы»;

- изучить основы работы с API Яндекс Карт;

- изучить основы работы с языком программирования C#;

- изучить основы работы с языком программирования JavaScript;

- изучить основы работы с СУБД MS SQL Server;

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

- реализовать аспект безопасности;

- создать веб-приложение на веб сервере IIS;

- составить пояснительную записку и оформить её в соответствии с методическими указаниями.

1. Проектирование информационной системы «Кадастровые границы Омска»

1.1 Анализ предметной области «Кадастровые границы Омска»

Чтобы приступить к проектированию базы данных и разработке веб-приложения необходимо понять, как будет осуществляться взаимодействие пользователя с сервером, на котором находится база данных и всё приложение. Для того, чтобы пользователь мог взаимодействовать с картой, на которой отображены участки, была написана клиентская часть веб-приложения с использованием языка программирования JavaScript. При загрузке Яндекс карты, где будут показаны кадастровые границы, с серверной части приложения отправляется несколько JSON файлов, которые содержат всю необходимую информацию. Основным функционалом данной информационной системы является отображение кадастровых границ участков города Омска на Яндекс карте с информацией о них, а именно: владелец, адрес, район, количество зданий, назначение участка, кадастровый номер участка. Вся эта информация берётся из БД и доступна пользователю только после его авторизации в системе. Также есть возможность посмотреть только те участки, границы которых пересекаются. Вычисление пересечений происходит с помощью специального сервиса (расширенный геопространственный анализ), к которому необходимо подключаться с помощью API. Таким образом, ИС предназначена для выполнения следующих главных задач:

· хранение данных географических координат всех вершин участков;

· хранение информации об этих участках;

· хранение и обработка данных пользователей;

· предоставление информации о границах кадастровых участков.

1.2 Проектирование базы данных «Maps»

Чтобы выполнить тестирование и дальнейшее использование информационной системы, была спроектирована база данных в СУБД MS SQL Server 2012. С этой БД осуществляется взаимодействие веб-приложения.

Создание таблиц базы данных.

Для функционирования всей системы потребовалось создать 3 таблицы (рисунок 4):

- Users - таблица с информацией о зарегистрированных пользователях (рисунок 1). В неё добавляются данные пользователей при регистрации, а также сравниваются с введёнными значениями при авторизации. Таблица содержит поля: имя (Name), фамилия (Surname), логин (Logins), хешированный пароль (Passwords), соль (Salt) - случайно сгенерированная строка.

Рисунок 1 - Таблица Users

- coords1 - данная таблица содержит координаты каждой вершины для каждого участка (рисунок 2). В ней содержатся следующие поля: идентификатор участка (id_ob), номер вершины (Versh), долгота (Coords_Long), широта (Coords_Lat).

Рисунок 2 - Таблица coords1

- info1 - эта таблица хранит в себе информацию о участке (рисунок 3). Она содержит в себе такие поля: идентификатор участка (id_ob), кадастровый номер участка (Number), назначение участка (Naznach), владелец участка (Vladelez), долгота (Long), широта (Lat), адрес (Address), район города, в котором расположен участок (Raion), количество строений на участке (Number_build).

Рисунок 3 - Таблица info1

Рисунок 4 - Структура БД Maps

Таблица info1 имеет связь «один ко многим» к таблице coords1. Так сделано потому, что у каждого участка не может быть меньше 3 вершин. Таблица Users ни с какой таблицей не связана, так как она используется только для регистрации и авторизации.

В результате разработки получилась схема базы данных, которая показана на рисунке ниже (рисунок 5).

Рисунок 5 - Схема БД Maps

Описание атрибутов таблиц и их типов данных

Во время выполнения запросов к базе данных должны выполняться определённые ограничения целостности в соответствии с существующими полями таблицы Users (рисунок 2). Например, нужно ограничить максимальную и минимальную длину вводимого пароля или ограничить так, чтобы логины пользователей не повторялись. Все эти ограничения целостности реализованы непосредственно в коде веб-приложения.

В таблице Users поля Name и Surname имеют тип данных varchar и могут иметь максимальную длину в 40 символов. Поля Logins, Passwords, Salt имеют такой же тип данных, что и у Name и Surname, но имеют максимальную длину строки 35, 32, 40 символов соответственно.

В таблице coords1 поля Coords_Long и Coords_Lat имеют тип данных varchar с максимальной длиной 10 символов, потому что географические координаты имеют примерно такой вид «73.361639» и могут быть длиной от 8 до 10 символов. Остальные два поля id_ob и Versh имеют типы данных int и varchar соответственно, при этом, Versh имеет максимальную длину строки в 2 символа, потому что вершин у участка может быть больше 10.

В таблице info1 поля Number, Naznach, Vladelez, Long, Lat, Address, Raion имеют тип данных varchar с максимальной длиной строки 16, 256, 256, 10, 10, 50, 20 символов соответственно. Number состоит из кадастрового номера участка, который не превышает 16 знаков. Длины строк у Naznach и Vladelez могут быть очень разнообразны, поэтому у них 256 знаков. Остальные два поля id_ob и Number_build имеют тип данных int, причём id_ob является первичным ключом.

Во всех вышеперечисленных таблицах все поля должны быть заполнены обязательно.

1.3 Реализация безопасности с помощью возможностей Visual Studio

В среде разработки Microsoft Visual Studio есть пространство имён System.Security.Cryptography. Данное пространство имён предоставляет различные криптографические службы шифрования или дешифрования данных и много других операций, например, хеширование, которое используется в реализуемой ИС.

Чтобы обеспечить безопасность информационной системы были приняты следующие меры по безопасности:

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

- введённый пароль при регистрации шифруются однонаправленно, то есть без возможности расшифровать, специальным алгоритмом - хеш значение MD5;

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

- ввод пароля по умолчанию вводится скрытно, однако, пользователь имеет возможность посмотреть его, нажав на «глаз», как при авторизации, так и при регистрации;

- размер пароля ограничен и имеет длину от 6 до 20 символов;

- логин является уникальным, то есть не может быть 2 пользователя с одинаковыми логинами.

Регистрация в ИС «Кадастровые границы Омска».

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

· берётся введённый пользователем логин и выполняется запрос к базе данных на наличие записи с таким логином. Если такой записи не найдено, то алгоритм работает дальше, если наоборот, то предлагается ввести новый логин;

· если логин не повторяется с уже имеющимися в БД, то происходит случайная генерация строки «соль» длиной 20 символов из английского алфавита и цифр;

· полученная строка «соль» с помощью конкатенации склеивается с введённым пользователем паролем;

· от полученной новой строки берётся хеш значение с помощью MD5;

· полученное хеш значение записывается вместе с остальными данными в БД;

· после этого можно сразу перейти на страницу авторизации.

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

Авторизация выполняется следующим образом.

Введённый пользователем логин добавляется в строку запроса и этот запрос направляется в СУБД для получения ответа. Если запись с таким логином имеется в БД, то выполняется следующее:

· берётся из БД созданная при регистрации случайная строка «соль»;

· строка «соль» с помощью конкатенации склеивается с введённым пользователем паролем;

· от полученной новой строки берётся хеш значение с помощью MD5;

· полученное хеш значение сравнивается с уже существующим хеш значением в БД;

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

1.4 Взаимодействие с API Яндекс Карты для отображения кадастровых границ участков

Чтобы начать работать с картой, необходимо подключить её через API с помощью строки «<script src ="http://api-maps.yandex.ru/1.1/index.xml?key= ==" type="text/javascript"></script>». После этого написать код, который будет накладывать изображение всего Омска, состоящее из заранее подготовленных тайлов, которые созданы для каждого уровня приближения и задать следующие параметры карты:

· максимально возможное приближение карты;

· максимально возможное отдаление карты;

· изначальное положение центра карты в координатах (в данном случае, центром был самый центр Омска);

· изначальный уровень приближения;

· возможность «скролить» карту.

Ниже представлена часть данного кода:

var options = {

tileUrlTemplate: "./%z/tile-%x-%y.png",

controls: {

toolBar: true,

scaleLine: false,

},

smoothZoomEnabled: true,

scrollZoomEnabled: true,

mapCenter: new YMaps.GeoPoint(73.3754610363281,54.9805515071693),

backgroundMapType: YMaps.MapType.MAP,

mapZoom: 11,

isTransparent: true,

layerKey: "my#layer",

mapType: {

name: "Yandex Maps",

textColor: "#000000",

},

},

map = new YMaps.Map(document.getElementById("YMapsID")),

myData = new YMaps.TileDataSource(options.tileUrlTemplate, options.isTransparent, options.smoothZooming);

myData.getTileUrl = function (tile, zoom) {

return this.getTileUrlTemplate().replace(/%x/i, tile.x).replace(/%y/i, tile.y).replace(/%z/i, zoom);

}

var MyLayer = function () {

return new YMaps.Layer(myData);

}

YMaps.Layers.add(options.layerKey, MyLayer);

var mapLayers = options.backgroundMapType ? options.backgroundMapType.getLayers() : [],

myMapType = new YMaps.MapType(YMaps.jQuery.merge(mapLayers, [options.layerKey]),

options.mapType.name, { textColor: options.mapType.textColor });

map.setCenter(options.mapCenter, options.mapZoom, myMapType);

map.setMaxZoom(15);

map.setMinZoom(11);

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

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

$.post('Poly.ashx', '', function (response) {

eval(response);

for (var i = 0; i < data.length; i++) {

if (data[i].ID != lastID) {

pl = new YMaps.Polyline(points);

pl.setStyle("line1");

map.addOverlay(pl);

points = [];}

points[i] = new YMaps.GeoPoint(data[i].Longitude, data[i].Latitude);

lastID = data[i].ID;}

pl = new YMaps.Polyline(points);

pl.setStyle("line1");

map.addOverlay(pl);

$.post('Handler.ashx', '', function (response) {

eval(response);

for (var k = 0; k < data1.length; k++) {

mark = new YMaps.GeoPoint(data1[k].Longitude, data1[k].Latitude);

var placemark = new YMaps.Placemark(mark, { hasHint: 1, style: "default#darkbluePoint" });

placemark.description = "<strong> Кадастровый номер:</strong> <i> " + data1[k].Number + "</i><br />" + "<strong> Район:</strong> <i>" + data1[k].Raion +

"</i><br />" + "<strong> Назначение участка:</strong> <i> " + data1[k].Naznach + "</i><br />" + "<strong> Владелец:</strong> <i>" + data1[k].Vladelec +

"</i><br />";

map.addOverlay(placemark);

}})})

Также возможно посмотреть только пересекающиеся участки. Для этого необходимо подключиться к библиотеке геопространсветнного анализатора «Turf.js» через API, а затем уже попарно сравнивать координаты вершин одного участка с другим участком и так до тех пор, пока участки не «кончатся». Чтобы это осуществить необходимо было создать один большой массив (bigmassive), в который будут записываться подмассивы (sector), соответствующие определённым участкам и в каждом из этих подмассивов находится ещё определённое число массивов, каждый из которых хранит географические координаты об определённой вершине. Сколько вершин, столько и массивов в подмассиве. Затем, из получившегося bigmassive нужно передавать подмассивы в геопространственный анализатор для попарного сравнения. Если анализатор обнаруживает пересечение участков, то он записывает в другой массив (intersectmass) идентификационные номера этих участков. Ниже представлен фрагмент кода, осуществляющий всё вышеперечисленное:

for (var i = 0; i < data.length; i++) {

if (data[i].ID != lastID) {

bigmassive[j] = [sector];

sector = [];

j++;

k = 0;

}

sector[k] = [data[i].Longitude, data[i].Latitude];

k++;

lastID = data[i].ID;

}

bigmassive[j] = [sector];

for(var i = 0; i <bigmassive.length; i++){

for (var j = 0; j < bigmassive.length; j++) {

if (i != j){

var poly = turf.polygon(bigmassive[i]);

var poly1 = turf.polygon(bigmassive[j]);

var intersection = turf.intersect(poly, poly1);

if (intersection != undefined) {

intersectmass[l] = i;

l++;}

poly = [];

poly1 = [];}}}

После того, как алгоритм отработает и массив intersectmass заполнится значениями, необходимо отобразить на карте все пересекающиеся участки. Для этого необходимо выполнить аналогичные действия, как и при отрисовке всех участков, только надо сравнивать полученное из JSON со значениями в intersectmass:

for (var i = 0; i < intersectmass.length; i++){

secondintersectmass[i] = intersectmass[i] + 1;}

for (var j = 0; j <= secondintersectmass.length; j++) {

for (var i = 0; i < data.length; i++) {

if(data[i].ID == secondintersectmass[j]){

points[i] = new YMaps.GeoPoint(data[i].Longitude, data[i].Latitude);}

else {

if (points.length != 0) {

pl = new YMaps.Polyline(points);

pl.setStyle("line2");

map.addOverlay(pl);

points = [];}}}}

points = [];

pl = [];

$.post('Handler.ashx', '', function (response) {

eval(response);

for (var j = 0; j <= secondintersectmass.length; j++) {

for (var k = 0; k < data1.length; k++) {

if (data1[k].ID_OB == secondintersectmass[j]) {

mark = new YMaps.GeoPoint(data1[k].Longitude, data1[k].Latitude);

var placemark = new YMaps.Placemark(mark, { hasHint: 1, style: "default#darkbluePoint" });

placemark.description = "<strong> Кадастровый номер:</strong> <i> " + data1[k].Number + "</i><br />" + "<strong> Район:</strong> <i>" + data1[k].Raion +

"</i><br />" + "<strong> Назначение участка:</strong> <i> " + data1[k].Naznach + "</i><br />" + "<strong> Владелец:</strong> <i>" + data1[k].Vladelec +

"</i><br />";

map.addOverlay(placemark);

}}}})})

2. Описание интерфейса веб-приложения «Кадастровые границы Омска»

Веб-приложение разработано в среде Microsoft Visual Studio с использованием двух языков программирования C# и JavaScript. Чтобы открыть просмотр карты необходимо пройти авторизацию (рисунок 6).

Рисунок 6 - Страница авторизации

Запрос к СУБД для авторизации выглядит следующим образом: "SELECT Logins, Passwords, Salt FROM Users WHERE Logins LIKE'" + LOGIN + "';".

Если логин введён неверно, то выдаётся, что аккаунт не найден (рисунок 7).

Рисунок 7 - Аккаунт не найден

Если всё же логин был введён правильно, а пароль неверный или же длина не соответствует требуемой, то выдаст ошибку, что пароль введён неверно (рисунок 8) или предупреждение о длине пароля (рисунок 9).

интерфейс информационный веб сервер

Рисунок 8 - Неверный пароль

Рисунок 9 - Пароль не соответствует длине

После того, как пользователь введёт верные данные, то ему станет доступна карта, для этого нужно будет нажать кнопку «Open Map» (рисунок 10).

Рисунок 10 - Успешная авторизация

Если у пользователя нет аккаунта для входа в систему, то необходимо будет перейти на страницу регистрации, нажав кнопку «Registration!» (рисунок 12).

Рисунок 12 - Страница регистрации

На странице регистрации пользователю необходимо заполнить все строки с данными о себе (имя, фамилия, логин, пароль, подтверждение пароля), если он не заполнит хотя бы одну строку и нажмёт «Save», то выдаст ошибку о том, что введены не все данные (рисунок 13).

Рисунок 13 - Не все данные введены

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

Запрос в СУБД для проверки на то, существует ли пользователь с таким логином выглядит следующим образом:

"SELECT * FROM Users WHERE Logins LIKE '" + LOGIN + "';"

Рисунок 14 - Логин уже существует

После того, как все данные будут введены и логин является уникальным, будет отображено, что аккаунт создан и необходимо авторизоваться, нажав кнопку «Log in» (рисунок 15).

Запрос на добавление данных пользователя выглядит так:

"INSERT INTO Users(Name, Surname, Logins, Passwords, Salt) VALUES(@param0, @param1,@param2, @param3, @param4)"

Рисунок 15 - Успешное создание аккаунта

После регистрации необходимо вернуться на страницу авторизации и ввести там логин и пароль. Затем открыть карту (рисунок 16).

Рисунок 16 - Интерфейс карты

Изначально на карте отображаются все имеющиеся участки в базе данных с информацией о них (рисунок 17). В данном случае, в БД имеется всего 8 участков.

Рисунок 18 - Все участки на карте

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

Рисунок 19 - Информация об участке

Чтобы посмотреть только пересекающиеся участки, необходимо нажать на кнопку «Показать пересекающиеся участки» (рисунок 20)

Рисунок 20 - Кнопка «Показать пересекающиеся участки»

После нажатия произойдёт перезагрузка страницы и отобразятся только пересекающиеся участки (рисунок 21).

Рисунок 22 - Отображение пересекающихся участков

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

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

3. Листинг программ веб-приложения

Файл AllSectors.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AllSectors.aspx.cs" Inherits="AllSectors" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>Yandex</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script src ="http://api-maps.yandex.ru/1.1/index.xml?key=AKgqHEkBAAAA-WzMYwIAeAeamm8ETZZZpdfp2R07eIuGyX4AAAAAAAAAAACjUCDoHIHZJ2pcl5mSL1zWVp2Myw==" type="text/javascript"></script>

<script type="text/javascript" src="http://js.static.yandex.net/jquery/1.3.2/_jquery.js"> </script>

<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>

<script type="text/javascript">

window.onload = function () {

var options = {

tileUrlTemplate: "./%z/tile-%x-%y.png",

controls: {

typeControl: true,

miniMap: false,

toolBar: true,

scaleLine: false,

},

smoothZoomEnabled: true,

scrollZoomEnabled: true,

mapCenter: new YMaps.GeoPoint(73.3754610363281, 54.9805515071693),

backgroundMapType: YMaps.MapType.MAP,

mapZoom: 11,

isTransparent: true,

layerKey: "my#layer",

mapType: {

name: "Yandex Maps",

textColor: "#000000",

},

},

map = new YMaps.Map(document.getElementById("YMapsID")),

myData = new YMaps.TileDataSource(options.tileUrlTemplate, options.isTransparent, options.smoothZooming);

myData.getTileUrl = function (tile, zoom) {

return this.getTileUrlTemplate().replace(/%x/i, tile.x).replace(/%y/i, tile.y).replace(/%z/i, zoom);

}

var MyLayer = function () {

return new YMaps.Layer(myData);

}

YMaps.Layers.add(options.layerKey, MyLayer);

var mapLayers = options.backgroundMapType ? options.backgroundMapType.getLayers() : [],

myMapType = new YMaps.MapType(YMaps.jQuery.merge(mapLayers, [options.layerKey]),

options.mapType.name, { textColor: options.mapType.textColor });

map.setCenter(options.mapCenter, options.mapZoom, myMapType);

map.setMaxZoom(15);

map.setMinZoom(11);

if (options.scrollZoomEnabled) {

map.enableScrollZoom();

}

map.addControl(new YMaps.Zoom());

YMaps.Events.observe(map, map.Events.Click, function (map, mEvent) {

var myHtml = "Координаты: " + mEvent.getGeoPoint();

var zoom = "Масштаб карты: " + map.getZoom();

document.getElementById('find').value = myHtml;

document.getElementById('find1').value = zoom;

});

var s = new YMaps.Style();

s.lineStyle = new YMaps.LineStyle();

s.lineStyle.strokeColor = '00000099';

s.lineStyle.strokeWidth = '3';

YMaps.Styles.add("line1", s);

$.post('Poly.ashx', '', function (response) {

eval(response);

var lastID = 1;

var pl = [];

var points = [];

for (var i = 0; i < data.length; i++) {

if (data[i].ID != lastID) {

pl = new YMaps.Polyline(points);

pl.setStyle("line1");

map.addOverlay(pl);

points = [];

}

points[i] = new YMaps.GeoPoint(data[i].Longitude, data[i].Latitude);

lastID = data[i].ID;

}

pl = new YMaps.Polyline(points);

pl.setStyle("line1");

map.addOverlay(pl);

$.post('Handler.ashx', '', function (response) {

eval(response);

for (var k = 0; k < data1.length; k++) {

mark = new YMaps.GeoPoint(data1[k].Longitude, data1[k].Latitude);

var placemark = new YMaps.Placemark(mark, { hasHint: 1, style: "default#darkbluePoint" });

placemark.description = "<strong> Кадастровый номер:</strong> <i> " + data1[k].Number + "</i><br />" + "<strong> Район:</strong> <i>" + data1[k].Raion +

"</i><br />" + "<strong> Назначение участка:</strong> <i> " + data1[k].Naznach + "</i><br />" + "<strong> Владелец:</strong> <i>" + data1[k].Vladelec +

"</i><br />";

map.addOverlay(placemark);

}

})

})

}

</script>

<style type="text/css">

#find {

width: 247px;

height: 21px;

}

#find1 {

width: 247px;

height: 21px;

}

#Button1 {

width: 247px;

height: 32px;

}

</style>

</head>

<body>

<form id="form1" runat="server">

<div>

<div id="toolsBox" style="float:left;padding:0;width:20%;height:100%;background-color:lightblue; margin-left: 0px;">

<div id="tools" style="padding:6pt;">

<div class="layer" style="background-color:gray;margin:0;padding:5px; width: 247px;">

<input type="hidden" name="layerContent" class="layerContent" />

</div>

<input type="text" id="find" />

<input type="text" id="find1" />&nbsp;

<table style="width:100%; height: 7px;" class="remover">

<tbody>

</tbody>

</table>

</div>

<div style="height: 228px">

&nbsp;

<input id="Button1" type="button" value="Показать пересекающиеся участки" onclick="location.href='YMaps.aspx'" />

<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged" style="margin-top: 28px"></asp:TextBox>

</div>

</div>

<div id="YMapsID" style="width:80%; height:900px; margin-left: 0px; margin-top: 4px;"></div>

</div>

</form>

</body>

</html>

Файл Ymaps.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="YMaps.aspx.cs" Inherits="YMaps" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>Yandex</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script src ="http://api-maps.yandex.ru/1.1/index.xml?key=AKgqHEkBAAAA-WzMYwIAeAeamm8ETZZZpdfp2R07eIuGyX4AAAAAAAAAAACjUCDoHIHZJ2pcl5mSL1zWVp2Myw==" type="text/javascript"></script>

<script type="text/javascript" src="http://js.static.yandex.net/jquery/1.3.2/_jquery.js"> </script>

<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>

<script type="text/javascript">

window.onload = function () {

var options = {

tileUrlTemplate: "./%z/tile-%x-%y.png",

controls: {

typeControl: true,

miniMap: false,

toolBar: true,

scaleLine: false,

},

smoothZoomEnabled: true,

scrollZoomEnabled: true,

mapCenter: new YMaps.GeoPoint(73.3754610363281, 54.9805515071693),

backgroundMapType: YMaps.MapType.MAP,

mapZoom: 11,

isTransparent: true,

layerKey: "my#layer",

mapType: {

name: "Yandex Maps",

textColor: "#000000",

},

},

map = new YMaps.Map(document.getElementById("YMapsID")),

myData = new YMaps.TileDataSource(options.tileUrlTemplate, options.isTransparent, options.smoothZooming);

myData.getTileUrl = function (tile, zoom) {

return this.getTileUrlTemplate().replace(/%x/i, tile.x).replace(/%y/i, tile.y).replace(/%z/i, zoom);

}

var MyLayer = function () {

return new YMaps.Layer(myData);

}

YMaps.Layers.add(options.layerKey, MyLayer);

var mapLayers = options.backgroundMapType ? options.backgroundMapType.getLayers() : [],

myMapType = new YMaps.MapType(YMaps.jQuery.merge(mapLayers, [options.layerKey]),

options.mapType.name, { textColor: options.mapType.textColor });

map.setCenter(options.mapCenter, options.mapZoom, myMapType);

map.setMaxZoom(15);

map.setMinZoom(11);

if (options.scrollZoomEnabled) {

map.enableScrollZoom();

}

map.addControl(new YMaps.Zoom());

YMaps.Events.observe(map, map.Events.Click, function (map, mEvent) {

var myHtml = "Координаты: " + mEvent.getGeoPoint();

var zoom = "Масштаб карты: " + map.getZoom();

document.getElementById('find').value = myHtml;

document.getElementById('find1').value = zoom;

// map.openBalloon(mEvent.getGeoPoint(), myHtml);

});

var s = new YMaps.Style();

s.lineStyle = new YMaps.LineStyle();

s.lineStyle.strokeColor = '00000099';

s.lineStyle.strokeWidth = '3';

YMaps.Styles.add("line1", s);

var s1 = new YMaps.Style();

s1.lineStyle = new YMaps.LineStyle();

s1.lineStyle.strokeColor = '0000FF99';

s1.lineStyle.strokeWidth = '3';

YMaps.Styles.add("line2", s1);

$.post('Poly.ashx', '', function (response) {

eval(response);

var sector = [];

var l = 0;

var k = 0;

var j = 0;

var pl = [];

var points = [];

var intersectmass = [];

var secondintersectmass = [];

var bigmassive = [];

var mark = [];

var lastID = data[0].ID;

for (var i = 0; i < data.length; i++) {

if (data[i].ID != lastID) {

bigmassive[j] = [sector];

sector = [];

j++;

k = 0;

}

sector[k] = [data[i].Longitude, data[i].Latitude];

k++;

lastID = data[i].ID;

}

bigmassive[j] = [sector];

for(var i = 0; i <bigmassive.length; i++)

{

for (var j = 0; j < bigmassive.length; j++) {

if (i != j)

{

var poly = turf.polygon(bigmassive[i]);

var poly1 = turf.polygon(bigmassive[j]);

var intersection = turf.intersect(poly, poly1);

if (intersection != undefined) {

intersectmass[l] = i;

l++;

}

poly = [];

poly1 = [];

}

}

}

for (var i = 0; i < intersectmass.length; i++)

{

secondintersectmass[i] = intersectmass[i] + 1;

}

for (var j = 0; j <= secondintersectmass.length; j++) {

for (var i = 0; i < data.length; i++) {

if(data[i].ID == secondintersectmass[j])

{

points[i] = new YMaps.GeoPoint(data[i].Longitude, data[i].Latitude);

}

else {

if (points.length != 0) {

pl = new YMaps.Polyline(points);

pl.setStyle("line2");

map.addOverlay(pl);

points = [];

}

}

}

}

points = [];

pl = [];

$.post('Handler.ashx', '', function (response) {

eval(response);

for (var j = 0; j <= secondintersectmass.length; j++) {

for (var k = 0; k < data1.length; k++) {

if (data1[k].ID_OB == secondintersectmass[j]) {

mark = new YMaps.GeoPoint(data1[k].Longitude, data1[k].Latitude);

var placemark = new YMaps.Placemark(mark, { hasHint: 1, style: "default#darkbluePoint" });

placemark.description = "<strong> Кадастровый номер:</strong> <i> " + data1[k].Number + "</i><br />" + "<strong> Район:</strong> <i>" + data1[k].Raion +

"</i><br />" + "<strong> Назначение участка:</strong> <i> " + data1[k].Naznach + "</i><br />" + "<strong> Владелец:</strong> <i>" + data1[k].Vladelec +

"</i><br />";

map.addOverlay(placemark);

}

}

}

})

})

}

</script>

<style type="text/css">

#find {

width: 247px;

height: 21px;

}

#find1 {

width: 247px;

height: 21px;

}

#Button1 {

width: 247px;

}

</style>

</head>

<body>

<form id="form1" runat="server">

<div>

<div id="toolsBox" style="float:left;padding:0;width:20%;height:100%;background-color:lightblue; margin-left: 0px;">

<div id="tools" style="padding:6pt;">

<div class="layer" style="background-color:gray;margin:0;padding:5px; width: 247px;">

<input type="hidden" name="layerContent" class="layerContent" />

</div>

<input type="text" id="find" />

<input type="text" id="find1" />&nbsp;

<table style="width:100%; height: 7px;" class="remover">

<tbody>

</tbody>

</table>

</div>

<div style="height: 228px">

&nbsp;<input id="Button1" type="button" value="Показать все участки" onclick="location.href='AllSectors.aspx'"/>

<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged" style="margin-top: 28px"></asp:TextBox>

</div>

</div>

<div id="YMapsID" style="width:80%; height:900px; margin-left: 0px; margin-top: 4px;"></div>

</div>

</form>

</body>

</html>

Файл Registration.aspx.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Security.Cryptography;

using System.Text;

using System.Data.SqlClient;

public partial class Registration : System.Web.UI.Page

{

string LOGIN;

string PASSWORD;

string NAME;

string SURNAME;

string intData;

string plus;

string Confirm_pass;

protected void Page_Load(object sender, EventArgs e)

{

}

string GetHashString(string s)

{

byte[] bytes = Encoding.Unicode.GetBytes(s);

MD5CryptoServiceProvider CSP = new MD5CryptoServiceProvider();

byte[] byteHash = CSP.ComputeHash(bytes);

string hash = string.Empty;

foreach (byte b in byteHash) hash += string.Format("{0:x2}", b);

return hash;

}

protected void Button1_Click(object sender, EventArgs e)

{

NAME = TextBox3.Text;

SURNAME = TextBox4.Text;

LOGIN = TextBox1.Text;

PASSWORD = TextBox2.Text;

Confirm_pass = TextBox6.Text;

if (Confirm_pass == PASSWORD)

{

Random rnd = new Random();

char[] pwdChars = new char[36] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

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

intData += pwdChars[rnd.Next(0, 35)];

plus = intData + PASSWORD;

string md5_hash = GetHashString(plus);

if (LOGIN == "" || PASSWORD == "" || NAME == "" || SURNAME == "")

{

TextBox5.Text = "Not all the data is entered";

}

else

{

if (PASSWORD.Length < 6)

{

TextBox5.Text = "Lenght of password " + PASSWORD.Length + " symbols. Min lenght 6!";

}

else

{

string connectionString = @"Data Source=MAGENTA;Initial Catalog=Maps;Integrated Security=True";

string sqlExpression = "INSERT INTO Users(Name, Surname, Logins, Passwords, Salt) VALUES(@param0, @param1,@param2, @param3, @param4)";

string sqlExpression2 = "SELECT * FROM Users WHERE Logins LIKE '" + LOGIN + "';";

using (SqlConnection connection = new SqlConnection(connectionString))

{

connection.Open();

SqlCommand command = new SqlCommand(sqlExpression2, connection);

SqlDataReader reader = command.ExecuteReader();

if (reader.HasRows) // если есть данные, то читаем их

{

TextBox5.Text = "Login '" + LOGIN + "' already exists. Please enter another";

}

else //если их нет, то вносятся данные в табл

{

reader.Close();

SqlCommand cmd = new SqlCommand(sqlExpression, connection);

cmd.Connection = connection;

cmd.Parameters.AddWithValue("@param0", NAME);

cmd.Parameters.AddWithValue("@param1", SURNAME);

cmd.Parameters.AddWithValue("@param2", LOGIN);

cmd.Parameters.AddWithValue("@param3", md5_hash);

cmd.Parameters.AddWithValue("@param4", intData);

cmd.ExecuteNonQuery();

TextBox1.Text = null;

TextBox2.Text = null;

TextBox3.Text = null;

TextBox4.Text = null;

TextBox5.Text = "Account created!! Press 'Log in' to continue";

}

//Thread.Sleep(1000);

connection.Close();

}

}

}

}

else

{

TextBox5.Text = "Passwords don't match";

}

}

protected void TextBox1_TextChanged(object sender, EventArgs e)

{

}

protected void Button2_Click(object sender, EventArgs e)

{

Response.Redirect(Request.RawUrl);

}

protected void TextBox4_TextChanged(object sender, EventArgs e)

{

}

protected void TextBox3_TextChanged(object sender, EventArgs e)

{

}

}

Файл RegAndLog.aspx.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using System.Security.Cryptography;

using System.Text;

using System.Data;

using System.Data.SqlClient;

using System.Data.Sql;

public partial class RegAndLog : System.Web.UI.Page

{

string LOGIN;

string PASSWORD;

string intData;

string pass;

string saltnew;

string plus;

protected void Page_Load(object sender, EventArgs e)

{

}

string GetHashString(string s)

{

byte[] bytes = Encoding.Unicode.GetBytes(s);

MD5CryptoServiceProvider CSP = new MD5CryptoServiceProvider();

byte[] byteHash = CSP.ComputeHash(bytes);

string hash = string.Empty;

foreach (byte b in byteHash) hash += string.Format("{0:x2}", b);

return hash;

}

protected void TextBox1_TextChanged(object sender, EventArgs e)

{

}

protected void Button1_Click(object sender, EventArgs e)

{

LOGIN = TextBox1.Text;

PASSWORD = TextBox2.Text;

if (TextBox1.Text == "" || TextBox2.Text == "")

{

TextBox4.Text = " Not all data entered";

}

else

{

if (PASSWORD.Length < 6)

{

TextBox4.Text = "Lenght of password " + PASSWORD.Length + " symbols. Min lenght 6!";

}

else

{

string connectionString = @"Data Source=MAGENTA;Initial Catalog=Maps;Integrated Security=True";

string sqlExpression1 = "SELECT Logins, Passwords, Salt FROM Users WHERE Logins LIKE'" + LOGIN + "';";

using (SqlConnection connection = new SqlConnection(connectionString))

{

connection.Open();

SqlCommand command = new SqlCommand(sqlExpression1, connection);

SqlDataReader reader = command.ExecuteReader();

if (reader.HasRows) // если есть данные, то читаем их

{

while (reader.Read()) // построчно считываем данные

{

object name = reader.GetValue(0);

object passw = reader.GetValue(1);

object salt = reader.GetValue(2);

intData = Convert.ToString(name);

pass = Convert.ToString(passw);

saltnew = Convert.ToString(salt);

plus = saltnew + PASSWORD;

string md5_hash = GetHashString(plus);

if (LOGIN == intData && pass == md5_hash)

{

TextBox4.Text = null;

TextBox3.Text = "Welcome! Click on 'Open map'";

Button3.Enabled = true;

}

else

{

if (LOGIN == intData)

{

TextBox4.Text = "Incorrect password";

}

}

}

connection.Close();

reader.Close();

}

else

{

TextBox4.Text = "Account not find";

}

}

}

}

}

protected void Button2_Click(object sender, EventArgs e)

{

Response.Redirect(Request.RawUrl);

}

protected void Button3_PreRender(object sender, EventArgs e)

{

}

protected void TextBox4_TextChanged(object sender, EventArgs e)

{

}

protected void TextBox3_TextChanged(object sender, EventArgs e)

{

}

protected void TextBox2_TextChanged(object sender, EventArgs e)

{

}

protected void Button3_Click(object sender, EventArgs e)

{

// Response.Redirect("Default.aspx?LOGIN=" + LOGIN.ToString());//System.Web.HttpUtility.UrlDecode(TextBox1.Text));

}

}

HTTP - обработчик Handler.ashx

<%@ WebHandler Language="C#" Class="Handler" %>

using System;

using System.Web;

using System.Web.Script.Serialization;

using System.Web.Configuration;

using System.Data.SqlClient;

using System.Net;

using System.Collections.Generic;

public class Handler : IHttpHandler

{

public void ProcessRequest(HttpContext context)

{

//формируется список, в котором будут находиться объекты

List<object> list = new List<object>();

string connString = @"Data Source=MAGENTA;Initial Catalog=Maps;Integrated Security=True";

using (SqlConnection con = new SqlConnection(connString))

{

string sql = "SELECT * FROM info1";

SqlCommand cmd = new SqlCommand(sql, con);

con.Open();

using (SqlDataReader reader = cmd.ExecuteReader())

{

while (reader.Read())

{

var data1 = new

{

ID_OB = reader.GetValue(0),

Number = reader.GetString(1),

Naznach = reader.GetString(2),

Vladelec = reader.GetString(3),

Longitude = reader.GetString(4),

Latitude = reader.GetString(5),

Address = reader.GetString(6),

Raion = reader.GetString(7)

};

list.Add(data1);

}

}

con.Close();

}

//сериализация данный для отправки его в формате JSON

JavaScriptSerializer serializer = new JavaScriptSerializer();

string output = string.Format("var data1 = [{0}];", string.Join(",", list.ConvertAll<string>(serializer.Serialize).ToArray()));

context.Response.ContentType = "text/plain";

context.Response.Write(output);

context.Response.End();

context.Response.Cache.SetNoServerCaching();

}

public bool IsReusable

{

get

{

return false;

}

}

}

HTTP - обработчик Poly.ashx

<%@ WebHandler Language="C#" Class="Poly" %>

using System;

using System.Web;

using System.Web.Script.Serialization;

using System.Web.Configuration;

using System.Data.SqlClient;

using System.Net;

using System.Collections.Generic;

public class Poly : IHttpHandler {

public void ProcessRequest(HttpContext context) {

//формируется список, в котором будут находиться объекты

List<object> list = new List<object>();

string connString = @"Data Source=MAGENTA;Initial Catalog=Maps;Integrated Security=True";

using (SqlConnection con = new SqlConnection(connString))

{

string sql = "USE Maps SELECT id_ob, Versh, Coords_Long, Coords_Lat FROM coords1";

SqlCommand cmd = new SqlCommand(sql, con);

con.Open();

using (SqlDataReader reader = cmd.ExecuteReader())

{

while (reader.Read())

{

var data = new

{

ID = reader.GetValue(0),

Vershina = reader.GetString(1),

Longitude = reader.GetString(2),

Latitude = reader.GetString(3),

};

list.Add(data);

}

}

con.Close();

}

JavaScriptSerializer serializer = new JavaScriptSerializer();

string output = string.Format("var data = [{0}];", string.Join(",", list.ConvertAll<string>(serializer.Serialize).ToArray()));

context.Response.ContentType = "text/plain";

context.Response.Write(output);

context.Response.End();

context.Response.Cache.SetNoServerCaching();

}

public bool IsReusable {

get {

return false;

}

}

}

Заключение

В результате выполнения курсовой работы была спроектирована информационная система «Кадастровые границы Омска». Процесс её проектирования позволил изучить данную предметную область, принцип взаимодействия с API Яндекс Карты и геопространственным анализатором Turf.js, выполнить создание связанных таблиц, нормализацию базы данных тем самым, проверив функциональные возможности СУБД MS SQL Server. Также был получен опыт в разработке веб-приложения с использованием шифрования данных и языков программирования C#, JavaScript.

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

Литература

1) Стихановская Л.М. Методические указания по оформлению тестовых документов студентами факультета “Информационные системы в управлении” / Л.М. Стихановская, И.И. Семенова - Омск: Изд-во СибАДИ, 2015г. - 50 с.

2) Молинаро Э., SQL. Сборник рецептов. - Пер. с англ. - СПб: Символ-Плюс, 2009. - 672 с.

Размещено на Allbest.ru


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.