Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement promote_to_multi when converting WKB to sfc #2369

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
maybe revert wkb to existing usage
paleolimbot committed Mar 31, 2024
commit 433124089d02ebf75585ce2db6dae371ba220ce6
8 changes: 6 additions & 2 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
@@ -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) {
2 changes: 1 addition & 1 deletion R/read.R
Original file line number Diff line number Diff line change
@@ -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
}
7 changes: 5 additions & 2 deletions R/wkb.R
Original file line number Diff line number Diff line change
@@ -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))) {
29 changes: 25 additions & 4 deletions inst/include/sf_RcppExports.h
Original file line number Diff line number Diff line change
@@ -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<SEXP>(Rcpp::wrap(wkb_list)), Shield<SEXP>(Rcpp::wrap(EWKB)), Shield<SEXP>(Rcpp::wrap(spatialite)), Shield<SEXP>(Rcpp::wrap(promote_multi)));
rcpp_result_gen = p_CPL_read_wkb(Shield<SEXP>(Rcpp::wrap(wkb_list)), Shield<SEXP>(Rcpp::wrap(EWKB)), Shield<SEXP>(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<std::string>(rcpp_result_gen).c_str());
return Rcpp::as<Rcpp::List >(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<SEXP>(Rcpp::wrap(wkb_list)), Shield<SEXP>(Rcpp::wrap(options)));
}
if (rcpp_result_gen.inherits("interrupted-error"))
throw Rcpp::internal::InterruptedException();
53 changes: 45 additions & 8 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
@@ -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<std::string> 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},
2 changes: 1 addition & 1 deletion src/gdal.cpp
Original file line number Diff line number Diff line change
@@ -497,7 +497,7 @@ Rcpp::List sfc_from_ogr(std::vector<OGRGeometry *> 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;
2 changes: 1 addition & 1 deletion src/geos.cpp
Original file line number Diff line number Diff line change
@@ -252,7 +252,7 @@ Rcpp::List sfc_from_geometry(GEOSContextHandle_t hGEOSCtxt, std::vector<GeomPtr>
}
}
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) {
34 changes: 32 additions & 2 deletions src/wkb.cpp
Original file line number Diff line number Diff line change
@@ -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:
//
2 changes: 1 addition & 1 deletion src/wkb.h
Original file line number Diff line number Diff line change
@@ -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);