Geografischer / Geospatialabstand zwischen 2 Listen von Breiten- / Längenpunkten (Koordinaten)

Ich habe 2 Listen ( list1 , list2 ) mit Breiten / Längen verschiedener Orte. Eine Liste ( list2 ) hat Ortsnamen, die list1 nicht hat.

Ich möchte einen ungefähren Ort für jeden Punkt in Liste1. Ich möchte also einen Punkt in list1 , versuchen, nach dem nächsten Punkt in list2 zu suchen und diesen Ort zu nehmen. Ich wiederhole das für jeden Punkt in list1 . Es will auch die Entfernung (in Metern) und den Index des Punktes (in list1 ), so dass ich einige Geschäftsregeln um ihn herum list1 kann – im Wesentlichen sind dies 2 neue near_dist , die zu indx hinzugefügt werden list1 ( near_dist , indx ).

Ich benutze die gdist function, aber ich kann dies nicht mit gdist Eingaben arbeiten.

Beispieleingabelisten:

 list1 <- data.frame(longitude = c(80.15998, 72.89125, 77.65032, 77.60599, 72.88120, 76.65460, 72.88232, 77.49186, 72.82228, 72.88871), latitude = c(12.90524, 19.08120, 12.97238, 12.90927, 19.08225, 12.81447, 19.08241, 13.00984, 18.99347, 19.07990)) list2 <- data.frame(longitude = c(72.89537, 77.65094, 73.95325, 72.96746, 77.65058, 77.66715, 77.64214, 77.58415, 77.76180, 76.65460), latitude = c(19.07726, 13.03902, 18.50330, 19.16764, 12.90871, 13.01693, 13.00954, 12.92079, 13.02212, 12.81447), locality = c("A", "A", "B", "B", "C", "C", "C", "D", "D", "E")) 

   

Um die geografische Entfernung zwischen zwei Punkten mit Längen- / Breitenkoordinaten zu berechnen, können Sie mehrere Formeln verwenden. Die geosphere des Pakets enthält die distCosine , distHaversine , distVincentySphere und distVincentyEllipsoid zur Berechnung der Entfernung. Von diesen wird das distVincentyEllipsoid als das genaueste angesehen, ist jedoch rechenintensiver als die anderen.

Mit einer dieser functionen können Sie eine Entfernungsmatrix erstellen. Anhand dieser Matrix können Sie dann Ortsnamen basierend auf der kürzesten Entfernung mit which.min und der entsprechenden Entfernung mit min (siehe hierzu den letzten Teil der Antwort) wie which.min zuordnen:

 library(geosphere) # create distance matrix mat < - distm(list1[,c('longitude','latitude')], list2[,c('longitude','latitude')], fun=distVincentyEllipsoid) # assign the name to the point in list1 based on shortest distance in the matrix list1$locality <- list2$locality[max.col(-mat)] 

das gibt:

 > list1 longitude latitude locality 1 80.15998 12.90524 D 2 72.89125 19.08120 A 3 77.65032 12.97238 C 4 77.60599 12.90927 D 5 72.88120 19.08225 A 6 76.65460 12.81447 E 7 72.88232 19.08241 A 8 77.49186 13.00984 D 9 72.82228 18.99347 A 10 72.88871 19.07990 A 

Eine andere Möglichkeit besteht darin, die locality basierend auf den durchschnittlichen Längen- und Breitenwerten der locality s in list2 :

 library(dplyr) list2a < - list2 %>% group_by(locality) %>% summarise_each(funs(mean)) %>% ungroup() mat2 < - distm(list1[,c('longitude','latitude')], list2a[,c('longitude','latitude')], fun=distVincentyEllipsoid) list1 <- list1 %>% mutate(locality2 = list2a$locality[max.col(-mat2)]) 

oder mit data.table :

 library(data.table) list2a < - setDT(list2)[,lapply(.SD, mean), by=locality] mat2 <- distm(setDT(list1)[,.(longitude,latitude)], list2a[,.(longitude,latitude)], fun=distVincentyEllipsoid) list1[, locality2 := list2a$locality[max.col(-mat2)] ] 

das gibt:

 > list1 longitude latitude locality locality2 1 80.15998 12.90524 DD 2 72.89125 19.08120 AB 3 77.65032 12.97238 CC 4 77.60599 12.90927 DC 5 72.88120 19.08225 AB 6 76.65460 12.81447 EE 7 72.88232 19.08241 AB 8 77.49186 13.00984 DC 9 72.82228 18.99347 AB 10 72.88871 19.07990 AB 

Wie Sie sehen können, führt dies bei den meisten (7 von 10) Anlässen zu einer anderen zugewiesenen locality .


Sie können die Entfernung hinzufügen mit:

 list1$near_dist < - apply(mat2, 1, min) 

oder ein anderer Ansatz mit max.col (was höchstwahrscheinlich schneller ist):

 list1$near_dist < - mat2[matrix(c(1:10, max.col(-mat2)), ncol = 2)] # or using dplyr list1 <- list1 %>% mutate(near_dist = mat2[matrix(c(1:10, max.col(-mat2)), ncol = 2)]) # or using data.table (if not already a data.table, convert it with 'setDT(list1)' ) list1[, near_dist := mat2[matrix(c(1:10, max.col(-mat2)), ncol = 2)] ] 

das Ergebnis:

 > list1 longitude latitude locality locality2 near_dist 1: 80.15998 12.90524 DD 269966.8970 2: 72.89125 19.08120 AB 65820.2047 3: 77.65032 12.97238 CC 739.1885 4: 77.60599 12.90927 DC 9209.8165 5: 72.88120 19.08225 AB 66832.7223 6: 76.65460 12.81447 EE 0.0000 7: 72.88232 19.08241 AB 66732.3127 8: 77.49186 13.00984 DC 17855.3083 9: 72.82228 18.99347 AB 69456.3382 10: 72.88871 19.07990 AB 66004.9900