lwgeom
lwgeom copied to clipboard
Result of st_split depends on the order of input points
Dear all, I was working on a project with Open Street Map data and I found a weird behaviour with st_split. In a few words, I think I found that the result of st_split depends on the order of points that are passed as input (i.e. the y argument). More precisely,
# packages
library(osmdata)
#> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(lwgeom)
#> Linking to liblwgeom 3.0.0beta1 r16016, GEOS 3.8.0, PROJ 6.3.1
# get data
osmdata_by_id <- opq_osm_id(c(133096444, 133097023), type = "way") %>%
osmdata_sf()
osm_lines <- osmdata_by_id$osm_lines
# plot
par(mar = rep(0, 4))
plot(st_geometry(osm_lines), reset = FALSE)
# calculate duplicated points
osm_points <- st_coordinates(osm_lines)[, 1:2]
unique_osm_points <- st_sfc(st_multipoint(osm_points[duplicated(osm_points), ]), crs = 4326)
# plot
plot(unique_osm_points, pch = 16, col = "red", add = TRUE)

Here I would like to get 4 different geometries, obtained by splitting the input data at the two red dots but this is the result:
# split
osm_lines_split <- lwgeom::st_split(osm_lines, unique_osm_points) %>%
st_collection_extract("LINESTRING")
osm_lines_split
#> Simple feature collection with 3 features and 1 field
#> geometry type: LINESTRING
#> dimension: XY
#> bbox: xmin: -1.153723 ymin: 50.7263 xmax: -1.15313 ymax: 50.72732
#> geographic CRS: WGS 84
#> highway geometry
#> 133096444 service LINESTRING (-1.153265 50.72...
#> 133096444.1 service LINESTRING (-1.153622 50.72...
#> 133097023 service LINESTRING (-1.153717 50.72...
plot(osm_lines_split, col = 1:3, lwd = 2)

Nevertheless, if I use the same input but in different order:
unique_osm_points <- osm_points[duplicated(osm_points), ]
unique_osm_points <- unique_osm_points[2:1, ]
unique_osm_points <- st_sfc(st_multipoint(unique_osm_points), crs = 4326)
osm_lines_split <- lwgeom::st_split(osm_lines, unique_osm_points) %>%
st_collection_extract("LINESTRING")
plot(osm_lines_split, col = 1:4, lwd = 2)

