Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird behaviour of to_spatial_subdivision with duplicated internal points #212

Open
agila5 opened this issue Jun 22, 2022 · 2 comments
Open
Labels
to_spatial_subdivision All issues related to function `to_spatial_subdivision()`

Comments

@agila5
Copy link
Collaborator

agila5 commented Jun 22, 2022

Describe the bug
While working on #211 I noticed that to_spatial_subdivision morpher behaves weirdly when there are identical internal points for a given LINESTRING.

Reproducible example

# packages
library(sf)
#> Linking to GEOS 3.9.1, GDAL 3.2.1, PROJ 7.2.1; sf_use_s2() is TRUE
library(tidygraph)
#> 
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(sfnetworks)

# simulate one segment with an internal duplicated point
seg = st_sfc(st_linestring(rbind(c(0, 0), c(1, 0), c(1, 0), c(2, 0))))
sfn = as_sfnetwork(seg)
convert(sfn, to_spatial_subdivision, .clean = TRUE)
#> # A sfnetwork with 3 nodes and 3 edges
#> #
#> # CRS:  NA 
#> #
#> # A directed multigraph with 1 component with spatially explicit edges
#> #
#> # Node Data:     3 x 1 (active)
#> # Geometry type: POINT
#> # Dimension:     XY
#> # Bounding box:  xmin: 0 ymin: 0 xmax: 2 ymax: 0
#>         x
#>   <POINT>
#> 1   (0 0)
#> 2   (1 0)
#> 3   (2 0)
#> #
#> # Edge Data:     3 x 3
#> # Geometry type: LINESTRING
#> # Dimension:     XY
#> # Bounding box:  xmin: 0 ymin: 0 xmax: 2 ymax: 0
#>    from    to            x
#>   <int> <int> <LINESTRING>
#> 1     1     2   (0 0, 1 0)
#> 2     2     2   (1 0, 1 0)
#> 3     2     3   (1 0, 2 0)

Created on 2022-06-22 by the reprex package (v2.0.1)

Expected behavior
I would say that the morpher should not modify the input edges in this case. What do you think?

R Session Info

