Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
NIImporter_VISUM.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2026 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/****************************************************************************/
21// A VISUM network importer
22/****************************************************************************/
23#include <config.h>
24
25#include <string>
32#include <netbuild/NBDistrict.h>
34#include <netbuild/NBPTStop.h>
35#include "NILoader.h"
36#include "NIImporter_VISUM.h"
37
38// use a string that distinguishes edge types from tsys-codes
39// (rename codes loaded as types prior to loading edge types)
40#define TSYSPREFIX "@"
41
43 { "VSYS", VISUM_SYS },
44 { "STRECKENTYP", VISUM_LINKTYPE },
45 { "KNOTEN", VISUM_NODE },
46 { "BEZIRK", VISUM_DISTRICT },
47 { "PUNKT", VISUM_POINT },
48 { "STRECKE", VISUM_LINK },
49 { "V0IV", VISUM_V0 },
50 { "VSYSSET", VISUM_TYPES },
51 { "RANG", VISUM_RANK },
52 { "KAPIV", VISUM_CAPACITY },
53 { "XKOORD", VISUM_XCOORD },
54 { "YKOORD", VISUM_YCOORD },
55 { "ID", VISUM_ID },
56 { "CODE", VISUM_CODE },
57 { "VONKNOTNR", VISUM_FROMNODE },
58 { "NACHKNOTNR", VISUM_TONODE },
59 { "TYPNR", VISUM_TYPE },
60 { "TYP", VISUM_TYP },
61 { "ANBINDUNG", VISUM_DISTRICT_CONNECTION },
62 { "BEZNR", VISUM_SOURCE_DISTRICT },
63 { "KNOTNR", VISUM_FROMNODENO },
64 { "RICHTUNG", VISUM_DIRECTION },
65 { "FLAECHEID", VISUM_SURFACEID },
66 { "TFLAECHEID", VISUM_FACEID },
67 { "VONPUNKTID", VISUM_FROMPOINTID },
68 { "NACHPUNKTID", VISUM_TOPOINTID },
69 { "KANTE", VISUM_EDGE },
70 { "ABBIEGER", VISUM_TURN },
71 { "UEBERKNOTNR", VISUM_VIANODENO },
72 { "ANZFAHRSTREIFEN", VISUM_NUMLANES },
73 { "INDEX", VISUM_INDEX },
74 { "STRECKENPOLY", VISUM_LINKPOLY },
75 { "FLAECHENELEMENT", VISUM_SURFACEITEM },
76 { "TEILFLAECHENELEMENT", VISUM_FACEITEM },
77 { "KANTEID", VISUM_EDGEID },
78 { "Q", VISUM_ORIGIN },
79 { "Z", VISUM_DESTINATION },
80 { "HALTEPUNKT", VISUM_STOPPOINT },
81 { "NAME", VISUM_NAME },
82 { "STRNR", VISUM_LINKNO },
83 { "RELPOS", VISUM_RELPOS },
84 { "KATNR", VISUM_CATID },
85 { "ZWISCHENPUNKT", VISUM_EDGEITEM },
86 { "POIKATEGORIE", VISUM_POICATEGORY },
87 { "NETZ", VISUM_NETWORK },
88 { "DEFKOORD", VISUM_PROJECTIONDEFINITION },
89 { "IV", VISUM_PRT },
90 { "NR", VISUM_NO } // must be the last one
91};
92
93
94
96
97// ===========================================================================
98// method definitions
99// ===========================================================================
100// ---------------------------------------------------------------------------
101// static methods (interface in this case)
102// ---------------------------------------------------------------------------
103void
105 // check whether the option is set (properly)
106 if (!oc.isSet("visum-file")) {
107 return;
108 }
109 // build the handler
110 NIImporter_VISUM loader(nb, oc.getString("visum-file"),
111 NBCapacity2Lanes(oc.getFloat("lanes-from-capacity.norm")),
112 oc.getBool("visum.use-type-priority"),
113 oc.getString("visum.language-file"));
114 // rename loaded types (tsys code interpretations) so they never clash with edge types
115 std::vector<std::string> codes;
116 for (auto it = nb.getTypeCont().begin(); it != nb.getTypeCont().end(); it++) {
117 codes.push_back(it->first);
118 }
119 for (const std::string& code : codes) {
120 nb.getTypeCont().updateEdgeTypeID(code, TSYSPREFIX + code);
121 }
122 loader.load();
123}
124
125
126
127// ---------------------------------------------------------------------------
128// loader methods
129// ---------------------------------------------------------------------------
131 const std::string& file,
132 NBCapacity2Lanes capacity2Lanes,
133 bool useVisumPrio,
134 const std::string& languageFile) :
135 myNetBuilder(nb), myFileName(file),
136 myCapacity2Lanes(capacity2Lanes), myUseVisumPrio(useVisumPrio) {
137 if (languageFile != "") {
138 loadLanguage(languageFile);
139 }
141
142 // the order of process is important!
143 // set1
150
151 // set2
152 // two types of "strecke"
155
156 // set3
157 if (OptionsCont::getOptions().getBool("visum.no-connectors")) {
159 } else {
161 }
162 // two types of "abbieger"
163 addParser("ABBIEGEBEZIEHUNG", &NIImporter_VISUM::parse_Turns);
165
169
170
171 // set4
172 // two types of lsa
175 // two types of knotenzulsa
179 // two types of signalgruppe
182 // three types of ABBZULSASIGNALGRUPPE
184 addParser("SIGNALGRUPPEZUABBIEGER", &NIImporter_VISUM::parse_TurnsToSignalGroups);
185 addParser("SIGNALGRUPPEZUFSABBIEGER", &NIImporter_VISUM::parse_TurnsToSignalGroups);
186
188
189 // two types of LSAPHASE
192
193 addParser("LSASIGNALGRUPPEZULSAPHASE", &NIImporter_VISUM::parse_SignalGroupsToPhases);
194 addParser("FAHRSTREIFENABBIEGER", &NIImporter_VISUM::parse_LanesConnections);
195
197}
198
199
201 for (NIVisumTL_Map::iterator j = myTLS.begin(); j != myTLS.end(); j++) {
202 delete j->second;
203 }
204}
205
206
207void
208NIImporter_VISUM::addParser(const std::string& name, ParsingFunction function) {
209 TypeParser p;
210 p.name = name;
211 p.function = function;
212 p.position = -1;
213 mySingleDataParsers.push_back(p);
214}
215
216
217void
219 // open the file
220 if (!myLineReader.setFile(myFileName)) {
221 throw ProcessError(TLF("Can not open visum-file '%'.", myFileName));
222 }
223 // scan the file for data positions
224 while (myLineReader.hasMore()) {
225 std::string line = myLineReader.readLine();
226 if (line.length() > 0 && line[0] == '$') {
227 ParserVector::iterator i;
228 for (i = mySingleDataParsers.begin(); i != mySingleDataParsers.end(); i++) {
229 std::string dataName = "$" + (*i).name + ":";
230 if (line.substr(0, dataName.length()) == dataName) {
231 (*i).position = myLineReader.getPosition();
232 (*i).pattern = line.substr(dataName.length());
233 WRITE_MESSAGE("Found: " + dataName + " at line " + toString<int>(myLineReader.getLineNumber()));
234 }
235 }
236 }
237 }
238 // go through the parsers and process all entries
239 for (ParserVector::iterator i = mySingleDataParsers.begin(); i != mySingleDataParsers.end(); i++) {
240 if ((*i).position < 0) {
241 // do not process using parsers for which no information was found
242 continue;
243 }
244 // ok, the according information is stored in the file
245 PROGRESS_BEGIN_MESSAGE("Parsing " + (*i).name);
246 // reset the line reader and let it point to the begin of the according data field
247 myLineReader.reinit();
248 myLineReader.setPos((*i).position);
249 // prepare the line parser
250 myLineParser.reinit((*i).pattern);
251 // read
252 bool singleDataEndFound = false;
253 while (myLineReader.hasMore() && !singleDataEndFound) {
254 std::string line = myLineReader.readLine();
255 if (line.length() == 0 || line[0] == '*' || line[0] == '$') {
256 singleDataEndFound = true;
257 } else {
258 myLineParser.parseLine(line);
259 try {
260 myCurrentID = "<unknown>";
261 (this->*(*i).function)();
262 } catch (OutOfBoundsException&) {
263 WRITE_ERRORF(TL("Too short value line in % occurred."), (*i).name);
264 } catch (NumberFormatException&) {
265 WRITE_ERRORF(TL("A value in % should be numeric but is not (id='%')."), (*i).name, myCurrentID);
266 } catch (UnknownElement& e) {
267 WRITE_ERRORF(TL("One of the needed values ('%') is missing in %."), std::string(e.what()), (*i).name);
268 }
269 }
270 }
271 // close single reader processing
273 }
274 myNetBuilder.getEdgeCont().reduceGeometries(POSITION_EPS);
275
276 // build traffic lights
277 for (NIVisumTL_Map::iterator j = myTLS.begin(); j != myTLS.end(); j++) {
278 j->second->build(myNetBuilder.getEdgeCont(), myNetBuilder.getTLLogicCont());
279 }
280 // build district shapes
281 for (std::map<NBDistrict*, PositionVector>::const_iterator k = myDistrictShapes.begin(); k != myDistrictShapes.end(); ++k) {
282 (*k).first->addShape((*k).second);
283 }
284}
285
286
287
288
289
290void
292 std::string code = myLineParser.know("VSysCode") ? myLineParser.get("VSysCode").c_str() : myLineParser.get(KEYS.getString(VISUM_CODE));
293 std::string name = myLineParser.get(KEYS.getString(VISUM_NAME)).c_str();
294 std::string type = myLineParser.know("VSysMode") ? myLineParser.get("VSysMode").c_str() : myLineParser.get(KEYS.getString(VISUM_TYP));
295 myVSysTypes.emplace(code, VSysType(type, StringUtils::to_lower_case(name)));
296}
297
298
299void
301 const std::string key = KEYS.getString(VISUM_PROJECTIONDEFINITION);
302 if (myLineParser.know(key)) {
303 std::string proj = myLineParser.get(key);
304 // visum network contains projected geometry, we only need the projection info computing lon, lat outputs
305 GeoConvHelper* result = new GeoConvHelper(proj, Position(0, 0), Boundary(0, 0, 1, 1), Boundary(0, 0, 1, 1));
307 }
308}
309
310
311void
313 // get the id
315 // get the maximum speed
316 double speed = getWeightedFloat2("v0-IV", KEYS.getString(VISUM_V0), "km/h");
317 if (speed == 0) {
318 // unlimited speed
319 speed = 3600;
320 } else if (speed < 0) {
321 WRITE_ERROR("Type '" + myCurrentID + "' has speed " + toString(speed));
322 }
323 // get the permissions
325 // get the priority
326 const int priority = 1000 - StringUtils::toInt(myLineParser.get(KEYS.getString(VISUM_RANK)));
327 // try to retrieve the number of lanes
328 const int numLanes = myCapacity2Lanes.get(getNamedFloat("Kap-IV", KEYS.getString(VISUM_CAPACITY)));
329 // insert the type
330 myNetBuilder.getTypeCont().insertEdgeType(myCurrentID, numLanes, speed / (double) 3.6, priority, permissions, LaneSpreadFunction::RIGHT,
332 myNetBuilder.getTypeCont().markEdgeTypeAsSet(myCurrentID, SUMO_ATTR_NUMLANES);
333 myNetBuilder.getTypeCont().markEdgeTypeAsSet(myCurrentID, SUMO_ATTR_SPEED);
334 myNetBuilder.getTypeCont().markEdgeTypeAsSet(myCurrentID, SUMO_ATTR_PRIORITY);
335 myNetBuilder.getTypeCont().markEdgeTypeAsSet(myCurrentID, SUMO_ATTR_ONEWAY);
336 myNetBuilder.getTypeCont().markEdgeTypeAsSet(myCurrentID, SUMO_ATTR_ALLOW);
337 myNetBuilder.getTypeCont().markEdgeTypeAsSet(myCurrentID, SUMO_ATTR_SPREADTYPE);
338}
339
340
341void
343 // get the id
345 // get the position
346 double x = getNamedFloat(KEYS.getString(VISUM_XCOORD));
347 double y = getNamedFloat(KEYS.getString(VISUM_YCOORD));
348 Position pos(x, y);
350 WRITE_ERRORF(TL("Unable to project coordinates for node %."), myCurrentID);
351 return;
352 }
353 // add to the list
354 if (!myNetBuilder.getNodeCont().insert(myCurrentID, pos)) {
355 WRITE_ERRORF(TL("Duplicate node occurred ('%')."), myCurrentID);
356 }
357}
358
359
360void
362 // get the id
364 // get the information whether the source and the destination
365 // connections are weighted
366 //bool sourcesWeighted = getWeightedBool("Proz_Q");
367 //bool destWeighted = getWeightedBool("Proz_Z");
368 // get the node information
369 double x = getNamedFloat(KEYS.getString(VISUM_XCOORD));
370 double y = getNamedFloat(KEYS.getString(VISUM_YCOORD));
371 Position pos(x, y);
372 if (!NBNetBuilder::transformCoordinate(pos, false)) {
373 WRITE_ERRORF(TL("Unable to project coordinates for district %."), myCurrentID);
374 return;
375 }
376 // build the district
377 NBDistrict* district = new NBDistrict(myCurrentID, pos);
378 if (!myNetBuilder.getDistrictCont().insert(district)) {
379 WRITE_ERRORF(TL("Duplicate district occurred ('%')."), myCurrentID);
380 delete district;
381 return;
382 }
383 if (myLineParser.know(KEYS.getString(VISUM_SURFACEID))) {
384 long long int flaecheID;
385 try {
386 flaecheID = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_SURFACEID)));
387 } catch (EmptyData&) {
388 flaecheID = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_NO)));
389 }
390 myShapeDistrictMap[flaecheID] = district;
391 }
392}
393
394
395void
397 long long int id = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_ID)));
398 double x = StringUtils::toDouble(myLineParser.get(KEYS.getString(VISUM_XCOORD)));
399 double y = StringUtils::toDouble(myLineParser.get(KEYS.getString(VISUM_YCOORD)));
400 Position pos(x, y);
401 if (!NBNetBuilder::transformCoordinate(pos, false)) {
402 WRITE_ERRORF(TL("Unable to project coordinates for point %."), toString(id));
403 return;
404 }
405 myPoints[id] = pos;
406}
407
408
409void
411 if (myLineParser.know(KEYS.getString(VISUM_TYPES)) && myLineParser.get(KEYS.getString(VISUM_TYPES)) == "") {
412 // no vehicle allowed; don't add
413 return;
414 }
415 // get the id
417 // get the from- & to-node and validate them
418 NBNode* from = getNamedNode("VonKnot", KEYS.getString(VISUM_FROMNODE));
419 NBNode* to = getNamedNode("NachKnot", KEYS.getString(VISUM_TONODE));
420 if (!checkNodes(from, to)) {
421 return;
422 }
423 // get the type
424 std::string type = myLineParser.know(KEYS.getString(VISUM_TYP)) ? myLineParser.get(KEYS.getString(VISUM_TYP)) : myLineParser.get(KEYS.getString(VISUM_TYPE));
425 // get the speed
426 double speed = myNetBuilder.getTypeCont().getEdgeTypeSpeed(type);
427 if (!OptionsCont::getOptions().getBool("visum.use-type-speed")) {
428 try {
429 std::string speedS = myLineParser.know("v0-IV") ? myLineParser.get("v0-IV") : myLineParser.get(KEYS.getString(VISUM_V0));
430 if (speedS.find("km/h") != std::string::npos) {
431 speedS = speedS.substr(0, speedS.find("km/h"));
432 }
433 speed = StringUtils::toDouble(speedS) / 3.6;
434 } catch (OutOfBoundsException&) {}
435 }
436 if (speed <= 0) {
437 speed = myNetBuilder.getTypeCont().getEdgeTypeSpeed(type);
438 }
439
440 // get the number of lanes
441 int nolanes = myNetBuilder.getTypeCont().getEdgeTypeNumLanes(type);
442 if (!OptionsCont::getOptions().getBool("visum.recompute-lane-number")) {
443 if (!OptionsCont::getOptions().getBool("visum.use-type-laneno")) {
444 if (myLineParser.know("Fahrstreifen")) {
445 nolanes = StringUtils::toInt(myLineParser.get("Fahrstreifen"));
446 } else if (myLineParser.know(KEYS.getString(VISUM_NUMLANES))) {
447 nolanes = StringUtils::toInt(myLineParser.get(KEYS.getString(VISUM_NUMLANES)));
448 }
449 }
450 } else {
451 if (myLineParser.know(KEYS.getString(VISUM_CAPACITY))) {
453 } else if (myLineParser.know("KAP-IV")) {
454 nolanes = myCapacity2Lanes.get(StringUtils::toDouble(myLineParser.get("KAP-IV")));
455 }
456 }
457 // check whether the id is already used
458 // (should be the opposite direction)
459 bool oneway_checked = true;
460 NBEdge* previous = myNetBuilder.getEdgeCont().retrieve(myCurrentID);
461 if (previous != nullptr) {
462 myCurrentID = '-' + myCurrentID;
464 oneway_checked = false;
465 }
466 if (find(myTouchedEdges.begin(), myTouchedEdges.end(), myCurrentID) != myTouchedEdges.end()) {
467 oneway_checked = false;
468 }
469 std::string tmpid = '-' + myCurrentID;
470 if (find(myTouchedEdges.begin(), myTouchedEdges.end(), tmpid) != myTouchedEdges.end()) {
471 previous = myNetBuilder.getEdgeCont().retrieve(tmpid);
472 if (previous != nullptr) {
474 }
475 oneway_checked = false;
476 }
477 std::string name = StringUtils::latin1_to_utf8(myLineParser.get(KEYS.getString(VISUM_NAME)));
478 // add the edge
479 const SVCPermissions permissions = getPermissions(KEYS.getString(VISUM_TYPES), type, myNetBuilder.getTypeCont().getEdgeTypePermissions(type));
480 int prio = myUseVisumPrio ? myNetBuilder.getTypeCont().getEdgeTypePriority(type) : -1;
481 if (nolanes != 0 && speed != 0) {
483 NBEdge* e = new NBEdge(myCurrentID, from, to, type, speed, NBEdge::UNSPECIFIED_FRICTION, nolanes, prio,
485 e->setPermissions(permissions);
486 if (!myNetBuilder.getEdgeCont().insert(e)) {
487 delete e;
488 WRITE_ERRORF(TL("Duplicate edge occurred ('%')."), myCurrentID);
489 }
490 }
491 myTouchedEdges.push_back(myCurrentID);
492}
493
494
495void
497 long long int id = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_ID)));
498 long long int from = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_FROMPOINTID)));
499 long long int to = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_TOPOINTID)));
500 myEdges[id] = std::make_pair(from, to);
501}
502
503
504void
506 long long int flaecheID = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_SURFACEID)));
507 long long int flaechePartID = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_FACEID)));
508 if (mySubPartsAreas.find(flaechePartID) == mySubPartsAreas.end()) {
509 mySubPartsAreas[flaechePartID] = std::vector<long long int>();
510 }
511 mySubPartsAreas[flaechePartID].push_back(flaecheID);
512}
513
514
515void
517 // get the source district
519 // get the destination node
520 NBNode* dest = getNamedNode(KEYS.getString(VISUM_FROMNODENO));
521 if (dest == nullptr) {
522 return;
523 }
524 // get the weight of the connection
525 double proz = 1;
526 if (myLineParser.know("Proz") || myLineParser.know("Proz(IV)")) {
527 proz = getNamedFloat("Proz", "Proz(IV)") / 100;
528 }
529 // get the information whether this is a sink or a source
530 std::string dir = myLineParser.get(KEYS.getString(VISUM_DIRECTION));
531 if (dir.length() == 0) {
532 dir = KEYS.getString(VISUM_ORIGIN) + KEYS.getString(VISUM_DESTINATION);
533 }
534 // build the source when needed
535 if (dir.find(KEYS.getString(VISUM_ORIGIN)) != std::string::npos) {
536 for (NBEdge* edge : dest->getOutgoingEdges()) {
537 myNetBuilder.getDistrictCont().addSource(bez, edge, proz);
538 }
539 }
540 // build the sink when needed
541 if (dir.find(KEYS.getString(VISUM_DESTINATION)) != std::string::npos) {
542 for (NBEdge* edge : dest->getIncomingEdges()) {
543 myNetBuilder.getDistrictCont().addSink(bez, edge, proz);
544 }
545 }
546}
547
548
549
550void
552 // get the source district
554 // get the destination node
555 NBNode* dest = getNamedNode(KEYS.getString(VISUM_FROMNODENO));
556 if (dest == nullptr) {
557 return;
558 }
559 // get the weight of the connection
560 double proz = 1;
561 if (myLineParser.know("Proz") || myLineParser.know("Proz(IV)")) {
562 proz = getNamedFloat("Proz", "Proz(IV)") / 100;
563 }
564 // get the duration to wait (unused)
565// double retard = -1;
566// if (myLineParser.know("t0-IV")) {
567// retard = getNamedFloat("t0-IV", -1);
568// }
569 // get the type;
570 // use a standard type with a large speed when a type is not given
571
572 std::string type = myLineParser.know(KEYS.getString(VISUM_TYP))
574 : "";
575 // add the connectors as an edge
576 std::string id = bez + "-" + dest->getID();
577 // get the information whether this is a sink or a source
578 std::string dir = myLineParser.get(KEYS.getString(VISUM_DIRECTION));
579 if (dir.length() == 0) {
580 dir = KEYS.getString(VISUM_ORIGIN) + KEYS.getString(VISUM_DESTINATION);
581 }
582 // build the source when needed
583 if (dir.find(KEYS.getString(VISUM_ORIGIN)) != std::string::npos) {
584 const EdgeVector& edges = dest->getOutgoingEdges();
585 bool hasContinuation = false;
586 for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
587 if (!(*i)->isMacroscopicConnector()) {
588 hasContinuation = true;
589 }
590 }
591 if (!hasContinuation) {
592 // obviously, there is no continuation on the net
593 WRITE_WARNINGF(TL("Incoming connector '%' will not be build - would be not connected to network."), id);
594 } else {
595 NBNode* src = buildDistrictNode(bez, dest, true);
596 if (src == nullptr) {
597 WRITE_ERRORF(TL("The district '%' could not be built."), bez);
598 return;
599 }
600 NBEdge* edge = new NBEdge(id, src, dest, "VisumConnector",
601 OptionsCont::getOptions().getFloat("visum.connector-speeds"), NBEdge::UNSPECIFIED_FRICTION,
602 OptionsCont::getOptions().getInt("visum.connectors-lane-number"),
606 if (!myNetBuilder.getEdgeCont().insert(edge)) {
607 WRITE_ERRORF(TL("A duplicate edge id occurred (ID='%')."), id);
608 return;
609 }
610 edge = myNetBuilder.getEdgeCont().retrieve(id);
611 if (edge != nullptr) {
612 myNetBuilder.getDistrictCont().addSource(bez, edge, proz);
613 }
614 }
615 }
616 // build the sink when needed
617 if (dir.find(KEYS.getString(VISUM_DESTINATION)) != std::string::npos) {
618 const EdgeVector& edges = dest->getIncomingEdges();
619 bool hasPredeccessor = false;
620 for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
621 if (!(*i)->isMacroscopicConnector()) {
622 hasPredeccessor = true;
623 }
624 }
625 if (!hasPredeccessor) {
626 // obviously, the network is not connected to this node
627 WRITE_WARNINGF(TL("Outgoing connector '%' will not be build - would be not connected to network."), id);
628 } else {
629 NBNode* src = buildDistrictNode(bez, dest, false);
630 if (src == nullptr) {
631 WRITE_ERRORF(TL("The district '%' could not be built."), bez);
632 return;
633 }
634 id = "-" + id;
635 NBEdge* edge = new NBEdge(id, dest, src, "VisumConnector",
636 OptionsCont::getOptions().getFloat("visum.connector-speeds"), NBEdge::UNSPECIFIED_FRICTION,
637 OptionsCont::getOptions().getInt("visum.connectors-lane-number"),
641 if (!myNetBuilder.getEdgeCont().insert(edge)) {
642 WRITE_ERRORF(TL("A duplicate edge id occurred (ID='%')."), id);
643 return;
644 }
645 edge = myNetBuilder.getEdgeCont().retrieve(id);
646 if (edge != nullptr) {
647 myNetBuilder.getDistrictCont().addSink(bez, edge, proz);
648 }
649 }
650 }
651}
652
653
654void
656 if (myLineParser.know(KEYS.getString(VISUM_TYPES)) && myLineParser.get(KEYS.getString(VISUM_TYPES)) == "") {
657 // no vehicle allowed; don't add
658 return;
659 }
660 // retrieve the nodes
661 NBNode* from = getNamedNode("VonKnot", KEYS.getString(VISUM_FROMNODE));
662 NBNode* via = getNamedNode("UeberKnot", KEYS.getString(VISUM_VIANODENO));
663 NBNode* to = getNamedNode("NachKnot", KEYS.getString(VISUM_TONODE));
664 if (from == nullptr || via == nullptr || to == nullptr) {
665 return;
666 }
667 // all nodes are known
668 std::string type = myLineParser.know("VSysCode")
669 ? myLineParser.get("VSysCode")
670 : myLineParser.get(KEYS.getString(VISUM_TYPES));
671 if (myVSysTypes.find(type) != myVSysTypes.end() &&
672 myVSysTypes.find(type)->second.type == KEYS.getString(VISUM_PRT)) {
673 // try to set the turning definition
674 NBEdge* src = from->getConnectionTo(via);
675 NBEdge* dest = via->getConnectionTo(to);
676 // check both
677 if (src == nullptr) {
678 if (OptionsCont::getOptions().getBool("visum.verbose-warnings")) {
679 WRITE_WARNINGF(TL("There is no edge from node '%' to node '%'."), from->getID(), via->getID());
680 }
681 return;
682 }
683 if (dest == nullptr) {
684 if (OptionsCont::getOptions().getBool("visum.verbose-warnings")) {
685 WRITE_WARNINGF(TL("There is no edge from node '%' to node '%'."), via->getID(), to->getID());
686 }
687 return;
688 }
689 // both edges found
690 // set them into the edge
691 src->addEdge2EdgeConnection(dest);
692 }
693}
694
695
696void
698 // get the from- & to-node and validate them
699 NBNode* from = getNamedNode("VonKnot", KEYS.getString(VISUM_FROMNODE));
700 NBNode* to = getNamedNode("NachKnot", KEYS.getString(VISUM_TONODE));
701 if (!checkNodes(from, to)) {
702 return;
703 }
704 bool failed = false;
705 int index;
706 double x, y;
707 try {
708 index = StringUtils::toInt(myLineParser.get(KEYS.getString(VISUM_INDEX)));
709 x = getNamedFloat(KEYS.getString(VISUM_XCOORD));
710 y = getNamedFloat(KEYS.getString(VISUM_YCOORD));
711 } catch (NumberFormatException&) {
712 WRITE_ERRORF(TL("Error in geometry description from node '%' to node '%'."), from->getID(), to->getID());
713 return;
714 }
715 Position pos(x, y);
717 WRITE_ERRORF(TL("Unable to project coordinates for node '%'."), from->getID());
718 return;
719 }
720 NBEdge* e = from->getConnectionTo(to);
721 if (e != nullptr) {
722 e->addGeometryPoint(index, pos);
723 } else {
724 failed = true;
725 }
726 e = to->getConnectionTo(from);
727 if (e != nullptr) {
728 e->addGeometryPoint(-index, pos);
729 failed = false;
730 }
731 // check whether the operation has failed
732 if (failed) {
733 if (OptionsCont::getOptions().getBool("visum.verbose-warnings")) {
734 WRITE_WARNINGF(TL("There is no edge from node '%' to node '%'."), from->getID(), to->getID());
735 }
736 }
737}
738
739
740void
742 // The base number of lanes for the edge was already defined in STRECKE
743 // this refines lane specific attribute (width) and optionally introduces splits for additional lanes
744 // It is permitted for KNOTNR to be 0
745 //
746 // get the edge
747 NBEdge* baseEdge = getNamedEdge(KEYS.getString(VISUM_LINKNO));
748 if (baseEdge == nullptr) {
749 return;
750 }
751 NBEdge* edge = baseEdge;
752 // get the node
753 NBNode* node = getNamedNodeSecure("KNOTNR");
754 if (node == nullptr) {
755 node = edge->getToNode();
756 } else {
757 edge = getNamedEdgeContinuating(KEYS.getString(VISUM_LINKNO), node);
758 }
759 // check
760 if (edge == nullptr) {
761 return;
762 }
763 // get the lane
764 std::string laneS = myLineParser.know("FSNR")
767 int lane = -1;
768 try {
769 lane = StringUtils::toInt(laneS);
770 } catch (NumberFormatException&) {
771 WRITE_ERRORF(TL("A lane number for edge '%' is not numeric (%)."), edge->getID(), laneS);
772 return;
773 }
774 lane -= 1;
775 if (lane < 0) {
776 WRITE_ERRORF(TL("A lane number for edge '%' is not positive (%)."), edge->getID(), laneS);
777 return;
778 }
779 // get the direction
780 std::string dirS = NBHelpers::normalIDRepresentation(myLineParser.get("RICHTTYP"));
781 int prevLaneNo = baseEdge->getNumLanes();
782 if ((dirS == "1" && !(node->hasIncoming(edge))) || (dirS == "0" && !(node->hasOutgoing(edge)))) {
783 // get the last part of the turnaround direction
784 NBEdge* cand = getReversedContinuating(edge, node);
785 if (cand) {
786 edge = cand;
787 }
788 }
789 // get the length
790 std::string lengthS = NBHelpers::normalIDRepresentation(myLineParser.get("LAENGE"));
791 double length = -1;
792 try {
793 length = StringUtils::toDouble(lengthS);
794 } catch (NumberFormatException&) {
795 WRITE_ERRORF(TL("A lane length for edge '%' is not numeric (%)."), edge->getID(), lengthS);
796 return;
797 }
798 if (length < 0) {
799 WRITE_ERRORF(TL("A lane length for edge '%' is not positive (%)."), edge->getID(), lengthS);
800 return;
801 }
802 //
803 if (dirS == "1") {
804 lane -= prevLaneNo;
805 }
806 //
807 if (length == 0) {
808 if ((int) edge->getNumLanes() > lane) {
809 // ok, we know this already...
810 return;
811 }
812 // increment by one
813 edge->incLaneNo(1);
814 } else {
815 // check whether this edge already has been created
816 if (isSplitEdge(edge, node)) {
817 if (edge->getID().substr(edge->getID().find('_')) == "_" + toString(length) + "_" + node->getID()) {
818 if ((int) edge->getNumLanes() > lane) {
819 // ok, we know this already...
820 return;
821 }
822 // increment by one
823 edge->incLaneNo(1);
824 return;
825 }
826 }
827 // nope, we have to split the edge...
828 // maybe it is not the proper edge to split - VISUM seems not to sort the splits...
829 bool mustRecheck = true;
830 double seenLength = 0;
831 while (mustRecheck) {
832 if (isSplitEdge(edge, node)) {
833 // ok, we have a previously created edge here
834 std::string sub = edge->getID();
835 sub = sub.substr(sub.rfind('_', sub.rfind('_') - 1));
836 sub = sub.substr(1, sub.find('_', 1) - 1);
837 double dist = StringUtils::toDouble(sub);
838 if (dist < length) {
839 seenLength += edge->getLength();
840 if (dirS == "1") {
841 // incoming -> move back
842 edge = edge->getFromNode()->getIncomingEdges()[0];
843 } else {
844 // outgoing -> move forward
845 edge = edge->getToNode()->getOutgoingEdges()[0];
846 }
847 } else {
848 mustRecheck = false;
849 }
850 } else {
851 // we have the center edge - do not continue...
852 mustRecheck = false;
853 }
854 }
855 // compute position
856 Position p;
857 double useLength = length - seenLength;
858 useLength = edge->getLength() - useLength;
859 if (useLength < 0 || useLength > edge->getLength()) {
860 WRITE_WARNINGF(TL("Could not find split position for edge '%'."), edge->getID());
861 return;
862 }
863 std::string edgeID = edge->getID();
864 p = edge->getGeometry().positionAtOffset(useLength);
865 if (isSplitEdge(edge, node)) {
866 edgeID = edgeID.substr(0, edgeID.find('_'));
867 }
868 NBNode* rn = new NBNode(edgeID + "_" + toString((int) length) + "_" + node->getID(), p);
869 if (!myNetBuilder.getNodeCont().insert(rn)) {
870 throw ProcessError(TL("Ups - could not insert node!"));
871 }
872 std::string nid = edgeID + "_" + toString((int) length) + "_" + node->getID();
873 myNetBuilder.getEdgeCont().splitAt(myNetBuilder.getDistrictCont(), edge, useLength, rn,
874 edge->getID(), nid, edge->getNumLanes() + 0, edge->getNumLanes() + 1);
875 // old edge is deleted and a new edge with the same name created
876 edge = myNetBuilder.getEdgeCont().retrieve(edgeID);
877 NBEdge* nedge = myNetBuilder.getEdgeCont().retrieve(nid);
878 nedge = nedge->getToNode()->getOutgoingEdges()[0];
879 while (isSplitEdge(edge, node)) {
880 assert(nedge->getToNode()->getOutgoingEdges().size() > 0);
881 nedge->incLaneNo(1);
882 nedge = nedge->getToNode()->getOutgoingEdges()[0];
883 }
884 }
885}
886
887
888void
891 const SUMOTime cycleTime = TIME2STEPS(getWeightedFloat2("Umlaufzeit", "UMLZEIT", "s"));
892 const SUMOTime intermediateTime = TIME2STEPS(getWeightedFloat2("StdZwischenzeit", "STDZWZEIT", "s"));
893 bool phaseBased = myLineParser.know("PhasenBasiert")
894 ? StringUtils::toBool(myLineParser.get("PhasenBasiert"))
895 : false;
896 const SUMOTime offset = myLineParser.know("ZEITVERSATZ") ? TIME2STEPS(getWeightedFloat("ZEITVERSATZ", "s")) : 0;
897 // add to the list
898 myTLS[myCurrentID] = new NIVisumTL(myCurrentID, cycleTime, offset, intermediateTime, phaseBased);
899}
900
901
902void
904 std::string node = myLineParser.get("KnotNr").c_str();
905 if (node == "0") {
906 // this is a dummy value which cannot be assigned to
907 return;
908 }
909 std::string trafficLight = myLineParser.get("LsaNr").c_str();
910 // add to the list
911 NBNode* n = myNetBuilder.getNodeCont().retrieve(node);
912 auto tlIt = myTLS.find(trafficLight);
913 if (n != nullptr && tlIt != myTLS.end()) {
914 tlIt->second->addNode(n);
915 } else {
916 WRITE_ERROR("Could not assign" + std::string(n == nullptr ? " missing" : "") + " node '" + node
917 + "' to" + std::string(tlIt == myTLS.end() ? " missing" : "") + " traffic light '" + trafficLight + "'");
918 }
919}
920
921
922void
925 std::string LSAid = NBHelpers::normalIDRepresentation(myLineParser.get("LsaNr"));
926 const SUMOTime startTime = TIME2STEPS(getNamedFloat("GzStart", "GRUENANF"));
927 const SUMOTime endTime = TIME2STEPS(getNamedFloat("GzEnd", "GRUENENDE"));
928 const SUMOTime yellowTime = myLineParser.know("GELB") ? TIME2STEPS(getNamedFloat("GELB")) : -1;
929 // add to the list
930 if (myTLS.find(LSAid) == myTLS.end()) {
931 WRITE_ERRORF(TL("Could not find TLS '%' for setting the signal group."), LSAid);
932 return;
933 }
934 myTLS.find(LSAid)->second->addSignalGroup(myCurrentID, startTime, endTime, yellowTime);
935}
936
937
938void
940 // get the id
941 std::string SGid = getNamedString("SGNR", "SIGNALGRUPPENNR");
942 if (!myLineParser.know("LsaNr")) {
944 WRITE_WARNING(TL("Ignoring SIGNALGRUPPEZUFSABBIEGER because LsaNr is not known"));
945 return;
946 }
947 std::string LSAid = getNamedString("LsaNr");
948 // nodes
949 NBNode* from = myLineParser.know("VonKnot") ? getNamedNode("VonKnot") : nullptr;
950 NBNode* via = myLineParser.know("KNOTNR")
951 ? getNamedNode("KNOTNR")
952 : getNamedNode("UeberKnot", "UeberKnotNr");
953 NBNode* to = myLineParser.know("NachKnot") ? getNamedNode("NachKnot") : nullptr;
954 // edges
955 NBEdge* edg1 = nullptr;
956 NBEdge* edg2 = nullptr;
957 if (from == nullptr && to == nullptr) {
958 edg1 = getNamedEdgeContinuating("VONSTRNR", via);
959 edg2 = getNamedEdgeContinuating("NACHSTRNR", via);
960 } else {
961 edg1 = getEdge(from, via);
962 edg2 = getEdge(via, to);
963 }
964 // add to the list
965 NIVisumTL::SignalGroup& SG = myTLS.find(LSAid)->second->getSignalGroup(SGid);
966 if (edg1 != nullptr && edg2 != nullptr) {
967 if (!via->hasIncoming(edg1)) {
968 std::string sid;
969 if (edg1->getID()[0] == '-') {
970 sid = edg1->getID().substr(1);
971 } else {
972 sid = "-" + edg1->getID();
973 }
974 if (sid.find('_') != std::string::npos) {
975 sid = sid.substr(0, sid.find('_'));
976 }
977 edg1 = getNamedEdgeContinuating(myNetBuilder.getEdgeCont().retrieve(sid), via);
978 }
979 if (!via->hasOutgoing(edg2)) {
980 std::string sid;
981 if (edg2->getID()[0] == '-') {
982 sid = edg2->getID().substr(1);
983 } else {
984 sid = "-" + edg2->getID();
985 }
986 if (sid.find('_') != std::string::npos) {
987 sid = sid.substr(0, sid.find('_'));
988 }
989 edg2 = getNamedEdgeContinuating(myNetBuilder.getEdgeCont().retrieve(sid), via);
990 }
991 SG.connections().push_back(NBConnection(edg1, edg2));
992 }
993}
994
995
996void
998 long long int id = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_FACEID)));
999 long long int edgeid = StringUtils::toLong(myLineParser.get(KEYS.getString(VISUM_EDGEID)));
1000 if (myEdges.find(edgeid) == myEdges.end()) {
1001 WRITE_ERROR(TL("Unknown edge in TEILFLAECHENELEMENT"));
1002 return;
1003 }
1004 std::string dir = myLineParser.get(KEYS.getString(VISUM_DIRECTION));
1005// get index (unused)
1006// std::string indexS = NBHelpers::normalIDRepresentation(myLineParser.get("INDEX"));
1007// int index = -1;
1008// try {
1009// index = StringUtils::toInt(indexS) - 1;
1010// } catch (NumberFormatException&) {
1011// WRITE_ERRORF(TL("An index for a TEILFLAECHENELEMENT is not numeric (id='%')."), toString(id));
1012// return;
1013// }
1014 PositionVector shape;
1015 shape.push_back(myPoints[myEdges[edgeid].first]);
1016 shape.push_back(myPoints[myEdges[edgeid].second]);
1017 if (dir.length() > 0 && dir[0] == '1') {
1018 shape = shape.reverse();
1019 }
1020 if (mySubPartsAreas.find(id) == mySubPartsAreas.end()) {
1021 WRITE_ERRORF(TL("Unknown are for area part '%'."), myCurrentID);
1022 return;
1023 }
1024
1025 const std::vector<long long int>& areas = mySubPartsAreas.find(id)->second;
1026 for (std::vector<long long int>::const_iterator i = areas.begin(); i != areas.end(); ++i) {
1028 if (d == nullptr) {
1029 continue;
1030 }
1031 if (myDistrictShapes.find(d) == myDistrictShapes.end()) {
1033 }
1034 if (dir.length() > 0 && dir[0] == '1') {
1035 myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].second]);
1036 myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].first]);
1037 } else {
1038 myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].first]);
1039 myDistrictShapes[d].push_back(myPoints[myEdges[edgeid].second]);
1040 }
1041 }
1042}
1043
1044
1045void
1047 // get the id
1048 const std::string phaseid = NBHelpers::normalIDRepresentation(myLineParser.get(KEYS.getString(VISUM_NO)));
1049 const std::string LSAid = NBHelpers::normalIDRepresentation(myLineParser.get("LsaNr"));
1050 const SUMOTime startTime = TIME2STEPS(getNamedFloat("GzStart", "GRUENANF"));
1051 const SUMOTime endTime = TIME2STEPS(getNamedFloat("GzEnd", "GRUENENDE"));
1052 const SUMOTime yellowTime = myLineParser.know("GELB") ? TIME2STEPS(getNamedFloat("GELB")) : -1;
1053 myTLS.find(LSAid)->second->addPhase(phaseid, startTime, endTime, yellowTime);
1054}
1055
1056
1058 // get the id
1059 std::string Phaseid = NBHelpers::normalIDRepresentation(myLineParser.get("PsNr"));
1060 std::string LSAid = NBHelpers::normalIDRepresentation(myLineParser.get("LsaNr"));
1061 std::string SGid = NBHelpers::normalIDRepresentation(myLineParser.get("SGNR"));
1062 // insert
1063 NIVisumTL* LSA = myTLS.find(LSAid)->second;
1064 NIVisumTL::SignalGroup& SG = LSA->getSignalGroup(SGid);
1065 NIVisumTL::Phase* PH = LSA->getPhases().find(Phaseid)->second;
1066 SG.phases()[Phaseid] = PH;
1067}
1068
1069
1071 NBNode* node = nullptr;
1072 NBEdge* fromEdge = nullptr;
1073 NBEdge* toEdge = nullptr;
1074 // get the node and edges depending on network format
1075 const std::string nodeID = getNamedString("KNOTNR", "KNOT");
1076 if (nodeID == "0") {
1077 fromEdge = getNamedEdge("VONSTRNR", "VONSTR");
1078 toEdge = getNamedEdge("NACHSTRNR", "NACHSTR");
1079 if (fromEdge == nullptr) {
1080 return;
1081 }
1082 node = fromEdge->getToNode();
1083 WRITE_WARNING(TL("Ignoring lane-to-lane connection (not yet implemented for this format version)"));
1084 return;
1085 } else {
1086 node = getNamedNode("KNOTNR", "KNOT");
1087 if (node == nullptr) {
1088 return;
1089 }
1090 fromEdge = getNamedEdgeContinuating("VONSTRNR", "VONSTR", node);
1091 toEdge = getNamedEdgeContinuating("NACHSTRNR", "NACHSTR", node);
1092 }
1093 if (fromEdge == nullptr || toEdge == nullptr) {
1094 return;
1095 }
1096
1097 int fromLaneOffset = 0;
1098 if (!node->hasIncoming(fromEdge)) {
1099 fromLaneOffset = fromEdge->getNumLanes();
1100 fromEdge = getReversedContinuating(fromEdge, node);
1101 } else {
1102 fromEdge = getReversedContinuating(fromEdge, node);
1103 NBEdge* tmp = myNetBuilder.getEdgeCont().retrieve(fromEdge->getID().substr(0, fromEdge->getID().find('_')));
1104 fromLaneOffset = tmp->getNumLanes();
1105 }
1106
1107 int toLaneOffset = 0;
1108 if (!node->hasOutgoing(toEdge)) {
1109 toLaneOffset = toEdge->getNumLanes();
1110 toEdge = getReversedContinuating(toEdge, node);
1111 } else {
1112 NBEdge* tmp = myNetBuilder.getEdgeCont().retrieve(toEdge->getID().substr(0, toEdge->getID().find('_')));
1113 toLaneOffset = tmp->getNumLanes();
1114 }
1115 // get the from-lane
1116 std::string fromLaneS = NBHelpers::normalIDRepresentation(myLineParser.get("VONFSNR"));
1117 int fromLane = -1;
1118 try {
1119 fromLane = StringUtils::toInt(fromLaneS);
1120 } catch (NumberFormatException&) {
1121 WRITE_ERRORF(TL("A from-lane number for edge '%' is not numeric (%)."), fromEdge->getID(), fromLaneS);
1122 return;
1123 }
1124 fromLane -= 1;
1125 if (fromLane < 0) {
1126 WRITE_ERRORF(TL("A from-lane number for edge '%' is not positive (%)."), fromEdge->getID(), fromLaneS);
1127 return;
1128 }
1129 // get the from-lane
1130 std::string toLaneS = NBHelpers::normalIDRepresentation(myLineParser.get("NACHFSNR"));
1131 int toLane = -1;
1132 try {
1133 toLane = StringUtils::toInt(toLaneS);
1134 } catch (NumberFormatException&) {
1135 WRITE_ERRORF(TL("A to-lane number for edge '%' is not numeric (%)."), toEdge->getID(), toLaneS);
1136 return;
1137 }
1138 toLane -= 1;
1139 if (toLane < 0) {
1140 WRITE_ERRORF(TL("A to-lane number for edge '%' is not positive (%)."), toEdge->getID(), toLaneS);
1141 return;
1142 }
1143 // !!! the next is probably a hack
1144 if (fromLane - fromLaneOffset < 0) {
1145 //fromLaneOffset = 0;
1146 } else {
1147 fromLane = (int)fromEdge->getNumLanes() - (fromLane - fromLaneOffset) - 1;
1148 }
1149 if (toLane - toLaneOffset < 0) {
1150 //toLaneOffset = 0;
1151 } else {
1152 toLane = (int)toEdge->getNumLanes() - (toLane - toLaneOffset) - 1;
1153 }
1154 //
1155 if ((int) fromEdge->getNumLanes() <= fromLane) {
1156 WRITE_ERRORF(TL("A from-lane number for edge '%' is larger than the edge's lane number (%)."), fromEdge->getID(), fromLaneS);
1157 return;
1158 }
1159 if ((int) toEdge->getNumLanes() <= toLane) {
1160 WRITE_ERRORF(TL("A to-lane number for edge '%' is larger than the edge's lane number (%)."), toEdge->getID(), toLaneS);
1161 return;
1162 }
1163 //
1164 fromEdge->addLane2LaneConnection(fromLane, toEdge, toLane, NBEdge::Lane2LaneInfoType::VALIDATED);
1165}
1166
1167
1169 std::string id = NBHelpers::normalIDRepresentation(myLineParser.get(KEYS.getString(VISUM_NO)));
1170 std::string name = StringUtils::latin1_to_utf8(myLineParser.get(KEYS.getString(VISUM_NAME)));
1171 SVCPermissions permissions = getPermissions(KEYS.getString(VISUM_TYPES), id, myDefaultPermissions);
1172 NBNode* from = getNamedNodeSecure(KEYS.getString(VISUM_FROMNODE));
1174 const std::string edgeID = myLineParser.get(KEYS.getString(VISUM_LINKNO));
1175 if (edgeID == "") {
1176 WRITE_WARNINGF(TL("Ignoring stopping place '%' without edge id"), id);
1177 } else if (from == nullptr && to == nullptr) {
1178 WRITE_WARNINGF(TL("Ignoring stopping place '%' without node information"), id);
1179 } else {
1180 NBEdge* edge = getNamedEdge(KEYS.getString(VISUM_LINKNO));
1181 if (edge == nullptr) {
1182 WRITE_WARNINGF(TL("Ignoring stopping place '%' with invalid edge reference '%'"), id, edgeID);
1183 return;
1184 } else if (from != nullptr) {
1185 if (edge->getToNode() == from) {
1186 NBEdge* edge2 = myNetBuilder.getEdgeCont().retrieve("-" + edge->getID());
1187 if (edge2 == nullptr) {
1188 WRITE_WARNINGF(TL("Could not find edge with from-node '%' and base id '%' for stopping place '%'"), from->getID(), edge->getID(), id);
1189 } else {
1190 edge = edge2;
1191 }
1192 } else if (edge->getFromNode() != from) {
1193 WRITE_WARNINGF(TL("Unexpected from-node '%' for edge '%' of stopping place '%'"), from->getID(), edge->getID(), id);
1194 }
1195 } else {
1196 if (edge->getFromNode() == to) {
1197 NBEdge* edge2 = myNetBuilder.getEdgeCont().retrieve("-" + edge->getID());
1198 if (edge2 == nullptr) {
1199 WRITE_WARNINGF(TL("Could not find edge with to-node '%' and base id '%' for stopping place '%'"), to->getID(), edge->getID(), id);
1200 } else {
1201 edge = edge2;
1202 }
1203 } else if (edge->getToNode() != to) {
1204 WRITE_WARNINGF(TL("Unexpected to-node '%' for edge '%' of stopping place '%'"), to->getID(), edge->getID(), id);
1205 }
1206 }
1207 double relPos = StringUtils::toDouble(myLineParser.get(KEYS.getString(VISUM_RELPOS)));
1209 Position pos = edge->getGeometry().positionAtOffset(edge->getLength() * relPos);
1210
1211 const double length = OptionsCont::getOptions().getFloat("osm.stop-output.length");
1212 SumoXMLTag element = isRailway(permissions) ? SUMO_TAG_TRAIN_STOP : SUMO_TAG_BUS_STOP;
1213 std::shared_ptr<NBPTStop> ptStop = std::make_shared<NBPTStop>(element, id, pos, edge->getID(), edge->getID(), length, name, permissions);
1214 myNetBuilder.getPTStopCont().insert(ptStop);
1215 }
1216}
1217
1218
1219double
1220NIImporter_VISUM::getWeightedFloat(const std::string& name, const std::string& suffix) {
1221 try {
1222 std::string val = myLineParser.get(name);
1223 if (val.find(suffix) != std::string::npos) {
1224 val = val.substr(0, val.find(suffix));
1225 }
1226 return StringUtils::toDouble(val);
1227 } catch (...) {}
1228 return -1;
1229}
1230
1231
1232double
1233NIImporter_VISUM::getWeightedFloat2(const std::string& name, const std::string& name2, const std::string& suffix) {
1234 double result = getWeightedFloat(name, suffix);
1235 if (result != -1) {
1236 return result;
1237 } else {
1238 return getWeightedFloat(name2, suffix);
1239 }
1240}
1241
1242bool
1243NIImporter_VISUM::getWeightedBool(const std::string& name) {
1244 try {
1245 return StringUtils::toBool(myLineParser.get(name));
1246 } catch (...) {}
1247 try {
1248 return StringUtils::toBool(myLineParser.get((name + "(IV)")));
1249 } catch (...) {}
1250 return false;
1251}
1252
1254NIImporter_VISUM::getPermissions(const std::string& name, const std::string& edgeType, SVCPermissions unknown) {
1255 SVCPermissions result = 0;
1256 NBTypeCont& tc = myNetBuilder.getTypeCont();
1257 for (std::string v : StringTokenizer(myLineParser.get(name), ",").getVector()) {
1258 const std::string v2 = TSYSPREFIX + v;
1259 const std::string v3 = StringUtils::to_lower_case(v);
1260 const std::string v4 = TSYSPREFIX + v3;
1261 if (tc.knows(v2)) {
1262 result |= tc.getEdgeTypePermissions(v2);
1263 } else if (tc.knows(v4)) {
1264 result |= tc.getEdgeTypePermissions(v4);
1265 } else {
1266 SVCPermissions guessed = SVC_IGNORING;
1267 std::string desc;
1268 auto it = myVSysTypes.find(v);
1269 if (it != myVSysTypes.end()) {
1270 desc = it->second.name;
1271 if (desc.find("taxi") != std::string::npos) {
1272 guessed = SVC_TAXI;
1273 } else if (desc.find("bus") != std::string::npos) {
1274 guessed = SVC_BUS;
1275 } else if (desc.find("seilbahn") != std::string::npos || desc.find("funiculaire") != std::string::npos || desc.find("cable") != std::string::npos || desc.find("funicular") != std::string::npos) {
1276 guessed = SVC_CABLE_CAR;
1277 } else if (desc.find("subway") != std::string::npos || desc.find("ubahn") != std::string::npos || desc.find("u-bahn") != std::string::npos) {
1278 guessed = SVC_SUBWAY;
1279 } else if (desc.find("train") != std::string::npos || desc.find("schiene") != std::string::npos || desc.find("rail") != std::string::npos || desc.find("bahn") != std::string::npos || desc.find("zug") != std::string::npos) {
1280 guessed = SVC_RAIL;
1281 } else if (desc.find("tram") != std::string::npos || desc.find("strab") != std::string::npos) {
1282 guessed = SVC_TRAM;
1283 } else if (desc.find("moto") != std::string::npos) {
1284 guessed = SVC_MOTORCYCLE;
1285 } else if (desc.find("bike") != std::string::npos || desc.find("velo") != std::string::npos || desc.find("bicycle") != std::string::npos || desc.find("rad") != std::string::npos) {
1286 guessed = SVC_BICYCLE;
1287 } else if (desc.find("foot") != std::string::npos || desc.find("ped") != std::string::npos || desc.find("fu\xdf") != std::string::npos
1288 || desc.find("fuss") != std::string::npos || desc.find("walk") != std::string::npos || desc.find("pied") != std::string::npos) {
1289 guessed = SVC_PEDESTRIAN;
1290 } else if (desc.find("lkw") != std::string::npos || desc.find("truck") != std::string::npos || desc.find("camion") != std::string::npos) {
1291 guessed = SVC_TRUCK;
1292 } else if (desc.find("pkw") != std::string::npos || desc.find("car") != std::string::npos || desc.find("auto") != std::string::npos) {
1293 guessed = SVC_PASSENGER;
1294 }
1295 }
1296 if (guessed == SVC_IGNORING) {
1297 WRITE_WARNINGF("Encountered unknown vehicle category '%' in type '%' (description: '%')", v3, edgeType, desc);
1298 guessed = unknown;
1299 } else {
1300 WRITE_WARNINGF("Encountered unknown vehicle category '%' in type '%' (guessed '%' based on description '%')", v3, edgeType, getVehicleClassNames(guessed), desc);
1301 }
1303 result |= guessed;
1304 }
1305 }
1306 return result;
1307}
1308
1309NBNode*
1310NIImporter_VISUM::getNamedNode(const std::string& fieldName) {
1311 std::string nodeS = NBHelpers::normalIDRepresentation(myLineParser.get(fieldName));
1312 NBNode* node = myNetBuilder.getNodeCont().retrieve(nodeS);
1313 if (node == nullptr) {
1314 WRITE_ERRORF(TL("The node '%' is not known."), nodeS);
1315 }
1316 return node;
1317}
1318
1319NBNode*
1320NIImporter_VISUM::getNamedNodeSecure(const std::string& fieldName, NBNode* fallback) {
1321 std::string nodeS = NBHelpers::normalIDRepresentation(myLineParser.get(fieldName));
1322 NBNode* node = myNetBuilder.getNodeCont().retrieve(nodeS);
1323 if (node == nullptr) {
1324 return fallback;
1325 }
1326 return node;
1327}
1328
1329
1330NBNode*
1331NIImporter_VISUM::getNamedNode(const std::string& fieldName1, const std::string& fieldName2) {
1332 if (myLineParser.know(fieldName1)) {
1333 return getNamedNode(fieldName1);
1334 } else {
1335 return getNamedNode(fieldName2);
1336 }
1337}
1338
1339
1340NBEdge*
1341NIImporter_VISUM::getNamedEdge(const std::string& fieldName) {
1342 std::string edgeS = NBHelpers::normalIDRepresentation(myLineParser.get(fieldName));
1343 NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(edgeS);
1344 if (edge == nullptr) {
1345 WRITE_ERRORF(TL("The edge '%' is not known."), edgeS);
1346 }
1347 return edge;
1348}
1349
1350
1351NBEdge*
1352NIImporter_VISUM::getNamedEdge(const std::string& fieldName1, const std::string& fieldName2) {
1353 if (myLineParser.know(fieldName1)) {
1354 return getNamedEdge(fieldName1);
1355 } else {
1356 return getNamedEdge(fieldName2);
1357 }
1358}
1359
1360
1361
1362NBEdge*
1364 std::string sid;
1365 if (edge->getID()[0] == '-') {
1366 sid = edge->getID().substr(1);
1367 } else {
1368 sid = "-" + edge->getID();
1369 }
1370 if (sid.find('_') != std::string::npos) {
1371 sid = sid.substr(0, sid.find('_'));
1372 }
1373 return getNamedEdgeContinuating(myNetBuilder.getEdgeCont().retrieve(sid), node);
1374}
1375
1376
1377NBEdge*
1379 if (begin == nullptr) {
1380 return nullptr;
1381 }
1382 NBEdge* ret = begin;
1383 std::string edgeID = ret->getID();
1384 // hangle forward
1385 while (ret != nullptr) {
1386 // ok, this is the edge we are looking for
1387 if (ret->getToNode() == node) {
1388 return ret;
1389 }
1390 const EdgeVector& nedges = ret->getToNode()->getOutgoingEdges();
1391 if (nedges.size() != 1) {
1392 // too many edges follow
1393 ret = nullptr;
1394 continue;
1395 }
1396 NBEdge* next = nedges[0];
1397 if (ret->getID().substr(0, edgeID.length()) != next->getID().substr(0, edgeID.length())) {
1398 // ok, another edge is next...
1399 ret = nullptr;
1400 continue;
1401 }
1402 if (next->getID().substr(next->getID().length() - node->getID().length()) != node->getID()) {
1403 ret = nullptr;
1404 continue;
1405 }
1406 ret = next;
1407 }
1408
1409 ret = begin;
1410 // hangle backward
1411 while (ret != nullptr) {
1412 // ok, this is the edge we are looking for
1413 if (ret->getFromNode() == node) {
1414 return ret;
1415 }
1416 const EdgeVector& nedges = ret->getFromNode()->getIncomingEdges();
1417 if (nedges.size() != 1) {
1418 // too many edges follow
1419 ret = nullptr;
1420 continue;
1421 }
1422 NBEdge* next = nedges[0];
1423 if (ret->getID().substr(0, edgeID.length()) != next->getID().substr(0, edgeID.length())) {
1424 // ok, another edge is next...
1425 ret = nullptr;
1426 continue;
1427 }
1428 if (next->getID().substr(next->getID().length() - node->getID().length()) != node->getID()) {
1429 ret = nullptr;
1430 continue;
1431 }
1432 ret = next;
1433 }
1434 return nullptr;
1435}
1436
1437
1438NBEdge*
1439NIImporter_VISUM::getNamedEdgeContinuating(const std::string& fieldName, NBNode* node) {
1440 std::string edgeS = NBHelpers::normalIDRepresentation(myLineParser.get(fieldName));
1441 NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(edgeS);
1442 if (edge == nullptr) {
1443 WRITE_ERRORF(TL("The edge '%' is not known."), edgeS);
1444 }
1445 return getNamedEdgeContinuating(edge, node);
1446}
1447
1448
1449NBEdge*
1450NIImporter_VISUM::getNamedEdgeContinuating(const std::string& fieldName1, const std::string& fieldName2,
1451 NBNode* node) {
1452 if (myLineParser.know(fieldName1)) {
1453 return getNamedEdgeContinuating(fieldName1, node);
1454 } else {
1455 return getNamedEdgeContinuating(fieldName2, node);
1456 }
1457}
1458
1459
1460NBEdge*
1462 EdgeVector::const_iterator i;
1463 for (i = FromNode->getOutgoingEdges().begin(); i != FromNode->getOutgoingEdges().end(); i++) {
1464 if (ToNode == (*i)->getToNode()) {
1465 return (*i);
1466 }
1467 }
1469 return nullptr;
1470}
1471
1472
1473double
1474NIImporter_VISUM::getNamedFloat(const std::string& fieldName) {
1475 std::string value = myLineParser.get(fieldName);
1476 if (StringUtils::endsWith(myLineParser.get(fieldName), "km/h")) {
1477 value = value.substr(0, value.length() - 4);
1478 }
1480}
1481
1482
1483double
1484NIImporter_VISUM::getNamedFloat(const std::string& fieldName, double defaultValue) {
1485 try {
1486 return StringUtils::toDouble(myLineParser.get(fieldName));
1487 } catch (...) {
1488 return defaultValue;
1489 }
1490}
1491
1492
1493double
1494NIImporter_VISUM::getNamedFloat(const std::string& fieldName1, const std::string& fieldName2) {
1495 if (myLineParser.know(fieldName1)) {
1496 return getNamedFloat(fieldName1);
1497 } else {
1498 return getNamedFloat(fieldName2);
1499 }
1500}
1501
1502
1503double
1504NIImporter_VISUM::getNamedFloat(const std::string& fieldName1, const std::string& fieldName2,
1505 double defaultValue) {
1506 if (myLineParser.know(fieldName1)) {
1507 return getNamedFloat(fieldName1, defaultValue);
1508 } else {
1509 return getNamedFloat(fieldName2, defaultValue);
1510 }
1511}
1512
1513
1514std::string
1515NIImporter_VISUM::getNamedString(const std::string& fieldName) {
1516 return NBHelpers::normalIDRepresentation(myLineParser.get(fieldName));
1517}
1518
1519
1520std::string
1521NIImporter_VISUM::getNamedString(const std::string& fieldName1,
1522 const std::string& fieldName2) {
1523 if (myLineParser.know(fieldName1)) {
1524 return getNamedString(fieldName1);
1525 } else {
1526 return getNamedString(fieldName2);
1527 }
1528}
1529
1530
1531
1532
1533
1534
1535NBNode*
1536NIImporter_VISUM::buildDistrictNode(const std::string& id, NBNode* dest,
1537 bool isSource) {
1538 // get the district
1539 NBDistrict* dist = myNetBuilder.getDistrictCont().retrieve(id);
1540 if (dist == nullptr) {
1541 return nullptr;
1542 }
1543 // build the id
1544 std::string nid;
1545 nid = id + "-" + dest->getID();
1546 if (!isSource) {
1547 nid = "-" + nid;
1548 }
1549 // insert the node
1550 if (!myNetBuilder.getNodeCont().insert(nid, dist->getPosition())) {
1551 WRITE_ERRORF(TL("Could not build connector node '%'."), nid);
1552 }
1553 // return the node
1554 return myNetBuilder.getNodeCont().retrieve(nid);
1555}
1556
1557
1558bool
1560 if (from == nullptr) {
1561 WRITE_ERROR(TL(" The from-node was not found within the net"));
1562 }
1563 if (to == nullptr) {
1564 WRITE_ERROR(TL(" The to-node was not found within the net"));
1565 }
1566 if (from == to) {
1567 WRITE_ERROR(TL(" Both nodes are the same"));
1568 }
1569 return from != nullptr && to != nullptr && from != to;
1570}
1571
1572bool
1574 return (edge->getID().length() > node->getID().length() + 1
1575 && (edge->getID().substr(edge->getID().length() - node->getID().length() - 1) == "_" + node->getID()));
1576}
1577
1578void
1579NIImporter_VISUM::loadLanguage(const std::string& file) {
1580 std::ifstream strm(file.c_str());
1581 if (!strm.good()) {
1582 throw ProcessError(TLF("Could not load VISUM language map from '%'.", file));
1583 }
1584 while (strm.good()) {
1585 std::string keyDE;
1586 std::string keyNew;
1587 strm >> keyDE;
1588 strm >> keyNew;
1589 if (KEYS.hasString(keyDE)) {
1590 VISUM_KEY key = KEYS.get(keyDE);
1591 KEYS.remove(keyDE, key);
1592 KEYS.insert(keyNew, key);
1593 } else if (keyDE != "") {
1594 WRITE_WARNINGF(TL("Unknown entry '%' in VISUM language map"), keyDE);
1595 }
1596 }
1597
1598}
1599
1600
1601/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:288
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
#define PROGRESS_DONE_MESSAGE()
Definition MsgHandler.h:291
#define TLF(string,...)
Definition MsgHandler.h:306
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition MsgHandler.h:290
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition NBCont.h:42
#define TSYSPREFIX
const std::string invalid_return< std::string >::value
#define TIME2STEPS(x)
Definition SUMOTime.h:60
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a (exclusive) railway edge.
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SVC_TRUCK
vehicle is a large transport vehicle
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_RAIL
vehicle is a not electrified rail
@ SVC_CABLE_CAR
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_MOTORCYCLE
vehicle is a motorcycle
@ SVC_TRAM
vehicle is a light rail
@ SVC_TAXI
vehicle is a taxi
@ SVC_BUS
vehicle is a bus
@ SVC_SUBWAY
@ SVC_PEDESTRIAN
pedestrian
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_TRAIN_STOP
A train stop (alias for bus stop).
LaneSpreadFunction
Numbers representing special SUMO-XML-attribute values Information how the edge's lateral offset shal...
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_ONEWAY
@ SUMO_ATTR_PRIORITY
@ SUMO_ATTR_NUMLANES
@ SUMO_ATTR_SPREADTYPE
The information about how to spread the lanes from the given position.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
static methods for processing the coordinates conversion for the current net
static void setLoaded(const GeoConvHelper &loaded)
sets the coordinate transformation loaded from a location element
A helper class which computes the lane number from given capacity.
A class representing a single district.
Definition NBDistrict.h:62
const Position & getPosition() const
Returns the position of this district's center.
Definition NBDistrict.h:120
The representation of a single edge during network building.
Definition NBEdge.h:92
void addGeometryPoint(int index, const Position &p)
Adds a further geometry point.
Definition NBEdge.cpp:1027
double getLength() const
Returns the computed length of the edge.
Definition NBEdge.h:599
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
Definition NBEdge.cpp:4504
NBNode * getToNode() const
Returns the destination node of the edge.
Definition NBEdge.h:552
static const double UNSPECIFIED_FRICTION
unspecified lane friction
Definition NBEdge.h:355
void incLaneNo(int by)
increment lane
Definition NBEdge.cpp:4237
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition NBEdge.h:789
bool addEdge2EdgeConnection(NBEdge *dest, bool overrideRemoval=false, SVCPermissions permission=SVC_UNSPECIFIED)
Adds a connection to another edge.
Definition NBEdge.cpp:1120
bool addLane2LaneConnection(int fromLane, NBEdge *dest, int toLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, KeepClear keepClear=KEEPCLEAR_UNSPECIFIED, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, double friction=UNSPECIFIED_FRICTION, double length=myDefaultConnectionLength, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED, SVCPermissions permissions=SVC_UNSPECIFIED, const bool indirectLeft=false, const std::string &edgeType="", SVCPermissions changeLeft=SVC_UNSPECIFIED, SVCPermissions changeRight=SVC_UNSPECIFIED, bool postProcess=false)
Adds a connection between the specified this edge's lane and an approached one.
Definition NBEdge.cpp:1156
const std::string & getID() const
Definition NBEdge.h:1551
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
Definition NBEdge.cpp:1015
int getNumLanes() const
Returns the number of lanes.
Definition NBEdge.h:526
@ VALIDATED
The connection was computed and validated.
Definition NBEdge.h:136
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition NBEdge.h:545
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition NBEdge.h:346
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition NBEdge.h:349
void setAsMacroscopicConnector()
Definition NBEdge.h:1135
static std::string normalIDRepresentation(const std::string &id)
converts the numerical id to its "normal" string representation
Definition NBHelpers.cpp:69
Instance responsible for building networks.
NBTypeCont & getTypeCont()
Returns a reference to the type container.
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=nullptr)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
Represents a single node (junction) during network building.
Definition NBNode.h:66
bool hasIncoming(const NBEdge *const e) const
Returns whether the given edge ends at this node.
Definition NBNode.cpp:1995
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node).
Definition NBNode.h:268
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node).
Definition NBNode.h:273
bool hasOutgoing(const NBEdge *const e) const
Returns whether the given edge starts at this node.
Definition NBNode.cpp:2001
NBEdge * getConnectionTo(NBNode *n) const
get connection to certain node
Definition NBNode.cpp:2802
A storage for available edgeTypes of edges.
Definition NBTypeCont.h:52
void insertEdgeType(const std::string &id, int numLanes, double maxSpeed, int prio, SVCPermissions permissions, LaneSpreadFunction spreadType, double width, bool oneWayIsDefault, double sidewalkWidth, double bikeLaneWidth, double widthResolution, double maxWidth, double minWidth)
Adds a edgeType into the list.
TypesCont::const_iterator begin() const
return begin iterator
SVCPermissions getEdgeTypePermissions(const std::string &edgeType) const
Returns allowed vehicle classes for the given edgeType.
bool knows(const std::string &edgeType) const
Returns whether the named edgeType is in the container.
TypesCont::const_iterator end() const
return end iterator
void updateEdgeTypeID(const std::string &oldId, const std::string &newId)
change edge type ID
void load()
Parses the VISUM-network file storing the parsed structures within myNetBuilder.
void parse_Phases()
Parses LSAPHASE/PHASE.
NBCapacity2Lanes myCapacity2Lanes
The converter to compute the lane number of edges from their capacity.
static StringBijection< VISUM_KEY > KEYS
link directions
NBNetBuilder & myNetBuilder
The network builder to fill with loaded values.
SVCPermissions myDefaultPermissions
void parse_Edges()
Parses STRECKE/STRECKEN.
double getWeightedFloat2(const std::string &name, const std::string &name2, const std::string &suffix)
as above but with two alternative names
~NIImporter_VISUM()
destructor
std::vector< std::string > myTouchedEdges
Already read edges.
void(NIImporter_VISUM::* ParsingFunction)()
Definition of a function for parsing a single line from a certain db.
NBEdge * getNamedEdge(const std::string &fieldName)
Tries to get the edge which name is stored in the given field.
double getWeightedFloat(const std::string &name, const std::string &suffix)
tries to get a double which is possibly assigned to a certain modality
void parse_VSysTypes()
Parses VSYS.
void parse_NodesToTrafficLights()
Parses KNOTENZULSA/SIGNALANLAGEZUKNOTEN.
void parse_PartOfArea()
Parses FLAECHENELEMENT.
void parse_Network()
Parses meta data (i.e. projection).
void parse_TrafficLights()
Parses LSA/SIGNALANLAGE.
NBNode * getNamedNodeSecure(const std::string &fieldName, NBNode *fallback=0)
void parse_Point()
Parses PUNKT.
void parse_Districts()
Parses BEZIRK.
VSysTypeNames myVSysTypes
The used vsystypes.
std::string myCurrentID
The name of the currently parsed item used for error reporting.
bool getWeightedBool(const std::string &name)
tries to get a bool which is possibly assigned to a certain modality
void parse_stopPoints()
Parses HALTEPUNKT (public transport stop locations).
std::map< NBDistrict *, PositionVector > myDistrictShapes
A temporary storage for district shapes as they are filled incrementally.
std::string myFileName
The name of the parsed file, for error reporting.
std::map< long long int, Position > myPoints
A map of point ids to positions.
void addParser(const std::string &name, ParsingFunction function)
Adds a parser into the sorted list of parsers to use.
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads network definition from the assigned option and stores it in the given network builder.
NIImporter_VISUM(NBNetBuilder &nb, const std::string &file, NBCapacity2Lanes capacity2Lanes, bool useVisumPrio, const std::string &languageFile)
constructor
static StringBijection< VISUM_KEY >::Entry KEYS_DE[]
Strings for the keywords.
std::map< long long int, std::pair< long long int, long long int > > myEdges
A map of edge (not road, but "edge" in this case) ids to from/to-points.
void parse_EdgePolys()
Parses STRECKENPOLY.
LineReader myLineReader
The line reader to use to read from the file.
bool myUseVisumPrio
Information whether VISUM priority information shall be used.
SVCPermissions getPermissions(const std::string &name, const std::string &edgeType, SVCPermissions unknown)
parse permissions
void loadLanguage(const std::string &file)
bool checkNodes(NBNode *from, NBNode *to)
Returns whether both nodes are a valid combination of from/to-nodes.
NBEdge * getReversedContinuating(NBEdge *edge, NBNode *node)
Returns the opposite direction of the given edge.
ParserVector mySingleDataParsers
List of known parsers.
void parse_SignalGroupsToPhases()
Parses LSASIGNALGRUPPEZULSAPHASE.
NBNode * getNamedNode(const std::string &fieldName)
Tries to get the node which name is stored in the given field.
void parse_Kante()
Parses FLAECHENELEMENT.
void parse_SignalGroups()
Parses LSASIGNALGRUPPE/SIGNALGRUPPE.
NBNode * buildDistrictNode(const std::string &id, NBNode *dest, bool isSource)
Builds a node for the given district and returns it.
void parse_Lanes()
Parses FAHRSTREIFEN.
NBEdge * getEdge(NBNode *FromNode, NBNode *ToNode)
Returns the edge that connects both nodes.
NamedColumnsParser myLineParser
the parser to parse the information from the data lines
double getNamedFloat(const std::string &fieldName)
Returns the value from the named column as a float.
std::map< long long int, NBDistrict * > myShapeDistrictMap
A map from district shape definition name to the district.
void parse_Turns()
Parses ABBIEGEBEZIEHUNG/ABBIEGER.
void parse_Nodes()
Parses KNOTEN.
void parse_TurnsToSignalGroups()
Parses ABBZULSASIGNALGRUPPE/SIGNALGRUPPEZUABBIEGER.
NBEdge * getNamedEdgeContinuating(const std::string &fieldName, NBNode *node)
Tries to get the edge which name is stored in the given field continuating the search for a subedge t...
std::string getNamedString(const std::string &fieldName)
Returns the value from the named column as a normalised string.
void parse_LanesConnections()
Parses FAHRSTREIFENABBIEGER.
static bool isSplitEdge(NBEdge *edge, NBNode *node)
whether the edge id ends with _nodeID
void parse_Types()
Parses STRECKENTYP.
void parse_Connectors()
Parses ANBINDUNG.
void parse_AreaSubPartElement()
Parses ABBZULSASIGNALGRUPPE/SIGNALGRUPPEZUABBIEGER.
std::map< long long int, std::vector< long long int > > mySubPartsAreas
A map from area parts to area ids.
NIVisumTL_Map myTLS
List of visum traffic lights.
A signal group can be defined either by a time period or by phases.
Definition NIVisumTL.h:103
std::map< std::string, Phase * > & phases()
Returns the phases map.
Definition NIVisumTL.h:118
NBConnectionVector & connections()
Returns the connections vector.
Definition NIVisumTL.h:113
Intermediate class for storing visum traffic lights during their import.
Definition NIVisumTL.h:41
std::map< std::string, Phase * > & getPhases()
Returns the map of named phases.
Definition NIVisumTL.h:159
SignalGroup & getSignalGroup(const std::string &name)
Returns the named signal group.
Definition NIVisumTL.cpp:66
const std::string & getID() const
Returns the id.
Definition Named.h:73
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).
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String).
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool).
static OptionsCont & getOptions()
Retrieves the options.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
A list of positions.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
PositionVector reverse() const
reverse position vector
std::vector< std::string > getVector()
return vector of strings
static long long int toLong(const std::string &sData)
converts a string into the long value described by it by calling the char-type converter,...
static std::string to_lower_case(const std::string &str)
Transfers the content to lower case.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static std::string latin1_to_utf8(std::string str)
Transfers from Latin 1 (ISO-8859-1) to UTF-8.
static bool endsWith(const std::string &str, const std::string suffix)
Checks whether a given string ends with the suffix.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
*brief user defined string literal for JSON values *sa std::size_t n
Definition json.hpp:21899
A complete call description for parsing a single db.
ParsingFunction function
Pointer to the function used for parsing.
std::string name
The name of the db.
long position
Position of the according db within the file.
Definition of a storage for vsystypes.
bijection entry