Come posso colbind due coordinate con una linea usando Leaflet in R

Sto cercando di usare il pacchetto Leaflet in R per disegnare un amplificatore e colbind i marker dati le informazioni sulla latitudine e la longitudine nella tabella sottostante.

     |  Osservazione |  InitialLat |  InitialLong |  NewLat |  NewLong |
     | ------------- | ------------ | ------------- | -------- --- | ----------- |
     |  A |  62.469722 |  6.187194 |  51.4749 |  -0.221619 |
     |  B |  48.0975 |  16.3108 |  51.4882 |  -0.302621 |
     |  C |  36,84 |  -2.435278 |  50.861822 |  -0.083278 |
     |  D |  50.834194 |  4.298361 |  54,9756 |  -1,62179 |
     |  E |  50.834194 |  4.298361 |  54,9756 |  -1,62179 |
     |  F |  50.834194 |  4.298361 |  51.4882 |  -0.302621 |
     |  G |  47.460427 |  -0.530804 |  51,44 |  -2.62021 |
     |  H |  51.5549 |  -0.108436 |  53.4281 |  -1.36172 |
     |  Io |  51.5549 |  -0.108436 |  52,9399 |  -1.13258 |
     |  J |  51.5549 |  -0.108436 |  51.889839 |  -0.193608 |
     |  |  51.5549 |  -0.108436 |  52.0544 |  1.14554 |

Voglio disegnare linee da un punto iniziale dato dalle coordinate nelle colonne InitialLat e InitialLong a un punto finale dato dalle colonne NewLat e NewLong .

Ecco il mio codice R attuale che disegna solo i marker sulla mappa.

     biblioteca (foglio illustrativo)
     map3 = leaflet (data)%>% addTiles ()
     map3%>% addMarkers (~ InitialLong, ~ InitialLat, popup = ~ Observation)

Ecco un modo alternativo utilizzando il pacchetto di leaflet . Ho appena preso due punti dati nei tuoi dati a scopo di dimostrazione.

 mydf <- data.frame(Observation = c("A", "B"), InitialLat = c(62.469722,48.0975), InitialLong = c(6.187194, 16.3108), NewLat = c(51.4749, 51.4882), NewLong = c(-0.221619, -0.302621), stringsAsFactors = FALSE) 

Ho cambiato il formato di mydf e mydf creato un nuovo data frame per il volantino. Puoi rimodellare i tuoi dati in vari modi.

 mydf2 <- data.frame(group = c("A", "B"), lat = c(mydf$InitialLat, mydf$NewLat), long = c(mydf$InitialLong, mydf$NewLong)) # group lat long #1 A 62.46972 6.187194 #2 B 48.09750 16.310800 #3 A 51.47490 -0.221619 #4 B 51.48820 -0.302621 library(leaflet) library(magrittr) leaflet()%>% addTiles() %>% addPolylines(data = mydf2, lng = ~long, lat = ~lat, group = ~group) 

Ho rifilato la mappa intertriggers che ho ottenuto. Si prega di consultare la mappa qui sotto. Sebbene due linee siano collegate in questa immagine, sono separate. Se esegui il codice e ingrandisci, vedrai che le due linee sono separate.

inserisci la descrizione dell'immagine qui

Il volantino può aggiungere linee usando la funzione addPolylines . Il problema con questo è che si presume che ogni linea sia connessa – li avrai tutti collegati.

Il modo migliore per risolvere questo problema (AFAIK) consiste nell’utilizzare un ciclo:

 library(leaflet) map3 = leaflet(data) %>% addTiles() map3 <- map3 %>% addMarkers(~InitialLong,~InitialLat, popup=~Observation) for(i in 1:nrow(data)){ map3 <- addPolylines(map3, lat = as.numeric(data[i, c(2, 4)]), lng = as.numeric(data[i, c(3, 5)])) } map3 

EDIT: C'è anche un modo più semplice usando la funzione points_to_line di Kyle Walker (vedi il fondo per una copia incollata del codice).

Prima rimodella i dati, quindi gli inizi e le estremità si trovano nelle stesse colonne:

 library(tidyr) library(dplyr) z <- gather(dta, measure, val, -Observation) %>% group_by(Observation) %>% do(data.frame( lat=c(.[["val"]][.[["measure"]]=="InitialLat"], .[["val"]][.[["measure"]]=="NewLat"]), long = c(.[["val"]][.[["measure"]]=="InitialLong"], .[["val"]][.[["measure"]]=="NewLong"]))) 

Quindi chiama points_to_line

 z <- as.data.frame(z) y <- points_to_line(z, "long", "lat", "Observation") 

Ora trama:

 map3 = leaflet(data) %>% addTiles() map3 %>% addMarkers(~InitialLong, ~InitialLat, popup = ~Observation) %>% addPolylines(data = y) 

