/*************************************************************************** * Project: osmdata * File: osmdata-sc.cpp * Language: C++ * * osmdata is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * * osmdata is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * osm-router. If not, see . * * Author: Mark Padgham * E-Mail: mark.padgham@email.com * * Description: Extract OSM data from an object of class XmlData and return * it in Rcpp::List format. * * Limitations: * * Dependencies: none (rapidXML header included in osmdata) * * Compiler Options: -std=c++11 ***************************************************************************/ #include "osmdata.h" #include "osmdata-sc.h" // Function to generate IDs for the edges in each way std::string random_id (size_t len) { auto randchar = []() -> char { const char charset[] = \ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; const size_t max_index = (sizeof(charset) - 1); //return charset [ rand() % max_index ]; size_t i = static_cast (floor (Rcpp::runif (1) [0] * max_index)); return charset [i]; }; std::string str (len, 0); std::generate_n (str.begin(), len, randchar); return str; } Rcpp::List rel_membs_as_list (XmlDataSC &xml) { std::unordered_map > rel_membs = xml.get_rel_membs (); Rcpp::List ret (rel_membs.size ()); std::vector retnames (rel_membs.size ()); size_t i1 = 0; // std::vector index is size_t int i2 = 0; // Rcpp index is int for (auto m: rel_membs) { retnames [i1++] = m.first; ret [i2++] = m.second; } ret.attr ("names") = retnames; return ret; } Rcpp::List way_membs_as_list (XmlDataSC &xml) { std::unordered_map > way_membs = xml.get_way_membs (); Rcpp::List ret (way_membs.size ()); std::vector retnames (way_membs.size ()); size_t i1 = 0; int i2 = 0; for (auto m: way_membs) { retnames [i1] = m.first; ret [i2++] = m.second; } ret.attr ("names") = retnames; return ret; } //' rcpp_osmdata_sc //' //' Return OSM data in silicate (SC) format //' //' @param st Text contents of an overpass API query //' @return Rcpp::List objects of OSM data //' //' @noRd // [[Rcpp::export]] Rcpp::List rcpp_osmdata_sc (const std::string& st) { #ifdef DUMP_INPUT { std::ofstream dump ("./osmdata-sf.xml"); if (dump.is_open()) { dump.write (st.c_str(), st.size()); } } #endif XmlDataSC xml (st); Rcpp::DataFrame vertex = Rcpp::DataFrame::create ( Rcpp::Named ("x_") = xml.get_vx (), Rcpp::Named ("y_") = xml.get_vy (), Rcpp::Named ("vertex_") = xml.get_vert_id (), Rcpp::_["stringsAsFactors"] = false ); Rcpp::DataFrame edge = Rcpp::DataFrame::create ( Rcpp::Named (".vx0") = xml.get_vx0 (), Rcpp::Named (".vx1") = xml.get_vx1 (), Rcpp::Named ("edge_") = xml.get_edge (), Rcpp::_["stringsAsFactors"] = false ); Rcpp::DataFrame oXe = Rcpp::DataFrame::create ( Rcpp::Named ("edge_") = xml.get_edge (), Rcpp::Named ("object_") = xml.get_object (), Rcpp::_["stringsAsFactors"] = false ); Rcpp::DataFrame obj_node = Rcpp::DataFrame::create ( Rcpp::Named ("vertex_") = xml.get_node_id (), Rcpp::Named ("key") = xml.get_node_key (), Rcpp::Named ("value") = xml.get_node_val (), Rcpp::_["stringsAsFactors"] = false ); Rcpp::DataFrame obj_way = Rcpp::DataFrame::create ( Rcpp::Named ("object_") = xml.get_way_id (), Rcpp::Named ("key") = xml.get_way_key (), Rcpp::Named ("value") = xml.get_way_val (), Rcpp::_["stringsAsFactors"] = false ); Rcpp::DataFrame obj_rel_memb = Rcpp::DataFrame::create ( Rcpp::Named ("relation_") = xml.get_rel_memb_id (), Rcpp::Named ("member") = xml.get_rel_ref (), Rcpp::Named ("type") = xml.get_rel_memb_type (), Rcpp::Named ("role") = xml.get_rel_role (), Rcpp::_["stringsAsFactors"] = false ); Rcpp::DataFrame obj_rel_kv = Rcpp::DataFrame::create ( Rcpp::Named ("relation_") = xml.get_rel_kv_id (), Rcpp::Named ("key") = xml.get_rel_key (), Rcpp::Named ("value") = xml.get_rel_val (), Rcpp::_["stringsAsFactors"] = false ); Rcpp::List rel_membs = rel_membs_as_list (xml), way_membs = way_membs_as_list (xml); Rcpp::List ret (9); ret [0] = vertex; ret [1] = edge; ret [2] = oXe; ret [3] = obj_node; ret [4] = obj_way; // The SC object table ret [5] = obj_rel_memb; ret [6] = obj_rel_kv; ret [7] = Rcpp::as (way_membs); ret [8] = Rcpp::as (rel_membs); std::vector retnames {"vertex", "edge", "object_link_edge", "nodes", "object", "relation_members", "relation_properties", "way_membs", "rel_membs"}; ret.attr ("names") = retnames; return ret; }