Session info
sessioninfo::session_info()
#> - Session info ---------------------------------------------------------------
#>  setting  value
#>  version  R version 4.1.3 (2022-03-10)
#>  os       Windows 10 x64 (build 19044)
#>  system   x86_64, mingw32
#>  ui       RTerm
#>  language (EN)
#>  collate  English_United Kingdom.1252
#>  ctype    English_United Kingdom.1252
#>  tz       Europe/Berlin
#>  date     2022-06-22
#>  pandoc   2.17.1.1 @ C:/Program Files/RStudio/bin/quarto/bin/ (via rmarkdown)
#> 
#> - Packages -------------------------------------------------------------------
#>  package         * version   date (UTC) lib source
#>  abind             1.4-5     2016-07-21 [1] CRAN (R 4.1.3)
#>  assertthat        0.2.1     2019-03-21 [1] CRAN (R 4.1.3)
#>  class             7.3-20    2022-01-16 [2] CRAN (R 4.1.3)
#>  classInt          0.4-3     2020-04-07 [1] CRAN (R 4.1.3)
#>  cli               3.3.0     2022-04-25 [1] CRAN (R 4.1.3)
#>  colorspace        2.0-3     2022-02-21 [1] CRAN (R 4.1.3)
#>  crayon            1.5.1     2022-03-26 [1] CRAN (R 4.1.3)
#>  DBI               1.1.2     2021-12-20 [1] CRAN (R 4.1.3)
#>  deldir            1.0-6     2021-10-23 [1] CRAN (R 4.1.3)
#>  digest            0.6.29    2021-12-01 [1] CRAN (R 4.1.3)
#>  dplyr             1.0.9     2022-04-28 [1] CRAN (R 4.1.3)
#>  e1071             1.7-9     2021-09-16 [1] CRAN (R 4.1.3)
#>  ellipsis          0.3.2     2021-04-29 [1] CRAN (R 4.1.3)
#>  evaluate          0.15      2022-02-18 [1] CRAN (R 4.1.3)
#>  fansi             1.0.3     2022-03-24 [1] CRAN (R 4.1.3)
#>  fastmap           1.1.0     2021-01-25 [1] CRAN (R 4.1.3)
#>  fs                1.5.2     2021-12-08 [1] CRAN (R 4.1.3)
#>  generics          0.1.2     2022-01-31 [1] CRAN (R 4.1.3)
#>  ggplot2           3.3.6     2022-05-03 [1] CRAN (R 4.1.3)
#>  glue              1.6.2     2022-02-24 [1] CRAN (R 4.1.3)
#>  goftest           1.2-3     2021-10-07 [1] CRAN (R 4.1.3)
#>  gtable            0.3.0     2019-03-25 [1] CRAN (R 4.1.3)
#>  highr             0.9       2021-04-16 [1] CRAN (R 4.1.3)
#>  htmltools         0.5.2     2021-08-25 [1] CRAN (R 4.1.3)
#>  igraph            1.3.1     2022-04-20 [1] CRAN (R 4.1.3)
#>  KernSmooth        2.23-20   2021-05-03 [2] CRAN (R 4.1.3)
#>  knitr             1.39      2022-04-26 [1] CRAN (R 4.1.3)
#>  lattice           0.20-45   2021-09-22 [2] CRAN (R 4.1.3)
#>  lifecycle         1.0.1     2021-09-24 [1] CRAN (R 4.1.3)
#>  lwgeom            0.2-8     2021-10-06 [1] CRAN (R 4.1.3)
#>  magrittr          2.0.3     2022-03-30 [1] CRAN (R 4.1.3)
#>  Matrix            1.4-0     2021-12-08 [2] CRAN (R 4.1.3)
#>  mgcv              1.8-39    2022-02-24 [2] CRAN (R 4.1.3)
#>  munsell           0.5.0     2018-06-12 [1] CRAN (R 4.1.3)
#>  nlme              3.1-155   2022-01-16 [2] CRAN (R 4.1.3)
#>  pillar            1.7.0     2022-02-01 [1] CRAN (R 4.1.3)
#>  pkgconfig         2.0.3     2019-09-22 [1] CRAN (R 4.1.3)
#>  polyclip          1.10-0    2019-03-14 [1] CRAN (R 4.1.3)
#>  proxy             0.4-26    2021-06-07 [1] CRAN (R 4.1.3)
#>  purrr             0.3.4     2020-04-17 [1] CRAN (R 4.1.3)
#>  R.cache           0.15.0    2021-04-30 [1] CRAN (R 4.1.3)
#>  R.methodsS3       1.8.1     2020-08-26 [1] CRAN (R 4.1.1)
#>  R.oo              1.24.0    2020-08-26 [1] CRAN (R 4.1.1)
#>  R.utils           2.11.0    2021-09-26 [1] CRAN (R 4.1.3)
#>  R6                2.5.1     2021-08-19 [1] CRAN (R 4.1.3)
#>  Rcpp              1.0.8.3   2022-03-17 [1] CRAN (R 4.1.3)
#>  reprex            2.0.1     2021-08-05 [1] CRAN (R 4.1.3)
#>  rlang             1.0.2     2022-03-04 [1] CRAN (R 4.1.3)
#>  rmarkdown         2.14      2022-04-25 [1] CRAN (R 4.1.3)
#>  rpart             4.1.16    2022-01-24 [2] CRAN (R 4.1.3)
#>  rstudioapi        0.13      2020-11-12 [1] CRAN (R 4.1.3)
#>  scales            1.2.0     2022-04-13 [1] CRAN (R 4.1.3)
#>  sessioninfo       1.2.2     2021-12-06 [1] CRAN (R 4.1.3)
#>  sf              * 1.0-7     2022-03-07 [1] CRAN (R 4.1.3)
#>  sfheaders         0.4.0     2020-12-01 [1] CRAN (R 4.1.3)
#>  sfnetworks      * 0.5.5.900 2022-06-22 [1] local
#>  spatstat          2.3-4     2022-04-01 [1] CRAN (R 4.1.3)
#>  spatstat.core     2.4-4     2022-05-18 [1] CRAN (R 4.1.3)
#>  spatstat.data     2.2-0     2022-04-18 [1] CRAN (R 4.1.3)
#>  spatstat.geom     2.4-0     2022-03-29 [1] CRAN (R 4.1.3)
#>  spatstat.linnet   2.3-2     2022-02-16 [1] CRAN (R 4.1.3)
#>  spatstat.random   2.2-0     2022-03-30 [1] CRAN (R 4.1.3)
#>  spatstat.sparse   2.1-1     2022-04-18 [1] CRAN (R 4.1.3)
#>  spatstat.utils    2.3-1     2022-05-06 [1] CRAN (R 4.1.3)
#>  stringi           1.7.6     2021-11-29 [1] CRAN (R 4.1.3)
#>  stringr           1.4.0     2019-02-10 [1] CRAN (R 4.1.3)
#>  styler            1.7.0     2022-03-13 [1] CRAN (R 4.1.3)
#>  tensor            1.5       2012-05-05 [1] CRAN (R 4.1.3)
#>  tibble            3.1.7     2022-05-03 [1] CRAN (R 4.1.3)
#>  tidygraph       * 1.2.1     2022-04-05 [1] CRAN (R 4.1.3)
#>  tidyr             1.2.0     2022-02-01 [1] CRAN (R 4.1.3)
#>  tidyselect        1.1.2     2022-02-21 [1] CRAN (R 4.1.3)
#>  units             0.8-0     2022-02-05 [1] CRAN (R 4.1.3)
#>  utf8              1.2.2     2021-07-24 [1] CRAN (R 4.1.3)
#>  vctrs             0.4.1     2022-04-13 [1] CRAN (R 4.1.3)
#>  withr             2.5.0     2022-03-03 [1] CRAN (R 4.1.3)
#>  xfun              0.31      2022-05-10 [1] CRAN (R 4.1.3)
#>  yaml              2.3.5     2022-02-21 [1] CRAN (R 4.1.3)
#> 
#>  [1] C:/Users/Andrea Gilardi/Documents/R/win-library/4.1
#>  [2] C:/Program Files/R/R-4.1.3/library
#> 
#> ------------------------------------------------------------------------------
@luukvdmeer
Copy link
Owner

