23 #include <boost/filesystem/path.hpp>    24 #include <boost/unordered_map.hpp>    25 #include <boost/filesystem/operations.hpp>    26 #include <boost/type_traits/is_same.hpp>    27 #include <unordered_set>    29 #include "../../extras/eaglexml/eaglexml.hpp"    30 #include "../../extras/eaglexml/eaglexml_iterators.hpp"    43 using boost::filesystem::path;
    44 using nl = std::numeric_limits<double>;
    53     : 
public eaglexml::stream_cache<>::stream_cache_observer
    58                                     | eaglexml::parse_normalize_whitespace
    59                                     | eaglexml::parse_trim_whitespace
    60                                     | eaglexml::parse_validate_closing_tags
    61                                     | eaglexml::parse_default;
    93     void parse(
const path& xml_file)
    99         std::ifstream xml_stream(xml_file.string());
   104         LOG_SEV(importer_log, info) << 
"Load xml-file \"" << xml_file.string() << 
"\"";
   106         fileSize = boost::filesystem::file_size(xml_file);
   108         LOG_SEV(importer_log, info) << 
"File size is " << 
fileSize / (1024) << 
"kb";
   110         nodes = boost::make_shared<std::vector<Node> >();
   111         ways = boost::make_shared<std::vector<Way> >();
   112         relations = boost::make_shared<std::vector<Relation> >();
   115         eaglexml::stream_cache<> cache(xml_stream, 8 * 1024 * 1024);
   116         eaglexml::xml_document<> document;
   119         cache.max_segments_to_read(1);
   120         cache.observer(
this);
   125             document.parse<parser_flags>(&cache);
   127             eaglexml::xml_node<>* osm = document.first_node(
"osm");
   137         }
catch(eaglexml::parse_error& e)
   196         std::map<std::string, void (OsmXmlParser::*)(eaglexml::xml_node<>*)> entities;
   204         for(eaglexml::node_iterator<> it(osmRoot);
   205             it != eaglexml::node_iterator<>();
   208             auto entityIt = entities.find(it->name());
   210             if(!ignoreUnknownEntities && entityIt == entities.end())
   214                 (this->*(entityIt->second))(&*it);
   216                 const auto id = *boost::get_error_info<excp::InfoUnresolvableId>(e);
   218                     LOG_SEV(importer_log, warning) << 
"Bad osm id[" << 
id << 
"]. Entity is skipped!";
   233             LOG_SEV(importer_log, info) << 
"Bounds tag in osm data is ignored by this software!";
   256             parseProperties<Node>(node->first_node(), &tags, 
nullptr, 
nullptr, 
nullptr, 
nullptr);
   279         std::vector<NodeId> nodeIds;
   281         parseProperties<Way>(way->first_node(), &tags, &nodeIds, 
nullptr, 
nullptr, 
nullptr);
   283         if (nodeIds.size() == 0)
   287         ways->push_back(
Way(nodeIds, tags));
   303         std::vector<NodeId> nodeIds;
   304         std::vector<WayId> wayIds;
   309         parseProperties<Relation>(relation->first_node(), &tags, &nodeIds, &nodeRoles, &wayIds, &wayRoles);
   311         if (nodeIds.size() == 0 && wayIds.size() == 0)
   333     template<
typename Target>
   336                                 std::vector<NodeId>* nodeRefIds,
   338                                 std::vector<WayId>* wayRefIds,
   341         BOOST_STATIC_ASSERT((boost::is_same<Target, Node>::value || boost::is_same<Target, Way>::value || boost::is_same<Target, Relation>::value));
   345         eaglexml::xml_node<>* prop = firstProp;
   346         for(;prop; prop = prop->next_sibling())
   348             const char* propName = firstProp->name();
   350             if(std::strcmp(propName, 
"tag") == 0)
   358                 (*tagMap)[key] = value;
   360             }
else if(boost::is_same<Target, Way>::value && std::strcmp(propName, 
"nd") == 0)
   368             }
else if(boost::is_same<Target, Relation>::value && std::strcmp(propName, 
"member") == 0)
   377                 eaglexml::xml_attribute<>* 
attr = prop->first_attribute(
"type");
   379                 if(!attr || attr->value_size() == 0)
   387                 const char* type = attr->value();
   388                 if(std::strcmp(type, 
"node") == 0)
   391                     nodeRefIds->push_back(nodeId);
   393                 }
else if(std::strcmp(type, 
"way") == 0)
   396                     wayRefIds->push_back(wayId);
   398                 }
else if(std::strcmp(type, 
"relation") == 0) {
   402                         LOG_SEV(importer_log, warning) << 
"This software does not support relation member in relations!";
   403                         LOG_SEV(importer_log, warning) << 
"Reference is ignored!";
   431         eaglexml::xml_attribute<>* 
attr = node->first_attribute(attrname.c_str(), attrname.size());
   436         const char* value = attr->value();
   438             *dest = boost::lexical_cast<T>(value);
   439         }
catch(boost::bad_lexical_cast& e)
   456     template<
typename IdType>
   457     IdType 
resolveOsmId(OsmIdType osmId, 
const boost::unordered_map<OsmIdType, IdType>& table)
   459         auto it = table.find(osmId);
   461         if(it == table.end())
   468     virtual void on_fetch( 
unsigned int chars_left, 
unsigned int need, node_type* active_node ) {}
   476         int after  = int(100 * (
double)
alreadyRead / (
double)fileSize);
   479             LOG_SEV(importer_log, info) << 
