Pull to refresh

Comments 51

Точки 0;89 и 180;89. Какое будет расстояние?

180

вопрос не праздный, на Чукотке будет косяк )

Остров Врангеля лежит в трёх полушариях…

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

ЕМНИП там есть способы всё это решить

Вообще впервые услышал о нем. Теперь почитал, да интересная штука, на будущее буду иметь ввиду. Вот это конструктивно и по делу, спасибо!

PostGIS тут как из пушки по воробьям)

Тут достаточно расширения earthdistance или cube или чисто gist (point_ops). Ещё и индексы будут работать эффективно, а не как у автора.

Вы очень сильно путаете радиусы с диаметрами.

Интересно, а как формулировалась задача? Зачем нужен вообще "радиус 20км" в недвижимости? Я понимаю -- "в получасе езды на машине", а какой смысл вкладывается в дистанцию 20 км?

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

Реальную удаленность отлично считает любой картографический сервис: Яндекс, Google, MapBox

А теперь попробуйте 100500 объектов. И вы сразу поймете, что нужно уметь это делать самому, а не рассчитывать на какой-то там условно бесплатный чужой REST где-то в облаке. Это задача построения маршрута, и да, она сложная.

И дело не только в вычислениях - радиус прост для понимания и представления. А якобы "реальная" удаленность вызывает у стороннего наблюдателя кучу вопросов по методике её подсчета.

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

И кстати, подсчет расстояний обычно сводится к построению некоей эквидистанты, куда можно добраться за 5 минут пешком. И на станциях метро Москвы эквидистанты показывают именно как круг — и в общем для пеших перемещений это близко к реальности (если нет железной дороги или реки). Но если нарисовать любую другую кривую — никаких вопросов это не вызывает (в моей практике, разумеется). Т.е. вопросы к методике — это в какой-то степени вопрос отображения.

Это прям какое-то "горе от ума" и усложнение на ровном месте.

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

Но если говорить от недвижимости, то почти никогда такого однозначного центра отсчета нет. Люди смотрят примерный район, который им нравится. Обычно это либо малоконкретный ориентир (район улицы такой-то), либо скорее даже полурандомная точка, ткнутая на карте. И никто не подразумевает, что "меня интересуют маршруты из/до неё" - имеется в виду "ну где-то примерно тут, покажите что у вас есть в округе". А все поправки на реки и определенные виды транспорта юзеру проще сделать самостоятельно.

>когда есть конкретная точка, от которой нужно вести отсчёт — то есть в логистических задачах.
Ну в общем да, я согласен. Я скорее о другом — радиусы и эквидистанты не взаимозаменяемы, ну или не всегда. И не всегда эквидистанты сложны для понимания, как вы изначально выразились. Я в основном про это.

>Но если говорить от недвижимости, то почти никогда такого однозначного центра отсчета нет.
Расстояние до метро (там где есть) — это именно что не радиус, а скорее даже время в пути. Так что эта точка — в какой-то степени ближайшая станция. Ну т.е. опять же — мне кажется истина где-то посредине. Наверное есть случаи, когда центра нет, и такие где он есть.

Это, конечно, полезные знания, но на практике не проще ли было выбрать БД которая поддерживает гео-запросы? Точно знаю что есть в mongo, и, емнип, в postgre.

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

как раз сам хотел сказать что в задачи "недвижимости" - погрешность в 1км на 20ти это никто не заметит. такую задачу точно решать вообще смысла нет. а если решать грубо - то широта и долгота становятся X и Y осями просто на плоскости и задача сводится к треугольнику.

 широта и долгота становятся X и Y осями просто на плоскости

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

Есть формулы преобразования геодезических координат в координаты в прямоугольной проекции (их много, но, насколько помню, сейчас достаточно распространена прямоугольная проекция Меркатора — всякие OSM работают именно с ней).

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

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

Большая полуось эллипсоида WGS84: a = 6378137.0 м
Малая полуось эллипсоида WGS84: b = 6356752.3142 м
lon/lat — долгота/широта в радианах
e — эксцентриситет эллипса

image

для эллипсоида WGS84 e = 0.08181919

Прямоугольные координаты (в метрах от точки пересечения экватора с гринвичским меридианом):

image

image

Реализовать пересчет WGS84 -> Меркатор на уровне UDF не вижу проблем.
полная чушь
прямоугольная проекция Меркатора

это что за зверь?

Прямоугольные координаты (в метрах от точки пересечения экватора с гринвичским меридианом):

при чём тут гринвический мередиан?

Реализовать пересчет WGS84 -> Меркатор на уровне UDF

postgis.net/docs/ST_Transform.html
Проекция Меркатора обладает свойством равноугольная, поэтому искажения расстояний в ней так же присутствует.

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

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

UFO just landed and posted this here
UFO just landed and posted this here

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

В моем варианте с координатами меркатора получите следующее:

select B.* from MyTable A
join MyTable B on (B.X between A.X - 20000 and A.X + 20000) and
                      (B.Y between A.Y - 20000 and B.Y + 20000)
where A.X = ? and A.Y = ?


Эта выборка даст вам все объекты в квадрате 20км от заданных координат.
Чтобы получить круг, надо так:

select B.* from MyTable A
join MyTable B on sqrt((A.X - B.X) * (A.X - B.X) + (A.Y - B.Y) * (A.Y - B.Y)) <= 20000
where A.X = ? and A.Y = ?


