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

Restructure #60

Merged
merged 4 commits into from
Dec 30, 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
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: geojsonsf
Type: Package
Title: GeoJSON to Simple Feature Converter
Version: 1.2.1
Date: 2018-11-19
Version: 1.3.0
Date: 2019-01-02
Authors@R: c(
person("David", "Cooley", ,"[email protected]", role = c("aut", "cre"))
)
Expand All @@ -12,7 +12,7 @@ Encoding: UTF-8
LazyData: true
Depends: R (>= 3.3.0)
LinkingTo:
jsonify (>= 0.1.2002),
jsonify (>= 0.1.2003),
rapidjsonr (>= 1.1),
Rcpp
Imports:
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@

## v1.3

* restructured C++ src code for easier navigation and linking


## v1.2.2

* `digits` argument for rounding coordinates
Expand Down
191 changes: 191 additions & 0 deletions inst/include/geojsonsf/geojson/api/df_api.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
#ifndef GEOJSONSF_GEOJSON_DF_API_H
#define GEOJSONSF_GEOJSON_DF_API_H

#include "jsonify/jsonify.hpp"
#include "jsonify/to_json/dataframe.hpp"

#include "geojsonsf/geojsonsf.h"
#include "geojsonsf/utils/where/where.hpp"
#include "geojsonsf/geojson/write_geometry.hpp"

namespace geojsonsf {
namespace api {

inline Rcpp::StringVector df_to_geojson(
Rcpp::DataFrame& df,
Rcpp::StringVector& geometry_columns,
int& digits ) {

rapidjson::StringBuffer sb;
rapidjson::Writer < rapidjson::StringBuffer > writer( sb );

size_t n_cols = df.ncol();
size_t n_rows = df.nrows();
size_t i, j;
Rcpp::StringVector column_names = df.names();

// the sfc_POINT
size_t n_geometry_columns = geometry_columns.size();
Rcpp::List geometry_vectors( n_geometry_columns );

size_t n_properties = n_cols - n_geometry_columns;
Rcpp::StringVector property_names( n_properties );

for ( i = 0; i < n_geometry_columns; i++ ) {
Rcpp::String this_geometry = geometry_columns[i];
geometry_vectors[i] = df[ this_geometry ];
}

std::string dim = geojsonsf::utils::make_dimension( n_geometry_columns );
Rcpp::CharacterVector cls = Rcpp::CharacterVector::create( dim , "POINT", "sfg");

int property_counter = 0;

for ( int i = 0; i < df.length(); i++ ) {

Rcpp::String this_column = column_names[i];
int idx = geojsonsf::utils::where::where_is( this_column, geometry_columns );

if ( idx == -1 ) { // i.e. it's not in the vector
property_names[property_counter] = column_names[i];
property_counter++;
}
}

writer.StartObject();
geojsonsf::writers::start_feature_collection( writer );

writer.StartArray();

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

writer.StartObject();

geojsonsf::writers::start_features( writer );
geojsonsf::writers::start_properties( writer );
writer.StartObject();
// properties first, then sfc

for( j = 0; j < n_properties; j++ ) {
const char *h = property_names[ j ];
SEXP this_vec = df[ h ];

jsonify::writers::write_value( writer, h );
jsonify::dataframe::dataframe_cell( writer, this_vec, i );
}
writer.EndObject();

writer.String("geometry");

Rcpp::NumericVector geom( n_geometry_columns );
for ( j = 0; j < n_geometry_columns; j++ ) {
Rcpp::NumericVector this_geometry_vector = geometry_vectors[j];
geom[j] = this_geometry_vector[i];
}
SEXP sfg = geom;
geojsonsf::write_geometry::write_geometry( writer, sfg, cls, digits );

writer.EndObject();
}

writer.EndArray();
writer.EndObject();

Rcpp::StringVector geojson = sb.GetString();
geojsonsf::attach_class( geojson );
return geojson;
}

inline Rcpp::StringVector df_to_geojson_atomise(
Rcpp::DataFrame& df,
Rcpp::StringVector& geometry_columns,
int& digits) {

size_t n_cols = df.ncol();
size_t n_rows = df.nrows();
size_t i, j;
Rcpp::StringVector column_names = df.names();

Rcpp::StringVector geojson( n_rows );


size_t n_geometry_columns = geometry_columns.size();
Rcpp::List geometry_vectors( n_geometry_columns );

size_t n_properties = n_cols - n_geometry_columns;
Rcpp::StringVector property_names( n_properties );

for ( i = 0; i < n_geometry_columns; i++ ) {
Rcpp::String this_geometry = geometry_columns[i];
geometry_vectors[i] = df[ this_geometry ];
}

std::string dim = geojsonsf::utils::make_dimension( n_geometry_columns );
Rcpp::CharacterVector cls = Rcpp::CharacterVector::create( dim , "POINT", "sfg");

int property_counter = 0;
for (int i = 0; i < df.length(); i++) {

Rcpp::String this_column = column_names[i];
int idx = geojsonsf::utils::where::where_is( this_column, geometry_columns );

if ( idx == -1 ) { // i.e. it's not in the vector

property_names[property_counter] = column_names[i];
property_counter++;
}
}


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

rapidjson::StringBuffer sb;
rapidjson::Writer < rapidjson::StringBuffer > writer( sb );

if ( n_properties > 0 ) {
writer.StartObject();
geojsonsf::writers::start_features( writer );
geojsonsf::writers::start_properties( writer );

writer.StartObject();

// properties first, then sfc
for( j = 0; j < n_properties; j++ ) {
const char *h = property_names[ j ];

SEXP this_vec = df[ h ];

jsonify::writers::write_value( writer, h );
jsonify::dataframe::dataframe_cell( writer, this_vec, i );
}
writer.EndObject();
}

// now geometries
if( n_properties > 0 ) {
writer.String("geometry");
}

Rcpp::NumericVector geom( n_geometry_columns );
for ( j = 0; j < n_geometry_columns; j++ ) {
Rcpp::NumericVector this_geometry_vector = geometry_vectors[j];
geom[j] = this_geometry_vector[i];
}
SEXP sfg = geom;
geojsonsf::write_geometry::write_geometry( writer, sfg, cls, digits );

if( n_properties > 0 ) {
writer.EndObject();
}
geojson[i] = sb.GetString();
}

geojsonsf::attach_class( geojson );
return geojson;
}

} // namespace geojsonsf
} // namespace api


