Search code examples
rr-sfepsg

Why sf::st_transform returns empty geometries when applied on a df with sf column (POINT)?


I am trying to st_transform sf-points (CRS: 4326, degree based) in a dataframe to a local metric projection (EPSG:23867, DGN95 / UTM zone 47N).

So I have a dataframe "waypoints" with all my attributes aswell as lon / lat as columns. I create an sf point geometry in the dataframe with "lat" and "lon" as input (waypoints_sf). (additionally I save the coordinates as Northing and Easting in two new columns)

waypoints_sf <-  st_as_sf(waypoints,
                      coords = c("lat", "lon"),
                      crs = 4326)
coordinates_tmp <- st_coordinates(waypoints_sf)
colnames(coordinates_tmp) <- c("E","N") 
waypoints_sf <- cbind(waypoints_sf,coordinates_tmp) # save coordinates as column E and N

class(waypoints_sf)
[1] "sf"         "grouped_df" "tbl_df"     "tbl"        "data.frame"

class(waypoints_sf$geometry)
[1] "sfc_POINT" "sfc"

st_crs(waypoints_sf$geometry)
[1] Coordinate Reference System:
    EPSG: 4326 
    proj4string: "+proj=longlat +datum=WGS84 +no_defs"

Now when i try to st_transform this dataframe, which doesn't throw an error or warning but it the sf points are empty geometries c(NaN, NaN) whatever I try.

 waypoints_sf <-  st_transform(waypoints_sf, 23867)
 waypoints_sf$geometry[1]
 [1] Geometry set for 1 feature  (with 1 geometry empty)
     geometry type:  POINT
     dimension:      XY
     bbox:           xmin: NA ymin: NA xmax: NA ymax: NA
     epsg (SRID):    23867
     proj4string:    +proj=utm +zone=47 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
     POINT EMPTY

So what am I doing wrong, maybe I am really missing sth simple, I really don't know why its not working? What would be simple workaround if its not working with st_transform maybe using N and E raw?

A workaround which for now works for me ("waypoints" is the simple df):

waypoints_sf <- waypoints
waypoints_sf <- waypoints_sf %>% mutate(longitude=lon,latitude=lat) # save if later needed
coordinates(waypoints_sf) <- c("lon","lat")
proj4string(waypoints_sf) <- CRS("+proj=longlat +datum=WGS84") # set crs
waypoints_sf <- spTransform(test, CRS("+init=epsg:23867")) # transform
waypoints_sf <- st_as_sf(waypoints_sf,crs = 23867)

Solution

  • I suspect you have the latitude & longitude swapped, which leads to illegal combination in the context of EPSG:23867

    Consider this code (note that I have swapped your lat lon coordinates!)

    library(sf)
    library(dplyr)
    library(leaflet)
    
    waypoints_sf <-  readr::read_csv("sample.csv") %>% 
      st_as_sf(coords = c("lon", "lat"), # note the order!
               crs = 4326)
    
    # this works...
    waypoints_trans <-  st_transform(waypoints_sf, crs = 23867)
    
    # sanity check - a leaflet plot of the original sf data frame
    leaflet(data = waypoints_sf) %>% 
      addTiles() %>% 
      addCircleMarkers(fillColor = "red",
                       stroke = FALSE)
    

    And as a sanity check & final confirmation a map in leaflet; does this look OK? I yes then your coordinates were flipped.

    enter image description here