将每个多线串仅转换为一个线串

问题描述 投票:0回答:3

在这个shapefile中,几何列是线串,除了4个流到达(

8168547, 8171738, 8170616 ,8169920
)是多线串。

我需要将每个多线串仅转换为一个线串。 我尝试了很多方法但没有成功。例如,我在 R 的 sf 包中尝试了

st_cast
。但是,它增加了行数(它将每个多线串转换为多个线串)。

如何将每个多线串转换为仅一个线串?

geopandas r-sf multilinestring
3个回答
5
投票

在 geopandas 中,这可以通过

explode
:

来完成
import geopandas as gpd
gdf = gpd.read_file(filepath)
exploded = gdf.explode()

2
投票

正如您提到的,将多线串转换为线串的

{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)

0
投票

如果您的多线串是干净的,则线段具有相同的方向并且它们已正确排序。你可以尝试这样的事情:

(但可能你必须先清理你的段:))

...
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)
© www.soinside.com 2019 - 2024. All rights reserved.