luukvdmeer / sfnetworks

Tidy Geospatial Networks in R
https://luukvdmeer.github.io/sfnetworks/
Other
347 stars 20 forks source link

to_spatial_smooth returns multilinestring when merged edge crosses itself #117

Closed loreabad6 closed 2 years ago

loreabad6 commented 3 years ago

Describe the bug I have a test network, created from points. When I pass it to to_spatial_smooth() it returns a network with edges as MULTILINESTRING geometries,

Reproducible example

library(sf)
library(sfnetworks)
library(tidygraph)

# Toy sfnetwork
p1 = st_point(c(0, 1))
p2 = st_point(c(1, 1))
p3 = st_point(c(2, 1))
p4 = st_point(c(3, 1))
p5 = st_point(c(4, 1))
p6 = st_point(c(3, 2))
p7 = st_point(c(3, 0))
p8 = st_point(c(4, 3))
p9 = st_point(c(4, 2))
p10 = st_point(c(4, 0))
p11 = st_point(c(5, 2))
p12 = st_point(c(5, 0))
p13 = st_point(c(5, -1))

# Create network from points
points = st_sfc(st_multipoint(c(p1, p2, p3, p4, p5, p6, p4, p7, p5, p8,
                                p11, p9, p5, p10, p12, p13, p10)))
net_p = as_sfnetwork(st_cast(points, "POINT")) 
net_p
#> # A sfnetwork with 17 nodes and 16 edges
#> #
#> # CRS:  NA 
#> #
#> # A rooted tree with spatially explicit edges
#> #
#> # Node Data:     17 x 1 (active)
#> # Geometry type: POINT
#> # Dimension:     XY
#> # Bounding box:  xmin: 0 ymin: -1 xmax: 5 ymax: 3
#>         x
#>   <POINT>
#> 1   (0 1)
#> 2   (1 1)
#> 3   (2 1)
#> 4   (3 1)
#> 5   (4 1)
#> 6   (3 2)
#> # ... with 11 more rows
#> #
#> # Edge Data:     16 x 3
#> # Geometry type: LINESTRING
#> # Dimension:     XY
#> # Bounding box:  xmin: 0 ymin: -1 xmax: 5 ymax: 3
#>    from    to            x
#>   <int> <int> <LINESTRING>
#> 1     1     2   (0 1, 1 1)
#> 2     2     3   (1 1, 2 1)
#> 3     3     4   (2 1, 3 1)
#> # ... with 13 more rows
smoo_p = convert(net_p, to_spatial_smooth)
smoo_p
#> # A sfnetwork with 2 nodes and 1 edges
#> #
#> # CRS:  NA 
#> #
#> # A rooted tree with spatially explicit edges
#> #
#> # Node Data:     2 x 2 (active)
#> # Geometry type: POINT
#> # Dimension:     XY
#> # Bounding box:  xmin: 0 ymin: 0 xmax: 4 ymax: 1
#>         x .tidygraph_node_index
#>   <POINT>                 <int>
#> 1   (0 1)                     1
#> 2   (4 0)                    17
#> #
#> # Edge Data:     1 x 4
#> # Geometry type: MULTILINESTRING
#> # Dimension:     XY
#> # Bounding box:  xmin: 0 ymin: -1 xmax: 5 ymax: 3
#>    from    to                                               x .tidygraph_edge_i~
#>   <int> <int>                               <MULTILINESTRING> <named list>      
#> 1     1     2 ((0 1, 1 1, 2 1, 3 1), (3 1, 4 1), (4 1, 3 2, ~ <dbl [16]>

Expected behavior The morpher should return edges with LINESTRINGs.

luukvdmeer commented 3 years ago

So this seems to happen when a merged edge crosses itself. That is not a valid linestring according to the simple feature standard and st_line_merge therefore refuses to merge them. This is not so easy to solve when using st_line_merge. The alternative could be to implement our own line merging function, e.g. by using sfheaders, but there are a lot of things to take into consideration when doing so.

Since this is quite an unusual case I'll mark this issue as low priority, but it is indeed a bug.

luukvdmeer commented 2 years ago

Fixed in v0.6.0