簡體   English   中英

R:連接 Map 上的點

[英]R: Connecting Dots on a Map

我正在使用 R 編程語言。

使用“傳單”庫,我為這 5 個城市制作了以下 map:

 library(dplyr) library(leaflet) map_data <- data.frame("Lat" = c(43.6426, 43.6424, 43.6544, 43.6452, 43.6629), "Long" = c(-79.3871, -79.3860, -79.3807, -79.3806,-79.3957 ), type = c(1,2,3,4,5)) map_data$type = as.factor(map_data$type) leaflet(map_data) %>% addTiles() %>% addCircleMarkers(stroke = FALSE, label = ~type,fillOpacity = 0.8, labelOptions = labelOptions(direction = "center",style = list('color' = "white"),noHide = TRUE, offset=c(0,0), fill = TRUE, opacity = 1, weight = 10, textOnly = TRUE))

在上面我創建的 map 上,我現在想根據它們的“編號”(例如,將 1 與 2 連接,2 與 3 連接)在 map(在路線中)上“連接”所有這些“點”(即城市) , 3 與 4, 4 與 5, 5 與 1), 以及 output 路線的“總距離”。 我發現以前的帖子顯示了如何執行此操作: How to show path and distance on map with leaflet, shiny 應用程序?

我試圖修改這篇文章中的代碼以適應我的問題:

 library(osrm) route = osrmRoute(c(-79.3871, -79.3860, -79.3807, -79.3806,-79.3957 ), c(43.6426, 43.6424, 43.6544, 43.6452, 43.6629), overview = 'full') route_summary = osrmRoute(c(-79.3871, -79.3860, -79.3807, -79.3806,-79.3957 ), c(43.6426, 43.6424, 43.6544, 43.6452, 43.6629), overview = FALSE) leaflet() %>% addTiles() %>% addCircleMarkers(c(-79.3871, -79.3860, -79.3807, -79.3806,-79.3957 ), c(43.6426, 43.6424, 43.6544, 43.6452, 43.6629), stroke = FALSE, label = ~type,fillOpacity = 0.8, labelOptions = labelOptions(direction = "center",style = list('color' = "white"),noHide = TRUE, offset=c(0,0), fill = TRUE, opacity = 1, weight = 10, textOnly = TRUE)) %>% addPolylines(route$lon,route$lat, label = paste(round(route_summary[1]/60), 'hr - ', round(route_summary[2]), 'km'), labelOptions = labelOptions(noHide = TRUE))

但這會返回以下錯誤:

 Error in UseMethod("metaData"): no applicable method for 'metaData' applied to an object of class "NULL"

有人可以告訴我如何解決這個問題嗎?

我想使用“傳單”而不是“rshiny”來做到這一點。 最后,我希望最終的 map 看起來像這樣(這應該代表旅行推銷員問題的“單一路徑”):

[ [在此處輸入圖片描述][2]][2]

注意:我開始認為問題可能是“osrmRoute()”function 可能無法工作超過 2 點?

一種方法是讓您撥打 API 電話:

https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md

我將概述您如何做到這一點:

數據

df <- data.frame( lon = c(-79.3871, -79.3860, -79.3807, -79.3806,-79.3957), lat = c(43.6426, 43.6424, 43.6544, 43.6452, 43.6629) )

url 來電

root <- "http://router.project-osrm.org/route/v1/driving/" options <- c( continue_straight = "true", overview = "full", annotations = "true", steps = "true" ) coords <- df %>% slice(c(seq_len(n()), 1)) %>% pmap_chr(str_c, sep = ",") %>% str_c(collapse = ";") options <- options %>% imap_chr(~str_c(.y, "=",.x)) %>% str_c(collapse = "&") %>% str_c("?",.) res <- rjson::fromJSON(file = str_c(root, coords, options))

請注意,我已將第一個點添加為第 6 行以制作圓形路線。

