forked from SymbolixAU/googlePolylines
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
874 additions
and
423 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.