r-spatial / lwgeom

bindings to the liblwgeom library
https://r-spatial.github.io/lwgeom/
60 stars 24 forks source link

Result of st_split depends on the order of input points #63

Closed agila5 closed 5 months ago

agila5 commented 3 years ago

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 ``` r 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.

edzer commented 5 months ago

I guess this is an upstream problem.