map

 res$routes[[1]]$geometry %>% googlePolylines::decode() %>%.[[1]] %>% leaflet() %>% addTiles() %>% addPolylines(lng = ~lon, lat = ~lat) %>% addCircleMarkers( data = df, stroke = FALSE, label = seq_len(nrow(df)), fillOpacity = 0.8, labelOptions = labelOptions( direction = "center", style = list('color' = "white"), noHide = TRUE, offset=c(0,0), fill = TRUE, opacity = 1, weight = 10, textOnly = TRUE ) )

距離

res$routes[[1]]$distance

這是以米為單位(文檔)

編輯

可能有更好的方法來標記折線,但我現在沒有時間:

 library(sf) segment_df <- df %>% rbind(df[1,]) d <- segment_df %>% st_as_sf(coords = c("lon", "lat"), crs = 4326) %>% {st_distance(.[-6,],.[-1,], by_element = TRUE)} %>% as.vector() %>% round() m <- leaflet() %>% addTiles() for(i in seq_len(nrow(segment_df) - 1)) m <- m %>% addPolylines( data = segment_df[i:(i+1),], lng = ~lon, lat = ~lat, color = "red", label = paste(d[[i]], "m"), labelOptions(noHide = TRUE, direction = 'top') ) m <- m %>% addCircleMarkers( data = df, stroke = FALSE, label = seq_len(nrow(df)), fillOpacity = 0.8, labelOptions = labelOptions( direction = "center", style = list('color' = "white"), noHide = TRUE, offset=c(0,0), fill = TRUE, opacity = 1, weight = 10, textOnly = TRUE ) )

如果您只想顯示總距離,那么這更容易並且不需要循環,只需將循環替換為:

 segment_df %>% leaflet() %>% addTiles() %>% addPolylines( lng = ~lon, lat = ~lat, color = "red", label = paste(sum(d), "m"), labelOptions = labelOptions(noHide = TRUE, direction = 'top') )

我希望你明白(並從地圖上看到)這是不可駕駛的。

這是我根據@det 的回答嘗試的答案:

 library(sf) library(geosphere) library(dplyr) library(leaflet) library(data.table) library(VPF) #add a 6th row that is equal to the 1st row - so that the path loops back map_data <- data.frame("Lat" = c(43.6426, 43.6424, 43.6544, 43.6452, 43.6629, 43.6426), "Long" = c(-79.3871, -79.3860, -79.3807, -79.3806,-79.3957, -79.3871 ), type = c(1,2,3,4,5,1)) map_data$type = as.factor(map_data$type) m1 = leaflet(map_data) %>% addTiles() %>% addCircleMarkers(stroke = FALSE, label = ~type,fillOpacity = 0.8, color = ~ifelse(type==1,"red","blue"), labelOptions = labelOptions(direction = "center",style = list('color' = "white"), noHide = TRUE, offset=c(0,0), fill = TRUE, opacity = 1, weight = 10, textOnly = TRUE)) m1 %>% addTiles() %>% addPolylines(data = map_data, lng = ~Long, lat = ~Lat, group = ~type)

現在,我想計算行程的總距離並將其顯示在 map 上:

 #distances (https://stackoverflow.com/questions/42119438/calculate-distance-between-two-long-lat-coordinates-in-a-dataframe) result = rbind( cbind(map_data[1:nrow(map_data)-1,c(1,2)], map_data[-1,c(1,2)]), cbind(map_data[nrow(map_data), c(1,2)], map_data[1,c(1,2)]) ) colnames(result) <- c("start_lat", "start_long", "end_lat", "end_long") result$id = as.factor(c(1,2,3,4,5,1)) result = data.frame(result) for (i in 1:nrow(result)) { a<-result$start_long[i] b<-result$start_lat[i] c<-result$end_long[i] d<-result$end_lat[i] result$distance[i]<-distm(c(a,b),c(c,d), fun = distHaversine) } #total distance of trip in meters d = result$distance total_d = signif(sum(d),3) m1 %>% addPolylines( data = map_data, lng = ~Long, lat = ~Lat, color = "blue", label = paste0(total_d, " meters"), labelOptions(noHide = TRUE, direction = 'top') )

我想我終於明白了 - 非常感謝@Det

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM