R package for downloading OpenStreetMap data
at main 179 lines 6.0 kB view raw
1/*************************************************************************** 2 * Project: osmdata 3 * File: osmdata-sc.cpp 4 * Language: C++ 5 * 6 * osmdata is free software: you can redistribute it and/or modify it under 7 * the terms of the GNU General Public License as published by the Free 8 * Software Foundation, either version 3 of the License, or (at your option) 9 * any later version. 10 * 11 * osmdata is distributed in the hope that it will be useful, but WITHOUT ANY 12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 14 * details. 15 * 16 * You should have received a copy of the GNU General Public License along with 17 * osm-router. If not, see <https://www.gnu.org/licenses/>. 18 * 19 * Author: Mark Padgham 20 * E-Mail: mark.padgham@email.com 21 * 22 * Description: Extract OSM data from an object of class XmlData and return 23 * it in Rcpp::List format. 24 * 25 * Limitations: 26 * 27 * Dependencies: none (rapidXML header included in osmdata) 28 * 29 * Compiler Options: -std=c++11 30 ***************************************************************************/ 31 32#include "osmdata.h" 33#include "osmdata-sc.h" 34 35// Function to generate IDs for the edges in each way 36std::string random_id (size_t len) { 37 auto randchar = []() -> char 38 { 39 const char charset[] = \ 40 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 41 const size_t max_index = (sizeof(charset) - 1); 42 //return charset [ rand() % max_index ]; 43 size_t i = static_cast <size_t> (floor (Rcpp::runif (1) [0] * max_index)); 44 return charset [i]; 45 }; 46 std::string str (len, 0); 47 std::generate_n (str.begin(), len, randchar); 48 return str; 49} 50 51Rcpp::List rel_membs_as_list (XmlDataSC &xml) 52{ 53 std::unordered_map <std::string, std::vector <std::string> > 54 rel_membs = xml.get_rel_membs (); 55 56 Rcpp::List ret (rel_membs.size ()); 57 std::vector <std::string> retnames (rel_membs.size ()); 58 59 size_t i1 = 0; // std::vector index is size_t 60 int i2 = 0; // Rcpp index is int 61 for (auto m: rel_membs) 62 { 63 retnames [i1++] = m.first; 64 ret [i2++] = m.second; 65 } 66 ret.attr ("names") = retnames; 67 68 return ret; 69} 70 71Rcpp::List way_membs_as_list (XmlDataSC &xml) 72{ 73 std::unordered_map <std::string, std::vector <std::string> > 74 way_membs = xml.get_way_membs (); 75 76 Rcpp::List ret (way_membs.size ()); 77 std::vector <std::string> retnames (way_membs.size ()); 78 79 size_t i1 = 0; 80 int i2 = 0; 81 for (auto m: way_membs) 82 { 83 retnames [i1] = m.first; 84 ret [i2++] = m.second; 85 } 86 ret.attr ("names") = retnames; 87 88 return ret; 89} 90 91//' rcpp_osmdata_sc 92//' 93//' Return OSM data in silicate (SC) format 94//' 95//' @param st Text contents of an overpass API query 96//' @return Rcpp::List objects of OSM data 97//' 98//' @noRd 99// [[Rcpp::export]] 100Rcpp::List rcpp_osmdata_sc (const std::string& st) 101{ 102#ifdef DUMP_INPUT 103 { 104 std::ofstream dump ("./osmdata-sf.xml"); 105 if (dump.is_open()) 106 { 107 dump.write (st.c_str(), st.size()); 108 } 109 } 110#endif 111 112 XmlDataSC xml (st); 113 114 Rcpp::DataFrame vertex = Rcpp::DataFrame::create ( 115 Rcpp::Named ("x_") = xml.get_vx (), 116 Rcpp::Named ("y_") = xml.get_vy (), 117 Rcpp::Named ("vertex_") = xml.get_vert_id (), 118 Rcpp::_["stringsAsFactors"] = false ); 119 120 Rcpp::DataFrame edge = Rcpp::DataFrame::create ( 121 Rcpp::Named (".vx0") = xml.get_vx0 (), 122 Rcpp::Named (".vx1") = xml.get_vx1 (), 123 Rcpp::Named ("edge_") = xml.get_edge (), 124 Rcpp::_["stringsAsFactors"] = false ); 125 126 Rcpp::DataFrame oXe = Rcpp::DataFrame::create ( 127 Rcpp::Named ("edge_") = xml.get_edge (), 128 Rcpp::Named ("object_") = xml.get_object (), 129 Rcpp::_["stringsAsFactors"] = false ); 130 131 Rcpp::DataFrame obj_node = Rcpp::DataFrame::create ( 132 Rcpp::Named ("vertex_") = xml.get_node_id (), 133 Rcpp::Named ("key") = xml.get_node_key (), 134 Rcpp::Named ("value") = xml.get_node_val (), 135 Rcpp::_["stringsAsFactors"] = false ); 136 137 Rcpp::DataFrame obj_way = Rcpp::DataFrame::create ( 138 Rcpp::Named ("object_") = xml.get_way_id (), 139 Rcpp::Named ("key") = xml.get_way_key (), 140 Rcpp::Named ("value") = xml.get_way_val (), 141 Rcpp::_["stringsAsFactors"] = false ); 142 143 Rcpp::DataFrame obj_rel_memb = Rcpp::DataFrame::create ( 144 Rcpp::Named ("relation_") = xml.get_rel_memb_id (), 145 Rcpp::Named ("member") = xml.get_rel_ref (), 146 Rcpp::Named ("type") = xml.get_rel_memb_type (), 147 Rcpp::Named ("role") = xml.get_rel_role (), 148 Rcpp::_["stringsAsFactors"] = false ); 149 150 Rcpp::DataFrame obj_rel_kv = Rcpp::DataFrame::create ( 151 Rcpp::Named ("relation_") = xml.get_rel_kv_id (), 152 Rcpp::Named ("key") = xml.get_rel_key (), 153 Rcpp::Named ("value") = xml.get_rel_val (), 154 Rcpp::_["stringsAsFactors"] = false ); 155 156 Rcpp::List rel_membs = rel_membs_as_list (xml), 157 way_membs = way_membs_as_list (xml); 158 159 Rcpp::List ret (9); 160 ret [0] = vertex; 161 ret [1] = edge; 162 ret [2] = oXe; 163 ret [3] = obj_node; 164 ret [4] = obj_way; // The SC object table 165 ret [5] = obj_rel_memb; 166 ret [6] = obj_rel_kv; 167 ret [7] = Rcpp::as <Rcpp::List> (way_membs); 168 ret [8] = Rcpp::as <Rcpp::List> (rel_membs); 169 170 std::vector <std::string> retnames {"vertex", 171 "edge", "object_link_edge", 172 "nodes", "object", 173 "relation_members", 174 "relation_properties", 175 "way_membs", "rel_membs"}; 176 ret.attr ("names") = retnames; 177 178 return ret; 179}