It is a weird result, but I am not sure if I find it unexpected. The question is mainly: what should the morpher do when an edge crosses itself, which is essentially what is happening here. I would say it should create a node there. Of course in this specific case the result is weird because the duplicated internal points come directly after each other, and a zero-length loop edge is created.

@luukvdmeer luukvdmeer added the to_spatial_subdivision All issues related to function `to_spatial_subdivision()` label Aug 19, 2022
@agila5
Copy link
Collaborator Author

agila5 commented Apr 19, 2023

Another (probably unavoidable) consequence of the current implementation behind to_spatial_subdivision is that the algorithm splits the duplicated segments (that may occur in road transport systems with dual carriageway and oneway roads as showcased here: https://luukvdmeer.github.io/sfnetworks/articles/sfn02_preprocess_clean.html#dealing-with-one-way-edges) at each internal point. For example:

# packages
library(sf)
#> Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 7.2.1; sf_use_s2() is TRUE
library(tidygraph)
#> 
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(sfnetworks)
options(sfn_max_print_active = Inf, sfn_max_print_inactive = Inf)

# define a toy set of segments
my_segments <- st_sfc(
  st_linestring(rbind(c(0, 0), c(0.5, 0.5), c(1, 1))), # this is a non one-way segment
  st_linestring(rbind(c(1, 1), c(2, 2))) # this is a oneway segment
)

# duplicate the one-way segment + create directed sfn
my_segments <- c(my_segments, st_reverse(my_segments[1])) # duplicate the non-one-way
my_sfn <- as_sfnetwork(my_segments)

# apply the to_spatial_subdivision morpher
convert(my_sfn, to_spatial_subdivision, .clean = TRUE)
#> # A sfnetwork with 4 nodes and 5 edges
#> #
#> # CRS:  NA 
#> #
#> # A directed simple graph with 1 component with spatially explicit edges
#> #
#> # Node Data:     4 x 1 (active)
#> # Geometry type: POINT
#> # Dimension:     XY
#> # Bounding box:  xmin: 0 ymin: 0 xmax: 2 ymax: 2
#>           x
#>     <POINT>
#> 1     (0 0)
#> 2 (0.5 0.5)
#> 3     (1 1)
#> 4     (2 2)
#> #
#> # Edge Data:     5 x 3
#> # Geometry type: LINESTRING
#> # Dimension:     XY
#> # Bounding box:  xmin: 0 ymin: 0 xmax: 2 ymax: 2
#>    from    to              x
#>   <int> <int>   <LINESTRING>
#> 1     1     2 (0 0, 0.5 0.5)
#> 2     2     3 (0.5 0.5, 1 1)
#> 3     3     4     (1 1, 2 2)
#> 4     3     2 (1 1, 0.5 0.5)
#> 5     2     1 (0.5 0.5, 0 0)

Created on 2023-04-19 with reprex v2.0.2

Do you think that it is worth exploring this problem more precisely and think about a solution? Moreover (but this is probably the topic for a separate issue), to_spatial_smooth doesn't help here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
to_spatial_subdivision All issues related to function `to_spatial_subdivision()`
Projects
None yet
Development

No branches or pull requests

2 participants