【问题标题】:Connect two sets of sfc points with arrows用箭头连接两组 sfc 点
【发布时间】:2021-01-07 11:17:58
【问题描述】:

我有一个数据框,其中两列是 sfc 点列表。

 > head(moves)
   hiring                      start                        end
 1      1 POINT (-2.030474 51.36306) POINT (-2.250102 51.41609)
 2      2 POINT (-2.319776 51.46162) POINT (-2.491189 51.41029)
 3      4 POINT (-2.025846 51.47712) POINT (-2.063781 51.49158)
 4      6 POINT (-2.426711 51.38076) POINT (-2.132722 51.46999)
 5      7  POINT (-2.116654 51.4887) POINT (-2.204403 51.51874)
 6      8  POINT (-2.122917 51.5861) POINT (-2.134635 51.51806)

我需要逐行从一个点到另一个点画线(理想情况下是指向的)。我的问题似乎是我的文件(移动)不是 sf 对象。我需要制作一个,还是将其中的数据转换成其他格式?

 > dput(head(moves))
 structure(list(hiring = c(1L, 2L, 4L, 6L, 7L, 8L), start = list(
     structure(c(-2.03047447566941, 51.3630641761757), class = c("XY", 
     "POINT", "sfg")), structure(c(-2.31977575385362, 51.4616210429381
     ), class = c("XY", "POINT", "sfg")), structure(c(-2.02584648038463, 
     51.4771163047678), class = c("XY", "POINT", "sfg")), 
 structure(c(-2.42671091326068, 
     51.3807643595824), class = c("XY", "POINT", "sfg")), 
 structure(c(-2.1166538974769, 
     51.4887039877758), class = c("XY", "POINT", "sfg")), 
 structure(c(-2.12291705783767, 
     51.5860957106472), class = c("XY", "POINT", "sfg"))), end = list(
     structure(c(-2.25010169528537, 51.4160891285008), class = c("XY", 
    "POINT", "sfg")), structure(c(-2.49118920138511, 51.4102939905029
     ), class = c("XY", "POINT", "sfg")), structure(c(-2.06378098244424, 
     51.491583244303), class = c("XY", "POINT", "sfg")), 
 structure(c(-2.13272163343155, 
     51.469987047928), class = c("XY", "POINT", "sfg")), 
 structure(c(-2.20440279315621, 
     51.5187438721622), class = c("XY", "POINT", "sfg")), 
 structure(c(-2.1346350057738, 
     51.5180564842074), class = c("XY", "POINT", "sfg")))), row.names = c(NA, 
 6L), class = "data.frame")

【问题讨论】:

  • 能否请您提供数据,以便人们可以轻松运行代码并帮助您?您可以简单地运行dput(head(moves)),然后其他人可以在他们的 R 会话中复制/粘贴输出并获取数据。另请说明您正在寻找哪种情节。它是在地图的顶部还是只是在两对点之间带有箭头的白色背景?
  • 我已经添加了数据。最终,我将添加 CRS 并将其放在地图上,但现在我的问题是找到一种方法来绘制我需要的东西。

标签: spatial sf sp


【解决方案1】:

很好的问题。对不起,没有箭头。结果只有直线。为了得到这个问题的答案,我需要将“移动”数据转换为两个矩阵对象:一个矩阵作为起点,第二个矩阵作为终点。

s_lon <- c(-2.030474, -2.319776, -2.025846, -2.426711, -2.116654, -2.122917)
s_lat <- c(51.36306, 51.46162, 51.47712, 51.38076, 51.4887, 51.5861)
e_lon <- c(-2.250102, -2.491189, -2.063781, -2.132722, -2.204403, -2.134635)
e_lat <- c(51.41609, 51.41029, 51.49158, 51.46999, 51.51874, 51.51806)

# Create matrixes from data

m_s <- matrix(data = c(s_lon, s_lat), nrow = 6, ncol = 2, byrow = FALSE)
m_e <- matrix(data = c(e_lon, e_lat), nrow = 6, ncol = 2, byrow = FALSE)

然后使用循环将每个矩阵中的数据转换为简单的特征几何点,并将每一对(起点和终点)组合成一个列表。

然后绘制每对起点/终点,以及连接它们的字符串。

n <- c(1:6)

