/*************************************************************************** * Project: osmdata * File: common.h * 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 / Andrew Smith * E-Mail: mark.padgham@email.com / andrew@casacazaz.net * * Description: Common header file for get-points/lines/polygons * * Limitations: * * Dependencies: none (rapidXML header included in osmdata) * * Compiler Options: -std=c++11 ***************************************************************************/ #pragma once // These lines suppress two classes of warnings from rapidxml, but note that // this is forbidden on CRAN: // https://cran.r-project.org/web/packages/policies.html // #pragma GCC diagnostic push // #pragma GCC diagnostic ignored "-Wdeprecated-dynamic-exception-spec" // #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" #include "rapidxml.h" // #pragma GCC diagnostic pop #include // Only for 'NA_REAL' // APS not good pratice to have all the headers included here, adds to compile time // better to #include as and where needed, ideally in source rather than headers, // and use fwd declarations wherever possible #include #include #include #include #include #include #include #include #include // APS uncomment to save xml input string to a file //#define DUMP_INPUT #ifdef DUMP_INPUT #include #endif // make clear the id type typedef long long osmid_t; typedef std::vector > float_arr2; typedef std::vector > > float_arr3; typedef std::vector > double_arr2; typedef std::vector > > double_arr3; typedef std::vector > string_arr2; typedef std::vector > > string_arr3; typedef std::vector > osmt_arr2; typedef std::vector > osm_str_vec; typedef std::vector >::iterator it_osm_str_vec; constexpr float FLOAT_MAX = std::numeric_limits::max (); constexpr double DOUBLE_MAX = std::numeric_limits::max (); // Convenience typedefs for some rapidxml types typedef std::unique_ptr > XmlDocPtr; typedef const rapidxml::xml_node<>* XmlNodePtr; typedef const rapidxml::xml_attribute<>* XmlAttrPtr; // ----- functions in common.cpp XmlDocPtr parseXML (const std::string& xmlString); // ----- end functions in common.cpp struct UniqueVals { // OSM IDs are sometimes duplicated, even though they ought not be. Unique // IDs are stored in the following sets, ensuring that only the first // instance of any given ID will be extracted. Using set.find in constructed // takes 45ms for trial code; time without these finds = 60ms - HUH? // NOTE: Previous code converted IDs to std::string and added // decimal places to generate unique IDs. This could be re-instated? std::set id_node, id_way, id_rel; // Unique keys are also stored to provide column names. Although std::set // is slower than an unordered_set, it is useful to have keys alphabetically // ordered. std::set k_point, k_way, k_rel; // A numeric index is also constructed to enable direct indexing into // key-val matrices. This is an unsigned int for indexing into Rcpp objects. std::map k_point_index, k_way_index, k_rel_index; }; struct RawNode { osmid_t id; std::string _version = "", _timestamp = "", _changeset = "", _uid = "", _user = ""; // metadata std::vector key, value; double lat = NA_REAL, lon = NA_REAL; }; struct Node { osmid_t id; std::string _version = "", _timestamp = "", _changeset = "", _uid = "", _user = ""; // metadata std::map key_val; double lat = NA_REAL, lon = NA_REAL; }; /* Traversing the XML tree means keys and values are read sequentially and * cannot be processed simultaneously. Each way is thus initially read as a * RawWay with separate vectors for keys and values. These are subsequently * converted in Way to a vector of . */ struct RawWay { osmid_t id; std::string _version, _timestamp, _changeset, _uid, _user; // metadata double _lat = NA_REAL, _lon = NA_REAL; // center std::vector key, value; std::vector nodes; }; struct OneWay { osmid_t id; std::string _version, _timestamp, _changeset, _uid, _user; // metadata double _lat = NA_REAL, _lon = NA_REAL; // center std::map key_val; std::vector nodes; }; struct RawRelation { bool ispoly; osmid_t id; std::string member_type; std::string _version, _timestamp, _changeset, _uid, _user; // metadata double _lat = NA_REAL, _lon = NA_REAL; // center // APS would (key,value) be better in a std::map? std::vector key, value, role_node, role_way, role_relation; std::vector nodes; std::vector ways; std::vector relations; // relations can contain relations }; struct Relation { bool ispoly; osmid_t id; std::string rel_type; std::string _version, _timestamp, _changeset, _uid, _user; // metadata double _lat = NA_REAL, _lon = NA_REAL; // center std::map key_val; // Relations may have nodes as members, but these are not used here. std::vector > nodes; // str = role std::vector > ways; // str = role std::vector > relations; // str = role }; typedef std::vector Relations; typedef std::map Ways; // MP: osmid_t (long long) is Node.id, and thus repetitive, but traverseNode has // to store the ID in the Node struct first, before this can be used to make the // map of Nodes. TODO: Is there a better way? typedef std::map Nodes;