"Loading [" << std::min(after, 99) << 
"%]";
   504     shared_ptr< std::vector<Node> > 
nodes;
   507     shared_ptr< std::vector<Way> > 
ways;
   554     LOG_SEV(importer_log, info) << 
"Clipping nodes with [lon: " << bounds.
minX << 
" to " << bounds.
maxX << 
", lat: " << bounds.
minY << 
" to " << bounds.
maxY << 
"]";
   556     shared_ptr<Geodata> geodata = boost::make_shared<Geodata>();
   559     LOG_SEV(importer_log, info) << 
"Start parsing...";
   560     parser.
parse(xml_file);
   562     LOG_SEV(importer_log, info) << 
"Insert into geodata...";
 shared_ptr< std::vector< Relation > > getParsedRelations() const 
Returns a vector with parsed relations. 
 
std::numeric_limits< double > nl
 
void parseNode(eaglexml::xml_node<> *node)
parses a node entity 
 
IdType resolveOsmId(OsmIdType osmId, const boost::unordered_map< OsmIdType, IdType > &table)
Resolves a osm id into an internal id. 
 
bool ignoreUnknownEntities
Specifies weather the parser should ignore unknown entities. 
 
shared_ptr< std::vector< Node > > nodes
List to be filled with nodes. 
 
void parseEntities(eaglexml::xml_node<> *osmRoot)
parses the osm-root element and creates given objects 
 
static const char * check_xml_entities
Check all xml entities. 
 
boost::unordered_map< OsmIdType, WayId > wayIdMapping
Mapping from osm ids to internal ids for ways. 
 
std::uintmax_t alreadyRead
Bytes already read from the xml file. 
 
shared_ptr< std::vector< Way > > ways
List to be filled with ways. 
 
boost::error_info< struct TagXmlEntityName, string > InfoXmlEntityName
Use this this to specify the exception related xml entity. 
 
TESTABLE shared_ptr< Geodata > importXML()
Parses an osm xml file specified in configuration containing osm data. 
 
static const char * max_lat
maximum node latitude to include into imported data 
 
Thrown if an osm id was not specified before resolving. 
 
shared_ptr< std::vector< Node > > getParsedNodes() const 
Returns a vector with parsed nodes. 
 
void parseProperties(eaglexml::xml_node<> *firstProp, DataMap< CachedString, CachedString > *tagMap, std::vector< NodeId > *nodeRefIds, DataMap< NodeId, CachedString > *nodeRoleMap, std::vector< WayId > *wayRefIds, DataMap< WayId, CachedString > *wayRoleMap)
parses properties of an osm-object 
 
boost::error_info< struct TagBadSourceValue, string > InfoBadSourceValue
String representation of a bad source value. 
 
bool contains(const basic_vector2< T > &p) const 
 
static const char * min_lat
minimum node latitude to include into imported data 
 
virtual void on_read_begin(unsigned int segments)
 
Importer(const shared_ptr< Configuration > &config)
Initializes the importer. 
 
OsmXmlParser(bool ignoreUnknownEntities, const FloatRect &bounds={-nl::max(),-nl::max(), nl::max(), nl::max()})
Creates a new parser and sets default settings. 
 
static const char * path_to_osmdata
Option to get the path to osm xml file (type: string) 
 
std::uintmax_t fileSize
Size of the xml file in bytes. 
 
virtual void on_segment_read()
 
const FloatRect clippingBounds
Specifies the rectangular area in which the nodes are kept. 
 
boost::unordered_map< OsmIdType, NodeId > nodeIdMapping
Mapping from osm ids to internal ids for nodes. 
 
#define LOG_SEV(log, lvl)
 
boost::error_info< struct TagWhatInfo, string > InfoWhat
Use this info to give an what msg to the exception. 
 
unsigned int segmentSize
Number of bytes read by one read operation. 
 
uint64_t OsmIdType
Type, where osm ids stored in. 
 
bool outputIgnoreRelation
Booleans for some output, which should only appear once. 
 
boost::error_info< struct TagUnresolvableId, long > InfoUnresolvableId
Specifies the id, which was not resolvable. 
 
Thrown if a file was not found. 
 
static const char * min_lon
minimum node longitude to include into imported data 
 
shared_ptr< Configuration > config
 
void parseWay(eaglexml::xml_node<> *way)
parses the way entity 
 
void parse(const path &xml_file)
Will parse a given xml file. 
 
basic_vector2< double > FloatPoint
 
void extractAttributeFromNode(const string &attrname, eaglexml::xml_node<> *node, T *dest)
Extracts the value of a specified xml-attribute from a given node. 
 
static const char * max_lon
maximum node longitude to include into imported data 
 
void parseBounds(eaglexml::xml_node<> *node)
parses the bound entity 
 
std::unordered_set< OsmIdType > clippedNodes
Id of clipped nodes. 
 
static const int parser_flags
flags for parsing the xml file 
 
shared_ptr< std::vector< Way > > getParsedWays() const 
Returns a vector with parsed ways. 
 
Represents a string which is cached into an internal cache. 
 
shared_ptr< std::vector< Relation > > relations
List to be filled with relations. 
 
std::size_t getNumberOfClippedNodes() const 
Returns the number of clipped nodes. 
 
void parseRelation(eaglexml::xml_node<> *relation)
parses the relation entity 
 
virtual void on_fetch(unsigned int chars_left, unsigned int need, node_type *active_node)
 
boost::error_info< struct TagFileName, string > InfoFileName
Use this to inform about a file name. 
 
virtual void on_buffer_resize()