Learn R Programming

⚠️There's a newer version (8.1.0-1) of this package.Take me there.

libproj

The goal of libproj is to provide access to the PROJ C API for high-performance geometry operations within the R package framework. This package contains a copy of the PROJ library, modified slightly to eliminate errors on all the platforms checked by CRAN and GitHub actions. This means you don’t have to install anything (other than the package) to take advantage of PROJ functions in R. It also means you don’t need a configure script if you’re writing a package that needs PROJ functionality (just LinkingTo: libproj).

Installation

You can install the development version from GitHub with:

# install.packages("remotes")
remotes::install_github("paleolimbot/libproj")

Example

This package only exists for its exported C API:

#include <Rcpp.h>
using namespace Rcpp;

// Packages will also need LinkingTo: libproj
// [[Rcpp::depends(libproj)]]

// needed in every file that uses proj_*() functions
#include "libproj.h"

// needed exactly once in your package or Rcpp script
// contains all the function pointers and the
// implementation of the function to initialize them
// (`libproj_init_api()`)
#include "libproj.c"

// this function needs to be called once before any proj_*() functions
// are called (e.g., in .onLoad() for your package)
// [[Rcpp::export]]
void cpp_libproj_init_api() {
  libproj_init_api();
}

// regular C or C++ code that uses proj_()* functions!
// [[Rcpp::export]]
List proj_coords(List xy, std::string from, std::string to) {
  NumericVector x = xy[0];
  NumericVector y = xy[1];
  
  PJ_CONTEXT* context = PJ_DEFAULT_CTX;
  
  PJ* trans = proj_create_crs_to_crs(context, from.c_str(), to.c_str(), NULL);
  if (trans == NULL) {
    int errorCode = proj_context_errno(context);
    std::stringstream err;
    err << "Error creating transform: " << proj_errno_string(errorCode);
    stop(err.str());
  }
  
  NumericVector xout = clone(x);
  NumericVector yout = clone(y);
  size_t stride = sizeof(double);
  
  proj_trans_generic(
    trans, PJ_FWD,
    &(xout[0]), stride, xout.size(),
    &(yout[0]), stride, yout.size(),
    nullptr, stride, 0,
    nullptr, stride, 0
  );
  
  int errorCode = proj_errno(trans);
  proj_destroy(trans);
  
  if (errorCode != 0) {
    std::stringstream err;
    err << "Error transforming coords: " << proj_errno_string(errorCode);
    stop(err.str());
  }
  
  return List::create(_["x"] = xout, _["y"]  = yout);
}
cpp_libproj_init_api()

sf::st_transform(sf::st_sfc(sf::st_point(c(-64, 45)), crs = 4326), 32620)
#> Geometry set for 1 feature 
#> geometry type:  POINT
#> dimension:      XY
#> bbox:           xmin: 421184.7 ymin: 4983437 xmax: 421184.7 ymax: 4983437
#> CRS:            EPSG:32620
#> POINT (421184.7 4983437)

# Note that the PROJ default axis ordering (at the C level)
# is not what you expect!
proj_coords(list(45, -64), "EPSG:4326", "EPSG:32620")
#> $x
#> [1] 421184.7
#> 
#> $y
#> [1] 4983437

Configuration

Users can configure libproj to point at any compatible proj.db file and/or data directory they would like (either permanently or temporarily!):

library(libproj)

# will download a grid shift file from the PROJ CDN
# to correct WGS84->NAD83
with_libproj_configuration(list(network_enabled = TRUE), {
  proj_coords(list(45, -64), "EPSG:4326", "EPSG:26920")
})
#> $x
#> [1] 421184.9
#> 
#> $y
#> [1] 4983437

If enabling network downloads, the cache is stored in a temporary directory (libproj_temp_dir()). You can configure this value to persist the cache between R sessions using options(libproj.user_writable_dir = ...) in your .Renviron or using with_libproj_configuration() or libproj_configure() to set this value temporarily. A useful user writable directory might be rappdirs::user_data_dir("R-libproj").

# in .Renviron (`usethis::edit_r_environ()`):
options(
  libproj.user_writable_dir = rappdirs::user_data_dir("R-libproj")
)

After R is restarted, libproj will use this value as the default:

libproj_configuration()
#> $db_path
#> [1] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/libproj/proj/proj.db"
#> 
#> $search_path
#> [1] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/libproj/proj"
#> 
#> $network_endpoint
#> [1] "https://cdn.proj.org"
#> 
#> $network_enabled
#> [1] FALSE
#> 
#> $user_writable_dir
#> [1] "/Users/dewey/Library/Application Support/R-libproj"

Copy Link

Version

Install

install.packages('libproj')

Monthly Downloads

9

Version

7.1.0-1

License

MIT + file LICENSE

Issues

Pull Requests

Stars

Forks

Maintainer

Dewey Dunnington

Last Published

August 26th, 2020

Functions in libproj (7.1.0-1)

libproj_version

PROJ configuration
libproj-package

libproj: Generic Coordinate Transformation Library ('PROJ') C API