Fonte di points_to_line di Kyle Walker:

 library(sp) library(maptools) points_to_line <- function(data, long, lat, id_field = NULL, sort_field = NULL) { # Convert to SpatialPointsDataFrame coordinates(data) <- c(long, lat) # If there is a sort field... if (!is.null(sort_field)) { if (!is.null(id_field)) { data <- data[order(data[[id_field]], data[[sort_field]]), ] } else { data <- data[order(data[[sort_field]]), ] } } # If there is only one path... if (is.null(id_field)) { lines <- SpatialLines(list(Lines(list(Line(data)), "id"))) return(lines) # Now, if we have multiple lines... } else if (!is.null(id_field)) { # Split into a list by ID field paths <- sp::split(data, data[[id_field]]) sp_lines <- SpatialLines(list(Lines(list(Line(paths[[1]])), "line1"))) # I like for loops, what can I say... for (p in 2:length(paths)) { id <- paste0("line", as.character(p)) l <- SpatialLines(list(Lines(list(Line(paths[[p]])), id))) sp_lines <- spRbind(sp_lines, l) } return(sp_lines) } } 

A seconda di quale sia lo scopo delle linee, un’altra big opzione è gcIntermediate (). Emette un object SpatialLines CURVED, basato sulla curvatura della terra. Non eccezionale per le indicazioni però. Gli oggetti di class SpatialLines funzionano molto bene con Leaflet. Vedi qui per un esempio eccellente. Ho pubblicato un modulo modificato, che inizia con la cornice dati di Paul Reiners.

 library(leaflet) library(geosphere) mydf <- data.frame(InitialLat = c(62.469722,48.0975), # initial df InitialLong = c(6.187194, 16.3108), NewLat = c(51.4749, 51.4882), NewLong = c(-0.221619, -0.302621)) p1 <- as.matrix(mydf[,c(2,1)]) # it's important to list lng before lat here p2 <- as.matrix(mydf[,c(4,3)]) # and here gcIntermediate(p1, p2, n=100, addStartEnd=TRUE, sp=TRUE) %>% leaflet() %>% addTiles() %>% addPolylines() 

So che questo è stato chiesto un anno fa, ma ho avuto la stessa domanda e ho capito come farlo nel volantino.

Per prima cosa devi regolare il tuo dataframe perché addPolyline collega solo tutte le coordinate in una sequenza. Creerò un dataframe con 4 posizioni finali separate ai fini di questa dimostrazione.

 dest_df <- data.frame (lat = c(41.82, 46.88, 41.48, 39.14), lon = c(-88.32, -124.10, -88.33, -114.90) ) 

Successivamente, creerò un frame di dati con la posizione centrale della stessa dimensione (4 in questo esempio) delle posizioni di destinazione. Spiegherò perché lo sto facendo presto

 orig_df <- data.frame (lat = c(rep.int(40.75, nrow(dest_df))), long = c(rep.int(-73.99,nrow(dest_df))) ) 

Il motivo per cui lo sto facendo è perché la funzione addPolylines collegherà tutte le coordinate in una sequenza. Il modo per aggirare questo per creare l'immagine che hai descritto è iniziando dal punto di partenza, poi andando al punto di destinazione, e poi di nuovo al punto di partenza, e poi al prossimo punto di destinazione. Per creare il dataframe per fare ciò, dovremo intrecciare i due dataframes inserendo righe come tali:

punto di partenza - punto di destinazione 1 - punto di partenza - punto di destinazione 2 - e così via ...

Il modo che farò è creare una chiave per entrambi i frame di dati. Per il dataframe di origine, inizierò da 1 e incrementerò di 2 (es. 1 3 5 7). Per il dataframe di destinazione, inizierò alle 2 e incrementerò di 2 (ad es. 2, 4, 6, 8). Quindi combinerò i 2 dataframes usando un UNION all. Quindi selezionerò la sequenza per fare di ogni altra riga il punto di partenza. Userò sqldf per questo perché è quello con cui mi trovo a mio agio. Potrebbe esserci un modo più efficiente.

 orig_df$sequence <- c(sequence = seq(1, length.out = nrow(orig_df), by=2)) dest_df$sequence <- c(sequence = seq(2, length.out = nrow(orig_df), by=2)) library("sqldf") q <- " SELECT * FROM orig_df UNION ALL SELECT * FROM dest_df ORDER BY sequence " poly_df <- sqldf(q) 

Il nuovo dataframe assomiglia a questo avviso come le posizioni di origine sono intrecciate tra la destinazione

E infine, puoi creare la tua mappa:

 library("leaflet") leaflet() %>% addTiles() %>% addPolylines( data = poly_df, lng = ~lon, lat = ~lat, weight = 3, opacity = 3 ) 

E alla fine dovrebbe assomigliare a questo, spero che questo aiuti chiunque stia cercando di fare qualcosa del genere in futuro

Pensa che questo è quello che vuoi:

 install.packages("leaflet") library(leaflet) mydf <- data.frame(Observation = c("A", "B","C","D","E"), InitialLat = c(62.469722,48.0975,36.84,50.834194,50.834194), InitialLong = c(6.187194, 16.3108,-2.435278,4.298361,4.298361), NewLat = c(51.4749, 51.4882,50.861822,54.9756,54.9756), NewLong = c(-0.221619, -0.302621,-0.083278,-1.62179,-1.62179), stringsAsFactors = FALSE) mydf Observation InitialLat InitialLong NewLat NewLong 1 A 62.46972 6.187194 51.47490 -0.221619 2 B 48.09750 16.310800 51.48820 -0.302621 3 C 36.84000 -2.435278 50.86182 -0.083278 4 D 50.83419 4.298361 54.97560 -1.621790 5 E 50.83419 4.298361 54.97560 -1.621790 m<-leaflet(data=mydf)%>%addTiles for (i in 1:nrow(mydf)) m<-m%>%addPolylines(lat=c(mydf[i,]$InitialLat,mydf[i,]$NewLat),lng=c(mydf[i,]$InitialLong,mydf[i,]$NewLong)) 

E mostra: Connessione di rete tramite Leaflet