在这个shapefile中,几何列是线串,除了4个流到达(
8168547, 8171738, 8170616 ,8169920
)是多线串。
我需要将每个多线串仅转换为一个线串。 我尝试了很多方法但没有成功。例如,我在 R 的 sf 包中尝试了
st_cast
。但是,它增加了行数(它将每个多线串转换为多个线串)。
如何将每个多线串转换为仅一个线串?
explode
: 来完成
import geopandas as gpd
gdf = gpd.read_file(filepath)
exploded = gdf.explode()
正如您提到的,将多线串转换为线串的
{sf}
方法是通过sf::st_cast()
。
但是您的数据存在问题 - 某些流无法制作成简单的线串。线串必须有一个起点和一个终点 - 这对于某些 rcids 来说根本不可能。结果,你的一些对象最终被复制。
由于这是一个普遍的失败 - 而不是 R 特定的失败 - 我希望该评论对于 geopandas 也有效,尽管我还没有运行代码来验证。
我建议首先将对象转换为线串,然后识别重复项并将其过滤掉。
library(sf)
library(dplyr)
streams <- st_read("tukituki_rivStrah3.shp") %>%
select(-length) %>% # filtering out, as length is a derived metric
st_cast("LINESTRING")
duplicities <- streams %>%
st_drop_geometry() %>%
group_by(rchid) %>%
tally %>%
filter(n > 1) %>%
pull(rchid)
# this will not do...
mapview::mapview(streams[streams$rchid == duplicities[2],])
clean_streams <- streams %>%
filter(!rchid %in% duplicities)
如果您的多线串是干净的,则线段具有相同的方向并且它们已正确排序。你可以尝试这样的事情:
(但可能你必须先清理你的段:))
...
from shapely.geometry import LineString, Point
...
def multiline_to_single_line(geometry):
if isinstance(geometry, LineString):
return geometry
coords = list(map(lambda part: list(part.coords), geometry.geoms))
flat_coords = [Point(*point) for segment in coords for point in segment]
return LineString(flat_coords)
gdf['geometry'] = gdf['geometry'].apply(multiline_to_single_line)