Skip to content

Commit

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

rcpp_interleave_sfc <- function(sfc) {
.Call(`_sfheaders_rcpp_interleave_sfc`, sfc)
}

rcpp_interleave_sf <- function(sf) {
.Call(`_sfheaders_rcpp_interleave_sf`, sf)
}

rcpp_fill_list <- function(v, line_ids) {
.Call(`_sfheaders_rcpp_fill_list`, v, line_ids)
}
Expand Down
89 changes: 67 additions & 22 deletions inst/include/sfheaders/interleave/interleave.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <Rcpp.h>
#include "sfheaders/df/sfc.hpp"
#include "sfheaders/df/sf.hpp"
#include "sfheaders/utils/lists/list.hpp"

namespace sfheaders {
Expand Down Expand Up @@ -66,7 +67,11 @@ namespace interleave {
}


inline SEXP interleave( Rcpp::List& sfc ) {
// TODO: unlist - to unlist some columns (like 'stroke_colour')
inline SEXP interleave(
Rcpp::List& sfc,
R_xlen_t& total_coordinates
) {

// the input will be a long data.frame
// or an sf object
Expand All @@ -82,11 +87,10 @@ namespace interleave {
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 total_coordinates = 0;
//R_xlen_t total_coordinates = 0;
Rcpp::List res_list( sfc.size() );
Rcpp::List res_indices( sfc.size() );
Rcpp::IntegerVector sfg_coordinates( sfc.size() );

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

Expand All @@ -106,7 +110,12 @@ namespace interleave {

R_xlen_t n_geometries = coords.nrow();
R_xlen_t n_coordinates = coords( n_geometries - 1, 1 );
n_coordinates = n_coordinates + 1;

// n_coordinates is the total number of coordinates for the given sfg
// this is what the data needs to be expanded by.
//n_coordinates = n_coordinates + 1;
sfg_coordinates[ i ] = n_coordinates;

Rcpp::IntegerVector start_indices = coords( Rcpp::_, 0 );
start_indices = start_indices + total_coordinates;

Expand All @@ -116,36 +125,72 @@ namespace interleave {
total_coordinates = total_coordinates + n_coordinates;
}

// TODO: expand the property columns
// Rcpp::NumericVector expanded_index( total_coordinates );
// R_xlen_t n_col = sf.ncol();
// Rcpp::CharacterVector sf_names = sf.names();
// R_xlen_t name_position = 0;
// for( i = 0; i < n_col; ++i ) {
//
// if( sf_names[ i ] != geom_column ) {
//
// res_names[ name_position ] = sf_names[ i ];
// SEXP v = sf[ i ];
// expand_vector( res, v, expanded_index, name_position );
// name_position += 1;
// }
// }
int stride = ( dim_expected == "XYZ" || dim_expected == "XYM" ? 3 : ( dim_expected == "XYZM" ? 4 : 2 ) );

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

inline SEXP interleave( Rcpp::List& sfc ) {
R_xlen_t total_coordinates = 0;
return interleave( sfc, total_coordinates );
}


// interleaves an `sf` object
inline Rcpp::List interleave( Rcpp::DataFrame& sf ) {
// and expand rows
std::string sfc_col = sf.attr("sf_column");
Rcpp::List sfc = sf[ sfc_col ];
std::string geom_column = sf.attr("sf_column");
Rcpp::CharacterVector sf_names = sf.names();
Rcpp::List sfc = sf[ geom_column ];
R_xlen_t n_col = sf.ncol();
R_xlen_t n_geometries = sf.nrow();
R_xlen_t i;
R_xlen_t j;

R_xlen_t total_coordinates = 0;
Rcpp::List interleaved = interleave( sfc, total_coordinates );
Rcpp::IntegerVector n_coordinates = interleaved["n_coordinates"];

Rcpp::NumericVector expanded_index( total_coordinates );
R_xlen_t counter = 0;

for( i = 0; i < n_geometries; ++i ) {
R_xlen_t expand_by = n_coordinates[ i ];

for( j = 0; j < expand_by; ++j ) {
expanded_index[ counter + j ] = i;
}
counter = counter + expand_by;
}

Rcpp::List res( n_col - 1 );
Rcpp::StringVector res_names( n_col - 1 );

R_xlen_t name_position = 0;

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

if( sf_names[ i ] != geom_column ) {

res_names[ name_position ] = sf_names[ i ];
SEXP v = sf[ i ];
sfheaders::df::expand_vector( res, v, expanded_index, name_position );
name_position += 1;
}
}

//res.names() = res_names;
Rcpp::DataFrame df = sfheaders::utils::make_dataframe( res, total_coordinates, res_names );

// construct final object
interleaved["data"] = df;
return interleaved;

}

Expand Down
24 changes: 24 additions & 0 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,28 @@ BEGIN_RCPP
return rcpp_result_gen;
END_RCPP
}
// rcpp_interleave_sfc
SEXP rcpp_interleave_sfc(Rcpp::List sfc);
RcppExport SEXP _sfheaders_rcpp_interleave_sfc(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(sfc));
return rcpp_result_gen;
END_RCPP
}
// rcpp_interleave_sf
SEXP rcpp_interleave_sf(Rcpp::DataFrame sf);
RcppExport SEXP _sfheaders_rcpp_interleave_sf(SEXP sfSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< Rcpp::DataFrame >::type sf(sfSEXP);
rcpp_result_gen = Rcpp::wrap(rcpp_interleave_sf(sf));
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 @@ -834,6 +856,8 @@ 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_sfc", (DL_FUNC) &_sfheaders_rcpp_interleave_sfc, 1},
{"_sfheaders_rcpp_interleave_sf", (DL_FUNC) &_sfheaders_rcpp_interleave_sf, 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
9 changes: 9 additions & 0 deletions src/interleave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ void interleave_geometry(SEXP& sfg, Rcpp::NumericVector& res, R_xlen_t& coordina

}

// [[Rcpp::export]]
SEXP rcpp_interleave_sfc( Rcpp::List sfc ) {
return sfheaders::interleave::interleave( sfc );
}

// [[Rcpp::export]]
SEXP rcpp_interleave_sf( Rcpp::DataFrame sf ) {
return sfheaders::interleave::interleave( sf );
}

// SEXP rcpp_interleave( Rcpp::List sfc ) {
//
Expand Down

0 comments on commit 299869f

Please sign in to comment.