Особенности функционирования интерактивных web-ориентированных картографических систем

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

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

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

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

Рис. 3. Overlay техника оптимизации отображения большого количества объектов на Яндекс.Картах

2. Использование встроенных объектов Яндекс.Карт: RemoteObjectManager или LoadingObjectManager, которые разработаны специально для отображения большого количества объектов. Они умеют самостоятельно подгружать с сервера информацию для карты с учётом координат видимого участка карты и обладают таким важным дополнительным функционалом как кластеризация отображаемых объектов при отдалении (рис. 2).

Рисунок 4. Пример автоматической кластеризации, выполняемой на клиенте

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

Второй подход более гибок и прост в реализации, однако, он требует от серверной части web-приложения возврата данных в формате JSONP, который отличается от формата JSON тем, что в случае с JSONP результатом интерпретации JSON'а является не объект, а вызов callback-функции с передачей ей объекта с геоданными сгенерированными на сервере.

Пример JSON:

{

"type": "FeatureCollection",

"features": [

{

"type": "Feature",

"id": 2,

"geometry": {

"type": "Point",

"coordinates": [55.763338, 37.565466]

},

"properties": {

"balloonContent": "Содержимое балуна",

"clusterCaption": "Метка 2",

"hintContent": "Текст подсказки"

}

}

]

Пример JSONP:

myCallback_x_1_y_2_z_5(

{

"type": "FeatureCollection",

"features": [

...

]

})

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

Рис. 5. Фильтр

Рис.6. Брендирование

Карточка объекта выглядит следующим образом:

Рис.7. Карточка объекта

Разработанное веб-приложение доступно на сайте vkr.abdulin.pro.

Заключение

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

Изучены особенности лицензирования данных каждым из популярных ГИС. Определены ГИС, допускающие свободное обращение с предоставляемыми данными и не ограничивающие доступ к ним в автоматическом режиме. Изучены API данных сервисов и форматы выгрузки данных.

Произведена выгрузка данных о заведениях общественного питания г. Москвы из источников data.mos.ru и OpenStreetMap. Обнаружена проблема большого процента дублей в итоговой выгрузке.

Разработан двухкритериальный алгоритм сведения данных о заведениях общественного питания, полученных из справочников обоих ГИС. Разработан алгоритм вычисления субоптимальных пороговых значений для обоих критериев. По результатам отработки алгоритма уточнены исходные пороговые значения для обоих критериев. Используя разработанный алгоритм, построен итоговый сводный справочник заведений.

Изучено картографическое API популярных ГИС. Разработан механизм вывода сводного справочника организаций (>10000) на Яндекс.Карты. Реализованы дополнительные опции для демонстрации возможностей системы.

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

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

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

Приложения

Feature.cs

using Newtonsoft.Json;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Text;

using System.Threading.Tasks;

using DAL;

using FuzzySearch;

namespace EPA

{

public class Feature : DAL.TransactObject<Feature>

{

public Feature() : base() { }

public Feature(long id) : base(id) { }

public override CachingType CacheType

{

get { return CachingType.None; }

}

public Feature FromJSON1(dynamic obj)

{

CoordX = obj.geometry.coordinates[0];

CoordY = obj.geometry.coordinates[1];

DatasetId = obj.properties.DatasetId;

VersionNumber = obj.properties.VersionNumber;

ReleaseNumber = obj.properties.ReleaseNumber;

RowId = obj.properties.RowId;

GlobalId = obj.properties.Attributes.global_id;

Name = obj.properties.Attributes.Name;

OperatingCompany = obj.properties.Attributes.OperatingCompany;

IsNetObject = obj.properties.Attributes.IsNetObject == "да";

AdmArea = obj.properties.Attributes.AdmArea;

District = obj.properties.Attributes.District;

Address = obj.properties.Attributes.Address;

if (PublicPhone != null)

PublicPhone = obj.properties.Attributes.PublicPhone[0].PublicPhone;

SeatsCount = obj.properties.Attributes.SeatsCount;

SocialPrivileges = obj.properties.Attributes.SocialPrivileges == "да";

return this;

}

public Feature FromJSON2(dynamic obj)

{

CoordX = obj.lon;

CoordY = obj.lat;

GlobalId = obj.id;

Name = obj.tags.name;

PublicPhone = obj.tags["contact:phone"];

return this;

}

public static List<Feature> Download2(string path, string source)

{

WebClient wc = new WebClient();

wc.Encoding = Encoding.UTF8;

string json = wc.DownloadString(path);

//Newtonsoft.Json.Serialization.ser

dynamic list = ((dynamic)JsonConvert.DeserializeObject(json)).elements;

List<Feature> res = new List<Feature>();

foreach (var obj in list)

{

res.Add(new Feature().FromJSON2(obj));

}

res = Merge(res, source);

Feature.Instance.InsertMany(res);

return res;

}

public static void Counts()

{

long mosRu = Feature.Instance.InvokeScalar<long>("select count(*) from Features where SourcesStr like '%mos.data.ru%'");

long osmRu = Feature.Instance.InvokeScalar<long>("select count(*) from Features where SourcesStr like '%OpenStreetMap.ru%'");

long mix = Feature.Instance.InvokeScalar<long>("select count(*) from Features where SourcesStr like '%mos.data.ru%' and SourcesStr like '%OpenStreetMap.ru%'");

}

private static List<Feature> Merge(List<Feature> src, string source)

{

var features = Feature.Instance.SelectMany();

List<Feature> res = new List<Feature>();

List<Feature> toUpdate = new List<Feature>();

foreach (Feature s in src)

{

bool found = false;

foreach (Feature d in features)

{

if (s.Near(d) && XgramCompare.FuzzyCompare(3, s.Name, d.Name) > 0.4)

{

if (!d.Sources.Contains(source))

{

toUpdate.Add(d);

d.Sources = d.Sources.Concat(new[] { source }).ToArray();

}

found = true;

break;

}

}

if (!found)

res.Add(s);

}

Feature.Instance.UpdateMany(toUpdate);

return res;

}

// M/(m/Grad)

double LongDifGrad = 50 / 111134.861111;

double LatDifGrad = 50 / 71240.3572324;

private bool Near(Feature d)

{

return CoordX < d.CoordX + LongDifGrad && CoordX > d.CoordX - LongDifGrad

&& CoordY < d.CoordY + LatDifGrad && CoordY > d.CoordY - LatDifGrad;

}

public static List<Feature> Get(double lng1, double lat1, double lng2, double lat2)

{

return Feature.Instance.SelectMany(x=>x.CoordX < lng2 && x.CoordX > lng1

&& x.CoordY < lat2 && x.CoordY > lat1);

}

public object ToJSONObj()

{

dynamic[] nets = new dynamic[] {

new { name= "макдоналдс", logo= "mcdonalds.svg", size=new Int32[] { 32, 32 } },

new { name= "старбакс", logo= "starbucks.png", size= new Int32[] {32, 32}},

new { name= "якитория", logo= "yakitoriya.png", size= new Int32[] {52, 32}},

new { name= "бургер кинг", logo= "bk.png", size= new Int32[] {32, 32}},

new { name= "иль патио", logo= "ilpatio.png", size= new Int32[] {32, 32}},

new { name= "кфс", logo= "kfc.png", size= new Int32[] {52, 52}},

new { name= "суши wok", logo= "shushivok.png", size= new Int32[] {62, 32}},

new { name= "суши сет", logo= "sushiset.png", size= new Int32[] {62, 32}},

new { name= "стардогс", logo= "stardogs.png", size= new Int32[] {62, 32}},

new { name= "суши шоп", logo= "sushishop.png", size= new Int32[] {62, 32}},

new { name= "тануки", logo= "tanuki.png", size= new Int32[] {32, 32}},

new { name= "шоколадница", logo= "shoko.png", size= new Int32[] {42, 32}},

new { name = "кофе хаус", logo = "coffehouse.png", size = new Int32[] { 32, 32 } }

// { name: 'суши сет', logo: 'sushiset.png', size: [32, 32}},

};

dynamic net = nets.FirstOrDefault(x => (Name != null ? Name.ToLower().Contains(x.name) : false) );

return new

{

id = Id,

geometry = new

{

coordinates = new double[] { CoordX, CoordY },

type = "Point"

},

properties = new

{

type = TypeStr.ToString().ToLower(),

DatasetId = DatasetId,

VersionNumber = VersionNumber,

ReleaseNumber = ReleaseNumber,

RowId = RowId,

iconContent = Name,

balloonContentHeader = Name,

balloonContentBody = (IsNetObject ? "Сетевое заведение. " : "") +

(!String.IsNullOrWhiteSpace(Address) ? "<br/> Адрес: " + AdmArea + ", " + District + ", " + Address : "") +

(!String.IsNullOrWhiteSpace(PublicPhone) ? "<br/> Телефон: " + PublicPhone : "") +

"<br/> Источник: <b>" + SourcesStr + "</b>",

hintContent = Address == null ? "" : Address,

Attributes = new

{

global_id = GlobalId,

Name = Name,

IsNetObject = IsNetObject ? "да" : "нет",

OperatingCompany = OperatingCompany,

AdmArea = AdmArea,

District = District,

Address = Address,

PublicPhone = new object[] { new { PublicPhone = PublicPhone } }

},

},

options = (net == null ? null : new

{

iconLayout = "default#image",

iconImageHref = "img/" + net.logo,

iconImageSize = net.size

}),

type = "Feature"

};

}

public static string ToJson()

{

List<Feature> features = Feature.Instance.SelectMany();

return JsonConvert.SerializeObject(new { features = features.Select(x => x.ToJSONObj()).ToArray() });

}

public static List<Feature> Download(long dataNumber)

{

WebClient wc = new WebClient();

wc.Encoding = Encoding.UTF8;

string json = wc.DownloadString("https://apidata.mos.ru/v1/datasets/{" + dataNumber + "}/features");

//Newtonsoft.Json.Serialization.ser

dynamic list = ((dynamic)JsonConvert.DeserializeObject(json)).features;

List<Feature> res = new List<Feature>();

foreach (var obj in list)

{

res.Add(new Feature().FromJSON1(obj));

}

Feature.Instance.InsertMany(res);

return res;

}

//37 long

public double CoordX

{

get { return Get<double>(); }

set { Set(value); }

}

//55 lat

public double CoordY

{

get { return Get<double>(); }

set { Set(value); }

}

public long DatasetId

{

get { return Get<long>(); }

set { Set(value); }

}

public long VersionNumber

{

get { return Get<long>(); }

set { Set(value); }

}

public long ReleaseNumber

{

get { return Get<long>(); }

set { Set(value); }

}

public string RowId

{

get { return Get(); }

set { Set(value); }

}

public long GlobalId

{

get { return Get<long>(); }

set { Set(value); }

}

public string Name

{

get { return Get(); }

set { Set(value); }

}

public string OperatingCompany

{

get { return Get(); }

set { Set(value); }

}

public bool IsNetObject

{

get { return Get<bool>(); }

set { Set(value); }

}

public string AdmArea

{

get { return Get(); }

set { Set(value); }

}

public string District

{

get { return Get(); }

set { Set(value); }

}

public string Address

{

get { return Get(); }

set { Set(value); }

}

public string PublicPhone

{

get { return Get(); }

set { Set(value); }

}

public string SeatsCount

{

get { return Get(); }

set { Set(value); }

}

public bool SocialPrivileges

{

get { return Get<bool>(); }

set { Set(value); }

}

public string SourcesStr

{

get { return Get(); }

set { Set(value); }

}

public string[] Sources

{

get { return SourcesStr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); }

set { SourcesStr = string.Join(", ", value); SourcesCnt = value.Length; }

}

public long SourcesCnt

{

get { return Get<long>(); }

set { Set(value); }

}

public long Type

{

get { return Get <long>(); }

set { Set(value); }

}

public object TypeStr {

get

{

switch (this.Type)

{

case 1797:

return "Предприятие быстрого обслуживания";

case 1794:

return "Кафетерий";

case 1793:

return "Столовые";

case 1792:

return "Кафе";

case 1790:

return "Магазины кулинарии";

case 1786:

return "Кофейни";

case 1784:

return "Буфеты";

case 1798:

return "Закусочные";

case 1788:

return "Рестораны";

case 1796:

return "Бары";

case 0:

return "";

default:

return "";

}

}

}

}

}

