还有一些其他的帖子,比如Post 1Post 2Post 3.然而,它们都没有实现我的期望.我想要的是能够从一个特定的点(采样位置)到一个完全围绕该点(湖泊边界)的多边形边缘,在一个特定的方向("正南"即向下)绘制一条线段.然后我想测量采样点和多边形边之间的线段的长度(实际上,这只是我想要的距离,所以如果我们不绘制线段就可以得到距离,那就更好了!).不幸的是,sfSee closed issue here中似乎没有实现这一点的功能.

I suspect,但是,这是可能的,通过修改这里提供的解决方案:See copy-pasted code below, modified by me.然而,我对sf中的工具非常不熟悉——我甚至制作了从点本身到多边形南部的线段,在某个点与多边形相交:

library(sf)
library(dplyr)

df = data.frame(
  lon = c(119.4, 119.4, 119.4, 119.5, 119.5),
  lat = c(-5.192,-5.192,-5.167,-5.167,-5.191)
)

polygon <- df %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  summarise(geometry = st_combine(geometry)) %>%
  st_cast("POLYGON")

plot(polygon)

df2 <- data.frame(lon = c(119.45, 119.49, 119.47),
                  lat = c(-5.172,-5.190,-5.183))

points <- df2 %>%
  st_as_sf(coords = c("lon", "lat"), crs = 4326) %>%
  summarise(geometry = st_combine(geometry)) %>%
  st_cast("MULTIPOINT")

plot(points, add = TRUE, col = "red")

# Solution via a loop

xmin <- min(df$lat)

m = list()
# Iterate and create lines
for (i in 1:3) {
  m[[i]] = st_linestring(matrix(
    c(df2[i, "lon"],
      df2[i, "lat"],
      df2[i, "lon"],
      xmin),
    nrow = 2,
    byrow = TRUE
  ))
}
test = st_multilinestring(m)

# Result is line MULTILINESTRING object

plot(test, col = "green", add = TRUE)

progress so far

但现在我不知道如何使用st_intersection或任何类似的函数来计算交点的位置.我认为,大多数问题在于,我正在创建的不是sf对象,我不知道如何使其成为sf对象.理想情况下,我可以用st_distance点的交点来测量,如果我可以用st_distance点的交点来测量的话.然而,由于湖泊多边形通常是复杂的,因此一段可能会多次与多边形相交(例如,如果给定点以南有一个半岛),在这种情况下,我想我可以找到每个采样点的"最北边"交点,并使用该交点,或者取每个采样点的最小距离.

不管怎样,如果有人能告诉我我错过的几步,那就太好了!我觉得我离得很近,但却离得很远...

推荐答案

考虑一下这个方法,灵感来self 之前的文章大约lines from points.

为了使其更具可复制性,我使用了著名的&;深受喜爱的北卡罗来纳州shapefile附带{sf}和三个半随机NC城市的数据框.

代码的作用是:

  • 通过for cycle在城市数据帧上迭代
  • 创建一条从每个城市("观测")开始到南极的线
  • 与北卡罗来纳州相交
  • 将交点爆破为单个线串
  • Select 在原点1米范围内经过的线串
  • 通过sf::st_lenghth()计算长度
  • 将结果保存为名为res的{sf}数据帧(result:)

为了使结果更清晰,我在最终对象中加入了实际线条,但您可以 Select 忽略它.

library(sf)
library(dplyr)
library(ggplot2)

shape <- st_read(system.file("shape/nc.shp", package="sf")) %>%  # included with sf package
  summarise() %>% 
  st_transform(4326) # to align CRS with cities

cities <- data.frame(name = c("Raleigh", "Greensboro", "Plymouth"),
                     x = c(-78.633333, -79.819444, -76.747778),
                     y = c(35.766667, 36.08, 35.859722)) %>% 
  st_as_sf(coords = c("x", "y"), crs = 4326)

# a quick overview
ggplot() +
   geom_sf(data = shape) + # polygon of North Carolina
   geom_sf(data = cities, color = "red") # 3 cities  

![enter image description here

# now here's the action!!!
for (i in seq_along(cities$name)) {
  
  # create a working linestring object
  wrk_line <- st_coordinates(cities[i, ]) %>% 
    rbind(c(0, -90)) %>% 
    st_linestring() %>% 
    st_sfc(crs = 4326) %>% 
    st_intersection(shape) %>% 
    st_cast("LINESTRING") # separate individual segments of multilines
  
  first_segment <- unlist(st_is_within_distance(cities[i, ], wrk_line, dist = 1))  
  
  # a single observation
  line_data <- data.frame(
    name = cities$name[i],
    length = st_length(wrk_line[first_segment]),
    geometry = wrk_line[first_segment]
  )
  
  # bind results rows to a single object
  if (i == 1) {
    res <- line_data
    
  } else {
    res <- dplyr::bind_rows(res, line_data)
    
  } # /if - saving results
  
  
} # /for

# finalize results
res <- sf::st_as_sf(res, crs = 4326) 
  
# result object    
res
# Simple feature collection with 3 features and 2 fields
# Geometry type: LINESTRING
# Dimension:     XY
# Bounding box:  xmin: -79.81944 ymin: 33.92945 xmax: -76.74778 ymax: 36.08
# Geodetic CRS:  WGS 84
#         name        length                       geometry
# 1    Raleigh 204289.21 [m] LINESTRING (-78.63333 35.76...
# 2 Greensboro 141552.67 [m] LINESTRING (-79.81944 36.08...
# 3   Plymouth  48114.32 [m] LINESTRING (-76.74778 35.85...

# a quick overview of the lines
ggplot() +
  geom_sf(data = shape) + # polygon of North Carolina
  geom_sf(data = res, color = "red") # 3 lines

enter image description here

R相关问答推荐

按R中不同长度的组将日期时间列值四舍五入到小时

rvest函数read_html_live()不允许html_elements()正确读取

如何提高以键ID为列的表中键查找的效率?

过滤Expand.Grid的结果

通过使用str_detect对具有相似字符串的组进行分组

par函数中的缩写,比如mgp,mar,mai是如何被破译的?

将饼图插入条形图

提取第一个下划线和最后一个下划线之间的任何内容,例外情况除外

如何提取所有完美匹配的10个核苷酸在一个成对的匹配与生物字符串在R?>

如何指定我的函数应该查找哪个引用表?

从服务器在Shiny中一起渲染图标和文本

基于R中的间隔扩展数据集行

Ggplot2中geom_tile的动态zoom

`夹心::vcovCL`不等于`AER::tobit`标准错误

将列表中的字符串粘贴到R中for循环内的dplyr筛选器中

R中时间间隔的大向量与参考时间间隔的相交

生存时间序列的逻辑检验

如何在R中创建这些列?

将数据从一列转换为按组累计计数的单个虚拟变量

使用同一行中的前一个值填充R矩阵中的缺失值