使用 sf 包从点到缓冲区通过平滑线
From points to buffer passing through a smoothed line using sf package
我有很多我必须在 R 中操作的点的 shapefile。
我的目标是 link 所有点都用一条线,平滑它(重新创建一种通过点的路径),将平滑线分割成小部分(每个部分必须有精确的长度)然后创建一个缓冲区对于每个线段(然后从线转换为多边形),最后计算多边形内的点。
我开始导入积分:
p <- st_read("/points.shp")
然后我创建行:
l <- p %>% st_coordinates() %>% st_linestring()
从直线到平滑线:
ls <- smooth(l, method = "ksmooth")
然后我创建了分段平滑线:
sls = st_segmentize(ls, 50)
最后是我的缓冲区:
mybuf <- st_buffer(sls, dist= 30, endCapStyle="ROUND")
不幸的是,使用最后一条命令我只能创建一个缓冲区,但我必须为每个部分获得一个长度为 50 米、高度为 30m 的“分段”缓冲区。
我正在使用 WGS84/UTM zone 32 N,epsg 32632 投影,我的缓冲区必须具有相同的投影。
也许还有另一种方法可以做到这一点?谢谢...
Here link 下载shapefile的一个子集
据我所知,要克服的主要问题是您的代码将通过点的线定义为单个特征,因此 st_buffer
是围绕整条线而不是每个线段绘制缓冲区点之间。我的目标是弄清楚如何确保每个 50 米段都是一个独特的功能。
library(sf)
library(smoothr)
cols <- c("red", "blue", "yellow")
source_file <- "./punti.shp"
par(mfrow = c(2,4))
p <- st_read(source_file)
plot(st_geometry(p), col = cols, main = "points")
l <- p %>% st_coordinates() %>% st_linestring()
plot(st_geometry(l), col = cols, main = "line")
l <- st_as_sf(data.frame(id = 1, geom=st_geometry(l)))
ls <- smooth(l, method = "ksmooth")
plot(st_geometry(ls), col = cols, main = "smoothed line")
# Note that segmentize doesn't slice a line
# Instead, it seems to just increases the number of vertices
sls <- st_segmentize(ls, 50)
slsp <- st_cast(sls, "POINT")
plot(st_geometry(slsp), col = cols, main = "segmented line vertices")
# Draw line between pairs of consecutive points
slsp <- st_as_sf(data.frame(id = 1, geom=st_geometry(slsp)))
slsp2 <- cbind(slsp[-nrow(slsp),"geometry"], slsp[-1,"geometry"])
ll <- st_sfc(mapply(function(a,b){
st_cast(st_union(a,b),"LINESTRING")}, slsp2$geometry, slsp2$geometry.1, SIMPLIFY=FALSE))
plot(st_geometry(ll), col = cols, main = "manually segmented line")
plot(st_geometry(head(ll)), col = cols, main = "man. segmented line, 1-10")
# Assign crs
st_crs(ll)
st_crs(ll) <- st_crs(p)
# Calculate buffers
mybuf <- st_buffer(ll, dist= 30, endCapStyle="ROUND")
plot(st_geometry(mybuf), col = cols, main = "buffers, all")
plot(st_geometry(head(mybuf)), col = cols, main = "buffers, 1-10")
# Count points in buffers
lengths(st_intersects(mybuf, p))
我有很多我必须在 R 中操作的点的 shapefile。 我的目标是 link 所有点都用一条线,平滑它(重新创建一种通过点的路径),将平滑线分割成小部分(每个部分必须有精确的长度)然后创建一个缓冲区对于每个线段(然后从线转换为多边形),最后计算多边形内的点。
我开始导入积分:
p <- st_read("/points.shp")
然后我创建行:
l <- p %>% st_coordinates() %>% st_linestring()
从直线到平滑线:
ls <- smooth(l, method = "ksmooth")
然后我创建了分段平滑线:
sls = st_segmentize(ls, 50)
最后是我的缓冲区:
mybuf <- st_buffer(sls, dist= 30, endCapStyle="ROUND")
不幸的是,使用最后一条命令我只能创建一个缓冲区,但我必须为每个部分获得一个长度为 50 米、高度为 30m 的“分段”缓冲区。 我正在使用 WGS84/UTM zone 32 N,epsg 32632 投影,我的缓冲区必须具有相同的投影。 也许还有另一种方法可以做到这一点?谢谢...
Here link 下载shapefile的一个子集
据我所知,要克服的主要问题是您的代码将通过点的线定义为单个特征,因此 st_buffer
是围绕整条线而不是每个线段绘制缓冲区点之间。我的目标是弄清楚如何确保每个 50 米段都是一个独特的功能。
library(sf)
library(smoothr)
cols <- c("red", "blue", "yellow")
source_file <- "./punti.shp"
par(mfrow = c(2,4))
p <- st_read(source_file)
plot(st_geometry(p), col = cols, main = "points")
l <- p %>% st_coordinates() %>% st_linestring()
plot(st_geometry(l), col = cols, main = "line")
l <- st_as_sf(data.frame(id = 1, geom=st_geometry(l)))
ls <- smooth(l, method = "ksmooth")
plot(st_geometry(ls), col = cols, main = "smoothed line")
# Note that segmentize doesn't slice a line
# Instead, it seems to just increases the number of vertices
sls <- st_segmentize(ls, 50)
slsp <- st_cast(sls, "POINT")
plot(st_geometry(slsp), col = cols, main = "segmented line vertices")
# Draw line between pairs of consecutive points
slsp <- st_as_sf(data.frame(id = 1, geom=st_geometry(slsp)))
slsp2 <- cbind(slsp[-nrow(slsp),"geometry"], slsp[-1,"geometry"])
ll <- st_sfc(mapply(function(a,b){
st_cast(st_union(a,b),"LINESTRING")}, slsp2$geometry, slsp2$geometry.1, SIMPLIFY=FALSE))
plot(st_geometry(ll), col = cols, main = "manually segmented line")
plot(st_geometry(head(ll)), col = cols, main = "man. segmented line, 1-10")
# Assign crs
st_crs(ll)
st_crs(ll) <- st_crs(p)
# Calculate buffers
mybuf <- st_buffer(ll, dist= 30, endCapStyle="ROUND")
plot(st_geometry(mybuf), col = cols, main = "buffers, all")
plot(st_geometry(head(mybuf)), col = cols, main = "buffers, 1-10")
# Count points in buffers
lengths(st_intersects(mybuf, p))