Skip to content

Commit

Permalink
interleaving #78
Browse files Browse the repository at this point in the history
  • Loading branch information
dcooley committed Apr 22, 2020
1 parent c3e58f7 commit ab2a757
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 149 deletions.
4 changes: 0 additions & 4 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ rcpp_cast_sf <- function(sf, cast_to, close = TRUE) {
.Call(`_sfheaders_rcpp_cast_sf`, sf, cast_to, close)
}

rcpp_interleave <- function(sfc) {
.Call(`_sfheaders_rcpp_interleave`, sfc)
}

rcpp_fill_list <- function(v, line_ids) {
.Call(`_sfheaders_rcpp_fill_list`, v, line_ids)
}
Expand Down
8 changes: 4 additions & 4 deletions inst/include/sfheaders/df/sf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ namespace df {
Rcpp::DataFrame& sf,
Rcpp::List& sfc,
std::string& geom_column,
Rcpp::NumericMatrix& sfc_coordinates,
Rcpp::IntegerMatrix& sfc_coordinates,
bool fill = false
) {

Expand Down Expand Up @@ -185,15 +185,15 @@ namespace df {

std::string geom_column = sf.attr("sf_column");
Rcpp::List sfc = sf[ geom_column ];
Rcpp::NumericMatrix sfc_coordinates = sfc_n_coordinates( sfc );
Rcpp::IntegerMatrix sfc_coordinates = sfc_n_coordinates( sfc );
return sf_to_df( sf, sfc, geom_column, sfc_coordinates, fill );
}

inline Rcpp::List sf_to_df(
Rcpp::DataFrame& sf,
Rcpp::List& sfc,
std::string& geom_column,
Rcpp::NumericMatrix& sfc_coordinates,
Rcpp::IntegerMatrix& sfc_coordinates,
Rcpp::StringVector& unlist,
bool fill = false
) {
Expand Down Expand Up @@ -251,7 +251,7 @@ namespace df {
) {
std::string geom_column = sf.attr("sf_column");
Rcpp::List sfc = sf[ geom_column ];
Rcpp::NumericMatrix sfc_coordinates = sfc_n_coordinates( sfc );
Rcpp::IntegerMatrix sfc_coordinates = sfc_n_coordinates( sfc );

return sf_to_df( sf, sfc, geom_column, sfc_coordinates, unlist, fill );
}
Expand Down
20 changes: 11 additions & 9 deletions inst/include/sfheaders/df/sfc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,12 @@ namespace df {
// if I make this cumulative, it gives me a vector where the last element
// is the size of any result, and each element
// is the row index where a new element starts
inline Rcpp::NumericMatrix sfc_n_coordinates(
inline Rcpp::IntegerMatrix sfc_n_coordinates(
Rcpp::List& sfc
) {
R_xlen_t cumulative_coords = 0;
R_xlen_t n = sfc.size();
Rcpp::NumericMatrix res( n, 2 );
Rcpp::IntegerMatrix res( n, 2 );
R_xlen_t i;

for( i = 0; i < n; ++i ) {
Expand All @@ -174,18 +174,20 @@ namespace df {
return res;
}

inline Rcpp::NumericMatrix sfg_n_coordinates(
inline Rcpp::IntegerMatrix sfg_n_coordinates(
SEXP& sfg
) {

switch( TYPEOF( sfg ) ) {
case INTSXP: {}
case REALSXP: {
Rcpp::NumericMatrix res(1,1); // starts filled with 0, so we only need to assign the second column
Rcpp::IntegerMatrix res(1,2); // starts filled with 0, so we only need to assign the second column
// Rcpp::Rcout << "res matrix: " << res << std::endl;
if( Rf_isMatrix( sfg ) ) {
res(0, 0) = sfheaders::utils::sexp_n_row( sfg );
// Rcpp::Rcout << "it's a matrix" << std::endl;
res(0, 1) = sfheaders::utils::sexp_n_row( sfg );
} else {
res(0, 0) = sfheaders::utils::get_sexp_length( sfg );
res(0, 1) = sfheaders::utils::get_sexp_length( sfg );
}
return res;
}
Expand All @@ -199,7 +201,7 @@ namespace df {
Rcpp::stop("sfheaders - unknown sfg type");
}
}
Rcpp::NumericMatrix res; // #nocov
Rcpp::IntegerMatrix res; // #nocov
return res; // #nocov
}

Expand Down Expand Up @@ -453,7 +455,7 @@ namespace df {

inline Rcpp::List sfc_to_df(
Rcpp::List& sfc,
Rcpp::NumericMatrix& sfc_coordinates
Rcpp::IntegerMatrix& sfc_coordinates
) {

R_xlen_t n_geometries = sfc_coordinates.nrow();
Expand Down Expand Up @@ -483,7 +485,7 @@ namespace df {
}

// seprated this so it's independant / not called twice from `sf_to_df()`
Rcpp::NumericMatrix sfc_coordinates = sfc_n_coordinates( sfc );
Rcpp::IntegerMatrix sfc_coordinates = sfc_n_coordinates( sfc );
return sfc_to_df( sfc, sfc_coordinates );
}

Expand Down
83 changes: 58 additions & 25 deletions inst/include/sfheaders/interleave/interleave.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,6 @@ namespace interleave {
return res;
}

// templated version with a vector you want to fill with the result of interleaving
// requires knowing the start index.
// template < int RTYPE >
// inline SEXP interleave(
// Rcpp::Matrix< RTYPE >& mat,
// Rcpp::Matrix< RTYPE >& to_fill,
// R_xlen_t& start_index
// ) {
// Rcpp::Vector< RTYPE > interleaved = interleave( mat );
// sfheaders::utils::fill_vector( to_fill, interleaved, start_index );
// return to_fill;
// }

inline SEXP interleave( SEXP& sfg ) {

switch( TYPEOF ( sfg ) ) {
Expand All @@ -59,28 +46,16 @@ namespace interleave {
case VECSXP: {
if( Rf_isNewList( sfg ) ) {
Rcpp::List lst = Rcpp::as< Rcpp::List >( sfg );
// iterate through until we get a matrix
// which can be interleaved
R_xlen_t n = lst.size();
R_xlen_t i;
Rcpp::List res( n ); // store interleaved vectors in the same nested-list structure

//R_xlen_t coordinate_counter = 0;

// Rcpp::NumericMatrix coords = sfheaders::df::sfc_n_coordinates( lst );
// Rcpp::Rcout << "sfg_coordinates: " << coords << std::endl;

Rcpp::Rcout << "n: " << n << std::endl;
for( i = 0; i < n; ++i ) {
Rcpp::Rcout << "i: " << i << std::endl;
SEXP sfg = lst[ i ];
// Rcpp::NumericMatrix coords = sfheaders::df::sfg_n_coordinates( sfg );
// Rcpp::Rcout << "sfg_coordinates: " << coords << std::endl;
res[ i ] = interleave( sfg );
}

return sfheaders::utils::unlist_list( res );
//return res;
}
}
default: {
Expand All @@ -90,6 +65,64 @@ namespace interleave {
return Rcpp::List::create();
}


inline SEXP interleave( Rcpp::List& sfc ) {

// the input will be a long data.frame
// or an sf object
// if it's a data.frame, it needs id columns and geometry columns
// can probably do this one later?
// and focus on the 'sf', because it doesn't need any extra headers / thought / logic

// the STRIDE depends on the dimension being the same for every pair of coordinates
Rcpp::CharacterVector cls;
std::string dim_expected;
std::string dim;

R_xlen_t n = sfc.length();
R_xlen_t i;

int stride = ( dim_expected == "XYZ" || dim_expected == "XYM" ? 3 : ( dim_expected == "XYZM" ? 4 : 2 ) );

R_xlen_t coordinate_counter = 0;
Rcpp::List res_list( sfc.size() );
Rcpp::List res_indices( sfc.size() );

for( i = 0; i < n; ++i ) {

SEXP sfg = sfc[ i ];

cls = sfheaders::utils::getSfgClass( sfg );
if( i == 0 ) {
dim_expected = cls[0];
} else {
dim = cls[0];
if ( dim != dim_expected ) {
Rcpp::stop("sfheaders - interleaving only works when all geometries have the same dimension (XY(Z(M)))");
}
}

Rcpp::IntegerMatrix coords = sfheaders::df::sfg_n_coordinates( sfg );

R_xlen_t n_geometries = coords.nrow();
R_xlen_t n_coordinates = coords( n_geometries - 1, 1 );
n_coordinates = n_coordinates + 1;
Rcpp::IntegerVector start_indices = coords( Rcpp::_, 0 );
start_indices = start_indices + coordinate_counter;

res_indices[ i ] = start_indices;
res_list[ i ] = sfheaders::interleave::interleave( sfg );

coordinate_counter = coordinate_counter + n_coordinates;
}

return Rcpp::List::create(
Rcpp::_["coordinates"] = sfheaders::utils::unlist_list( res_list ),
Rcpp::_["start_indices"] = sfheaders::utils::unlist_list( res_indices ),
Rcpp::_["stride"] = stride
);
}

} // interleave
} // sfheaders

Expand Down
12 changes: 0 additions & 12 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,6 @@ BEGIN_RCPP
return rcpp_result_gen;
END_RCPP
}
// rcpp_interleave
SEXP rcpp_interleave(Rcpp::List sfc);
RcppExport SEXP _sfheaders_rcpp_interleave(SEXP sfcSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< Rcpp::List >::type sfc(sfcSEXP);
rcpp_result_gen = Rcpp::wrap(rcpp_interleave(sfc));
return rcpp_result_gen;
END_RCPP
}
// rcpp_fill_list
Rcpp::List rcpp_fill_list(Rcpp::NumericVector v, Rcpp::IntegerMatrix line_ids);
RcppExport SEXP _sfheaders_rcpp_fill_list(SEXP vSEXP, SEXP line_idsSEXP) {
Expand Down Expand Up @@ -845,7 +834,6 @@ static const R_CallMethodDef CallEntries[] = {
{"_sfheaders_rcpp_count_new_sfc_objects", (DL_FUNC) &_sfheaders_rcpp_count_new_sfc_objects, 2},
{"_sfheaders_rcpp_cast_sfc", (DL_FUNC) &_sfheaders_rcpp_cast_sfc, 3},
{"_sfheaders_rcpp_cast_sf", (DL_FUNC) &_sfheaders_rcpp_cast_sf, 3},
{"_sfheaders_rcpp_interleave", (DL_FUNC) &_sfheaders_rcpp_interleave, 1},
{"_sfheaders_rcpp_fill_list", (DL_FUNC) &_sfheaders_rcpp_fill_list, 2},
{"_sfheaders_rcpp_list_sizes", (DL_FUNC) &_sfheaders_rcpp_list_sizes, 1},
{"_sfheaders_rcpp_list_type", (DL_FUNC) &_sfheaders_rcpp_list_type, 1},
Expand Down
Loading

0 comments on commit ab2a757

Please sign in to comment.