我试图通过沿线的成对点分割大线条形状。根据以前的问题主要由@mbcaradima here,here,here和here提出,我已经汇总了一些适用于单点的代码,但不适用于多个点。
请参阅下面的可重复示例:
# libraries
library(tidyverse)
library(sf)
library(rgdal)
library(sp)
river <- structure(list(FWK_Code = structure(1L, .Label = "1_F461", class = "factor"),
FWK_Name = structure(1L, .Label = "Glonn von Odelzhausen bis Mündung in die Amper", class = "factor"),
Achse_SWK = structure(NA_integer_, .Label = character(0), class = "factor"),
GEWKZ_11 = structure(1L, .Label = "1648", class = "factor"),
NAM11_SEG = structure(1L, .Label = "Glonn", class = "factor"),
GWO11_SEG = structure(1L, .Label = "1330", class = "factor"),
FKT11_SEG = structure(1L, .Label = "2403", class = "factor"),
ZUST_WWA = structure(1L, .Label = "M", class = "factor"),
ZUST_REG = structure(1L, .Label = "OB", class = "factor"),
FF_LAND = structure(1L, .Label = "DEBY", class = "factor"),
GEW_TYP_K = structure(1L, .Label = "F2.2", class = "factor"),
GEW_TYP_L = structure(1L, .Label = "Kleine Flüsse des Alpenvorlandes", class = "factor"),
HMWB = structure(1L, .Label = "HMWB", class = "factor"),
length_m = 27210, code_vis = structure(1L, .Label = "1_F461", class = "factor"),
geometry = structure(list(structure(c(4454482.82717063, 4454477.69,
4454464.67, 4454447.61, 4454437.73, 4454426.51, 4454409.9,
4454391.94, 4454373.98, 4454359.62, 4454344.8, 4454335.82,
4454317.21, 4454313.45, 4454312.77, 4454309.34, 4454300.59,
4454291.38, 4454284.64, 4454268.93, 4454253.67, 4454234.36,
4454211.47, 4454186.33, 4454158.04, 4454140.98, 4454133.83,
4454125.77, 4454120.53, 4454117.07, 4454097.87, 4454073.83,
4454011.25, 4453877.38, 4453783.85, 4453742.74, 4453742.32,
4453727.02, 4453716.29, 4453710.08, 4453698.84, 4453688.08,
4453682.1, 4453664.37, 4453653.96, 4453641.58, 4453618.07,
4453588.82, 4453561.8, 4453548.29, 4453537.32, 4453529.3,
4453523.71, 4453522.55, 4453517.06, 4453514.53, 4453514.95,
4453523.81, 4453525.5, 4453522.97, 4453510.31, 4453495.53,
4453463.67, 4453452.21, 4453432.45, 4453423.25, 4453395.29,
4453350.73, 4453259.43, 4453181.41, 4453163.58, 4453158.68,
4453154.58, 4453146.63, 4453134.59, 4453098.66, 4453000.7,
4452909.68, 4452627.91, 4452620.51, 4452562.96, 4452508.19,
4452448.4, 4452400.29, 4452376.72, 4452311.09, 4452225.2,
4452203.98, 4452176.98, 4452166.66, 4452135.14, 4452101.77,
4452052.37, 4452014.28, 4451988.32, 4451899.24, 4451893.85,
4451871.58, 4451817.72, 4451785.2, 4451761.21, 4451731.24,
4451712.01, 4451693.25, 4451682.14, 4451657.13, 4451636.02,
4451630.51, 4451622.89, 4451615.39, 4451591.93, 4451581.61,
4451560.51, 4451537.06, 4451523.92, 4451511.73, 4451483.78,
4451476.25, 4451471.86, 4451469.3, 4451438.56, 4451384.62,
4451284.5, 4451259.71, 4451221.42, 4451119.19, 4451110.21,
4451107.87, 4451099.18, 4451091.28, 4451046.03, 4450945.32,
4450884.24, 4450846.94, 4450819.81, 4450790.1, 4450758.62,
4450714.54, 4450696.54, 4450669.05, 4450656.15, 4450619.21,
4450587.43, 4450583.75, 4450567.55, 4450507.21, 4450483.95,
4450465.2, 4450375.63, 4450354.81, 4450328, 4450252.04, 4450237.08,
4450220.65, 4450187.34, 4450152.66, 4450131.38, 4450124.66,
4450110.43, 4450085.02, 4450056.18, 4450033.86, 4450018.41,
4449976.87, 4449966.73, 4449964.81, 4449954.93, 4449938.61,
4449917.72, 4449902.2, 4449887.72, 4449884.86, 4449859, 4449853.42,
4449849, 4449844.8, 4449803.42, 4449777.71, 4449752.73, 4449744.70318071,
5358599.95603184, 5358596.63, 5358590.34, 5358582.71, 5358576.42,
5358568.79, 5358556.22, 5358541.86, 5358527.04, 5358514.47,
5358500.11, 5358493.82, 5358477.42, 5358473.28, 5358472.52,
5358468.68, 5358456.59, 5358443.54, 5358432.76, 5358410.32,
5358389.67, 5358362.73, 5358328.61, 5358290.45, 5358242.86,
5358215.93, 5358210, 5358204.52, 5358201.19, 5358198.95,
5358187.14, 5358181.75, 5358176.36, 5358173.05, 5358175.29,
5358176.19, 5358176.2, 5358172.41, 5358157.12, 5358147.5,
5358123.63, 5358104, 5358093.08, 5358067.75, 5358055.79,
5358041.58, 5358016, 5357984.17, 5357955.89, 5357933.94,
5357912.84, 5357896.38, 5357876.81, 5357872.74, 5357846.99,
5357828.42, 5357811.11, 5357733.87, 5357711.07, 5357689.55,
5357645.65, 5357603.02, 5357523.83, 5357493.98, 5357445.35,
5357424.83, 5357379.53, 5357334.4, 5357245.54, 5357170.31,
5357153.66, 5357149.82, 5357146.6, 5357140.36, 5357130.91,
5357110.43, 5357055.29, 5357002.09, 5356939.82, 5356937.7,
5356920.74, 5356906.82, 5356890.51, 5356880.48, 5356875.56,
5356856.4, 5356828.51, 5356822.82, 5356812.72, 5356808.62,
5356788.72, 5356764.09, 5356726.68, 5356706.5, 5356696.34,
5356684.31, 5356683.6, 5356679.74, 5356656.68, 5356636.56,
5356613.5, 5356583.86, 5356560.41, 5356531.79, 5356511.3,
5356451.12, 5356398.12, 5356387.4, 5356381.23, 5356374.67,
5356363.88, 5356362, 5356357.31, 5356355.43, 5356355.43,
5356357.31, 5356362.31, 5356363.6, 5356364.35, 5356364.6,
5356367.63, 5356373.26, 5356382.3, 5356382.62, 5356379.07,
5356353.88, 5356351.95, 5356351.44, 5356348.99, 5356347.05,
5356335.95, 5356307.71, 5356291.47, 5356283.7, 5356278.35,
5356278.2, 5356289.69, 5356311.72, 5356321.69, 5356330.54,
5356332.74, 5356335.88, 5356329.43, 5356328.02, 5356321.84,
5356294.15, 5356285.09, 5356277.79, 5356250.55, 5356243.77,
5356235.05, 5356200.51, 5356193.71, 5356184.67, 5356163.04,
5356144.16, 5356135.23, 5356134.24, 5356132.14, 5356131.8,
5356136.6, 5356145.19, 5356151.37, 5356173.49, 5356177.49,
5356178.04, 5356178.04, 5356176.53, 5356173.65, 5356168.12,
5356161.8, 5356159.97, 5356138.51, 5356131.75, 5356126.26,
5356121.43, 5356074.91, 5356049.16, 5356016.55, 5356007.68509448
), .Dim = c(180L, 2L), class = c("XY", "LINESTRING", "sfg"
))), class = c("sfc_LINESTRING", "sfc"), precision = 0, bbox = structure(c(xmin = 4449744.70318071,
ymin = 5356007.68509448, xmax = 4454482.82717063, ymax = 5358599.95603184
), class = "bbox"), crs = structure(list(epsg = NA_integer_,
proj4string = "+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0 +ellps=bessel +towgs84=598.1,73.7,418.2,0.202,0.045,-2.455,6.7 +units=m +no_defs"), class = "crs"), n_empty = 0L)), row.names = 0L, class = c("sf",
"data.frame"), sf_column = "geometry", agr = structure(c(FWK_Code = NA_integer_,
FWK_Name = NA_integer_, Achse_SWK = NA_integer_, GEWKZ_11 = NA_integer_,
NAM11_SEG = NA_integer_, GWO11_SEG = NA_integer_, FKT11_SEG = NA_integer_,
ZUST_WWA = NA_integer_, ZUST_REG = NA_integer_, FF_LAND = NA_integer_,
GEW_TYP_K = NA_integer_, GEW_TYP_L = NA_integer_, HMWB = NA_integer_,
length_m = NA_integer_, code_vis = NA_integer_), class = "factor", .Label = c("constant",
"aggregate", "identity")))
sites <- st_line_sample(river, density = 1/1500) %>%
st_jitter(500) %>%
st_sf() %>%
st_cast('POINT') %>%
mutate(group = c(1,1,2,2)) %>%
mutate(type = rep(c("start","stop"),2))
mapview(sites) + river
仅使用一个站点,以下代码有效。由于spapped点与线不完全相交,我添加了一个小缓冲区。这不是很优雅,但会适合我的情况。
nrst = st_nearest_points(sites, river)
on_line = st_cast(nrst, "POINT")[2]
buf <- st_buffer(on_line,0.1)
parts = st_collection_extract(lwgeom::st_split(river$geometry, buf),"LINESTRING")
mapview(parts[1],color="red",lwd=5) + mapview(parts[2],color="green",lwd=5) + mapview(parts[3],lwd=5)
使用多个站点生成Error in st_split.sfc(river$geometry, buf_all) :
length(y) == 1 is not TRUE
on_line_all = st_cast(nrst, "POINT")
buf_all <- st_buffer(on_line_all,0.1)
parts_all = st_collection_extract(lwgeom::st_split(river$geometry, buf_all),"LINESTRING")
不幸的是,在这种情况下,我不确定“y”是什么。而且,如果起始点和停止点对之间的所有线段可以自动保存到单独的对象,而不是必须手动选择它们,那将是理想的。 QGIS。
任何建议将不胜感激!
原来lwgeom::st_split
的文档中有错误。它说y
是
物体分裂(刀片);如果y包含多个要素几何,则几何是st_combined
但是,在提供多功能st_combine
时(如在您的情况下),它们不是sfc
d。
要让你的st_split
工作,你需要事先将它们结合起来:
on_line_all = st_cast(nrst, "POINT")
buf_all <- st_combine(st_buffer(on_line_all,0.1))
parts_all = st_collection_extract(lwgeom::st_split(river$geometry, buf_all),"LINESTRING")
parts_all = st_as_sf(
data.frame(
id = 1:length(parts_all),
geometry = parts_all
)
)
mapview(parts_all, burst = "id")
不确定它是否是您正在寻找的,但是此函数将LINESTRING
或POLYGON
分解为由几何体本身的坐标定义的段:
stdh_cast_substring <- function(x, to = "MULTILINESTRING") {
ggg <- st_geometry(x)
if (!unique(st_geometry_type(ggg)) %in% c("POLYGON", "LINESTRING")) {
stop("Input should be LINESTRING or POLYGON")
}
for (k in 1:length(st_geometry(ggg))) {
sub <- ggg[k]
geom <- lapply(
1:(length(st_coordinates(sub)[, 1]) - 1),
function(i)
rbind(
as.numeric(st_coordinates(sub)[i, 1:2]),
as.numeric(st_coordinates(sub)[i + 1, 1:2])
)
) %>%
st_multilinestring() %>%
st_sfc()
if (k == 1) {
endgeom <- geom
}
else {
endgeom <- rbind(endgeom, geom)
}
}
endgeom <- endgeom %>% st_sfc(crs = st_crs(x))
if (class(x)[1] == "sf") {
endgeom <- st_set_geometry(x, endgeom)
}
if (to == "LINESTRING") {
endgeom <- endgeom %>% st_cast("LINESTRING")
}
return(endgeom)
}
您可能想查看我描述函数Cast a line to subsegments in R.的帖子