Eclipse SUMO - Simulation of Urban MObility
PCLoaderOSM.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2008-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
19 // A reader of pois and polygons stored in OSM-format
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27 
28 #include <string>
29 #include <map>
30 #include <fstream>
33 #include <utils/common/ToString.h>
35 #include <utils/common/StdDefs.h>
36 #include <utils/common/SysUtils.h>
37 #include <utils/common/RGBColor.h>
38 #include <utils/geom/GeomHelper.h>
39 #include <utils/geom/Position.h>
41 #include <utils/xml/XMLSubSys.h>
45 #include <utils/options/Option.h>
47 #include "PCLoaderOSM.h"
48 
49 // static members
50 // ---------------------------------------------------------------------------
52 
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
56 // ---------------------------------------------------------------------------
57 // static interface
58 // ---------------------------------------------------------------------------
59 std::set<std::string> PCLoaderOSM::initMyKeysToInclude() {
60  std::set<std::string> result;
61  result.insert("highway");
62  result.insert("railway");
63  result.insert("railway:position");
64  result.insert("railway:position:exact");
65  result.insert("waterway");
66  result.insert("aeroway");
67  result.insert("aerialway");
68  result.insert("power");
69  result.insert("man_made");
70  result.insert("building");
71  result.insert("leisure");
72  result.insert("amenity");
73  result.insert("shop");
74  result.insert("tourism");
75  result.insert("historic");
76  result.insert("landuse");
77  result.insert("natural");
78  result.insert("military");
79  result.insert("boundary");
80  result.insert("admin_level");
81  result.insert("sport");
82  result.insert("polygon");
83  result.insert("place");
84  result.insert("population");
85  result.insert("openGeoDB:population");
86  result.insert("openGeoDB:name");
87  return result;
88 }
89 
90 void
92  PCTypeMap& tm) {
93  if (!oc.isSet("osm-files")) {
94  return;
95  }
96  // parse file(s)
97  std::vector<std::string> files = oc.getStringVector("osm-files");
98  // load nodes, first
99  std::map<long long int, PCOSMNode*> nodes;
100  bool withAttributes = oc.getBool("all-attributes");
102  NodesHandler nodesHandler(nodes, withAttributes, *m);
103  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
104  // nodes
105  if (!FileHelpers::isReadable(*file)) {
106  WRITE_ERROR("Could not open osm-file '" + *file + "'.");
107  return;
108  }
109  const long before = SysUtils::getCurrentMillis();
110  PROGRESS_BEGIN_MESSAGE("Parsing nodes from osm-file '" + *file + "'");
111  if (!XMLSubSys::runParser(nodesHandler, *file)) {
112  for (std::map<long long int, PCOSMNode*>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
113  delete (*i).second;
114  }
115  throw ProcessError();
116  }
117  PROGRESS_TIME_MESSAGE(before);
118  }
119  // load relations to see which additional ways may be relevant
120  Relations relations;
121  RelationsMap additionalWays;
122  RelationsHandler relationsHandler(additionalWays, relations, withAttributes, *m);
123  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
124  // edges
125  const long before = SysUtils::getCurrentMillis();
126  PROGRESS_BEGIN_MESSAGE("Parsing relations from osm-file '" + *file + "'");
127  XMLSubSys::runParser(relationsHandler, *file);
128  PROGRESS_TIME_MESSAGE(before);
129  }
130 
131  // load ways
132  EdgeMap edges;
133  EdgesHandler edgesHandler(nodes, edges, additionalWays, withAttributes, *m);
134  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
135  // edges
136  const long before = SysUtils::getCurrentMillis();
137  PROGRESS_BEGIN_MESSAGE("Parsing edges from osm-file '" + *file + "'");
138  XMLSubSys::runParser(edgesHandler, *file);
139  PROGRESS_TIME_MESSAGE(before);
140  }
141 
142  // build all
143  const bool useName = oc.getBool("osm.use-name");
144  const double mergeRelationsThreshold = OptionsCont::getOptions().getFloat("osm.merge-relations");
145  // create polygons from relations
146  if (mergeRelationsThreshold >= 0) {
147  for (PCOSMRelation* rel : relations) {
148  if (!rel->keep || rel->myWays.empty()) {
149  continue;
150  }
151  // filter unknown and empty ways
152  int numNodes = 0;
153  for (auto it = rel->myWays.begin(); it != rel->myWays.end();) {
154  if (edges.count(*it) == 0 || edges[*it]->myCurrentNodes.empty()) {
155  it = rel->myWays.erase(it);
156  } else {
157  numNodes += (int)edges[*it]->myCurrentNodes.size();
158  it++;
159  }
160  }
161  if (numNodes == 0) {
162  WRITE_WARNING("Could not import polygon from relation '" + toString(rel->id) + "' (missing ways)");
163  continue;
164  }
165  PCOSMEdge* e = new PCOSMEdge();
166  e->id = rel->id;
167  e->name = rel->name;
168  e->myAttributes = rel->myAttributes;
169  e->myIsClosed = false;
170  e->standalone = true;
171 
172  std::set<long long int> remaining(rel->myWays.begin(), rel->myWays.end());
173  PCOSMEdge* minEdge = edges[rel->myWays.front()];
174  e->myCurrentNodes.insert(e->myCurrentNodes.end(), minEdge->myCurrentNodes.begin(), minEdge->myCurrentNodes.end());
175  Position prev(convertNodePosition(nodes[minEdge->myCurrentNodes.back()]));
176  minEdge->standalone = false;
177  remaining.erase(minEdge->id);
178  bool ok = true;
179  while (!remaining.empty()) {
180  // assemble in an order that greedily reduces jump size
181  double minDist = std::numeric_limits<double>::max();
182  bool minFront = false;
183  for (long long int wayID : remaining) {
184  PCOSMEdge* part = edges[wayID];
185  Position frontPos(convertNodePosition(nodes.find(part->myCurrentNodes.front())->second));
186  const double frontDist = prev.distanceTo2D(frontPos);
187  Position backPos(convertNodePosition(nodes.find(part->myCurrentNodes.back())->second));
188  const double backDist = prev.distanceTo2D(backPos);
189  if (frontDist < minDist) {
190  minDist = frontDist;
191  minEdge = part;
192  minFront = true;
193  }
194  if (backDist < minDist) {
195  minDist = backDist;
196  minEdge = part;
197  minFront = false;
198  }
199  }
200  if (minDist > mergeRelationsThreshold) {
201  double length = 0.;
202  for (long long int wayID : remaining) {
203  PCOSMEdge* part = edges[wayID];
205  for (long long int nodeID : part->myCurrentNodes) {
206  Position nodePos(convertNodePosition(nodes[nodeID]));
207  if (last != Position::INVALID) {
208  length += last.distanceTo2D(nodePos);
209  }
210  last = nodePos;
211  }
212  if (part->myIsClosed) {
213  length += last.distanceTo2D(convertNodePosition(nodes[part->myCurrentNodes.front()]));
214  }
215  }
216  if (length > mergeRelationsThreshold) {
217  WRITE_WARNING("Could not import polygon from relation '" + toString(rel->id) +
218  "' (name:" + e->name + " reason: found gap of " + toString(minDist) +
219  "m to way '" + toString(minEdge->id) +
220  "')\n Total length of remaining ways: " + toString(length) + "m.");
221  ok = false;
222  }
223  break;
224  }
225  if (minFront) {
226  e->myCurrentNodes.insert(e->myCurrentNodes.end(), minEdge->myCurrentNodes.begin(), minEdge->myCurrentNodes.end());
227  prev = convertNodePosition(nodes[minEdge->myCurrentNodes.back()]);
228  } else {
229  e->myCurrentNodes.insert(e->myCurrentNodes.end(), minEdge->myCurrentNodes.rbegin(), minEdge->myCurrentNodes.rend());
230  prev = convertNodePosition(nodes[minEdge->myCurrentNodes.front()]);
231  }
232  minEdge->standalone = false;
233  remaining.erase(minEdge->id);
234  }
235  if (ok) {
236  edges[e->id] = e;
237  WRITE_MESSAGE("Assembled polygon from relation '" + toString(rel->id) + "' (name:" + e->name + ")");
238  } else {
239  delete e;
240  // export ways by themselves
241  for (long long int wayID : rel->myWays) {
242  PCOSMEdge* part = edges[wayID];
243  part->standalone = true;
244  }
245  }
246  }
247  }
248 
249  // instatiate polygons
250  for (EdgeMap::iterator i = edges.begin(); i != edges.end(); ++i) {
251  PCOSMEdge* e = (*i).second;
252  if (e->myAttributes.size() == 0) {
253  // cannot be relevant as a polygon
254  continue;
255  }
256  if (!e->standalone && mergeRelationsThreshold >= 0) {
257  // part of a relation
258  continue;
259  }
260  if (e->myCurrentNodes.size() == 0) {
261  WRITE_ERROR("Polygon '" + toString(e->id) + "' has no shape.");
262  continue;
263  }
264  // compute shape
265  PositionVector vec;
266  for (std::vector<long long int>::iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) {
267  PCOSMNode* n = nodes.find(*j)->second;
268  Position pos(n->lon, n->lat);
269  if (!GeoConvHelper::getProcessing().x2cartesian(pos)) {
270  WRITE_WARNING("Unable to project coordinates for polygon '" + toString(e->id) + "'.");
271  }
272  vec.push_back_noDoublePos(pos);
273  }
274  const bool ignorePruning = OptionsCont::getOptions().isInStringVector("prune.keep-list", toString(e->id));
275  // add as many polygons as keys match defined types
276  int index = 0;
277  std::string unknownPolyType = "";
278  for (std::map<std::string, std::string>::iterator it = e->myAttributes.begin(); it != e->myAttributes.end(); ++it) {
279  const std::string& key = it->first;
280  const std::string& value = it->second;
281  const std::string fullType = key + "." + value;
282  if (tm.has(key + "." + value)) {
283  index = addPolygon(e, vec, tm.get(fullType), fullType, index, useName, toFill, ignorePruning, withAttributes);
284  } else if (tm.has(key)) {
285  index = addPolygon(e, vec, tm.get(key), fullType, index, useName, toFill, ignorePruning, withAttributes);
286  } else if (MyKeysToInclude.count(key) > 0) {
287  unknownPolyType = fullType;
288  }
289  }
290  const PCTypeMap::TypeDef& def = tm.getDefault();
291  if (index == 0 && !def.discard && unknownPolyType != "") {
292  addPolygon(e, vec, def, unknownPolyType, index, useName, toFill, ignorePruning, withAttributes);
293  }
294  }
295 
296 
297  // instantiate pois
298  for (std::map<long long int, PCOSMNode*>::iterator i = nodes.begin(); i != nodes.end(); ++i) {
299  PCOSMNode* n = (*i).second;
300  if (n->myAttributes.size() == 0) {
301  // cannot be relevant as a poi
302  continue;
303  }
304  Position pos(n->lon, n->lat);
305  if (!GeoConvHelper::getProcessing().x2cartesian(pos)) {
306  WRITE_WARNING("Unable to project coordinates for POI '" + toString(n->id) + "'.");
307  }
308  const bool ignorePruning = OptionsCont::getOptions().isInStringVector("prune.keep-list", toString(n->id));
309  // add as many POIs as keys match defined types
310  int index = 0;
311  std::string unKnownPOIType = "";
312  for (std::map<std::string, std::string>::iterator it = n->myAttributes.begin(); it != n->myAttributes.end(); ++it) {
313  const std::string& key = it->first;
314  const std::string& value = it->second;
315  const std::string fullType = key + "." + value;
316  if (tm.has(key + "." + value)) {
317  index = addPOI(n, pos, tm.get(fullType), fullType, index, useName, toFill, ignorePruning, withAttributes);
318  } else if (tm.has(key)) {
319  index = addPOI(n, pos, tm.get(key), fullType, index, useName, toFill, ignorePruning, withAttributes);
320  } else if (MyKeysToInclude.count(key) > 0) {
321  unKnownPOIType = fullType;
322  }
323  }
324  const PCTypeMap::TypeDef& def = tm.getDefault();
325  if (index == 0 && !def.discard && unKnownPOIType != "") {
326  addPOI(n, pos, def, unKnownPOIType, index, useName, toFill, ignorePruning, withAttributes);
327  }
328  }
329  // delete nodes
330  for (std::map<long long int, PCOSMNode*>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
331  delete (*i).second;
332  }
333  // delete edges
334  for (EdgeMap::iterator i = edges.begin(); i != edges.end(); ++i) {
335  delete (*i).second;
336  }
337  // delete relations
338  for (Relations::iterator i = relations.begin(); i != relations.end(); ++i) {
339  delete (*i);
340  }
341 }
342 
343 
344 Position
346  Position pos(n->lon, n->lat);
348  return pos;
349 }
350 
351 
352 int
353 PCLoaderOSM::addPolygon(const PCOSMEdge* edge, const PositionVector& vec, const PCTypeMap::TypeDef& def, const std::string& fullType, int index, bool useName, PCPolyContainer& toFill, bool ignorePruning, bool withAttributes) {
354  if (def.discard) {
355  return index;
356  } else {
357  const bool closedShape = vec.front() == vec.back();
358  const std::string idSuffix = (index == 0 ? "" : "#" + toString(index));
359  const std::string id = def.prefix + (useName && edge->name != "" ? edge->name : toString(edge->id)) + idSuffix;
360  SUMOPolygon* poly = new SUMOPolygon(
362  StringUtils::escapeXML(OptionsCont::getOptions().getBool("osm.keep-full-type") ? fullType : def.id),
363  def.color, vec, false, def.allowFill && closedShape, 1, def.layer);
364  if (withAttributes) {
365  poly->updateParameter(edge->myAttributes);
366  }
367  if (!toFill.add(poly, ignorePruning)) {
368  return index;
369  } else {
370  return index + 1;
371  }
372  }
373 }
374 
375 
376 int
377 PCLoaderOSM::addPOI(const PCOSMNode* node, const Position& pos, const PCTypeMap::TypeDef& def, const std::string& fullType,
378  int index, bool useName, PCPolyContainer& toFill, bool ignorePruning, bool withAttributes) {
379  if (def.discard) {
380  return index;
381  } else {
382  const std::string idSuffix = (index == 0 ? "" : "#" + toString(index));
383  const std::string id = def.prefix + (useName && node->name != "" ? node->name : toString(node->id)) + idSuffix;
384  PointOfInterest* poi = new PointOfInterest(
386  StringUtils::escapeXML(OptionsCont::getOptions().getBool("osm.keep-full-type") ? fullType : def.id),
387  def.color, pos, false, "", 0, 0, (double)def.layer);
388  if (withAttributes) {
389  poi->updateParameter(node->myAttributes);
390  }
391  if (!toFill.add(poi, ignorePruning)) {
392  return index;
393  } else {
394  return index + 1;
395  }
396  }
397 }
398 
399 
400 // ---------------------------------------------------------------------------
401 // definitions of PCLoaderOSM::NodesHandler-methods
402 // ---------------------------------------------------------------------------
403 PCLoaderOSM::NodesHandler::NodesHandler(std::map<long long int, PCOSMNode*>& toFill,
404  bool withAttributes, MsgHandler& errorHandler) :
405  SUMOSAXHandler("osm - file"), myWithAttributes(withAttributes), myErrorHandler(errorHandler),
406  myToFill(toFill), myLastNodeID(-1) {}
407 
408 
410 
411 
412 void
414  myParentElements.push_back(element);
415  if (element == SUMO_TAG_NODE) {
416  bool ok = true;
417  long long int id = attrs.get<long long int>(SUMO_ATTR_ID, nullptr, ok);
418  if (!ok) {
419  return;
420  }
421  myLastNodeID = -1;
422  if (myToFill.find(id) == myToFill.end()) {
423  myLastNodeID = id;
424  // assume we are loading multiple files...
425  // ... so we won't report duplicate nodes
426  PCOSMNode* toAdd = new PCOSMNode();
427  toAdd->id = id;
428  bool ok = true;
429  toAdd->lon = attrs.get<double>(SUMO_ATTR_LON, toString(id).c_str(), ok);
430  toAdd->lat = attrs.get<double>(SUMO_ATTR_LAT, toString(id).c_str(), ok);
431  if (!ok) {
432  delete toAdd;
433  return;
434  }
435  myToFill[toAdd->id] = toAdd;
436  }
437  }
438  if (element == SUMO_TAG_TAG && myParentElements.size() > 2 && myParentElements[myParentElements.size() - 2] == SUMO_TAG_NODE
439  && myLastNodeID != -1) {
440  bool ok = true;
441  std::string key = attrs.getOpt<std::string>(SUMO_ATTR_K, toString(myLastNodeID).c_str(), ok, "", false);
442  std::string value = attrs.getOpt<std::string>(SUMO_ATTR_V, toString(myLastNodeID).c_str(), ok, "", false);
443  if (key == "name") {
444  myToFill[myLastNodeID]->name = value;
445  } else if (key == "") {
446  myErrorHandler.inform("Empty key in a a tag while parsing node '" + toString(myLastNodeID) + "' occurred.");
447  ok = false;
448  }
449  if (!ok) {
450  return;
451  }
452  myToFill[myLastNodeID]->myAttributes[key] = value;
453  }
454 }
455 
456 
457 void
459  if (element == SUMO_TAG_NODE) {
460  myLastNodeID = -1;
461  }
462  myParentElements.pop_back();
463 }
464 
465 
466 // ---------------------------------------------------------------------------
467 // definitions of PCLoaderOSM::RelationsHandler-methods
468 // ---------------------------------------------------------------------------
470  Relations& relations,
471  bool withAttributes,
472  MsgHandler& errorHandler) :
473  SUMOSAXHandler("osm - file"),
474  myAdditionalWays(additionalWays),
475  myRelations(relations),
476  myWithAttributes(withAttributes),
477  myErrorHandler(errorHandler),
478  myCurrentRelation(nullptr) {
479 }
480 
481 
483 }
484 
485 
486 void
488  myParentElements.push_back(element);
489  // parse "relation" elements
490  if (element == SUMO_TAG_RELATION) {
491  myCurrentWays.clear();
492  const std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
493  if (action == "delete") {
494  myCurrentRelation = nullptr;
495  } else {
497  myCurrentRelation->keep = false;
498  bool ok = true;
499  myCurrentRelation->id = attrs.get<long long int>(SUMO_ATTR_ID, nullptr, ok);
500  myRelations.push_back(myCurrentRelation);
501  }
502  return;
503  } else if (myCurrentRelation == nullptr) {
504  return;
505  }
506  // parse member elements
507  if (element == SUMO_TAG_MEMBER) {
508  bool ok = true;
509  std::string role = attrs.hasAttribute("role") ? attrs.getStringSecure("role", "") : "";
510  long long int ref = attrs.get<long long int>(SUMO_ATTR_REF, nullptr, ok);
511  if (role == "outer" || role == "inner") {
512  std::string memberType = attrs.get<std::string>(SUMO_ATTR_TYPE, nullptr, ok);
513  if (memberType == "way") {
514  myCurrentWays.push_back(ref);
515  }
516  }
517  return;
518  }
519  // parse values
520  if (element == SUMO_TAG_TAG && myParentElements.size() > 2 && myParentElements[myParentElements.size() - 2] == SUMO_TAG_RELATION
521  && myCurrentRelation != nullptr) {
522  bool ok = true;
523  std::string key = attrs.getOpt<std::string>(SUMO_ATTR_K, toString(myCurrentRelation).c_str(), ok, "", false);
524  std::string value = attrs.getOpt<std::string>(SUMO_ATTR_V, toString(myCurrentRelation).c_str(), ok, "", false);
525  if (key == "") {
526  myErrorHandler.inform("Empty key in a a tag while parsing way '" + toString(myCurrentRelation) + "' occurred.");
527  ok = false;
528  }
529  if (!ok) {
530  return;
531  }
532  if (key == "name") {
533  myCurrentRelation->name = value;
534  } else if (MyKeysToInclude.count(key) > 0) {
535  myCurrentRelation->keep = true;
536  for (std::vector<long long int>::iterator it = myCurrentWays.begin(); it != myCurrentWays.end(); ++it) {
538  }
539  }
540  myCurrentRelation->myAttributes[key] = value;
541  }
542 }
543 
544 
545 void
547  myParentElements.pop_back();
548  if (element == SUMO_TAG_RELATION) {
550  myCurrentRelation = nullptr;
551  myCurrentWays.clear();
552  }
553 }
554 
555 
556 // ---------------------------------------------------------------------------
557 // definitions of PCLoaderOSM::EdgesHandler-methods
558 // ---------------------------------------------------------------------------
559 PCLoaderOSM::EdgesHandler::EdgesHandler(const std::map<long long int, PCOSMNode*>& osmNodes,
560  EdgeMap& toFill,
561  const RelationsMap& additionalWays,
562  bool withAttributes, MsgHandler& errorHandler) :
563  SUMOSAXHandler("osm - file"),
564  myWithAttributes(withAttributes),
565  myErrorHandler(errorHandler),
566  myOSMNodes(osmNodes),
567  myEdgeMap(toFill),
568  myAdditionalWays(additionalWays) {
569 }
570 
571 
573 }
574 
575 
576 void
578  myParentElements.push_back(element);
579  // parse "way" elements
580  if (element == SUMO_TAG_WAY) {
581  bool ok = true;
582  const long long int id = attrs.get<long long int>(SUMO_ATTR_ID, nullptr, ok);
583  const std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : "";
584  if (action == "delete" || !ok) {
585  myCurrentEdge = nullptr;
586  return;
587  }
588  myCurrentEdge = new PCOSMEdge();
589  myCurrentEdge->id = id;
590  myCurrentEdge->myIsClosed = false;
591  myCurrentEdge->standalone = false;
592  myKeep = (myAdditionalWays.find(id) != myAdditionalWays.end());
593  }
594  // parse "nd" (node) elements
595  if (element == SUMO_TAG_ND && myCurrentEdge != nullptr) {
596  bool ok = true;
597  const long long int ref = attrs.get<long long int>(SUMO_ATTR_REF, nullptr, ok);
598  if (ok) {
599  if (myOSMNodes.find(ref) == myOSMNodes.end()) {
600  WRITE_WARNING("The referenced geometry information (ref='" + toString(ref) + "') is not known");
601  return;
602  }
603  myCurrentEdge->myCurrentNodes.push_back(ref);
604  }
605  }
606  // parse values
607  if (element == SUMO_TAG_TAG && myParentElements.size() > 2 && myParentElements[myParentElements.size() - 2] == SUMO_TAG_WAY
608  && myCurrentEdge != nullptr) {
609  bool ok = true;
610  std::string key = attrs.getOpt<std::string>(SUMO_ATTR_K, toString(myCurrentEdge->id).c_str(), ok, "", false);
611  std::string value = attrs.getOpt<std::string>(SUMO_ATTR_V, toString(myCurrentEdge->id).c_str(), ok, "", false);
612  if (key == "") {
613  myErrorHandler.inform("Empty key in a a tag while parsing way '" + toString(myCurrentEdge->id) + "' occurred.");
614  ok = false;
615  }
616  if (!ok) {
617  return;
618  }
619  if (key == "name") {
620  myCurrentEdge->name = value;
621  } else if (MyKeysToInclude.count(key) > 0) {
622  myKeep = true;
623  myCurrentEdge->standalone = true;
624  }
625  myCurrentEdge->myAttributes[key] = value;
626  }
627 }
628 
629 
630 void
632  myParentElements.pop_back();
633  if (element == SUMO_TAG_WAY && myCurrentEdge != nullptr) {
634  if (myKeep) {
635  RelationsMap::const_iterator it = myAdditionalWays.find(myCurrentEdge->id);
636  if (it != myAdditionalWays.end()) {
637  myCurrentEdge->myAttributes.insert((*it).second->myAttributes.begin(), (*it).second->myAttributes.end());
638  }
640  } else {
641  delete myCurrentEdge;
642  }
643  myCurrentEdge = nullptr;
644  }
645 }
646 
647 
648 /****************************************************************************/
649 
std::string id
The new type id to use.
Definition: PCTypeMap.h:61
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:72
std::map< std::string, std::string > myAttributes
Additional attributes.
Definition: PCLoaderOSM.h:95
An internal definition of a loaded edge.
Definition: PCLoaderOSM.h:103
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:81
static void loadIfSet(OptionsCont &oc, PCPolyContainer &toFill, PCTypeMap &tm)
Loads pois/polygons assumed to be stored as OSM-XML.
Definition: PCLoaderOSM.cpp:91
void myEndElement(int element)
Called when a closing tag occurs.
EdgeMap & myEdgeMap
A map of built edges.
Definition: PCLoaderOSM.h:352
A single definition of values that shall be used for a given type.
Definition: PCTypeMap.h:59
PCOSMRelation * myCurrentRelation
The currently parsed relation.
Definition: PCLoaderOSM.h:271
bool isInStringVector(const std::string &optionName, const std::string &itemName)
Returns the named option is a list of string values containing the specified item.
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:49
An internal definition of a loaded relation.
Definition: PCLoaderOSM.h:87
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:244
bool add(SUMOPolygon *poly, bool ignorePruning=false)
Adds a polygon to the storage.
static GeoConvHelper & getProcessing()
the coordinate transformation to use for input conversion and processing
Definition: GeoConvHelper.h:87
bool x2cartesian(Position &from, bool includeInBoundary=true)
Converts the given coordinate into a cartesian and optionally update myConvBoundary.
RelationsMap & myAdditionalWays
additional ways which are reference by relations
Definition: PCLoaderOSM.h:259
static Position convertNodePosition(PCOSMNode *n)
retrieve cartesian coordinate for given node
std::vector< long long int > myCurrentWays
the ways within the current relation
Definition: PCLoaderOSM.h:274
double layer
The layer to use.
Definition: PCTypeMap.h:67
long long int myLastNodeID
The id of the last parsed node.
Definition: PCLoaderOSM.h:199
Relations & myRelations
the loaded relations
Definition: PCLoaderOSM.h:262
long long int id
The node&#39;s id.
Definition: PCLoaderOSM.h:73
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
RelationsHandler(RelationsMap &additionalWays, Relations &relations, bool withAttributes, MsgHandler &errorHandler)
Constructor.
static std::set< std::string > initMyKeysToInclude()
Definition: PCLoaderOSM.cpp:59
SAX-handler base for SUMO-files.
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false)
Runs the given handler on the given file; returns if everything&#39;s ok.
Definition: XMLSubSys.cpp:113
NodesHandler(std::map< long long int, PCOSMNode *> &toFill, bool withAttributes, MsgHandler &errorHandler)
Contructor.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
bool discard
Information whether polygons of this type shall be discarded.
Definition: PCTypeMap.h:73
A storage for loaded polygons and pois.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
MsgHandler & myErrorHandler
The handler to report errors to (will be the WarningsHandler if –ignore-errors was set) ...
Definition: PCLoaderOSM.h:346
double lon
The longitude the node is located at.
Definition: PCLoaderOSM.h:75
bool keep
whether this relation is a valid polygon
Definition: PCLoaderOSM.h:97
RGBColor color
The color to use.
Definition: PCTypeMap.h:63
static int addPOI(const PCOSMNode *node, const Position &pos, const PCTypeMap::TypeDef &def, const std::string &fullType, int index, bool useName, PCPolyContainer &toFill, bool ignorePruning, bool withAttributes)
try add the POI and return the next index on success
std::map< long long int, PCOSMEdge * > EdgeMap
Definition: PCLoaderOSM.h:120
long long int id
The edge&#39;s id.
Definition: PCLoaderOSM.h:105
A class which extracts relevant way-ids from relations in a parsed OSM-file.
Definition: PCLoaderOSM.h:214
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
#define PROGRESS_TIME_MESSAGE(before)
Definition: MsgHandler.h:243
static const std::set< std::string > MyKeysToInclude
Definition: PCLoaderOSM.h:133
double lat
The latitude the node is located at.
Definition: PCLoaderOSM.h:77
std::map< std::string, std::string > myAttributes
Additional attributes.
Definition: PCLoaderOSM.h:113
A storage for type mappings.
Definition: PCTypeMap.h:45
const TypeDef & get(const std::string &id)
Returns a type definition.
Definition: PCTypeMap.cpp:71
PCOSMEdge * myCurrentEdge
The currently built edge.
Definition: PCLoaderOSM.h:358
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
void myEndElement(int element)
Called when a closing tag occurs.
MsgHandler & myErrorHandler
The handler to report errors to (will be the WarningsHandler if –ignore-errors was set) ...
Definition: PCLoaderOSM.h:190
void updateParameter(const std::map< std::string, std::string > &mapArg)
Adds or updates all given parameters from the map.
void myEndElement(int element)
Called when a closing tag occurs.
std::string name
The relation&#39;s name (if any)
Definition: PCLoaderOSM.h:91
Encapsulated SAX-Attributes.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
A list of positions.
std::map< std::string, std::string > myAttributes
Additional attributes.
Definition: PCLoaderOSM.h:81
bool has(const std::string &id)
Returns the information whether the named type is known.
Definition: PCTypeMap.cpp:77
bool myIsClosed
Information whether this area is closed.
Definition: PCLoaderOSM.h:109
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:241
MsgHandler & myErrorHandler
The handler to report errors to (will be the WarningsHandler if –ignore-errors was set) ...
Definition: PCLoaderOSM.h:268
A class which extracts OSM-edges from a parsed OSM-file.
Definition: PCLoaderOSM.h:296
std::map< long long int, PCOSMRelation * > RelationsMap
Definition: PCLoaderOSM.h:119
long long int id
The relation&#39;s id.
Definition: PCLoaderOSM.h:89
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
bool myKeep
whether the last edge (way) should be kept because it had a key from the inclusion list ...
Definition: PCLoaderOSM.h:364
std::vector< int > myParentElements
Current path in order to know to what occuring values belong.
Definition: PCLoaderOSM.h:361
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
A class which extracts OSM-nodes from a parsed OSM-file.
Definition: PCLoaderOSM.h:146
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
std::string prefix
The prefix to use.
Definition: PCTypeMap.h:65
std::vector< long long int > myParentElements
Current path in order to know to what occuring values belong.
Definition: PCLoaderOSM.h:277
std::vector< int > myParentElements
Current path in order to know to what occuring values belong.
Definition: PCLoaderOSM.h:196
std::vector< PCOSMRelation * > Relations
Definition: PCLoaderOSM.h:118
std::vector< long long int > myCurrentNodes
The list of nodes this edge is made of.
Definition: PCLoaderOSM.h:111
static int addPolygon(const PCOSMEdge *edge, const PositionVector &vec, const PCTypeMap::TypeDef &def, const std::string &fullType, int index, bool useName, PCPolyContainer &toFill, bool ignorePruning, bool withAttributes)
try add the polygon and return the next index on success
virtual std::string getStringSecure(int id, const std::string &def) const =0
Returns the string-value of the named (by its enum-value) attribute.
alternative definition for junction
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:118
A storage for options typed value containers)
Definition: OptionsCont.h:90
std::string name
The edge&#39;s name (if any)
Definition: PCLoaderOSM.h:107
const TypeDef & getDefault()
get the default type according to the given options
Definition: PCTypeMap.h:115
bool myWithAttributes
Whether all attributes shall be stored.
Definition: PCLoaderOSM.h:265
std::vector< long long int > myWays
The list of ways this relation is made of.
Definition: PCLoaderOSM.h:93
std::string name
The nodes name (if any)
Definition: PCLoaderOSM.h:79
void push_back_noDoublePos(const Position &p)
insert in back a non double position
A point-of-interest.
bool myWithAttributes
Whether all attributes shall be stored.
Definition: PCLoaderOSM.h:187
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:39
EdgesHandler(const std::map< long long int, PCOSMNode *> &osmNodes, EdgeMap &toFill, const RelationsMap &additionalWays, bool withAttributes, MsgHandler &errorHandler)
Constructor.
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:240
const std::map< long long int, PCOSMNode * > & myOSMNodes
The previously parsed nodes.
Definition: PCLoaderOSM.h:349
std::map< long long int, PCOSMNode * > & myToFill
The nodes container to fill.
Definition: PCLoaderOSM.h:193
const RelationsMap & myAdditionalWays
additional ways which are reference by relations
Definition: PCLoaderOSM.h:355
bool allowFill
Information whether polygons of this type can be filled.
Definition: PCTypeMap.h:75
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:285
An internal representation of an OSM-node.
Definition: PCLoaderOSM.h:71