Created on 2020-11-10 by the reprex package (v0.3.0)
Session info
devtools::session_info()
#> - Session info ---------------------------------------------------------------
#> setting value
#> version R version 3.6.3 (2020-02-29)
#> os Windows 10 x64
#> system x86_64, mingw32
#> ui RTerm
#> language (EN)
#> collate Italian_Italy.1252
#> ctype Italian_Italy.1252
#> tz Europe/Berlin
#> date 2020-11-10
#>
#> - Packages -------------------------------------------------------------------
#> package * version date lib source
#> assertthat 0.2.1 2019-03-21 [1] CRAN (R 3.6.0)
#> backports 1.1.10 2020-09-15 [1] CRAN (R 3.6.3)
#> callr 3.5.1 2020-10-13 [1] CRAN (R 3.6.3)
#> class 7.3-17 2020-04-26 [1] CRAN (R 3.6.3)
#> classInt 0.4-3 2020-04-07 [1] CRAN (R 3.6.3)
#> cli 2.1.0 2020-10-12 [1] CRAN (R 3.6.3)
#> crayon 1.3.4 2017-09-16 [1] CRAN (R 3.6.0)
#> curl 4.3 2019-12-02 [1] CRAN (R 3.6.1)
#> DBI 1.1.0 2019-12-15 [1] CRAN (R 3.6.3)
#> desc 1.2.0 2018-05-01 [1] CRAN (R 3.6.0)
#> devtools 2.3.2 2020-09-18 [1] CRAN (R 3.6.3)
#> digest 0.6.27 2020-10-24 [1] CRAN (R 3.6.3)
#> dplyr 1.0.2 2020-08-18 [1] CRAN (R 3.6.3)
#> e1071 1.7-4 2020-10-14 [1] CRAN (R 3.6.3)
#> ellipsis 0.3.1 2020-05-15 [1] CRAN (R 3.6.3)
#> evaluate 0.14 2019-05-28 [1] CRAN (R 3.6.0)
#> fansi 0.4.1 2020-01-08 [1] CRAN (R 3.6.2)
#> fs 1.5.0 2020-07-31 [1] CRAN (R 3.6.3)
#> generics 0.1.0 2020-10-31 [1] CRAN (R 3.6.3)
#> glue 1.4.2 2020-08-27 [1] CRAN (R 3.6.3)
#> highr 0.8 2019-03-20 [1] CRAN (R 3.6.0)
#> htmltools 0.5.0 2020-06-16 [1] CRAN (R 3.6.3)
#> httr 1.4.2 2020-07-20 [1] CRAN (R 3.6.3)
#> jsonlite 1.7.1 2020-09-07 [1] CRAN (R 3.6.3)
#> KernSmooth 2.23-17 2020-04-26 [1] CRAN (R 3.6.3)
#> knitr 1.30 2020-09-22 [1] CRAN (R 3.6.3)
#> lattice 0.20-41 2020-04-02 [1] CRAN (R 3.6.3)
#> lifecycle 0.2.0 2020-03-06 [1] CRAN (R 3.6.2)
#> lubridate 1.7.9 2020-06-08 [1] CRAN (R 3.6.3)
#> lwgeom * 0.2-5 2020-06-12 [1] CRAN (R 3.6.3)
#> magrittr 1.5 2014-11-22 [1] CRAN (R 3.6.3)
#> memoise 1.1.0 2017-04-21 [1] CRAN (R 3.6.0)
#> mime 0.9 2020-02-04 [1] CRAN (R 3.6.2)
#> osmdata * 0.1.3.020 2020-10-28 [1] Github (ropensci/osmdata@fc2332e)
#> pillar 1.4.6 2020-07-10 [1] CRAN (R 3.6.3)
#> pkgbuild 1.1.0 2020-07-13 [1] CRAN (R 3.6.3)
#> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 3.6.1)
#> pkgload 1.1.0 2020-05-29 [1] CRAN (R 3.6.3)
#> prettyunits 1.1.1 2020-01-24 [1] CRAN (R 3.6.2)
#> processx 3.4.4 2020-09-03 [1] CRAN (R 3.6.3)
#> ps 1.4.0 2020-10-07 [1] CRAN (R 3.6.3)
#> purrr 0.3.4 2020-04-17 [1] CRAN (R 3.6.3)
#> R6 2.5.0 2020-10-28 [1] CRAN (R 3.6.3)
#> Rcpp 1.0.5 2020-07-06 [1] CRAN (R 3.6.3)
#> remotes 2.2.0 2020-07-21 [1] CRAN (R 3.6.3)
#> rlang 0.4.8 2020-10-08 [1] CRAN (R 3.6.3)
#> rmarkdown 2.5 2020-10-21 [1] CRAN (R 3.6.3)
#> rprojroot 1.3-2 2018-01-03 [1] CRAN (R 3.6.0)
#> rvest 0.3.6 2020-07-25 [1] CRAN (R 3.6.3)
#> sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.6.0)
#> sf * 0.9-6 2020-09-13 [1] CRAN (R 3.6.3)
#> sp 1.4-4 2020-10-07 [1] CRAN (R 3.6.3)
#> stringi 1.4.6 2020-02-17 [1] CRAN (R 3.6.2)
#> stringr 1.4.0 2019-02-10 [1] CRAN (R 3.6.0)
#> testthat 2.3.2 2020-03-02 [1] CRAN (R 3.6.3)
#> tibble 3.0.4 2020-10-12 [1] CRAN (R 3.6.3)
#> tidyselect 1.1.0 2020-05-11 [1] CRAN (R 3.6.3)
#> units 0.6-7 2020-06-13 [1] CRAN (R 3.6.3)
#> usethis 1.6.3 2020-09-17 [1] CRAN (R 3.6.3)
#> vctrs 0.3.4 2020-08-29 [1] CRAN (R 3.6.3)
#> withr 2.3.0 2020-09-22 [1] CRAN (R 3.6.3)
#> xfun 0.19 2020-10-30 [1] CRAN (R 3.6.3)
#> xml2 1.3.2 2020-04-23 [1] CRAN (R 3.6.3)
#> yaml 2.2.1 2020-02-01 [1] CRAN (R 3.6.2)
#>
#> [1] C:/Users/Utente/Documents/R/win-library/3.6
#> [2] C:/Program Files/R/R-3.6.3/library
I really don't understand what's going on since I would expect obtaining the same results in both scenarios.