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