diff --git a/R/RcppExports.R b/R/RcppExports.R index b08d09c1a..1ee3c878f 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -393,8 +393,12 @@ CPL_create <- function(file, nxy, value, wkt, xlim, ylim) { invisible(.Call(`_sf_CPL_create`, file, nxy, value, wkt, xlim, ylim)) } -CPL_read_wkb <- function(wkb_list, EWKB = FALSE, spatialite = FALSE, promote_multi = FALSE) { - .Call(`_sf_CPL_read_wkb`, wkb_list, EWKB, spatialite, promote_multi) +CPL_read_wkb <- function(wkb_list, EWKB = FALSE, spatialite = FALSE) { + .Call(`_sf_CPL_read_wkb`, wkb_list, EWKB, spatialite) +} + +CPL_read_wkb2 <- function(wkb_list, options) { + .Call(`_sf_CPL_read_wkb2`, wkb_list, options) } CPL_write_wkb <- function(sfc, EWKB = FALSE) { diff --git a/R/read.R b/R/read.R index 57cadf6f4..f4635b5a7 100644 --- a/R/read.R +++ b/R/read.R @@ -243,7 +243,7 @@ process_cpl_read_ogr_stream = function(x, geom_column_info, num_features, fid_co column_wkb = df[[index]] class(column_wkb) <- "WKB" - column_sfc = sf::st_as_sfc(column_wkb, crs = crs, promote_multi = promote_to_multi) + column_sfc = sf::st_as_sfc(column_wkb, crs = crs, promote_to_multi = promote_to_multi) df[[index]] = column_sfc names(df)[index] = name } diff --git a/R/wkb.R b/R/wkb.R index 49ed32125..9116c8a8d 100644 --- a/R/wkb.R +++ b/R/wkb.R @@ -33,7 +33,7 @@ skip0x = function(x) { #' st_as_sfc(wkb, EWKB = TRUE) #' @export st_as_sfc.WKB = function(x, ..., EWKB = FALSE, spatialite = FALSE, pureR = FALSE, crs = NA_crs_, - promote_multi = FALSE) { + promote_to_multi = FALSE) { if (EWKB && spatialite) stop("arguments EWKB and spatialite cannot both be TRUE") if (spatialite && pureR) @@ -50,7 +50,10 @@ st_as_sfc.WKB = function(x, ..., EWKB = FALSE, spatialite = FALSE, pureR = FALSE ret = if (pureR) R_read_wkb(x, readWKB, EWKB = EWKB) else - CPL_read_wkb(x, EWKB, spatialite, promote_multi) + CPL_read_wkb2(x, + list(EKWB = EWKB, + spatialite = spatialite, + promote_to_multi = promote_to_multi)) if (is.na(crs) && (EWKB || spatialite) && !is.null(attr(ret, "srid")) && attr(ret, "srid") != 0) crs = attr(ret, "srid") if (! is.na(st_crs(crs))) { diff --git a/inst/include/sf_RcppExports.h b/inst/include/sf_RcppExports.h index 3b2820ec4..aa63b7899 100644 --- a/inst/include/sf_RcppExports.h +++ b/inst/include/sf_RcppExports.h @@ -24,17 +24,38 @@ namespace sf { } } - inline Rcpp::List CPL_read_wkb(Rcpp::List wkb_list, bool EWKB = false, bool spatialite = false, bool promote_multi = false) { - typedef SEXP(*Ptr_CPL_read_wkb)(SEXP,SEXP,SEXP,SEXP); + inline Rcpp::List CPL_read_wkb(Rcpp::List wkb_list, bool EWKB = false, bool spatialite = false) { + typedef SEXP(*Ptr_CPL_read_wkb)(SEXP,SEXP,SEXP); static Ptr_CPL_read_wkb p_CPL_read_wkb = NULL; if (p_CPL_read_wkb == NULL) { - validateSignature("Rcpp::List(*CPL_read_wkb)(Rcpp::List,bool,bool,bool)"); + validateSignature("Rcpp::List(*CPL_read_wkb)(Rcpp::List,bool,bool)"); p_CPL_read_wkb = (Ptr_CPL_read_wkb)R_GetCCallable("sf", "_sf_CPL_read_wkb"); } RObject rcpp_result_gen; { RNGScope RCPP_rngScope_gen; - rcpp_result_gen = p_CPL_read_wkb(Shield(Rcpp::wrap(wkb_list)), Shield(Rcpp::wrap(EWKB)), Shield(Rcpp::wrap(spatialite)), Shield(Rcpp::wrap(promote_multi))); + rcpp_result_gen = p_CPL_read_wkb(Shield(Rcpp::wrap(wkb_list)), Shield(Rcpp::wrap(EWKB)), Shield(Rcpp::wrap(spatialite))); + } + if (rcpp_result_gen.inherits("interrupted-error")) + throw Rcpp::internal::InterruptedException(); + if (Rcpp::internal::isLongjumpSentinel(rcpp_result_gen)) + throw Rcpp::LongjumpException(rcpp_result_gen); + if (rcpp_result_gen.inherits("try-error")) + throw Rcpp::exception(Rcpp::as(rcpp_result_gen).c_str()); + return Rcpp::as(rcpp_result_gen); + } + + inline Rcpp::List CPL_read_wkb2(Rcpp::List wkb_list, Rcpp::List options) { + typedef SEXP(*Ptr_CPL_read_wkb2)(SEXP,SEXP); + static Ptr_CPL_read_wkb2 p_CPL_read_wkb2 = NULL; + if (p_CPL_read_wkb2 == NULL) { + validateSignature("Rcpp::List(*CPL_read_wkb2)(Rcpp::List,Rcpp::List)"); + p_CPL_read_wkb2 = (Ptr_CPL_read_wkb2)R_GetCCallable("sf", "_sf_CPL_read_wkb2"); + } + RObject rcpp_result_gen; + { + RNGScope RCPP_rngScope_gen; + rcpp_result_gen = p_CPL_read_wkb2(Shield(Rcpp::wrap(wkb_list)), Shield(Rcpp::wrap(options))); } if (rcpp_result_gen.inherits("interrupted-error")) throw Rcpp::internal::InterruptedException(); diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 18331f4b2..abf19d937 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -1343,23 +1343,57 @@ BEGIN_RCPP END_RCPP } // CPL_read_wkb -Rcpp::List CPL_read_wkb(Rcpp::List wkb_list, bool EWKB, bool spatialite, bool promote_multi); -static SEXP _sf_CPL_read_wkb_try(SEXP wkb_listSEXP, SEXP EWKBSEXP, SEXP spatialiteSEXP, SEXP promote_multiSEXP) { +Rcpp::List CPL_read_wkb(Rcpp::List wkb_list, bool EWKB, bool spatialite); +static SEXP _sf_CPL_read_wkb_try(SEXP wkb_listSEXP, SEXP EWKBSEXP, SEXP spatialiteSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::traits::input_parameter< Rcpp::List >::type wkb_list(wkb_listSEXP); Rcpp::traits::input_parameter< bool >::type EWKB(EWKBSEXP); Rcpp::traits::input_parameter< bool >::type spatialite(spatialiteSEXP); - Rcpp::traits::input_parameter< bool >::type promote_multi(promote_multiSEXP); - rcpp_result_gen = Rcpp::wrap(CPL_read_wkb(wkb_list, EWKB, spatialite, promote_multi)); + rcpp_result_gen = Rcpp::wrap(CPL_read_wkb(wkb_list, EWKB, spatialite)); return rcpp_result_gen; END_RCPP_RETURN_ERROR } -RcppExport SEXP _sf_CPL_read_wkb(SEXP wkb_listSEXP, SEXP EWKBSEXP, SEXP spatialiteSEXP, SEXP promote_multiSEXP) { +RcppExport SEXP _sf_CPL_read_wkb(SEXP wkb_listSEXP, SEXP EWKBSEXP, SEXP spatialiteSEXP) { SEXP rcpp_result_gen; { Rcpp::RNGScope rcpp_rngScope_gen; - rcpp_result_gen = PROTECT(_sf_CPL_read_wkb_try(wkb_listSEXP, EWKBSEXP, spatialiteSEXP, promote_multiSEXP)); + rcpp_result_gen = PROTECT(_sf_CPL_read_wkb_try(wkb_listSEXP, EWKBSEXP, spatialiteSEXP)); + } + Rboolean rcpp_isInterrupt_gen = Rf_inherits(rcpp_result_gen, "interrupted-error"); + if (rcpp_isInterrupt_gen) { + UNPROTECT(1); + Rf_onintr(); + } + bool rcpp_isLongjump_gen = Rcpp::internal::isLongjumpSentinel(rcpp_result_gen); + if (rcpp_isLongjump_gen) { + Rcpp::internal::resumeJump(rcpp_result_gen); + } + Rboolean rcpp_isError_gen = Rf_inherits(rcpp_result_gen, "try-error"); + if (rcpp_isError_gen) { + SEXP rcpp_msgSEXP_gen = Rf_asChar(rcpp_result_gen); + UNPROTECT(1); + Rf_error("%s", CHAR(rcpp_msgSEXP_gen)); + } + UNPROTECT(1); + return rcpp_result_gen; +} +// CPL_read_wkb2 +Rcpp::List CPL_read_wkb2(Rcpp::List wkb_list, Rcpp::List options); +static SEXP _sf_CPL_read_wkb2_try(SEXP wkb_listSEXP, SEXP optionsSEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::traits::input_parameter< Rcpp::List >::type wkb_list(wkb_listSEXP); + Rcpp::traits::input_parameter< Rcpp::List >::type options(optionsSEXP); + rcpp_result_gen = Rcpp::wrap(CPL_read_wkb2(wkb_list, options)); + return rcpp_result_gen; +END_RCPP_RETURN_ERROR +} +RcppExport SEXP _sf_CPL_read_wkb2(SEXP wkb_listSEXP, SEXP optionsSEXP) { + SEXP rcpp_result_gen; + { + Rcpp::RNGScope rcpp_rngScope_gen; + rcpp_result_gen = PROTECT(_sf_CPL_read_wkb2_try(wkb_listSEXP, optionsSEXP)); } Rboolean rcpp_isInterrupt_gen = Rf_inherits(rcpp_result_gen, "interrupted-error"); if (rcpp_isInterrupt_gen) { @@ -1443,7 +1477,8 @@ END_RCPP static int _sf_RcppExport_validate(const char* sig) { static std::set signatures; if (signatures.empty()) { - signatures.insert("Rcpp::List(*CPL_read_wkb)(Rcpp::List,bool,bool,bool)"); + signatures.insert("Rcpp::List(*CPL_read_wkb)(Rcpp::List,bool,bool)"); + signatures.insert("Rcpp::List(*CPL_read_wkb2)(Rcpp::List,Rcpp::List)"); signatures.insert("Rcpp::List(*CPL_write_wkb)(Rcpp::List,bool)"); } return signatures.find(sig) != signatures.end(); @@ -1452,6 +1487,7 @@ static int _sf_RcppExport_validate(const char* sig) { // registerCCallable (register entry points for exported C++ functions) RcppExport SEXP _sf_RcppExport_registerCCallable() { R_RegisterCCallable("sf", "_sf_CPL_read_wkb", (DL_FUNC)_sf_CPL_read_wkb_try); + R_RegisterCCallable("sf", "_sf_CPL_read_wkb2", (DL_FUNC)_sf_CPL_read_wkb2_try); R_RegisterCCallable("sf", "_sf_CPL_write_wkb", (DL_FUNC)_sf_CPL_write_wkb_try); R_RegisterCCallable("sf", "_sf_RcppExport_validate", (DL_FUNC)_sf_RcppExport_validate); return R_NilValue; @@ -1556,7 +1592,8 @@ static const R_CallMethodDef CallEntries[] = { {"_sf_CPL_write_gdal", (DL_FUNC) &_sf_CPL_write_gdal, 13}, {"_sf_CPL_extract", (DL_FUNC) &_sf_CPL_extract, 3}, {"_sf_CPL_create", (DL_FUNC) &_sf_CPL_create, 6}, - {"_sf_CPL_read_wkb", (DL_FUNC) &_sf_CPL_read_wkb, 4}, + {"_sf_CPL_read_wkb", (DL_FUNC) &_sf_CPL_read_wkb, 3}, + {"_sf_CPL_read_wkb2", (DL_FUNC) &_sf_CPL_read_wkb2, 2}, {"_sf_CPL_write_wkb", (DL_FUNC) &_sf_CPL_write_wkb, 2}, {"_sf_CPL_get_z_range", (DL_FUNC) &_sf_CPL_get_z_range, 2}, {"_sf_CPL_get_m_range", (DL_FUNC) &_sf_CPL_get_m_range, 2}, diff --git a/src/gdal.cpp b/src/gdal.cpp index f1afaabd0..d89026f56 100644 --- a/src/gdal.cpp +++ b/src/gdal.cpp @@ -497,7 +497,7 @@ Rcpp::List sfc_from_ogr(std::vector g, bool destroy = false) { if (destroy) OGRGeometryFactory::destroyGeometry(g[i]); } - Rcpp::List ret = CPL_read_wkb(lst, false, false, false); + Rcpp::List ret = CPL_read_wkb(lst, false, false); ret.attr("crs") = crs; ret.attr("class") = "sfc"; return ret; diff --git a/src/geos.cpp b/src/geos.cpp index f20b21a17..e9ff03a02 100644 --- a/src/geos.cpp +++ b/src/geos.cpp @@ -252,7 +252,7 @@ Rcpp::List sfc_from_geometry(GEOSContextHandle_t hGEOSCtxt, std::vector } } GEOSWKBWriter_destroy_r(hGEOSCtxt, wkb_writer); - return CPL_read_wkb(out, true, false, false); + return CPL_read_wkb(out, true, false); } Rcpp::NumericVector get_dim(double dim0, double dim1) { diff --git a/src/wkb.cpp b/src/wkb.cpp index f2e863641..d65fe8c8e 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -495,8 +495,7 @@ static void read_wkb_promote_multi_if_possible(Rcpp::List output, int64_t* all_t *all_types = sf_type_bitmask(sf_type_multi); } -// [[Rcpp::export]] -Rcpp::List CPL_read_wkb(Rcpp::List wkb_list, bool EWKB = false, bool spatialite = false, bool promote_multi = false) { +static Rcpp::List CPL_read_wkb_internal(Rcpp::List wkb_list, bool EWKB = false, bool spatialite = false, bool promote_multi = false) { Rcpp::List output(wkb_list.size()); int type = 0, n_empty = 0; @@ -540,6 +539,37 @@ Rcpp::List CPL_read_wkb(Rcpp::List wkb_list, bool EWKB = false, bool spatialite return output; } + +// This function is used by other packages that link to sf, so its signature cannot be changed +// [[Rcpp::export]] +Rcpp::List CPL_read_wkb(Rcpp::List wkb_list, bool EWKB = false, bool spatialite = false) { + return CPL_read_wkb_internal(wkb_list, EWKB, spatialite); +} + + +// This version of the function is designed to allow evolution of options without +// breaking compatability with existing usage +// [[Rcpp::export]] +Rcpp::List CPL_read_wkb2(Rcpp::List wkb_list, Rcpp::List options) { + bool EWKB = false; + bool spatialite = false; + bool promote_to_multi = false; + + if (options.containsElementNamed("EWKB")) { + EWKB = options("EWKB"); + } + + if (options.containsElementNamed("spatialite")) { + spatialite = options("spatialite"); + } + + if (options.containsElementNamed("promote_to_multi")) { + promote_to_multi = options("promote_to_multi"); + } + + return CPL_read_wkb_internal(wkb_list, EWKB, spatialite, promote_to_multi); +} + // // write wkb: // diff --git a/src/wkb.h b/src/wkb.h index c1e682779..445f4ba6e 100644 --- a/src/wkb.h +++ b/src/wkb.h @@ -19,7 +19,7 @@ #define SF_Triangle 17 #define SF_Type_Max 17 -Rcpp::List CPL_read_wkb(Rcpp::List wkb_list, bool EWKB, bool spatialite, bool promote_multi); +Rcpp::List CPL_read_wkb(Rcpp::List wkb_list, bool EWKB, bool spatialite); Rcpp::List CPL_write_wkb(Rcpp::List sfc, bool EWKB); unsigned int make_type(const char *cls, const char *dim, bool EWKB, int *tp, int srid); Rcpp::List get_dim_sfc(Rcpp::List sfc);