Русский
Русский
English
Статистика
Реклама

Maps api

Как помочь школьникам выучить географическую карту с помощью Leaflet

01.06.2021 16:23:51 | Автор: admin

Привет! Меня зовут Николай, я преподаю географию в школе.

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

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

Проблема: ученики плохо ориентируются по карте

Пока дети в 5 или 6 классе, выучить с ними материки, океаны, основные горы, равнины большого труда не составляет, но в 7 классе начинается география материков и океанов и по окончании этого курса в головах должно сохраниться более 600 географических объектов. А в 8 классе начинается веселье с изучением регионов России и географических объектов. Запомнить где Кировская область, а где Калмыкия детям тяжело, ещё есть те, кто с трудом отличает Кавказ от Урала.

Как проблема решалась раньше

1 Карты в атласах для изучения и проверка на уроке у доски или с помощью бумажных карт.

2 Сайт Мотовских - хороший вариант для изучения карты, но там только политические и административные карты. Рек, гор и проч. там нет.

3 Seterra.com - тоже хороший сервис для изучения и проверки карты. Но там есть далеко не все объекты, которые требуются по школьной программе и однотонная карта не даёт представления о особенностях рельефа территории.

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

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

Первой проблемой стало найти подходящую подложку для карты. Сначала были попытки что-то сделать на основе векторной карты России, но от этой идеи отказались ввиду веса SVG карты более 40 мб.

Далее судьба свела с @denismosolov и вместе стали перебирать различные варианты картографических движков от Google Maps, Яндекс Карты и т.д. В ЯК и OSM не было подходящей подложки с физической картой, а в Google Maps была подходящая подложка Terrain, но цены за использования API кусались. Ещё были попытки сделать свою подложку, но опыта работы с ГИС не было и эту идею отложили.

В итоге взяли тайлы с maps for free и отображаем их на странице при помощи библиотеки Leaflet.js

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

Для этого использовали geoman.io(сейчас этот сервис не работает, пользуемся конструктором карт Яндекса)

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

Что готово в настоящее время

1.Возможность выбирать объекты по регионам и категориям.

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

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

Для примера ссылка на тест по странам Южной Америки:

https://www.maptomind.ru/t/zEQacNq

А по этой ссылке можно смотреть результаты тех, кто тест прошёл.

https://www.maptomind.ru/r/zEQacNq

Регистрироваться не нужно, достаточно имени или никнейма.

Промежуточные результаты

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

Ближайшие перспективы

1.Убрать шероховатости, которые ещё остались, в основном это границы объектов.

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

3. Сделать собственную подложку для карты с нормальной отмывкой рельефа и водными объектами.

4.Английская версия

Самостоятельно повыбирать и повспоминать карту можно по ссылке

Если вам интересно чуть более пристально следить за жизнью проекта, приглашаю вас в нашу группу ВК

Спасибо за внимание!

Подробнее..

Как мы нарисовали на карте несколько тысяч интерактивных объектов без вреда для перформанса

29.07.2020 10:12:50 | Автор: admin

Привет, меня зовут Дарья, и я Frontend-разработчик юнита Гео вАвито. Хочу поделиться опытом того, как мы сделали навебе новый поиск покарте, заменив кластеры более удобным решением и сняв ограничение наколичество отображаемых объектов.


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



Чем нас не устраивал старый поиск покарте


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


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


Выглядело это так:



Что мы решили изменить


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


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


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


$limit = viewPort.width viewPort.height / (pinDiameter^2 9)$


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


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


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

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



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



Выбраны фильтры, которые дают небольшую выдачу показываем пины



Приблизились на уровень, когда виды дома, и можем отобразить все объявления показываем пины


Далее я перечислю вопросы, скоторыми мы столкнулись впроцессе реализации, и расскажу, как их решали.


Как нарисовали на карте несколько тысяч точек


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



Поиск двухкомнатных квартир повсей России


Мы используем Яндекс-карты, API которых предоставляет разные способы отрисовки объектов. Например, кластеры мы рисовали черезинструмент ObjectManager, и он отлично подходит дляслучаев, когда количество объектов накарте не превышает 1000. Если попробовать нарисовать сего помощью, например, 3000объектов, карта начинает подтормаживать привзаимодействии сней.


Мы понимали, что может появиться необходимость отрисовать несколько тысяч объектов безвреда дляпроизводительности. Поэтому посмотрели всторону ещё одного API Яндекс-карт картиночного слоя, длякоторого используется класс Layer.