Handler.ashx:

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

using System;

using System.Collections.Generic;

using System.Globalization;

using System.Web;

using EPA;

using Newtonsoft.Json;

using System.Linq;

public class Handler : IHttpHandler {

public void ProcessRequest (HttpContext context)

{

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

if (context.Request["update"] == "true")

{

Feature.Download2("http://overpass.osm.rambler.ru/cgi/interpreter?data=[out:json];node[%22amenity%22=%22restaurant%22](55.625282274095,37.345962524414,55.875696039004,37.889099121094);out;",

"OpenStreetMap.ru");

Feature.Download2("http://overpass.osm.rambler.ru/cgi/interpreter?data=[out:json];node[%22amenity%22=%22cafe%22](55.625282274095,37.345962524414,55.875696039004,37.889099121094);out;",

"OpenStreetMap.ru");

return;

}

string bbox = context.Request["bbox"];

string[] arr = bbox.Split(',');

List<Feature> features = Feature.Get(double.Parse(arr[0], CultureInfo.InvariantCulture),

double.Parse(arr[1], CultureInfo.InvariantCulture),

double.Parse(arr[2], CultureInfo.InvariantCulture),

double.Parse(arr[3], CultureInfo.InvariantCulture));

string result = JsonConvert.SerializeObject( features.Select(x => x.ToJSONObj()).ToArray(), Formatting.Indented );

context.Response.Write("/**/ typeof " + context.Request["callback"] + " === \"function\" && " + context.Request["callback"] +

"({ \"error\": null, \"data\": "+ result + "});");

}

public bool IsReusable {

get {

return false;

}

}

}

TrigramCompare.cs:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace FuzzySearch

{

public static class XgramCompare

{

public static double FuzzyCompare(int gramm, string left, string right)

{

if (left != null)

left = left.ToLower();

if (right != null)

right = right.ToLower();

if (left == right || left == null || left.Length < 3)

return 1;

return Math.Max(_compare(gramm, left, right), _compare(gramm, right, left));

}

//Gramm = 2 or 3

private static double _compare(int gramm, string left, string right)

{

double foundCnt = 0;

for (int i = 0; i < left.Length - (gramm - 1); i++)

foundCnt += right.Contains(left.Substring(i, gramm)) ? 1 : 0;

return foundCnt / (left.Length - (gramm - 1));

}

}

}

Index.html:

<!DOCTYPE html>

<html>

<head>

<title>Агрегация мест общественного питания</title>

<script src="//yandex.st/jquery/2.1.1/jquery.min.js" type="text/javascript"></script>

<script src="//api-maps.yandex.ru/2.1/?lang=ru-RU&coordorder=longlat"></script>

<script type="text/javascript">

/*global ymaps*/

ymaps.ready(function () {

// инициируем объект карты

var myMap = window.map = new ymaps.Map('YMapsID', {

center: [37.633265, 55.761384],

zoom: 18,

controls: ["zoomControl", "fullscreenControl"]

}, {

// minZoom: 5

});

// инициируем менеджер объектов на карте и настраиваем его на

// автоматическую загрузку данных с нашей прокси-страницы

var objectManager = new ymaps.LoadingObjectManager('/handler.ashx?bbox=%b&zoom=%z', {

clusterHasBalloon: true, // у кластеров будут свои балуны

clusterize: true, // включаем автоматическую кластеризацию

});

// Задаем стиль иконок для одиночных меток.

objectManager.objects.options.set('preset', 'islands#yellowStretchyIcon');

// Стиль иконок кластеров.

objectManager.clusters.options.set('preset', 'islands#greenClusterIcons');

// добавляем менеджер объектов на карту

myMap.geoObjects.add(objectManager);

// инициируем элемент управления -- список типов заведений (фильтр)

var placeType = new ymaps.control.ListBox({

data: {

content: 'Выбрать тип заведения'

},

items: [

new ymaps.control.ListBoxItem({data: {content: 'Магазины кулинарии'}}),

new ymaps.control.ListBoxItem({data: {content: 'Кафетерий'}}),

new ymaps.control.ListBoxItem({data: {content: 'Закусочные'}}),

new ymaps.control.ListBoxItem({data: {content: 'Кофейни'}}),

new ymaps.control.ListBoxItem({data: {content: 'Буфеты'}}),

new ymaps.control.ListBoxItem({data: {content: 'Предприятие быстрого обслуживания'}}),

new ymaps.control.ListBoxItem({data: {content: 'Рестораны'}}),

new ymaps.control.ListBoxItem({data: {content: 'Столовые'}}),

new ymaps.control.ListBoxItem({data: {content: 'Кафе'}}),

new ymaps.control.ListBoxItem({data: {content: 'Бары'}}),

]

});

// отмечаем все значения фильтра в позицю выбрано

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

{

placeType.getAll()[i].select();

}

// добавляем элемент управления на карту

myMap.controls.add(placeType);

// обработчик клика по списку (т.е. по конкретному типу общепита)

var filterPlaces = function (e) {

e.preventDefault();

// формируем строку для фильтраиции объектов на карте по принадлежности к типу общепита

var filterStr = '';

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

{

var li = placeType.getAll()[i];

if (li.isSelected()) // если данный тип заведения выбран в списке, добавляем для него условие фильтрации

filterStr += (filterStr != '' ? ' || ' : '') + 'properties.type == "' + li.data.get('content').toLowerCase() + '"';

}

if (filterStr == '') // не выбран ни один из типов заведений

filterStr = 'properties.type == 9999'; // ... отфильтровываем вообще все объекты

objectManager.setFilter(filterStr);

};

placeType.events.add('select', filterPlaces);

placeType.events.add('deselect', filterPlaces);

});

