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