如何使用R中的Leaflet将两个坐标与一条线连接起来

mal*_*lmk 19 r leaflet r-leaflet

我试图用宣传单封装中的R画一个放大器和连接给出下表中的经度和纬度信息的标记.


    | Observation | 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  |
    | I           | 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   |

我想从由坐标给出一个初始点画线InitialLatInitialLong列由给定的终点NewLatNewLong列.

这是我当前的R代码,它只在地图上绘制标记.


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

jaz*_*rro 21

这是使用该leaflet包的另一种方法.为了演示,我只是在您的数据中提取了两个数据点.

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)
Run Code Online (Sandbox Code Playgroud)

我更改了mydf传单的格式并为传单创建了一个新的数据框.您可以通过各种方式重塑数据.

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)
Run Code Online (Sandbox Code Playgroud)

我修剪了我得到的互动地图.请参阅下面的地图.虽然在此图像中连接了两条线,但它们是分开的.如果您运行代码并放大,您将看到两条线是分开的.

在此输入图像描述

  • 我想这曾经有效,但现在真的不行了。即使使用 ~group,传单也会连接所有折线(也在“放大这张地图”时)。 (2认同)

jer*_*ycg 12

Leaflet可以使用该addPolylines函数添加行.这个问题是假设每条线路都已连接 - 你会将它们全部链接起来.

解决此问题的最佳方法(AFAIK)是使用循环:

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
Run Code Online (Sandbox Code Playgroud)

编辑:使用Kyle Walker 的points_to_line函数还有一种更简单的方法(请参阅最底部的代码粘贴副本).

首先重塑数据,因此开始和结束位于相同的列中:

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"])))
Run Code Online (Sandbox Code Playgroud)

然后打电话 points_to_line

z <- as.data.frame(z)
y <- points_to_line(z, "long", "lat", "Observation")
Run Code Online (Sandbox Code Playgroud)

现在情节:

map3 = leaflet(data) %>% addTiles()
map3 %>% addMarkers(~InitialLong, ~InitialLat, popup = ~Observation) %>%
         addPolylines(data = y)
Run Code Online (Sandbox Code Playgroud)

Kyle Walker的points_to_line来源:

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)
  }
}
Run Code Online (Sandbox Code Playgroud)