</script>

<style type="text/css">

html, body, #YMapsID {

width: 100%;

height: 100%;

padding: 0;

margin: 0;

}

</style>

</head>

<body>

<!-- Див в котором будет отображена Яндекс.Карта -->

<div id="YMapsID"></div>

</body>

</html>

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


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

  • Возможности интерфейса программирования приложений ARI крупных картографических веб-сервисов в процессе создания двух картографических веб-сервисов. Анализ существующих веб-сервисов. Карты Яндекса и Google, пользовательские карты. Выбор среды разработки.

    дипломная работа [4,5 M], добавлен 24.09.2012

  • Человек и компьютер, особенности взаимодействия. Свобода массовой информации в Российской Федерации. Объективность и субъективность, полнота, достоверность информации. Общее понятие про информационные технологии. Основные примеры носителей информации.

    презентация [259,1 K], добавлен 02.06.2012

  • Разработка и реализация алгоритма динамического контроля корректности использования директив OpenMP в программах, написанных на языке Fortran. Минимизация количества потребляемых ресурсов при работе отладчика. Сравнительный обзор существующих отладчиков.

    дипломная работа [83,0 K], добавлен 14.10.2010

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

    курсовая работа [5,3 M], добавлен 31.05.2014

  • Средства поиска информации в сети Интернет. Основные требования и методика поиска информации. Структура и характеристика поисковых сервисов. Глобальные поисковые машины WWW (World Wide Web). Планирование поиска и сбора информации в сети Интернет.

    реферат [32,2 K], добавлен 02.11.2010

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

    курсовая работа [2,7 M], добавлен 10.05.2015

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

    дипломная работа [366,7 K], добавлен 02.06.2014

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

    презентация [200,9 K], добавлен 06.11.2011

  • Разработка интерактивных сервисов доступа к расписанию занятий СевКавГТУ в среде программирования Eclipse и базы данных для них с использованием фреймворк Django. Информационное и программное обеспечение разработки. Расчет цены программного продукта.

    дипломная работа [6,1 M], добавлен 29.06.2011

  • Исследование организационно-управленческой структурной схемы СевКавГТУ. Пути реализации интерактивных сервисов доступа к телефонному справочнику учреждения. Выбор среды разработки Eclipse, СУБД и языка программирования Python для разработки базы данных.

    дипломная работа [6,5 M], добавлен 29.06.2011

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