CRS mismatch error in Shiny not found in local preview

My shiny app relies on custom packages hosted on github, along with sf and nngeo amongst others. One of these custom packages is an API wrapper to an API that requires authentication. One of the processes in the app is to calculate sf::st_join() on two sf objects with the same CRS.

All this works fine on my system, rendering a Shiny dashboard with maps that project all objects correctly. When I publish to ShinyIO, however, I receive the following error. It seems that ShinyIO thinks the two objects have different coordinate reference systems; but I have verified that this is not the case. Please can you help?


Attaching package: ‘shinydashboard’

The following object is masked from ‘package:graphics’:

    box

Loading required package: sf
Linking to GEOS 3.5.1, GDAL 2.2.2, PROJ 4.9.2
Loading required package: nngeo
Loading required package: dplyr

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

Loading required package: tidyr
Loading required package: lubridate

Attaching package: ‘lubridate’

The following objects are masked from ‘package:base’:

    date, intersect, setdiff, union

Loading required package: stringr
Loading required package: magrittr

Attaching package: ‘magrittr’

The following object is masked from ‘package:tidyr’:

    extract

Error in value[[3L]](cond) : 'x' and 'y' need to be in the same CRS
Calls: local ... tryCatch -> tryCatchList -> tryCatchOne -> <Anonymous>
Execution halted

I believe I've isolated the problem to this function, but again it works fine on my system and I've checked all the inputs so I'm not sure why it would fail on ShinyIO.

gtcharge <- function(geotab){
  geotab <- geotab %>%
    dplyr::filter(dplyr::across(dplyr::contains("stopPoint"), ~!is.na(.x))) %>%
    sf::st_as_sf(coords = c("stopPoint.x", "stopPoint.y"), crs = 4326) %>%
    sf::st_transform(27700)

  distance_to_nearest <- nngeo::st_nn(geotab, ncr, sparse = TRUE, k = 1, maxdist = Inf,
                               returnDist = TRUE, progress = TRUE)

  sf::st_join(geotab, ncr, join = sf::st_nearest_feature, left = TRUE) %>%
    dplyr::bind_cols(list(dist = unlist(distance_to_nearest$dist)))
}

I suspect you have an issue with PROJ - one of the three backends supporting {sf}.

Version 4.9.2 is rather out of date, you should consider upgrading it. There were breaking changes in the way CRS is expressed recently.

Thanks for the observation - I think this is probably the reason for the error. My local version of PROJ is actually 6.3.1, so this issue is squarely with ShinyIO. I will raise it with them.

This would be a good idea - there has been a breaking change in PROJ circa 6, and objects projected in current versions of PROJ are not recognized in the lower versions; see https://gis.stackexchange.com/questions/360322/sfst-crs-compatibility-across-different-versions-of-proj for an illustration of the difference.

If this is not feasible you may get creative and get hold of a very old R installation (3.6.3 would be perfect) with old PROJ version to project your spatial objects. The incompatibility is one way = higher PROJ versions will recognize objects generated in low version, but low version will not accept new ones. This is what I ended up doing when facing your situation.

A workaround since updating the PROJ version is not always possible (but is probably the best solution). You could transform both datasets with the same PROJ version by including a second transformation.

If I understand your code correctly, that would be

ncr <- sf::st_transform(ncr, geotab)

# before distance_to_nearest ...
1 Like

Unfortunately this did not help. The second argument to st_transform() cannot be an sf object, but changing this to

ncr <- sf::st_transform(ncr, st_crs(geotab))

gives the following error.

Warning in CPL_transform(x, crs, aoi, pipeline, reverse) :
GDAL Error 1: No PROJ.4 translation for source SRS, coordinate transformation initialization has failed.
Error in value[3L] :
OGRCreateCoordinateTransformation() returned NULL: PROJ available?
Calls: local ... tryCatch -> tryCatchList -> tryCatchOne ->
Execution halted

Hmmm... this is hard to debug remotely, especially without the data and the same PROJ version. It makes the solution for upgrading even more appealing (also make sure you run the latest sf version). If upgrading was not possible, here's what I would try to do if I was in your situation:

  1. Try to get the remote crs definition and compare with the local definition. You mentioned this worked locally, but not remotely. Maybe dput(st_crs(geotab)) and dput(st_crs(ncr)) on the server and compare the result with the local results?

  2. Try to execute in another crs, maybe UTM 29N (EPSG:32629)? Transform and save the data locally, then push it to the server and see if it solves the problem.