Основной принцип этого API заключается втом, что вся карта делится натайлы (изображения вpng или svg формате) фиксированного размера, которые маркируются через номера X, Y и зум Z. Эти тайлы накладываются поверх самой карты, и витоге каждая область представляется каким-то количеством изображений взависимости отразмера области и разрешения экрана. Собственно, API берёт насебя всю фронтовую часть, запрашивая нужные тайлы привзаимодействии скартой (изменении уровня зума и сдвиге), а бэкенд-часть нужно писать самостоятельно.



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


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


Чтобы реализовать бэкенд, мы взяли формулы дляприведения координат точек ксистеме тайлов впроекции Меркатора:


func (*Tile) Deg2num(t *Tile) (x int, y int) {    x = int(math.Floor((t.Long + 180.0) / 360.0 * (math.Exp2(float64(t.Z)))))    y = int(math.Floor((1.0 - math.Log(math.Tan(t.Lat*math.Pi/180.0)+1.0/math.Cos(t.Lat*math.Pi/180.0))/math.Pi) / 2.0 * (math.Exp2(float64(t.Z)))))    return}func (*Tile) Num2deg(t *Tile) (lat float64, long float64) {    n := math.Pi - 2.0*math.Pi*float64(t.Y)/math.Exp2(float64(t.Z))    lat = 180.0 / math.Pi * math.Atan(0.5*(math.Exp(n)-math.Exp(-n)))    long = float64(t.X)/math.Exp2(float64(t.Z))*360.0 - 180.0    return lat, long}

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


Нарисовав svg поданным, мы получили подобные изображения тайлов:



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


