Ответ 1
В вашем случае вы должны смотреть GeoHash, что позволяет быстро запросить координаты на заданном расстоянии.
FYI, MongoDB использует geohash внутри, и он отлично работает.
У меня есть матрица, имеющая около 1000 геопространственных точек (долгота, широта), и я пытаюсь найти точки, находящиеся в диапазоне 1KM.
ПРИМЕЧАНИЕ: "Точки динамические, представьте, что движутся 1000 автомобилей, поэтому я должен повторно рассчитать все расстояния каждые несколько секунд"
Я сделал некоторые поиски и прочитал о алгоритмах Graph, таких как (Floyd-Warshall), чтобы решить эту проблему, и у меня появилось много ключевых слов, и теперь я немного потерялся. Я рассматриваю производительность, и поскольку радиус поиска короткий, я не буду рассматривать кривизну земли.
В принципе, кажется, что я должен рассчитать расстояние между каждой точкой и каждой другой точкой, а затем сортировать расстояния, начиная с каждой точки матрицы, и получать точки, находящиеся в его диапазоне. Поэтому, если у меня 1000 координат, я должен выполнить этот процесс (1000 ^ 2-1000) раз, и я не верю, что это оптимальное решение. Спасибо.
В вашем случае вы должны смотреть GeoHash, что позволяет быстро запросить координаты на заданном расстоянии.
FYI, MongoDB использует geohash внутри, и он отлично работает.
Если вы создадите модель с сеткой с шагом 1 км:
0 1 2 3
___|____|____|____
0 | | |
c| b|a | d
___|____|____|____
1 | | |
| |f |
___|e___|____|____
2 | |g |
допустим, что ваша отправная точка - это a. Если ваша сетка имеет размер 1 км, точки в расстоянии 1 км должны находиться в одной и той же ячейке или одном из 8 соседей (точки b, d, e, f).
Любая другая ячейка может быть проигнорирована (c, g).
В то время как d почти на таком же расстоянии от c, c может быть отброшен раньше, потому что есть два препятствия для пересечения, а a и d лежат на противоположных участках их границы и, следовательно, находятся почти на 2 км от друг друга.
Для раннего удаления элемента вы можете исключить, достаточно проверить x- или y-часть координаты. Так как a принадлежит (0,2), если x равно 0 или меньше, или > 3, точка уже вне допустимого диапазона.
После фильтрации только нескольких кандидатов вы можете использовать исчерпывающий поиск.
Вы можете вычислить геокоды шириной 1 км вокруг каждой из этих 1000 координат и проверить, находятся ли некоторые точки в этом диапазоне. Может быть, это не оптимально, но вы сохраните себе некоторую сортировку.
Если вы хотите найти матрицу для каждой точки по отношению к каждой точке, то вы уже получили правильную формулу (1000 ^ 2-1000). Для этого расчета нет никакого ярлыка. Однако, когда вы знаете, с чего начать поиск, и вы хотите искать точки в радиусе 1KM, вы можете использовать сетку или пространственный алгоритм для ускорения поиска. Скорее всего, он использует алгоритм деления и покорения, а самый дешевый из них - геостат или кривая z. Вы также можете попробовать kd-дерево. Может быть, это еще проще. Но если ваши точки находятся в эвклидовом пространстве, то здесь описан этот планарный метод: http://en.wikipedia.org/wiki/Closest_pair_of_points_problem.
Edit: Когда я говорю 1000 ^ 2-1000, то я имею в виду размер сетки, но на самом деле 1000 ^ (1000 - 1)/2 пары точек, поэтому намного меньше математики.
У меня есть нечто похожее на веб-странице, над которой я работал, я думаю. Пользователь нажимает местоположение на карте и вводит радиус, а функция возвращает все местоположения в базе данных в пределах данного радиуса. Вы имеете в виду, что вы пытаетесь найти точки, находящиеся в пределах 1 км от одной из точек в радиусе? Или вы пытаетесь найти точки, находящиеся в пределах 1 км друг от друга? Я думаю, вы должны сделать что-то вроде этого.
radius = given radius
x1 = latitude of given point;
y1 = longitude of given point;
x2 = null;
y2 = null;
x = null;
y = null;
dist = null;
for ( i=0; i<locationArray.length; i++ ) {
x2 = locationArray[i].latitude;
y2 = locationArray[i].longitude;
x = x1 - x2;
y = y1 - y2;
dist = sqrt(x^2 + y^2);
if (dist <= radius)
these are your points
}
Если вы пытаетесь вычислить все точки, находящиеся в пределах 1 км от другой точки, вы можете добавить внешний цикл, предоставляющий информацию о x1 и y1, которая затем сделает внутреннюю проверку цикла расстоянием между данной точкой и каждая другая точка дает каждую точку в вашей матрице в качестве входных данных. Вычисления не должны занимать слишком много времени, так как это так важно.
Попробуйте использовать R-Tree. R-Tree поддерживает операцию, чтобы найти все точки, наиболее близкие к заданной точке, которые находятся не дальше заданного радиуса. Время выполнения является оптимальным, и я думаю, что это O (number_of_points_in_the_result).
У меня была такая же проблема, но в разработке веб-сервисов В моем случае, чтобы избежать проблемы с расчетом, я использовал простое решение для разделения и завоевания. Идея заключалась в том, чтобы начать вычисление расстояния между новой точкой и другими в каждой новой вставке данных, чтобы мое приложение напрямую достигало расстояния между этими пункты буксировки, которые уже были рассчитаны и помещены в мою базу данных