#endif
172 changes: 172 additions & 0 deletions inst/include/geojsonsf/geojson/api/sf_api.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#ifndef GEOJSONSF_GEOJSON_SF_API_H
#define GEOJSONSF_GEOJSON_SF_API_H

#include "jsonify/jsonify.hpp"
#include "jsonify/to_json/dataframe.hpp"

#include "geojsonsf/geojsonsf.h"
#include "geojsonsf/geojson/write_geometry.hpp"

namespace geojsonsf {
namespace api {

inline Rcpp::StringVector sfc_to_geojson( Rcpp::List& sfc, int& digits ) {
// atomise - each row is a separate GeoJSON string

size_t n_rows = sfc.size();
size_t i;

Rcpp::StringVector geojson( n_rows );

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

rapidjson::StringBuffer sb;
rapidjson::Writer < rapidjson::StringBuffer > writer( sb );

geojsonsf::write_geometry::write_geometry( writer, sfc, i, digits );
geojson[i] = sb.GetString();
}
geojsonsf::attach_class( geojson );
return geojson;
}

/*
* sf_to_geojson
*
* Converts sf object to GeoJSON
*/
inline Rcpp::StringVector sf_to_geojson( Rcpp::DataFrame& sf, int& digits ) {
rapidjson::StringBuffer sb;
rapidjson::Writer < rapidjson::StringBuffer > writer( sb );

std::string geom_column = sf.attr("sf_column");

size_t n_cols = sf.ncol();
size_t n_properties = n_cols - 1;
size_t n_rows = sf.nrows();
size_t i, j;
Rcpp::StringVector column_names = sf.names();
Rcpp::StringVector property_names(sf.size() - 1);

int property_counter = 0;
for (int i = 0; i < sf.length(); i++) {
if (column_names[i] != geom_column) {
property_names[property_counter] = column_names[i];
property_counter++;
}
}

writer.StartObject();
geojsonsf::writers::start_feature_collection( writer );

writer.StartArray();

for( i = 0; i < n_rows; i++ ) {
writer.StartObject();
geojsonsf::writers::start_features( writer );
geojsonsf::writers::start_properties( writer );
writer.StartObject();

// properties first, then sfc
for( j = 0; j < n_properties; j++ ) {
const char *h = property_names[ j ];

SEXP this_vec = sf[ h ];

jsonify::writers::write_value( writer, h );
jsonify::dataframe::dataframe_cell( writer, this_vec, i );
}
writer.EndObject();

writer.String("geometry");

Rcpp::List sfc = sf[ geom_column ];
geojsonsf::write_geometry::write_geometry( writer, sfc, i, digits );

writer.EndObject();
}

writer.EndArray();
writer.EndObject();

Rcpp::StringVector geojson = sb.GetString();
geojsonsf::attach_class( geojson );
return geojson;
}

/*
*
* sf_to_geojson_atomise
*
* Takes an sf object, converts to atomised GeoJSON
* Where every geometry is turned into an individual array
*/
inline Rcpp::StringVector sf_to_geojson_atomise( Rcpp::DataFrame& sf, int& digits ) {
// atomise - each row is a separate GeoJSON string

std::string geom_column = sf.attr("sf_column");

size_t n_cols = sf.ncol();
size_t n_properties = n_cols - 1;
size_t n_rows = sf.nrows();
size_t i, j;
Rcpp::StringVector column_names = sf.names();
Rcpp::StringVector property_names(sf.size() - 1);

Rcpp::StringVector geojson( n_rows );

int property_counter = 0;
for (int i = 0; i < sf.length(); i++) {
if (column_names[i] != geom_column) {
property_names[property_counter] = column_names[i];
property_counter++;
}
}

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

rapidjson::StringBuffer sb;
rapidjson::Writer < rapidjson::StringBuffer > writer( sb );

if ( n_properties > 0 ) {
writer.StartObject();
geojsonsf::writers::start_features( writer );
geojsonsf::writers::start_properties( writer );

writer.StartObject();

// properties first, then sfc
for( j = 0; j < n_properties; j++ ) {
const char *h = property_names[ j ];

SEXP this_vec = sf[ h ];

jsonify::writers::write_value( writer, h );
jsonify::dataframe::dataframe_cell( writer, this_vec, i );
}
writer.EndObject();
}

// now geometries
if( n_properties > 0 ) {
writer.String("geometry");
}

Rcpp::List sfc = sf[ geom_column ];
geojsonsf::write_geometry::write_geometry( writer, sfc, i, digits );

if( n_properties > 0 ) {
writer.EndObject();
}
geojson[i] = sb.GetString();
}

geojsonsf::attach_class( geojson );
return geojson;
}

} // namespace geojsonsf
} // namespace api


#endif
Loading