- PVSM.RU - https://www.pvsm.ru -
Идея про небольшой стартап пришла в голову когда я в очередной раз застрял на Переделкинском переезде объезжая стоячую пробку на МКАДе. На этот раз все было очень плохо, шлагбаум не открывался минут по 20. Мысль пришла вполне логичная: почему бы не сделать микросайт, где можно было бы глянуть когда на этот проклятый переезд лучше не соваться. Получился типичный гео-сервис. При разработке были решены стандартные, для такого рода сервисов, задачи. Надеюсь, эта статья сэкономит время тем, кто столкнется с внедрением гео-функций в свой проект.
Список типичных задач:
На первый взгляд, задача не такая сложная: теорему Пифагора все помнят со школы. Но есть одна проблема: существует мнение, что Земля не совсем плоская, а местами даже шарообразная и, ко всему этому, еще и крутится. Поэтому, работает такая формула:
dist = 6372797*acos(sin(PI*Lt1/180)*sin(PI*Lt2/180)+ cos(PI*Lt1/180)* cos(PI*Lt2/180)* cos(abs(PI*Lg2/180- PI*Lg1/180))) где: Lt1, Lg1 – широта/долгота первой точки Lt2, Lg2 – широта/долгота второй точки PI – PI
Точной магии, почему эта формула работает никто не знает, но результат очень близок к тому, что отмеряет линейка Яндекс-карт.
Люди в 21м веке стали ленивыми и если ваш сервис не покажет нужных пользователю объектов в радиусе Х метров от того места где он находится, он обязательно уйдет на сервис конкурентов.
Приведу рецепт гео-поиска по базе MongoDB. Прежде всего, нужно произвести несколько подготовительных действий:
Команда создания 2d-индекса выглядит так:
db.<collection>.ensureIndex( { <location field> : "2d" })
Теперь можно поискать ближайшие точки к заданной:
db.<collection>.find( { <location field> : {$near: [lt, lg], $maxDistance: 5} })
Сам по-себе запрос не сложный, нуждается в разъяснении только параметр про максимальную дистанцию. К сожалению, она измеряется не в метрах/километрах/милях, а в мало-понятных радианах. Дело осложняется, как уже было сказано выше, шарообразностью нашей планеты. Строго говоря, количество метров в одном радиане разное на разных широтах. Чем выше широта, тем метров в радиане меньше. К счастью, в большинстве задач поиска близлежащих объектов особой точности не требуется и можно пользоваться примерными коэффициентами. Для наших широт, если ищем в километрах, исходное значение радиуса поиска нужно делить на 111.
Например, ищем все точки в радиусе 5км:
db.<collection>.find( { <location field> : {$near: [lt, lg], $maxDistance: (5/111)} })
С этим все стало просто благодаря HTML5. Если отбросить всякое броузерное старье и упрямых животных, для определения текущего положения пользователя достаточно нескольких строк кода:
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(pos) {
var Coords = [pos.coords.latitude, pos.coords.longitude]
},null,{timeout:60000})
}
… и согласия пользователя, что бы его посчитали.
Надеюсь, эта заметка поможет кому-нибудь создать свой гео-шедевр, а упомянутый в начале статьи микросайт [1], проезжать без пробок через переезды.
Полезные ссылки:
Автор: kolbaskinmax
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/mongodb/57790
Ссылки в тексте:
[1] упомянутый в начале статьи микросайт: http://crossings.ru
[2] Занимательная геодезия: http://habrahabr.ru/post/143898/
[3] Источник: http://habrahabr.ru/post/216569/
Нажмите здесь для печати.