Skip to content

Commit

Permalink
restructuring SymbolixAU#38
Browse files Browse the repository at this point in the history
  • Loading branch information
dcooley committed Feb 8, 2020
1 parent 668ef9e commit 2662a79
Show file tree
Hide file tree
Showing 15 changed files with 874 additions and 423 deletions.
5 changes: 4 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ SystemRequirements: C++11
Depends: R (>= 3.3.0)
Imports:
Rcpp (>= 0.12.13)
LinkingTo: Rcpp, BH
LinkingTo:
Rcpp,
BH,
sfheaders
RoxygenNote: 6.1.0
Suggests:
covr,
Expand Down
8 changes: 4 additions & 4 deletions R/Encode.R
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ encode <- function(obj, ...) UseMethod("encode")
encode.sf <- function(obj, strip = FALSE, ...) {

geomCol <- sfGeometryColumn(obj)
lst <- rcpp_encodeSfGeometry(obj[[geomCol]], strip)

##lst <- rcpp_encodeSfGeometry(obj[[geomCol]], strip)
lst <- rcpp_encode_sfc( obj[[geomCol]], strip)
if(!strip) sfAttrs <- sfGeometryAttributes(obj)

# obj[[geomCol]] <- lst[['XY']]
Expand Down Expand Up @@ -126,8 +126,8 @@ encode.sf <- function(obj, strip = FALSE, ...) {

#' @export
encode.sfc <- function(obj, strip = FALSE, ...) {
lst <- rcpp_encodeSfGeometry(obj, strip)

##lst <- rcpp_encodeSfGeometry(obj, strip)
lst <- rcpp_encode_sfc( obj, strip )
# ## TODO(remove this vapply step and return from rcpp a flag if the ZM attrs are attached)
# if (all(vapply(lst[['ZM']], length, 0L)) == 0) {
#
Expand Down
4 changes: 2 additions & 2 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

rcpp_encodeSfGeometry <- function(sfc, strip) {
.Call('_googlePolylines_rcpp_encodeSfGeometry', PACKAGE = 'googlePolylines', sfc, strip)
rcpp_encode_sfc <- function(sfc, strip) {
.Call('_googlePolylines_rcpp_encode_sfc', PACKAGE = 'googlePolylines', sfc, strip)
}

rcpp_decode_polyline_list <- function(encodedList, attribute) {
Expand Down
4 changes: 2 additions & 2 deletions inst/include/googlePolylines.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void split(const std::string &s, char delim, Out result);

void split(const std::string &s, char delim);

Rcpp::CharacterVector getSfClass(SEXP sf);
//Rcpp::CharacterVector getSfClass(SEXP sf);

Rcpp::List decode_polyline(std::string encoded,
std::vector<std::string>& col_headers,
Expand All @@ -57,7 +57,7 @@ void EncodeSignedNumber(std::ostringstream& os, int num);
std::string encode_polyline();

Rcpp::List decode_data(Rcpp::StringVector pl,
const char *cls = NULL);
const char *cls = NULL);


namespace global_vars {
Expand Down
51 changes: 51 additions & 0 deletions inst/include/googlepolylines/decode.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#ifndef R_GOOGLEPOLYLINES_DECODE_H
#define R_GOOGLEPOLYLINES_DECODE_H

namespace googlepolylines {
namespace decode {

inline void decode(
std::string& encoded,
std::vector<double>& pointsLat,
std::vector<double>& pointsLon
) {

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

pointsLat.clear();
pointsLon.clear();

while (index < len){
char b;
unsigned int shift = 0;
int result = 0;
do {
b = encoded.at(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
float dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;

shift = 0;
result = 0;
do {
b = encoded.at(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
float dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;

pointsLat.push_back(lat * (float)1e-5);
pointsLon.push_back(lng * (float)1e-5);
}
}

} // decode
} // googlepolylines

#endif
253 changes: 253 additions & 0 deletions inst/include/googlepolylines/encode.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
#ifndef R_GOOGLEPOLYLINES_ENCODE_H
#define R_GOOGLEPOLYLINES_ENCODE_H

#include <Rcpp.h>
#include "googlepolylines/googlepolylines.h"

#include "sfheaders/df/sfg.hpp"

namespace googlepolylines {
namespace encode {

// inline void add_to_stream(
// std::ostringstream& os,
// std::string& encoded_string
// ) {
// os << encoded_string << ' ';
// }

inline void encode_number(
std::ostringstream& os,
int num
) {

std::string out_str;

while(num >= 0x20){
out_str += (char)(0x20 | (int)(num & 0x1f)) + 63;
num >>= 5;
}

out_str += char(num + 63);
os << out_str;
}

inline void encode_signed_number(
std::ostringstream& os,
int num
) {

unsigned int ui = num; //3
ui <<= 1; //4
ui = (num < 0) ? ~ui : ui; //5
encode_number(os, ui);
}

inline void encode(
Rcpp::NumericVector& lons,
Rcpp::NumericVector& lats,
std::ostringstream& os
) {
int plat = 0;
int plon = 0;
int late5;
int lone5;

R_xlen_t i;
R_xlen_t n = lats.size();

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

late5 = lats[ i ] * 1e5;
lone5 = lons[ i ] * 1e5;

encode_signed_number(os, late5 - plat);
encode_signed_number(os, lone5 - plon);

plat = late5;
plon = lone5;
}
}

inline std::string encode(
Rcpp::NumericVector& lons,
Rcpp::NumericVector& lats
) {
std::ostringstream os;
encode( lons, lats, os );
Rcpp::Rcout << "os" << os.str() << std::endl;
return os.str();
}

inline std::string encode(
Rcpp::NumericMatrix& mat
) {
if( mat.ncol() < 2 ) {
Rcpp::stop("googlepolylines - expecting at least 2 columns in a matrix");
}

Rcpp::Rcout << "n_row: " << mat.nrow() << std::endl;

Rcpp::NumericVector lons = mat( Rcpp::_, 0 );
Rcpp::NumericVector lats = mat( Rcpp::_, 1 );
return encode( lons, lats );
}

// encode sfg objects
inline std::string encode_point(
Rcpp::NumericVector& sfg
) {

//Rcpp::DataFrame df = sfheaders::df::sfg_to_df(sfg);
// but I don't know what type of sfg it is yet...

if( sfg.length() < 2 ) {
Rcpp::stop("googlepolylines - not enough values in a point");
}
Rcpp::NumericVector lons(1);
Rcpp::NumericVector lats(1);
lons[0] = sfg[0];
lats[0] = sfg[1];
return encode( lons, lats );
}

inline Rcpp::StringVector encode_multipoint(
Rcpp::NumericMatrix& sfg
) {

if( sfg.ncol() < 2 ) {
Rcpp::stop("googlepolylines - not enough columns in the matrix");
}
R_xlen_t n = sfg.nrow();
Rcpp::Rcout << "n: " << n << std::endl;
R_xlen_t i;
Rcpp::StringVector res( n );
for( i = 0; i < n; ++i ) {
double lon = sfg( i, 0 );
double lat = sfg( i, 1 );
Rcpp::NumericVector lons(1);
Rcpp::NumericVector lats(1);
lons[0] = lon;
lats[0] = lat;
res[i] = encode( lons, lats );
}
return res;
}

inline Rcpp::StringVector encode_linestring(
Rcpp::NumericMatrix& sfg
) {

R_xlen_t n = sfg.nrow();
if( n == 0 ) {
return Rcpp::StringVector::create();
}
return encode( sfg );
}

inline Rcpp::StringVector encode_multilinestring(
Rcpp::List& sfg
) {
int n = sfg.length();
int i;
Rcpp::StringVector res( n );

for( i = 0; i < n; ++i ) {
Rcpp::NumericMatrix line = sfg[ i ];
res[ i ] = encode( line );
}
return res;
}

inline Rcpp::StringVector encode_polygon(
Rcpp::List& sfg
) {
return encode_multilinestring( sfg );
}

inline Rcpp::StringVector encode_multipolygon(
Rcpp::List& sfg
) {

int n = sfg.length();
int i, j;
Rcpp::List polygons( n );
int line_counter = 0;

for( i = 0; i < n; ++i ) {
Rcpp::List polygon = sfg[ i ];
polygons[ i ] = encode_polygon( polygon );
line_counter = line_counter + polygon.size() + 1; // to add the SPLIT_CHAR "-" to separate polygons
}

Rcpp::StringVector res( line_counter );
// unpack the polygon list
int counter = 0;
for( i = 0; i < polygons.size(); ++i ) {
Rcpp::List poly = polygons[ i ];
for( j = 0; j < poly.size(); ++j ) {
std::string line = poly[ j ];
res[ counter ] = line;
counter = counter + 1;
}
res[ counter ] = SPLIT_CHAR;
counter = counter + 1;
}

// remove the final SPLIT_CHAR
res.erase( line_counter - 1 );

//return polygons;
return res;
}

inline Rcpp::List encode_sfc(
Rcpp::List& sfc
) {
// Rcpp::Rcout << "encode_sfc " << std::endl;
R_xlen_t n = sfc.size();
R_xlen_t i;
Rcpp::List res( n );
Rcpp::CharacterVector cls;
std::string geometry;

// Rcpp::Rcout << "n: " << n << std::endl;

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

SEXP sfg = sfc[ i ];
cls = sfheaders::df::getSfgClass( sfg );
geometry = cls[1];

// Rcpp::Rcout << "geometry: " << geometry << std::endl;

if( geometry == "POINT" ) {
Rcpp::NumericVector nv = Rcpp::as< Rcpp::NumericVector >( sfg );
res[i] = encode_point( nv );
} else if ( geometry == "MULTIPOINT" ) {
Rcpp::NumericMatrix nm = Rcpp::as< Rcpp::NumericMatrix >( sfg );
res[i] = encode_multipoint( nm );
} else if ( geometry == "LINESTRING" ) {
Rcpp::NumericMatrix nm = Rcpp::as< Rcpp::NumericMatrix >( sfg );
res[i] = encode_linestring( nm );
} else if ( geometry == "MULTILINESTRING" ) {
Rcpp::List mls = Rcpp::as< Rcpp::List >( sfg );
res[i] = encode_multilinestring( mls );
} else if ( geometry == "POLYGON" ) {
Rcpp::List pl = Rcpp::as< Rcpp::List >( sfg );
res[i] = encode_polygon( pl );
} else if ( geometry == "MULTIPOLYGON" ) {
Rcpp::List mpl = Rcpp::as< Rcpp::List >( sfg );
res[i] = encode_multipolygon( mpl );
} else {
Rcpp::stop("googlepolylines - unknown sfg type");
}
}
return res;
}


} // encode
} // googlepolylines

#endif
Loading

0 comments on commit 2662a79

Please sign in to comment.