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

Refactor and NA handling for 'decode()' #35

Merged
merged 4 commits into from
Sep 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions inst/include/googlePolylines.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,18 @@ std::vector<std::string> split(const std::string &s, char delim);

Rcpp::CharacterVector getSfClass(SEXP sf);

Rcpp::DataFrame decode_polyline(std::string encoded, std::string encoded_type);
Rcpp::List decode_polyline(std::string encoded,
std::vector<std::string>& col_headers,
std::vector<double>& pointsLat,
std::vector<double>& pointsLon);

Rcpp::String EncodeNumber(int num);
std::vector<std::string> get_col_headers(Rcpp::String sfg_dim);

Rcpp::String EncodeSignedNumber(int num);
Rcpp::List na_dataframe(std::vector<std::string>& col_headers);

void EncodeNumber(std::ostringstream& os, int num);

void EncodeSignedNumber(std::ostringstream& os, int num);

Rcpp::String encode_polyline(Rcpp::NumericVector latitude,
Rcpp::NumericVector longitude);
Expand Down
4 changes: 2 additions & 2 deletions src/RcppExports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ BEGIN_RCPP
END_RCPP
}
// rcpp_decode_polyline
Rcpp::List rcpp_decode_polyline(Rcpp::StringVector encodedStrings, std::string encoded_type);
Rcpp::List rcpp_decode_polyline(Rcpp::StringVector encodedStrings, Rcpp::String encoded_type);
RcppExport SEXP _googlePolylines_rcpp_decode_polyline(SEXP encodedStringsSEXP, SEXP encoded_typeSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< Rcpp::StringVector >::type encodedStrings(encodedStringsSEXP);
Rcpp::traits::input_parameter< std::string >::type encoded_type(encoded_typeSEXP);
Rcpp::traits::input_parameter< Rcpp::String >::type encoded_type(encoded_typeSEXP);
rcpp_result_gen = Rcpp::wrap(rcpp_decode_polyline(encodedStrings, encoded_type));
return rcpp_result_gen;
END_RCPP
Expand Down
6 changes: 3 additions & 3 deletions src/encode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void make_type(const char *cls, int *tp = NULL,
else if (strcmp(cls, "GEOMETRY") == 0)
type = SF_Geometry;
else if (strcmp(cls, "GEOMETRYCOLLECTION") == 0)
type = SF_GeometryCollection;
type = SF_GeometryCollection;
else
type = SF_Unknown;
if (tp != NULL)
Expand Down Expand Up @@ -135,8 +135,8 @@ void encode_points( std::ostringstream& os, std::ostringstream& oszm, Rcpp::Nume
Rcpp::NumericVector pointLon;
Rcpp::NumericVector pointLat;

Rcpp::NumericVector elev(1);
Rcpp::NumericVector meas(1);
//Rcpp::NumericVector elev(1);
//Rcpp::NumericVector meas(1);

for (int i = 0; i < n; i++){
pointLon = point(i, 0);
Expand Down
95 changes: 66 additions & 29 deletions src/googlePolylines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,33 @@ Rcpp::List rcpp_decode_polyline_list( Rcpp::List encodedList, std::string attrib
size_t n = encodedList.size();
Rcpp::List output(n);
Rcpp::CharacterVector sfg_dim;
std::string encoded_type;
std::vector<double> pointsLat;
std::vector<double> pointsLon;
std::vector<std::string> col_headers;

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

Rcpp::StringVector polylines = encodedList[i];

sfg_dim = polylines.attr( attribute );
encoded_type = as< std::string>( sfg_dim[0] );
col_headers = get_col_headers(sfg_dim[0]);

size_t pn = polylines.size();
Rcpp::List polyline_output(pn);

for (size_t j = 0; j < pn; j++ ) {

// If polylines[j] is NA, assign a data frame of NA values
if (Rcpp::StringVector::is_na(polylines[j])) {
polyline_output[j] = na_dataframe(col_headers);
continue;
}

Rcpp::StringVector sv(1);
sv[0] = polylines[j];

std::string s = Rcpp::as< std::string >(sv);
polyline_output[j] = decode_polyline(s, encoded_type );
polyline_output[j] = decode_polyline(s, col_headers, pointsLat, pointsLon);
}
output[i] = polyline_output;
}
Expand All @@ -40,16 +48,25 @@ Rcpp::List rcpp_decode_polyline_list( Rcpp::List encodedList, std::string attrib
}

// [[Rcpp::export]]
Rcpp::List rcpp_decode_polyline(Rcpp::StringVector encodedStrings, std::string encoded_type) {
Rcpp::List rcpp_decode_polyline(Rcpp::StringVector encodedStrings, Rcpp::String encoded_type) {

int encodedSize = encodedStrings.size();
Rcpp::List results(encodedSize);
std::vector<double> pointsLat;
std::vector<double> pointsLon;
std::vector<std::string> col_headers = get_col_headers(encoded_type);

for(int i = 0; i < encodedSize; i++){

// If encodedStrings[i] is NA, assign a data frame of NA values
if (Rcpp::StringVector::is_na(encodedStrings[i])) {
results[i] = na_dataframe(col_headers);
continue;
}

std::string encoded = Rcpp::as< std::string >(encodedStrings[i]);

Rcpp::DataFrame decoded = decode_polyline(encoded, encoded_type);
Rcpp::List decoded = decode_polyline(encoded, col_headers, pointsLat, pointsLon);

results[i] = decoded;
}
Expand All @@ -59,15 +76,18 @@ Rcpp::List rcpp_decode_polyline(Rcpp::StringVector encodedStrings, std::string e


// @param type the type of decoded object, coordinates or ZM Attribute
Rcpp::DataFrame decode_polyline(std::string encoded, std::string encoded_type){
Rcpp::List decode_polyline(std::string encoded,
std::vector<std::string>& col_headers,
std::vector<double>& pointsLat,
std::vector<double>& pointsLon) {

int len = encoded.size();
int index = 0;
float lat = 0;
float lng = 0;

Rcpp::NumericVector pointsLat;
Rcpp::NumericVector pointsLon;
pointsLat.clear();
pointsLon.clear();

while (index < len){
char b;
Expand Down Expand Up @@ -96,31 +116,48 @@ Rcpp::DataFrame decode_polyline(std::string encoded, std::string encoded_type){
}

//TODO(ZM attributes)

// Create List output that has the necessary attributes to make it a
// data.frame object.
Rcpp::List out = Rcpp::List::create(
Named(col_headers[0]) = pointsLat,
Named(col_headers[1]) = pointsLon
);

out.attr("class") = "data.frame";
out.attr("row.names") = seq(1, pointsLat.size());


if (encoded_type == "XYZ" ) {
return Rcpp::DataFrame::create(
Named("Z") = pointsLon,
Named("M") = pointsLat
);
} else if (encoded_type == "XYM") {
return Rcpp::DataFrame::create(
Named("M") = pointsLon,
Named("Z") = pointsLat
);
} else if (encoded_type == "XYZM" ) {
return Rcpp::DataFrame::create(
Named("Z") = pointsLon,
Named("M") = pointsLat
);
return out;
}

std::vector<std::string> get_col_headers(Rcpp::String sfg_dim) {
std::vector<std::string> out;
if (sfg_dim == "XYZ" || sfg_dim == "XYZM") {
out.push_back("Z");
out.push_back("M");
} else if (sfg_dim == "XYM") {
out.push_back("M");
out.push_back("Z");
} else {
out.push_back("lat");
out.push_back("lon");
}


// putting latitude first
return Rcpp::DataFrame::create(
Named("lat") = pointsLat,
Named("lon") = pointsLon);
return out;
}

Rcpp::List na_dataframe(std::vector<std::string>& col_headers) {
// Create List output that has the necessary attributes to make it a
// data.frame object.
Rcpp::List out = Rcpp::List::create(
Named(col_headers[0]) = NA_REAL,
Named(col_headers[1]) = NA_REAL
);

out.attr("class") = "data.frame";
out.attr("row.names") = 1;

return out;
}

void EncodeNumber(std::ostringstream& os, int num){
Expand Down
5 changes: 5 additions & 0 deletions tests/testthat/test-Decode.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ test_that("decode works", {
expect_error(decode(data.frame()),"I don't know how to decode this object")
})

test_that("NA inputs handled properly", {
expect_equal(decode(NA_character_),
list(data.frame("lat" = NA_real_, "lon" = NA_real_)))
})


# test_that("decoding ZM columns", {
#
Expand Down