const createTilesUrl = (tileNumber, tileZoom) => {// params - выбранные фильтры в формате строки параметров, которые можно передать в GET-запросreturn `/web/1/map/tiles?${params}&z=${tileZoom}&x=${tileNumber[0]}&y=${tileNumber[1]}`;};const tilesLayer = new window.ymaps.Layer(createTilesUrl, { tileTransparent: true });ymap.layers.add(tilesLayer);

В итоге карта стайлами, подготовленными набэкенде и отрисованными черезLayer, выглядит так:



Как оптимизировали бэкенд


Используя механизм тайлов, мы будем присылать накаждую область примерно 15-30запросов отодного пользователя, и примаксимальном трафике накарте нагрузка насервис будет достигать 5000rps. Приэтом наш сервис только формирует изображения длякарты наосновании запросов сфронта, а данные дляобъектов собирает сервис поиска. Очевидно, всервис поиска не нужно ходить накаждый запрос.


Решая проблему сетевых походов вдругой сервис, мы придумали запрашивать данные дляобласти внесколько раз больше, чем реально отображаемая область. Будем называть её большой областью. Приэтом дляразных уровней зума мы установили разный коэффициент. Например, дляуровня, когда отображается вся Россия, это 4, а максимальное значение равно 25.


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



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


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


Время жизни разных запросов вRedis отличается. Дляшироких и популярных запросов, например, повсей России безфильтров, оно больше, чем длязапросов сузкими фильтрами. Кроме долгого кэша вRedis есть быстрый кэш непопулярных запросов вin-memory. Он позволяет уменьшить нагрузку насеть и освободить место вRedis.


Поскольку наш сервис горизонтально масштабирован и поднят нанескольких десятках подов, важно, чтобы параллельные запросы отодного пользователя попали наодин под. Тогда мы можем взять эти данные изin-memory cache пода, и не хранить одну и ту же большую область наразных подах. Этот механизм называется стики-сессиями. Насхеме его можно представить так:



Сейчас среднее время ответа запроса тайла на99перцентиле составляет ~140ms. То есть 99% измеряемых запросов выполняются за это или меньшее время. Длясравнения: вреализации черезкластеры запрос выполнялся ~230ms натом же перцентиле.


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



Итак, мы решили проблему сотрисовкой большого числа объектов накарте. Осталось разобраться синтерактивностью.


Кликабельность, ховер и просмотренность точек


Кликабельность. Самой критичной длянас была кликабельность, поэтому мы начали снеё. Врамках ресёрча мы сделали простое решение отправку запроса скоординатами набэк, бэк проверял, есть ли вкэше объявления поэтим координатам срадиусом 50метров. Если объявление находилось, рисовался пин. Если вкэше не было данных по области, вкоторой находились координаты, то есть истекло время хранения кэша, бэк запрашивал данные изсервиса поиска. Это решение оказалось нестабильным иногда пин рисовался втом месте, где не было точки как объекта накарте. Так происходило потому, что кэш набэке протухал, и появлялись новые объявления данные расходились стем, что есть накарте.


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



Ховер. Идея присылать данные нафронт отлично решала также проблему ховера мы могли подписаться насобытие движения мыши покарте и проверять, попадают ли координаты курсора врадиус какой-то източек, что нам прислал бэкенд. Если совпадения найдены, рисуется красная точка накарте. Понашему опыту даже для10 тысяччерез forEach точек это выглядит нормально.



Просмотренность. Просмотренность пинов накарте уже была реализована наклиенте. Мы хранили вlocalStorage стек из1000id объявлений. Ids вытеснялись более свежими, которые были просмотрены позже других. Бэкенд ничего не знал пропросмотренные объявления, отдавал одинаковые данные всем пользователям, а клиент делал пин просмотренным наосновании данных изlocalStorage.


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


Поскольку запросы затайлами и запрос запинами и точками независимые, иногда мы можем видеть небольшой лаг вокрашивании точек вбледно-голубой. Тайлы обычно приходят раньше ответа запроса поточкам/пинам, и соответветственно, сначала мы увидим все синие точки, а потом нарисуем просмотренные точки как объекты. Сейчас длянас это не выглядит критичным моментом.


В целевом состоянии мы планируем перевести хранение просмотренных объявлений набэкенд и обогащать данные наэтапе рисования svg и формирования ответа запроса запинами. Тогда тайлы будут рисоваться сразу сбледно-голубыми точками.



Просмотренный пин выделен бледно-голубым



Просмотренная точка выделена бледно-голубым


Заключение


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

Подробнее..

Из песочницы Геомаркетинг как инструмент повышения качества проектов

09.11.2020 02:23:12 | Автор: admin

*Меня зовут Алексей Козыкин, я работаю в департаменте аналитических решений КОРУС Консалтинг, где мы реализовываем проекты по управлению данными и геомаркетинговому анализу. Геоданные способны дать дополнительную информацию о ваших клиентах и пользователях и объяснить отклонения. Но есть предубеждение, что использование пространственных данных сопряжено с высокой технической подготовкой и огромными трудозатратами, поэтому проекты по их сбору и использованию часто не выходят за рамки пилотного проекта.


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


Что такое геомаркетинговый анализ


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


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


  • Анализ эффективности размещения объекта
    Базовый алгоритм определяет влияние социально-экономических процессов в районе на KPI объекта. Если он изменяется в зависимости от расстояния между ними, то можно определить, насколько оптимально размещен данный объект.
  • Кластеризация объектов
    Часто объекты объединяют для дальнейшего анализа по схожим показателям или внутренней специфике; геоданные улучшают эту группировку, добавляя в число характеристик внешние процессы. Чем лучше кластеризация, тем эффективнее ассортиментное планирование, прогнозирование продаж, маркетинг и другие активности.
  • Оценка конкуренции
    Инструмент позволяет понять, какой процент вашей целевой аудитории забирают к себе ваши конкуренты. На основе полученных данных можно построить модель пространственной дифференциации Хотеллинга, оптимизировать цены на продукты.
  • Выявление трафикообразующих полигонов
    Как и в задаче анализа эффективности размещения, алгоритм определяет показатели влияния различных типов зданий и достопримечательностей на деятельность объектов. При этом можно получить дополнительную информацию о целевой аудитории (например, как она сформировалась в данном районе или что ей интересно рядом с вашим объектом).
  • Сегментация целевой аудитории
    Часто компании разделяют своих клиентов на группы для более качественной работы с ними. Для них можно создать персональные рекомендации, улучшать сервис, выявлять потребности, предсказывать отток и многое другое. Для этого используются данные, полученные внутри торговой точки: историю покупок, персональные данные участников программы лояльности. Также проводить сегментацию целевой аудитории можно с помощью геоданных. Вероятностные модели позволяют определить финансовые возможности клиентов, демографическую сегментацию и многое другое.
  • Определение оптимального ассортимента и/или формата объекта
    Геоданные помогают охарактеризовать вашу целевую аудиторию в конкретном районе с точки зрения демографии, социальных и духовных потребностей, финансовых возможностей и так далее. Это позволяет качественнее выстроить стратегию продаж.
  • Прогноз размера целевой аудитории
    Вышеуказанные инструменты позволяют построить вероятностные модели посещения магазина. Имея множество характеристик районов и торговых точек, можно определить размер целевой аудитории на основе сравнения этих характеристик для нового района или на основе модели Хаффа.
  • Определение каналов коммуникации с целевой аудиторией
    Геоплатформы собирают данные о поисковых запросах определенных товаров и услуг с привязкой к местности это упрощает поиск каналов коммуникаций с клиентами.
  • Прогнозирование объёмов продаж товаров/услуг
    Перечисленные инструменты наполняют модели прогнозирования дополнительной информацией, позволяя более обоснованно агрегировать продажи товаров в разных магазинах, определять предельный спрос и многое другое. Это дает полноценную информацию о распределении временных рядов продаж и улучшает качество прогнозов.
  • Оценка скорости экспансии
    Как и при анализе эффективности размещения, модель определяет влияние процессов на KPI объекта. В данном случае под KPI понимаются показатели, соответствующие стратегии экспансии компании.

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


Дьявол в деталях: как производится анализ


Шаг первый. Формируем гипотезу и выстраиваем структуру данных


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


Чтобы не довольствоваться усеченными сведениями вне зависимости от выбранной гипотезы необходимо построить базовую структуру данных: найти исследуемые объекты, определить их расположение, название. Для этого используются API ГИС (платные или с открытым доступом например, сервис OpenStreetMap). Платные API обрабатывают запросы быстрее, это их ключевое достоинство. Но некоторые задачи подразумевают сотни тысяч запросов, что увеличивает время поиска.


По набору функций API можно разделить на четыре типа:


  1. Справочник позволяет находить нужную информацию об объектах по заданным параметрам (по наименованию, месторасположению, рубрике, в заданном радиусе и т.д.);
  2. Геокодинг позволяет преобразовывать адреса в координаты и наоборот;
  3. Маршрутизация позволяет найти оптимальный маршрут по заданным параметрам;
  4. Визуализация позволяет использовать графическое представление данных.

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


Шаг второй. Проверяем гипотезы на моделях


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


  • Влияние трафикообразующих объектов (потребителей, поставщиков, кинотеатров, метро и так далее).
  • Модель конкуренции (модель Хотеллинга и аналоги).
  • Модель, определяющая соотношение уникальности предложения конкурента к его доступности.
  • Гравитационная модель притяжения (модель Хаффа или дрeubt модели).
  • Вероятностная модель, предсказывающая приток клиентов в конкретную торговую точку из конкретного полигона.
  • Доступность объектов (пешая, автомобильная).
  • Количество населения в районе.
  • Качество инфраструктуры и элитности района.

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


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


Шаг третий. Уточняем модели


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


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


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


image


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


  • Миграция населения;
  • Средний заработок в районе;
  • Предрасположенность района к увеличению преступности;
  • Предрасположенность к переходу на доставку продуктов;
  • Средний доход в доме;
  • И так далее.

Как запустить в компании геомаркетинг


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


Геомаркетинг дает возможность проверить большое количество гипотез и проследить эффект от использования геоданных на проекте на базе только open source технологий. Для запуска работы на базовом уровне не нужно много денег и ресурсов достаточно начать с появления в штате аналитика и сбора доступной информации. А вот глубокое копание в данных и использование социально-экономических показателей для уточнения моделей ведет к резкому удорожанию проекта за счет стоимости информации из внешних баз насколько вам это необходимо и какой объем средств вы готовы инвестировать в эту задачу, решать вам на основе показателей вашего бизнеса и ваших целей.


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

Подробнее..

Аспекты учета и поиска геоинформационных объектов с задействованием MongoDB

02.04.2021 04:18:46 | Автор: admin

Онлайн-курс:"OTUS.NoSQL".

Проект: https://github.com/BorisPlus/mongodb_geo

Введение

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

Академический подход написания статей подразумевал "сведения, отражающие свойства ... объектов материального мира". Однако на практике имелся факт осуществления энтузиастом накладки поверх Гугл-карт через штатное API рисунков с топографией Средиземья и построение маршрутов героев Дж. Толкина, что не совсем "материально". Другим стыком с нематериальным может служить пример наборов данных по типуGeoIP,E.164,ABC.

Результат исследования представляет собой инструмент отображения хранящихся в MongoDB сведений о геообъектах на карте посредством web-доступа. Клиентская часть реализована с использованиемLeaflet(JavaScript-библиотека с открытым исходным кодом для мобильных интерактивных карт) и набора соответствующих процедур асинхронного получения сведений от серверной части. Сервис разработан на базе созданного ранее на курсе"OTUS.Web-python"конструктора программного обеспечения"Dummy WSGI Framework"(репозиторий) на языке программирования Python3 с задействованием WSGI.

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

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

Гео-объекты MongoDB

В данной статье продемонстрированы базовые возможности оперирования в MongoDB такимигеообъектамикак:точка,линия,полигон.

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

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

<field>: { type: <GeoJSON type> , coordinates: <coordinates> }

В рамках получения сведений клиентской стороной от серверной геообъекты искусственно поделены на два вида - статичные и динамичные.

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

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

Предполагается, что инфраструктура MongoDB развернута.
mongo  192.168.102.99  --port 49326 ---> use otus switched to db otus > db.dropDatabase() { "dropped" : "otus", "ok" : 1 } > use otus switched to db otus > db otus > show collections

Точки (статичные)

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

> db.meteorites.createIndex( { "ident": 1 }, { unique: true } )> db.meteorites.createIndex( { "location" : "2dsphere" } ) 

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

location: { type: 'Point' , coordinates: [ LON, LAT ] }

Загрузка исходных данных о метеоритах:

mongoimport --host 192.168.102.99  --port 49326 \--db otus --collection meteorites --jsonArray \--file ./foreign/meteorites/data.json2021-03-28T10:28:09.443+0300    connected to: mongodb://192.168.102.99:49326/2021-03-28T10:28:12.443+0300    [<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"><span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);">#</span>##.....................] otus.meteorites      1.62MB/10.1MB (16.0%)</span>2021-03-28T10:28:15.443+0300    [<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"><span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);">#</span>########...............] otus.meteorites      3.97MB/10.1MB (39.4%)</span>2021-03-28T10:28:18.443+0300    [<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"><span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);">#</span>###########............] otus.meteorites      5.39MB/10.1MB (53.4%)</span>2021-03-28T10:28:21.443+0300    [<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"><span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);">#</span>################.......] otus.meteorites      7.23MB/10.1MB (71.6%)</span>2021-03-28T10:28:24.443+0300    [<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"><span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);">#</span>####################...] otus.meteorites      8.83MB/10.1MB (87.5%)</span>2021-03-28T10:28:27.443+0300    [<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"><span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);">#</span>######################.] otus.meteorites      9.71MB/10.1MB (96.3%)</span>2021-03-28T10:28:28.453+0300    [<span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);"><span class="pl-c" style="box-sizing: border-box; color: var(--color-prettylights-syntax-comment);">#</span>#######################] otus.meteorites      10.1MB/10.1MB (100.0%)</span>2021-03-28T10:28:28.454+0300    45716 document(s) imported successfully. 0 document(s) failed to import.

Исходя из уже имеющегося опыта, из набора 45716 объектов необходимо удалить метеорит, который не относится к земной поверхности (марсианский метеоритMeridiani Planum), так как его координаты не соответствуют стандарту земного геопозиционирования и не могут быть помещены в индекс (индексирование приводит к ошибкеCan't extract geo keys: ... longitude/latitude is out of bounds, ..., равно как и вставка таких данных в индекс).

db.meteorites.remove({"ident" : "32789"});

Кроме этого в наборе имеется 7315 метеоритов, чье местоположение не известно. Данный факт также не позволит включить их в гео-индекс и приведет к ошибке. Поэтому в индексе учтены только те метеориты, чье местоположение известно.

db.meteorites.updateMany(     {"geolocation":{$exists:true}},    [{        $set: {            "location" : {                "type": "Point",                "coordinates" : [                     { $toDouble: "$geolocation.longitude" } ,                     { $toDouble: "$geolocation.latitude" }                 ]            }        }    }]);

В результате в MongoDB в коллекцииmeteoritesв атрибутахlocationсодержится информация о местоположении 38400 метеоритах из их общего числа 45716.

Важное замечание:согласнодокументацииданный порядок следования координат{ долгота, широта }является единственно верным с точки зрения MongoDB (If specifying latitude and longitude coordinates, list the longitude first and then latitude). Необходимо заострить внимание на этом обстоятельстве, так как в последующем при отображении информации на карте Leaflet нужен будет другойпорядокабсолютно для всех координат любых геообъектов -{ широта, долгота }. Указанное приводит к тому, что после получения сведений из MongoDB требуется произвести перестановку в парах координат или представить их в виде "словаря"{ lon: долгота, lat: широта }. Если для точки это выражается в одной перестановке, то для полигона это происходит в рамках итерации по точкам границы. Было бы хорошо, если бы MongoDB поддерживала хранение и в формате{ широта, долгота }.

Полигоны (статичные)

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

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

Необходимые коллекция, поля и индексы:

db.geo_wikimapia_polygons.createIndex( { "ident": 1 }, { unique: true } )db.geo_wikimapia_polygons.createIndex( { "area" : "2dsphere" } ) 

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

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

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

area: { type: 'Polygon' , coordinates: [[ [LON_1, LAT_1], [LON_2, LAT_2], ..., [LON_1, LAT_1] ]] }

В результате запросов к WikiMapia:

python3 ./foreign/onetime_static_load_polygons_wikimapia.py Page 1 has docs count 50Page 2 has docs count 50...Page 37 has docs count 35Max page 37 with some data

в MongoDB накоплена информация в отношении:

> db.geo_wikimapia_polygons.count()

1832 зданий и сооружений.

Важное замечание: в MongoDB сведения о полигоне должны удовлетворять спецификации (пункт 3.1.6 RFC 7946 "GeoJSON" August 2016). В частности, полигон, имеющий пересечение граней, не может быть добавлен (иначе в MongoDB возникает ошибкаEdges <number K> and <number M> cross. Edge locations in degrees: [Kx1, Ky1]-[Kx2, Ky2] and [Mx1, My1]-[Mx2,My2]). Кроме того, важно, чтобы полигон был "замкнут", то есть крайняя точка должна совпадать и первоначальной (иначе в MongoDB возникает ошибкаLoop is not closed). WikiMapia же иным образом подходит к требованиям достоверности координат. Поэтому из 1835 полигонов, полученных в описанном ранее абзаце (36 страниц * 50 полигонов + 35 полигонов = 1835 полигонов), сохранены 1832 объекта.

Линии (динамичные)

В качестве демонстрационных динамичных геообъектов выбранылиниии точки, отражающие крайние части маршрутов и фактическое пребывание автомобилей таксопарка компании "Яндекс" соответственно.

Важное замечание: сведения о линии должны удовлетворять спецификации (пункт 3.1.4 RFC 7946 "GeoJSON" August 2016), то есть линия должна содержать две разные точки (при этом она может также содержать и одинаковые).

Сбор демонстрационных данныхреализованна языке программирования Python3 с использованием библиотекrequests,pymongoи задействованием пакета многопроцессорной обработкиmultiprocessing. Необходимость крайнего обусловлена требованиями увеличения скорости получения актуальных сведений о местоположении и пути следования автомобилей с целью повышения эффективности частоты прорисовки маршрутов на карте (максимизации интерактивности). Сведения получаются в отношении заранее определенных точек района г. Санкт-Петербурга. Точки сбора данной информации располагаются на определенном коротком расстоянии друг от друга и образуют заранее рассчитанную в проекте "ячеистую" структуру. Данный подход отличается оталгоритма "заливки", применявшегося иным разработчиком, исследовавшим подобную информацию ранее.

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

Изначально сведения о маршруте не имеют необходимой MongoDB структуры для геообъекта типа "линия". Поэтому в качестве данного атрибута выступает дополнительное полеpath, куда перенесены сведения в необходимом формате. Структура геообъекта типалинияимеет вид:

path: { type: 'LineString' , coordinates: [ [LON_1, LAT_1], [LON_2, LAT_2], ..., [LON_N, LAT_N] ] }

Операции с геообъектами

В рамках работы рассматриваются такиеоперациикак:$geoIntersectsи$nearSphere.

Операция$geoIntersectsявляется основной реализованной в проекте и используется для нахождения всех геообъектов, имеющих пересечение по георасположению с текущей областью карты. Например, если в область карты (соответствующий полигон, описываемый двумя крайними диаметрально расположенными координатами) попадет часть маршрута (линии) или часть здания (полигона), то они будут получены из базы данных и отображены на карте. Точки, соответственно, появятся при их попадании в данную область.

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

Использование иной операции$nearSphereпродемонстрировано на примере выборки из MongoDb полигонов и метеоритов с целью отображения их на карте только при условии присутствия их в "круговой" окрестности наблюдения (для полигона - пересечение с окружностью).

Операции$geoWithin(выборка геообъектов, имеющих полное включение в заданную область) и$near(выборка геообъектов в окрестности точки) в рамках настоящей работы не рассматриваются.

Операции$nearи$nearSphereшире по возможности, чем просто "нахождение в круговой окрестности", так как описывают не только максимальное удаление ($maxDistance) от точки наблюдения, но и минимальное ($minDistance). Данное обстоятельство может быть использовано при работе с секторами, учитывающими "примерное" удаление объектов от исходной точки наблюдения: секторное поле зрения на панораме "Яндекс.Карты", "классические" области действия сотовых вышек, углы обзора видеокамер городского наружного наблюдения и иное.

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

Сервис реализован на базе авторского конструктора программного Web-обеспечения"Dummy WSGI Framework"(репозиторий), является легковесным (около 45 килобайт кода).

pip3 install -r ./service/requirements.txtuwsgi --http 127.0.0.1:8080 --wsgi-file ./service/application.py

Обстановка в области карты

По адресуhttp://127.0.0.1:8080вниманию представлен район г. Санкт-Петербурга, где отображены полигоны зданий. По мере перемещения по карте или изменении масштаба карты в асинхронном режиме подгружаются иные полигоны.

Разработчикам на заметку: для записи GIF-анимации использовалось программное обеспечениеPeek.

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

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

Очередным открытием в данных NASA явилось наличие 64 метеоритов, местоположения падения которых имеют абсолютно одинаковые координаты. Указанное обнаружено в результате визуального изучения метеоритов на карте (выделяющаяся темная тень).

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

> db.meteorites.find({"location.coordinates": [13.43333,58.58333] }).count()    64> db.meteorites.find({"location.coordinates": [13.43333,58.58333] }, {name: 1, _id: 0})    { "name" : "Osterplana" }    { "name" : "sterplana 002" }    { "name" : "sterplana 003" }    ...    { "name" : "sterplana 064" }

Данные "необычные" сведения соответствуют метеориту "sterplana", имеющему удивительнуюисторию(рус.).

Для интерактивной демонстрации динамичных геообъектов необходима следующая коллекция:

db.geo_yandex_taxi.deleteMany({})db.geo_yandex_taxi.createIndex( { "ident": 1 }, { unique: true } )db.geo_yandex_taxi.createIndex( { "last_point" : "2dsphere" } )db.geo_yandex_taxi.createIndex( { "path" : "2dsphere" } )

и фоновый сбор актуальных данных:

python3 ./foreign/upsert_yandex_taxi_loop.py 9       2.61409401893615729       2.4818162918090829       2.5282382965087899       2.3746058940887459       2.53371548652648939       2.72976160049438489       2.605773925781259       2.5869448184967049       2.5660433769226074

Исходные сведения о перемещении таксопарка "Яндекс" обезличены и содержат крайние точки пройденных маршрутов:

{'id': 'bcc095db8e3b56e057caebdb97af5694', 'display_tariff': 'business', 'free': True, 'static_icon': False, 'positions': [{'lon': 30.326291, 'lat': 59.974395, 'direction': 50.0, 'timestamp': '2021-03-24T23:49:01.000000+0000'}, {'lon': 30.326291, 'lat': 59.974395, 'direction': 50.0, 'timestamp': '2021-03-24T23:48:52.000000+0000'}, {'lon': 30.326291, 'lat': 59.974395, 'direction': 50.0, 'timestamp': '2021-03-24T23:48:43.000000+0000'}, {'lon': 30.326291, 'lat': 59.974395, 'direction': 50.0, 'timestamp': '2021-03-24T23:48:34.000000+0000'}]}

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

На их основании сформированы линия перемещения и точка крайнего местоположения.

Помимо мониторинга на предмет появления нового динамичного объекта в текущей области карты системой осуществляется проверка покидания объектами ее границ. В ином бы случае движущиеся объекты останавливались и скапливались по краям карты (в случае работы подобного сервиса с "подконтрольными" сведениями необходимость в данной особенности полностью отсутствует).

Обстановка в области круговой окрестности

По адресуhttp://localhost:8080/circle/продемонстрирована выборка только тех геообъектов, которые попадают в круговую окрестность, располагаемую по центру карты.

Важное замечание: с целью использованияnearиnearSphereтребуется создать индекс2dили2dsphere, иначе их вызов приведет к ошибке исполнения:

error processing query: ns=otus.geo_wikimapia_polygonsTree: GEONEAR  field=area maxdist=500 isNearSphere=0Sort: {}Proj: { _id: 0 } planner returned error :: caused by :: unable to find index for $geoNear query, full error: {'ok': 0.0, 'errmsg': 'error processing query: ns=otus.geo_wikimapia_polygonsTree: GEONEAR  field=area maxdist=500 isNearSphere=0\nSort: {}\nProj: { _id: 0 }\n planner returned error :: caused by :: unable to find index for $geoNear query', 'code': 291, 'codeName': 'NoQueryExecutionPlans'}

Технические особенности реализации

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

Конфигурационный файл

Параметр конфигурации сервисаbase_config.pyсодержит отсылку на вид ("статичный", "динамичный"), название коллекции базы MongoDB ("meteorites", "geo_wikimapia_polygons", "geo_yandex_taxi") и атрибуты ("location", "area", "last_point", "path"), содержащие сведения о геообъектах с указанием их GeoJSON-типа ("Point", "LineString", "Polygon"), а именно:

...MONGODB_DB_COLLECTIONS = dict(    static={        "meteorites": {            "location": POINT_OBJECT,        },        "geo_wikimapia_polygons": {            "area": POLYGON_OBJECT,        },    },    dynamic={        "geo_yandex_taxi": {            "last_point": POINT_OBJECT,            "path": LINE_STRING_OBJECT,        },    },)...

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

При отсутствии в конфигурации динамичной коллекции, генерируемая сервисом HTML-страница не содержит инструкцию на JavaScript, осуществляющую периодический запрос сведений при неизменной локации. Указанное устраняет излишнюю нагрузку на серверную часть сервиса.

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

"Ненагружающий" запоздалый AJAX запрос

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

 function get_data(...){    ...    if (xhr && !(xhr.readyState === 4)) {        xhr.abort();        console.log('Previous AJAX #' + xhr.__dt + ' was aborted');    }    clearTimeout(timer);    xhr = new XMLHttpRequest();    xhr.responseType = 'json';    xhr.__dt = Date.now();    console.log('Start AJAX #' + xhr.__dt);    timer = setTimeout(function() {        // find objects in area.    }}

Демонстрация работы по старту и прерыванию AJAX-запросов доступна в консоли web-браузера при включении в нем режима "отладки" (F12).

Направления работы

Соответствие координат

MongoDB использует систему координат WGS84 (MongoDB geospatial queries on GeoJSON objects calculate on a sphere; MongoDB uses the WGS84 reference system for geospatial queries on GeoJSON objects) (поиск вглоссариислова "wgs84").

При этом Leaflet по-умолчанию использует систему координат EPSG 3857.

Исходя из описания,EPSG 3857допустима для координат между85.06Sи85.06N.

То есть в рамках рабочей эксплуатации необходимо в Leaflet установить параметр CRS равным"L.CRS.EPSG4326", посколькуонне имеет таких ограничений и целиком соответствует системе геокодирования MongoDB.

Запредельные координаты

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

pymongo.errors.OperationFailure: longitude/latitude is out of bounds, lng: 561.213 lat: 89.9823 ... Valid longitude values are between -180 and 180, both inclusive.Valid latitude values are between -90 and 90, both inclusive.

Данный момент возможно решить, если проводить "нормирование" запрашиваемой области (операции по типу остатка от деления, поиск соответствия "нормальному" двумерному "интервалу"), а при отображении на карте - "денормирование" координат полученных геообъектов (в зависимости от смещения относительно них периметра карты).

-тестирование

В рамках работы не рассматривались вопросы шардирования сведений о геообъектах (операции ихподдерживают в MongoDBу версий выше 4.0) и не исследовалась отдача при нагрузке.

Расширение числа источников

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

Выводы

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

Вместо заключения

Лучше один раз увидеть, чем сто раз услышать.

Отдельные участки поражают изобилием метеоритов, особенно в сравнении с "соседними".

Спасибо курсам"OTUS" ("OTUS.Web-python" 2018 и "OTUS.NoSQL" 2020)за приобретенный опыт Fullstack-разработки (в частности интеграции Python, Javascript и MongoDB).

Подробнее..
Категории: Python , Otus , Mongodb , Maps api , Leaflet

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru