Search code examples
rr-rasterr-sprgdalr-sf

Spatial line start and end point in R


I am attempting to use the sp package to access the start and end points of a linestring, similar to what ST_StartPoint and ST_EndPoint would produce using psql.

No matter how I try to access the line, I get errors or NULL value:

> onetrip@lines[[1]][1]
Error in onetrip@lines[[1]][1] : object of type 'S4' is not subsettable

> onetrip@lines@Lines@coords
    Error: trying to get slot "Lines" from an object of a basic class ("list") with no slots

> onetrip@lines$Lines
NULL

The only solution that works is verbose and requires conversion to SpatialLines, and I can only easily get the first point:

test = as(onetrip, "SpatialLines")@lines[[1]]
> test@Lines[[1]]@coords[1,]
[1] -122.42258   37.79494

Both the str() below and a simple plot(onetrip) show that my dataframe is not empty.

What is the workaround here - how would one return the start and endpoints of a linestring in sp?

I have subset the first record of a larger SpatialLinesDataFrame:

> str(onetrip)
Formal class 'SpatialLinesDataFrame' [package "sp"] with 4 slots
  ..@ data       :'data.frame': 1 obs. of  6 variables:
  .. ..$ start_time : Factor w/ 23272 levels "2018/02/01 00:12:40",..: 23160
  .. ..$ finish_time: Factor w/ 23288 levels "1969/12/31 17:00:23",..: 23288
  .. ..$ distance   : num 2.74
  .. ..$ duration   : int 40196
  .. ..$ route_id   : int 5844736
  .. ..$ vehicle_id    : int 17972
  ..@ lines      :List of 1
  .. ..$ :Formal class 'Lines' [package "sp"] with 2 slots
  .. .. .. ..@ Lines:List of 1
  .. .. .. .. ..$ :Formal class 'Line' [package "sp"] with 1 slot
  .. .. .. .. .. .. ..@ coords: num [1:3114, 1:2] -122 -122 -122 -122 -122 ...
  .. .. .. ..@ ID   : chr "0"
  ..@ bbox       : num [1:2, 1:2] -122.4 37.8 -122.4 37.8
  .. ..- attr(*, "dimnames")=List of 2
  .. .. ..$ : chr [1:2] "x" "y"
  .. .. ..$ : chr [1:2] "min" "max"
  ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
  .. .. ..@ projargs: chr "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs"

Solution

  • Since you tagged question with sf as well, I'll provide a solution in sf. Note you can transform your sp object to sf using

    library(sf)
    st_as_sf(sp_obj)
    

    Create linestring

    line <- st_as_sfc(c("LINESTRING(0 0 , 0.5 1 , 1 1 , 1 0.3)")) %>% 
      st_sf(ID = "poly1")   
    

    Convert each vertex to point

    pt <- st_cast(line, "POINT")
    

    Start and end are simply the first and last row of the data.frame

    start <- pt[1,]
    end <- pt[nrow(pt),]
    

    plot - green is start point, red is end point

    library(ggplot2)
    ggplot() +
      geom_sf(data = line) +
      geom_sf(data = start, color = 'green') +
      geom_sf(data = end, color = 'red') +
      coord_sf(datum = NULL)
    

    enter image description here