【发布时间】:2019-09-17 11:51:09
【问题描述】:
我有一条平滑线(海岸线的简化抽象),它是 linestring,我想沿着它以频繁的间隔测量线的长度。我可以创建平滑线,并测量它的长度:
library(raster)
library(sf)
library(tidyverse)
library(rnaturalearth)
library(smoothr)
# create bounding box for the line
xmin=-80
xmax=-66
ymin=24
ymax=45
bbox <- extent(xmin, xmax, ymin, ymax)
# get coarse outline of the US
usamap <- rnaturalearth::ne_countries(scale = "small", country = "united states of america", returnclass = "sf")[1] %>%
st_cast("MULTILINESTRING")
# crop to extent of the bbox and get rid of a border line that isn't coastal
bbox2 <- st_set_crs(st_as_sf(as(raster::extent(-80, -74, 42, 45.5), "SpatialPolygons")), st_crs(usamap))
cropmap <- usamap %>%
st_crop(bbox) %>%
st_difference(bbox2)
# smooth the line
smoothmap <- cropmap %>%
smoothr::smooth(method="ksmooth", smoothness=8)
# measure the line length
st_length(smoothmap) # I get 1855956m
我将把样本站点“捕捉”到沿这条线的点,我需要知道它们沿海岸线有多远。但是,我不知道如何沿着海岸线每隔一段时间测量线的长度。间隔大小并不是非常重要,只要它具有相对精细的分辨率,可能每 1 公里或每 0.01 度。
我想要生成的是一个数据框,其中 x,y 列包含沿线的点的纬度/经度,以及包含沿线距离(从原点到该点)的“长度”列。以下是我尝试过的一些事情:
迭代边界框。我尝试用越来越小的边界框裁剪线(使用纬度/经度的规则间隔),但是因为线在 -76、38 附近“向后”弯曲,一些裁剪框不包含我预期的完整线段。这种方法适用于该行的右上半部分,但不适用于左下半部分——它只返回零长度。
在实现平滑之前先裁剪范围,然后测量线条。 由于平滑功能如果只是测量原始线条的一部分,则不会产生相同的形状,因此这不会实际上沿着同一条线测量距离。
用st_coordinates获取linestring的坐标,剪掉一行(线上的一个点),并将剩余的坐标重铸为linestring。这种方法不产生一个linestring,而是一个点链(因为st_cast不知道如何再次连接它们),因此无法正常测量。
理想的做法是“编辑”smoothmap 的几何图形,一次删除一行坐标,重复测量直线,然后将终点坐标和直线长度写入数据帧。但是,我不确定是否可以编辑 sf 对象的坐标而不将其转换为数据框。
【问题讨论】: