Skip to content

Commit

Permalink
Merge pull request #60 from SymbolixAU/restructure
Browse files Browse the repository at this point in the history
Restructure
  • Loading branch information
SymbolixAU authored Dec 30, 2018
2 parents d349113 + 65e2f89 commit caa97b6
Show file tree
Hide file tree
Showing 36 changed files with 2,272 additions and 2,048 deletions.
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

0 comments on commit caa97b6

Please sign in to comment.