Это даст все объекты на расстоянии 20км от заданного (вместо A.X =? and A.Y =? можно прямо A.Name =? — задаете имя и получаете список объектов в радиусе 20км от него)

На IBM DB2 for i такая конструкция работает — проверял.

Вам остается только реализовать преобразование lon -> X и lat -> Y и хранить в таблице кроме lat, lon еще соответсnвующие им X, Y
20000 в меркаторе — это не 20км на реальной земле. На уровне Москвы вы получите ~30 километра вместо желающих 20.
Тут не могу сказать порядок погрешности. Что она будет — точно. Но сомневаюсь что проекция с такими искажениями на таком удалении от полюсов прижилась бы.
Проекция используется в картографии, в том числе и в масштабных топокартах. Так что не думаю, что на таких расстояниях такие сильные искажения.

Можно, конечно, использовать Гаусса-Крюгера для СК42 (используемых для старых карт ГШ). Но там будут определенные проблемы с зонами которые придется учитывать.

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

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

Искажение расстояний существенны, наверное у нас специально не принято демонстрировать Россию на уровне экватора, чтобы патриоты не расстраивались. Искажения настолько большие, что карту ограничивают 80 параллелью, а в самом полюсе масштаб искажений бесконечность. Собственно коэффициент увеличения обратно пропорционален косинусу широты и на уровне Москвы увеличивает в 1.7 раза

А вы проверьте численно.

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

На небольших участках (пара сотен километров) в средних широтах - искажения не слишком заметны, участок поверхности слабо отличим от плоскости. Соответственно, на таких картах можно один раз посчитать (1км поверхности = 1см карты) и пользоваться во всех направлениях.

Если же сделать карту всей земли - то 1см в районе полюса и на экваторе будут различаться очень сильно. Соответственно, прежде чем отвечать "есть ли тут 20км расстояния" нужно ответить "какова длина одного километра поверхности в сантиметрах карты на нужной широте"

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

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

Для начала нужно учитывать не расстояние по координатам, а расстояние построенного маршрута. Еще лучше время в пути. У меня от работы до дома 18 км, но первые 12 км я проезжаю за 7 минут, а остальные 6 км за 13 минут. А есть поселок дальше по шоссе до него все 23 км, но ехать всего 15 минут.

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

В целом, в вашем методе есть еще один очень важный просчет: вы вычисляете не попадание точки в окружность (ибо окружность это 2д фигура, а вы работаете с 3д координатами), а попадание в шаровой сегмент, который образуется пересечением конуса и геоида. Конус при этом лежит в центре Земли и именно его параметры вы вычисляете, переводя «градусы в километры». Сегмент с увеличением радиуса будет иметь все большую кривизну и решение задачи «в радиусе N км» будет все менее точным.
Более точным путем будет переход другим геодезические проекциям, где можно будет применить другие формулы, вплоть евклидового расстояния. Но для этого придется преобразовывать еще и все координаты городов. Почитайте о преобразованиях тут.
За что минусуют? За то, что не взял готовое, а разобрался и написал сам?

Это НЛО боты) Они всех минусуют, чтобы рекламу не мог отключить)

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

Я не в коем случае и не говорил, что это лучшее решение моей задачи, но это было лучшее из того, что я нашел

Жертва ЕГЭ открыла для себя косинус и с восторгом решила поделиться этим открытием с миром. Скоро на Хабре будут статьи про определение расстояния на прямоугольной сетке координат, про теорему Пифагора?

  1. ЕГЭ я никогда не сдавал

  2. С геометрией у меня реально все плохо

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

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

Мы вычисляем дельту ширины и долготы одинаково по одной и той же формуле, поскольку мы условились что у нас идеальный шар и эта погрешность нам допустима.

Но дельта по долготе зависит от широты, а дельта по широте от долготы не зависит — длина всех меридианов одинакова. Значит, при её расчёте на косинус умножать не нужно. Для Ваших координат у меня получилось 0.17985935 и 0.31722869 соответственно.
UFO just landed and posted this here

Нет, не знаете :)

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

UFO just landed and posted this here

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

Заминусовали, спасибо! Буду знать, что есть способы лучше, но по честному 31 закладка на момент написания этого комментария говорит о том, что полезная эта статья гораздо больше, чем хейта под ней, просто те кто делает закладки, не все могут ставить плюсы и минусы. Но я для себя понимаю, что статья все-таки полезная, пусть в ней и много недочетов

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

Тригонометрия то была. Но как то нам так преподавали, что мы вообще никто не понимал, зачем эти синусы, косинусы и тангенсы. Для чего они были придуманы кроме как осложнить жизнь школьника. И уже только в институте стало понятно зачем, там получше объяснили и на каких-то примерах показали. А в школе это был сферический конь в вакууме, в которого мы должны были верить, что так надо и всё. Не помню чтобы в школе мы вычисляли расстояния между точками на шаре или что-то подобное, даже знания о меридианах и параллелях возникло из георгафии, а не из геометрии. Не помню чтобы мы когда либо изображали шар и что-то считали. Может в качестве чисто формул и рассчитывали, но без изображений шаров, это все просто вылетело из головы как страшный сон

UFO just landed and posted this here
Sign up to leave a comment.

Articles