myplotfct <- function(i, s1, e1, pt_s1.sfg, pt_e1.sfg, mylist) {
if(i == 1) {
    plot(mylist, axes = TRUE, xlim = c(-2.5, -1.8), ylim = c(51.3, 51.65), pch = 19, cex = 3, col = "red", )
    ln1 <- st_nearest_points(pt_s1.sfg, pt_e1.sfg) 
    plot(ln1, add = TRUE) 
 } else {    
    plot(mylist, add = TRUE, pch = 19, cex = 3, col = "blue")
    ln1 <- st_nearest_points(pt_s1.sfg, pt_e1.sfg) 
    plot(ln1, add = TRUE)
    
    }
 }

my_s <- function(n, .) {   # Start Pt Function
    m_s[n,]    
}


my_e <- function(n, .) {     # End Pt Function
    m_e[n,]
}

for(i in 1:6) {
    s1 <- my_s(i, m_s[x,])     #  Fct call
    e1 <- my_e(i, m_e[x,])
    
    pt_s1.sfg <- st_point(x = c(s1), dim = "XY")  # convert s1 to geometric 
    pt_e1.sfg <- st_point(x = c(e1), dim = "XY")   # convert e1 to geometric
    mylist <- c(pt_s1.sfg, pt_e1.sfg)              # create a list of the two geometric points (start - end)
    myplotfct(i, s1, e1, pt_s1.sfg, pt_e1.sfg, mylist)
   
}

如果需要,可以通过更改每对的颜色来改善输出。可以从这个link:查看输出

【讨论】:

  • 只是一个快速提示:如果您使用包reprex 来运行您的示例,您可以获取代码以直接复制/粘贴作为您的答案,其中包含嵌入式图形和所有内容。另外:我不明白你为什么在my_smy_e 的定义中有.,因为它似乎没有任何用途。
【解决方案2】:

在空白背景(无地图)上带有基本图形的简单箭头。

编辑:根据原始帖子中现在给出的数据,我意识到moves$startmoves$end 不是sfc 对象,而只是sfg 对象的列表。它们可以用sf::st_as_sfc 转换成sfc 对象,然后可以提取坐标。完整代码为:

library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
moves <- structure(
  list(hiring = c(1L, 2L, 4L, 6L, 7L, 8L), 
       start = list(
         structure(c(-2.03047447566941, 51.3630641761757),
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.31977575385362, 51.4616210429381), 
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.02584648038463, 51.4771163047678), 
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.42671091326068, 51.3807643595824), 
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.1166538974769, 51.4887039877758), 
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.12291705783767, 51.5860957106472), 
                   class = c("XY", "POINT", "sfg"))),
       end = list(
         structure(c(-2.25010169528537, 51.4160891285008), 
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.49118920138511, 51.4102939905029), 
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.06378098244424, 51.491583244303), 
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.13272163343155, 51.469987047928), 
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.20440279315621, 51.5187438721622), 
                   class = c("XY", "POINT", "sfg")), 
         structure(c(-2.1346350057738, 51.5180564842074), 
                   class = c("XY", "POINT", "sfg")))), 
       w.names = c(NA, 6L), class = "data.frame")

co_s <- st_coordinates(st_as_sfc(moves$start))
co_e <- st_coordinates(st_as_sfc(moves$end))
s_lon <- co_s[,"X"]
s_lat <- co_s[,"Y"]
e_lon <- co_e[,"X"]
e_lat <- co_e[,"Y"]
plot(c(s_lon, e_lon), c(s_lat, e_lat), col = rep(c("red", "blue"), each = 6),
     pch = 20, cex = 2, xlab = "lon", ylab = "lat")
arrows(s_lon, s_lat, e_lon, e_lat)

【讨论】:

  • 谢谢,但我的问题正是第二部分,如何从定义为 sfc 对象的点中获取坐标,或根据 sfc 点对绘制线。 st_coordinates 没有帮助。
  • 嗨,Ege,这太好了,非常感谢!剩下的唯一问题是这不适用于我的数据集;我收到的响应是“UseMethod 中的错误(“st_as_sfc”):没有适用于“st_as_sfc”的方法应用于类“c('sfc_POINT','sfc')”的对象。显然,移动是一个数据框,但这函数将其识别为其他东西。我想知道为什么?
  • 在您的示例 data.frame 中,列是类 sfg 的简单列表。在这种情况下,您必须使用命令st_as_sfg() 将它们转换为sfc 对象。如果你真正的data.frame 已经有sfc 类的列,你应该省略这部分。例如:co_s &lt;- st_coordinate(moves$start)。您可以使用lapply(moves, class) 检查每一列的类别。如果这解决了问题,请接受此答案,以便其他人可以看到问题已解决。
  • 我很高兴它成功了@Mikhail。请考虑按复选标记接受答案,以便其他人可以看到问题已解决。
猜你喜欢
  • 2020-01-04
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
  • 2015-04-09
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多