Как сгруппировать «близкие» друг к другу точки широты и долготы?

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

Сначала казалось, что я могу просто группировать по строкам, которые имеют одинаковую широту / долготу для первых трех десятичных знаков (примерно прямоугольник 300x300, понимая, что он меняется по мере удаления от экватора).

Однако этого метода, похоже, совсем не хватает. «Близость» не может существенно отличаться от расстояния, которое представляет каждый десятичный знак. При этом не учитывается, что два местоположения могут иметь разные цифры в третьем (или любом) десятичном разряде, но все же находиться в пределах расстояния, которое представляет это место (33.1239 и 33.1240).

Я также обдумывал ситуацию, когда точка A и точка C находятся «близко» к точке B (но не друг к другу) - должны ли они быть сгруппированы вместе? Если да, то что происходит, когда точка D находится «близко» к точке C (и нет других точек) - следует ли ее также сгруппировать. Конечно, я должен определить желаемое поведение, но как это реализовать?

Может ли кто-нибудь указать мне в правильном направлении, как это можно сделать и какие различные методы / подходы можно использовать?

Мне кажется, что я упускаю что-то очевидное.

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


person Tim Lytle    schedule 03.12.2010    source источник
comment
возможно, здесь есть информация: en.wikipedia.org/wiki/Geodatabase   -  person Stéphane    schedule 03.12.2010
comment
нет. Никто не сможет указать вам правильное направление, если вы не объясните, в чем заключаются ваши цели. почему вы хотите сгруппировать точки?   -  person Unreason    schedule 03.12.2010
comment
@Unreason - немного подробнее, точки представляют пользователей, которые «помечают» определенные местоположения, предполагается, что если несколько пользователей отметили местоположение, которое находится рядом друг с другом, оно должно учитываться только как одно местоположение. Однако заявленная цель группировки точек широты и долготы, находящихся в пределах ~ 500 футов друг от друга, кажется довольно конкретной и уже дала информативные ответы.   -  person Tim Lytle    schedule 03.12.2010
comment
@TimLytle, ты можешь сказать мне, как ты наконец решил свою проблему?   -  person zeus    schedule 27.03.2018


Ответы (5)


Существует несколько способов определения расстояния между двумя точками, но для построения точек на двухмерном графике вам, вероятно, понадобится Евклидово расстояние. Если (x1, y1) представляет вашу первую точку, а (x2, y2) - вторую, расстояние равно

d = sqrt( (x2-x1)^2 + (y2-y1)^2 )

Что касается группировки, вы можете использовать какое-то двумерное средство, чтобы определить, насколько «близки» объекты друг к другу. Например, если у вас есть три точки, (x1, y1), (x2, y2), (x3, y3), вы можете найти центр этих трех точек простым усреднением:

x(mean) = (x1+x2+x3)/3
y(mean) = (y1+y2+y3)/3

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


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

person eykanal    schedule 03.12.2010
comment
Есть идеи, как этот подход к группировке будет реализован с использованием большего количества точек? - person Tim Lytle; 03.12.2010
comment
Да, я надеялся, что вы об этом не спросите :) Существует ряд очень сложных алгоритмов кластеризации, и я обновлю сообщение, чтобы отразить некоторые из них. - person eykanal; 03.12.2010
comment
Расстояние - это только часть истории. Может быть бесконечное количество точек, расположенных на окружности с центром в (0,0) и r = расстояние. И они могут быть очень далеко друг от друга. Также следует определить угол. Конечно, реальным ответом на эту проблему является некоторый алгоритм кластеризации. - person Michał Klimczak; 31.01.2013

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

Например, расширение earthdistance для PostgreSQL работает путем преобразования пар широта / долгота в декартовы координаты (x, y, z), моделируя Землю как однородную сферу. PostgreSQL имеет сложную систему индексирования, которая позволяет индексировать эти координаты или прямоугольники вокруг них в R-деревьях, но вы можете скомпоновать что-то, что по-прежнему полезно и без этого.

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

Если вы хотите найти все точки в пределах X км от некоторой целевой точки, вы генерируете все «имена ящиков» вокруг этой точки (после того, как вы также преобразовали вашу целевую точку в тройку (x, y, z), это легко) и удалите все прямоугольники, которые не пересекают поверхность Земли (хитрость, но использование формулы x^2+y^2+z^2=R^2 в каждом углу скажет вам), вы получите список прямоугольников, в которые могут быть включены целевые точки - так что просто ищите все баллы, соответствующие одному из этих квадратов, что также вернет вам дополнительные баллы. Итак, на заключительном этапе вам нужно рассчитать фактическое расстояние до целевой точки и устранить некоторые (опять же, это можно ускорить, работая в декартовых координатах и ​​преобразовав радиус целевого расстояния по большому кругу в секущее расстояние).

Возникновение сводится к тому, чтобы вам не пришлось искать слишком много ящиков, но в то же время не набирать слишком много дополнительных очков. Я счел полезным индексировать каждую точку на нескольких разных сетках (например, с разрешением 1 км, 5 км, 25 км, 125 км и т. Д.). В идеале вы хотите искать только одно поле, помните, что оно расширяется как минимум до 27, как только ваш целевой радиус превышает размер вашей сетки.

Я использовал этот метод для построения пространственного индекса с помощью Lucene, а не для вычислений в базах данных SQL. Он действительно работает, хотя для его настройки нужно немного возиться, а для генерации индексов требуется время, и они довольно большие. Использование R-дерева для хранения всех координат - гораздо более приятный подход, но для этого потребуется больше настраиваемого кодирования - этот метод в основном просто требует быстрого поиска по хеш-таблице (поэтому, вероятно, он будет хорошо работать со всеми базами данных NoSQL, которые являются ярости в наши дни, и ее также следует использовать в базе данных SQL).

person araqnid    schedule 03.12.2010

Может быть, перебор, но мне это кажется проблемой кластеризации: distance measure определит, как рассчитывается схожесть двух элементов. Если вам нужно менее простое решение, попробуйте Data Mining: практические инструменты машинного обучения и Методы и используйте Weka или Оранжевый

person Roberto Russo    schedule 03.12.2010

Если бы я брался за это, я бы начал с сетки. Поместите каждую точку в квадрат на сетке. Ищите густонаселенные сетки. Если соседние сетки не заселены, значит, у вас приличная группа.

Если у вас есть соседние густонаселенные сетки, вы всегда можете поместить круг в центре каждой сетки и оптимизировать для площади круга vs (количество точек в круге * некоторый настраиваемый вес). Не идеально, но легко. Лучшее группирование - это гораздо более сложные проблемы оптимизации.

person patros    schedule 03.12.2010

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

person Deepak Upreti    schedule 08.07.2011