sfnetworks
sfnetworks copied to clipboard
to_spatial_subdivision merges nodes with equal coordinates
Describe the bug
The goal of the to_spatial_subdivision morpher is to subdivide edges at locations where an interior point of that edges matches either an interior point or endpoint of another edge. Internally, it recreates a network. Unintentionally that means now that in networks that has different nodes with equal coordinates, these nodes ar merged into a single node. That is not the goal of the morpher and should therefore not happen. Or is this actually convenient? I am not sure.
Reproducible example The original network has two nodes (node 2 and node 3) with equal coordinates. Also it has an interior point in edge 1 that is shared with an interior point in edge 2. The subdivision morpher correctly subdivides edge 1 and edge 2 and adds a new node at their intersection. However, it also merged node 2 and node 3 into a single node.
library(sfnetworks)
library(sf)
#> Linking to GEOS 3.9.0, GDAL 3.2.0, PROJ 7.2.0
library(tidygraph)
#>
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:stats':
#>
#> filter
p1 = st_point(c(0, 1))
p2 = st_point(c(3, 1))
p3 = st_point(c(4, 1))
p4 = st_point(c(3, 2))
p5 = st_point(c(3, 0))
p6 = st_point(c(4, 2))
pts = st_cast(st_sfc(c(p1, p3, p3, p4, p5, p6)), "POINT")
l1 = st_sfc(st_linestring(c(p1, p2, p3)))
l2 = st_sfc(st_linestring(c(p4, p2, p5)))
l3 = st_sfc(st_linestring(c(p3, p6)))
lns = c(l1, l2, l3)
nodes = st_sf(geom = pts)
edges = st_sf(from = c(1, 4, 3), to = c(2, 5, 6), geom = lns)
net = sfnetwork(nodes, edges)
#> Checking if spatial network structure is valid...
#> Spatial network structure is valid
net
#> # A sfnetwork with 6 nodes and 3 edges
#> #
#> # CRS: NA
#> #
#> # A rooted forest with 3 trees with spatially explicit edges
#> #
#> # Node Data: 6 x 1 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 0 ymin: 0 xmax: 4 ymax: 2
#> geom
#> <POINT>
#> 1 (0 1)
#> 2 (4 1)
#> 3 (4 1)
#> 4 (3 2)
#> 5 (3 0)
#> 6 (4 2)
#> #
#> # Edge Data: 3 x 3
#> # Geometry type: LINESTRING
#> # Dimension: XY
#> # Bounding box: xmin: 0 ymin: 0 xmax: 4 ymax: 2
#> from to geom
#> <int> <int> <LINESTRING>
#> 1 1 2 (0 1, 3 1, 4 1)
#> 2 4 5 (3 2, 3 1, 3 0)
#> 3 3 6 (4 1, 4 2)
plot(net)

new_net = convert(net, to_spatial_subdivision)
#> Warning: to_spatial_subdivision assumes attributes are constant over geometries
new_net
#> # A sfnetwork with 6 nodes and 5 edges
#> #
#> # CRS: NA
#> #
#> # A rooted tree with spatially explicit edges
#> #
#> # Node Data: 6 x 2 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 0 ymin: 0 xmax: 4 ymax: 2
#> geom .tidygraph_node_index
#> <POINT> <int>
#> 1 (0 1) 1
#> 2 (3 1) NA
#> 3 (4 1) 2
#> 4 (3 2) 4
#> 5 (3 0) 5
#> 6 (4 2) 6
#> #
#> # Edge Data: 5 x 4
#> # Geometry type: LINESTRING
#> # Dimension: XY
#> # Bounding box: xmin: 0 ymin: 0 xmax: 4 ymax: 2
#> from to geom .tidygraph_edge_index
#> <int> <int> <LINESTRING> <int>
#> 1 1 2 (0 1, 3 1) 1
#> 2 2 3 (3 1, 4 1) 1
#> 3 4 2 (3 2, 3 1) 2
#> # … with 2 more rows
plot(new_net)

Created on 2021-01-31 by the reprex package (v0.3.0)
Expected behavior Subdivide the edges but don't merge the equal nodes.
This is a quite unusual case, since normally you would not have several nodes at the same location. I'll mark it as low priority, but it is still a bug that needs to be fixed.