Как я могу рассчитать расстояние между данными о широте и долготе? - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть 1100 данных о местоположении станции (широта и долгота) и 10000 данных о местоположении дома (широта и долгота). Можно ли рассчитать наименьшее расстояние между станцией и домом для каждого дома, используя R-коды? Я также хочу станцию, которая дает самое низкое расстояние для каждого дома. Возможно ли это?

1 Ответ

0 голосов
/ 04 февраля 2020

Вот игрушечный пример для нахождения массовых расстояний между m точками и n городами. Это должно перевести непосредственно к вашей проблеме станции / дома.

Я поднял мировые города, развернул земной шар (так сказать) и остановился на четырех городах. Затем я снова развернулся и остановился на двух точках. Два отсчета здесь несущественны: если у нас есть 4 и 2 или 1100 и 10000, это не должно иметь большого значения.

worldcities <- read.csv(header = TRUE, stringsAsFactors = FALSE, text = "
lat,lon
39.7642548,-104.9951942
48.8588377,2.2770206
26.9840891,49.4080842
13.7245601,100.493026")

coords <- read.csv(header = TRUE, stringsAsFactors = FALSE, text = "
lat,lon
27.9519571,66.8681431
40.5351151,-108.4939948")

(Небольшое примечание ... часто инструменты дают нам координаты в «широте», долгота ", по крайней мере, по моему опыту. geosphere функции, однако, предполагают" долготу, широту ". Поэтому мои координаты выше были скопированы прямо из случайных видов на картах Google, и я не хотел их редактировать; из-за этого Я переворачиваю столбцы ниже с помощью индексации столбцов [,2:1]. Если вы забудете и дадите координаты, которые, несомненно, не верны, вы получите ошибку Error in .pointsToMatrix(p1) : latitude < -90, которая должна быть продуктом, который вы, вероятно, изменили на порядок ваших координат В этот момент вы почесываете голову и удивляетесь, что все ваши другие проекты использовали неправильные координаты, ставя под сомнение ваши выводы. Не я, я никогда там не был. В этом году.)

Давайте найдем расстояние в метрах между каждым из coords (каждый ряд) и каждым городом (каждый столбец):

dists <- outer(seq_len(nrow(coords)), seq_len(nrow(worldcities)),
               function(i, j) geosphere::distHaversine(coords[i,2:1], worldcities[j,2:1]))
dists
#            [,1]    [,2]     [,3]     [,4]
# [1,] 12452329.0 5895577  1726433  3822220
# [2,]   309802.8 7994185 12181477 13296825

Оно должно быть прямым чтобы определить, какой город находится ближе всего к каждой координате, с помощью

apply(dists, 1, which.min)
# [1] 3 1

То есть первая точка ближе всего к третьему городу, а вторая точка ближе к первому городу.

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

worldcities_big <- do.call(rbind, replicate(250, worldcities, simplify = FALSE))
nrow(worldcities_big)
# [1] 1000
coords_big <- do.call(rbind, replicate(5000, coords, simplify = FALSE))
nrow(coords_big)
# [1] 10000
system.time(
  dists <- outer(seq_len(nrow(coords_big)), seq_len(nrow(worldcities_big)),
                 function(i, j) geosphere::distHaversine(coords_big[i,2:1], worldcities_big[j,2:1]))
)
#    user  system elapsed 
#   67.62    2.22   70.03 

Итак да , это не было мгновенно, но 70 секунд не страшно для 10 000 000 расчётов расстояния. Не могли бы вы сделать это быстрее? Возможно, не уверен точно, как, легко . Я бы подумал, что некоторые эвристики могут уменьшить его до O(m*log(n)) с O(m*n) времени, но я не знаю, стоит ли это той сложности кодирования, которую он представит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...