将每个多线链转换为仅一个linestring

发布于 2025-02-04 19:24:58 字数 495 浏览 2 评论 0原文

在此 8168547,8171738,8170616,8169920 )是多inineString的。

我需要将每个多界线转换为一个linestring。 我尝试过很多事情,但没有任何事情可以。例如,我在R中的SF软件包中尝试了st_cast。但是,它增加了行的数量(它将每个多线线转换为几个线条)。

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

In this shapefile, the geometry column is linestring apart from 4 stream reaches (8168547, 8171738, 8170616 ,8169920) that are multilinestring.

enter image description here

I need to convert each multilinestring to one linestring only .
I have tried many things but none worked. For example, I tried st_cast in sf package in R. However, it increased the number of the rows (it converts each multilinestring to several linestrings).

How can I convert each multilinestring to one linestring only?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

四叶草在未来唯美盛开 2025-02-11 19:24:58

在geopandas中,可以用

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

in geopandas, this can be done with explode:

import geopandas as gpd
gdf = gpd.read_file(filepath)
exploded = gdf.explode()
◇流星雨 2025-02-11 19:24:58

正如您提到的那样,将多in子转换为线索的{sf}通过sf :: st_cast(),将是通过sf :: ST_CAST()。

但是您的数据存在问题 - 某些流无法进入简单的线条。 linestring必须具有一个起点和一个终点 - 对于某些RCHID来说,这根本是不可能的。结果,您的某些对象最终被复制。

由于这是一个普遍的失败 - 而不是特定的故障 - 我希望该评论对地理杂物也有效,尽管我没有运行代码来验证。

我建议首先将您的对象投入到线林中,然后识别重复物并将其过滤掉。

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)

The {sf} way of converting multilinestrings to linestrings would be, as you mention, via sf::st_cast().

But there is a problem with your data - some of the streams are not possible to make into simple linestrings. A linestring must have a single start and a single end point - this is simply not possible for some of your rchids. As a result some of your objects end up being duplicated.

As this is a general failure - and not a R specific one - I would expect the comment to be valid also for geopandas, although I have not ran the code to verify.

I suggest first casting your object to linestrings, then identifying duplicites and filtering them out.

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],])

enter image description here

clean_streams <- streams %>% 
  filter(!rchid %in% duplicities)
彡翼 2025-02-11 19:24:58

在Geopandas中,您可以合并Linesements。如果您的多轨道干净,则段的方向相同,并且对它们进行了正确的分类。您可以尝试这样的事情:(

但可能您必须首先清洁您的细分市场:))

...
from shapely.geometry import LineString, Point
...

def multiline_to_single_line(geometry: Union[LineString, MultiLineString]) -> LineString:
  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)

In geopandas you can merge linesegments. If your multilinestring is clean, segments have the same direction and they are properly sorted. You can try something like that:

(But probably you have to clean your segments first :))

...
from shapely.geometry import LineString, Point
...

def multiline_to_single_line(geometry: Union[LineString, MultiLineString]) -> LineString:
  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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文