Eclipse SUMO - Simulation of Urban MObility
NIImporter_Vissim.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-2024 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 // -------------------
23 /****************************************************************************/
24 #include <config.h>
25 
26 
27 #include <string>
28 #include <fstream>
33 #include <netbuild/NBNetBuilder.h>
34 #include "NIImporter_Vissim.h"
90 
91 
92 #include "tempstructs/NIVissimTL.h"
105 
107 #include <utils/xml/XMLSubSys.h>
112 
113 #include <netbuild/NBEdgeCont.h> // !!! only for debugging purposes
114 
115 
116 // ===========================================================================
117 // static variables
118 // ===========================================================================
127  { "linkPolyPoint", NIImporter_Vissim::VISSIM_TAG_LINKPOLYPOINT },
129  { "fromLinkEndPt", NIImporter_Vissim::VISSIM_TAG_FROM },
130  { "toLinkEndPt", NIImporter_Vissim::VISSIM_TAG_TO },
134  { "intObjectRef", NIImporter_Vissim::VISSIM_TAG_INTOBJECTREF },
135  { "desSpeedDecision", NIImporter_Vissim::VISSIM_TAG_SPEED_DECISION },
136  {
137  "desSpeedDistribution",
139  },
140  {
141  "speedDistributionDataPoint",
143  },
144  {
145  "vehicleRoutingDecisionStatic",
147  },
148  {
149  "vehicleRouteStatic",
151  },
152  { "conflictArea", NIImporter_Vissim::VISSIM_TAG_CA },
154 };
155 
156 
158  { "no", NIImporter_Vissim::VISSIM_ATTR_NO }, //id
170  { "intLink", NIImporter_Vissim::VISSIM_ATTR_INTLINK }, //edgeID
182 };
183 
184 
185 // ===========================================================================
186 // method definitions
187 // ===========================================================================
188 // ---------------------------------------------------------------------------
189 // static methods (interface in this case)
190 // ---------------------------------------------------------------------------
191 void
193  if (!oc.isSet("vissim-file")) {
194  return;
195  }
196  NIImporter_Vissim(nb).load(oc);
197 }
198 
199 
200 // ---------------------------------------------------------------------------
201 // definitions of NIVissimXMLHandler_Streckendefinition-methods
202 // ---------------------------------------------------------------------------
204  //std::map<int, VissimXMLEdge>& toFill)
205  nodeMap& elemData)
206  : GenericSAXHandler(vissimTags, VISSIM_TAG_NOTHING,
207  vissimAttrs, VISSIM_ATTR_NOTHING,
208  "vissim - file"),
209  myElemData(elemData),
210  myHierarchyLevel(0),
211  isConnector(false) {
212  myElemData.clear();
213 }
214 
216 
217 void
219  myHierarchyLevel++;
220 
221  // finding an actual LINK
222  if (element == VISSIM_TAG_LINK) {
223  //parse all links
224  bool ok = true;
225  int id = attrs.get<int>(VISSIM_ATTR_NO, nullptr, ok);
226  myLastNodeID = id;
227 
228  // !!! assuming empty myElemData
229  myElemData["id"].push_back(attrs.get<std::string>(VISSIM_ATTR_NO, nullptr, ok));
230  // error ignored if name is empty
231  myElemData["name"].push_back(attrs.get<std::string>(VISSIM_ATTR_NAME, nullptr, ok, false));
232  myElemData["type"].push_back(attrs.get<std::string>(VISSIM_ATTR_LINKBEHAVETYPE, nullptr, ok));
233  myElemData["zuschlag1"].push_back(attrs.get<std::string>(VISSIM_ATTR_ZUSCHLAG1, nullptr, ok));
234  myElemData["zuschlag2"].push_back(attrs.get<std::string>(VISSIM_ATTR_ZUSCHLAG2, nullptr, ok));
235  }
236 
237  if (element == VISSIM_TAG_LANE) {
238  bool ok = true;
239  // appends empty element if no width found
240  // error ignored if name is empty
241  myElemData["width"].push_back(attrs.get<std::string>(VISSIM_ATTR_WIDTH, nullptr, ok, false));
242  }
243 
244  if (element == VISSIM_TAG_FROM) {
245  if (isConnector != true) {
246  isConnector = true;
247  }
248  bool ok = true;
249  std::vector<std::string> from(StringTokenizer(attrs.get<std::string>(
250  VISSIM_ATTR_LANE, nullptr, ok), " ").getVector());
251  myElemData["from_pos"].push_back(attrs.get<std::string>(VISSIM_ATTR_POS, nullptr, ok));
252  myElemData["from_id"].push_back(from[0]);
253  myElemData["from_lane"].push_back(from[1]);
254  }
255 
256  if (element == VISSIM_TAG_TO) {
257  bool ok = true;
258  std::vector<std::string> to(StringTokenizer(attrs.get<std::string>(
259  VISSIM_ATTR_LANE, nullptr, ok), " ").getVector());
260  myElemData["to_pos"].push_back(attrs.get<std::string>(VISSIM_ATTR_POS, nullptr, ok));
261  myElemData["to_id"].push_back(to[0]);
262  myElemData["to_lane"].push_back(to[1]);
263  }
264 
265  if (element == VISSIM_TAG_POINT3D || element == VISSIM_TAG_LINKPOLYPOINT) {
266  bool ok = true;
267  // create a <sep> separated string of coordinate data
268  std::string sep(" ");
269 
270  std::string posS(attrs.get<std::string>(VISSIM_ATTR_X, nullptr, ok));
271  posS += sep;
272  posS.append(attrs.get<std::string>(VISSIM_ATTR_Y, nullptr, ok));
273  // allow for no Z
274  std::string z(attrs.get<std::string>(VISSIM_ATTR_ZOFFSET, nullptr, ok, false));
275  if (z.length() > 0) {
276  posS += sep;
277  posS.append(z);
278  }
279  myElemData["pos"].push_back(posS);
280  }
281 
282 
283 }
284 
285 void
287  if (element == VISSIM_TAG_LINK && myHierarchyLevel == 3) {
288  //std::cout << "elemData len:" << myElemData.size() << std::endl;
289 
290  NIVissimClosedLanesVector clv; //FIXME -> clv einlesen
291  std::vector<int> assignedVehicles; //FIXME -> assignedVehicles einlesen
292  int id(StringUtils::toInt(myElemData["id"].front()));
293 
294  PositionVector geom;
295  // convert all position coordinate strings to PositionVectors
296  while (!myElemData["pos"].empty()) {
297  std::vector<std::string> sPos_v(StringTokenizer(
298  myElemData["pos"].front(), " ").getVector());
299  myElemData["pos"].pop_front();
300  std::vector<double> pos_v(3);
301 
302  // doing a transform with explicit hint on function signature
303  std::transform(sPos_v.begin(), sPos_v.end(), pos_v.begin(),
305  geom.push_back_noDoublePos(Position(pos_v[0], pos_v[1], pos_v[2]));
306  }
307  // FIXME: a length = 0 PosVec seems fatal -> segfault
308  double length(geom.length());
309 
310  if (!isConnector) {
311  // Add Edge
312  std::vector<double> laneWidths;
313  for (std::string& w : myElemData["width"]) {
314  laneWidths.push_back(StringUtils::toDouble(w));
315  }
316  NIVissimEdge* edge = new NIVissimEdge(id,
317  myElemData["name"].front(),
318  myElemData["type"].front(),
319  laneWidths,
320  StringUtils::toDouble(myElemData["zuschlag1"].front()),
321  StringUtils::toDouble(myElemData["zuschlag2"].front()),
322  length, geom, clv);
323  NIVissimEdge::dictionary(id, edge);
324  } else {
325  int numLanes = (int)myElemData["width"].size();
326  std::vector<int> laneVec(numLanes);
327  // Add Connector
328 
329  //NOTE: there should be only 1 lane number in XML
330  // subtraction of 1 as in readExtEdgePointDef()
331  laneVec[0] = StringUtils::toInt(myElemData["from_lane"].front()) - 1;
332  // then count up, building lane number vector
333  for (std::vector<int>::iterator each = ++laneVec.begin(); each != laneVec.end(); ++each) {
334  *each = *(each - 1) + 1;
335  }
336 
337  NIVissimExtendedEdgePoint from_def(
338  StringUtils::toInt(myElemData["from_id"].front()),
339  laneVec,
340  StringUtils::toDouble(myElemData["from_pos"].front()),
341  assignedVehicles);
342 
343  //NOTE: there should be only 1 lane number in XML
344  // subtraction of 1 as in readExtEdgePointDef()
345  laneVec[0] = StringUtils::toInt(myElemData["to_lane"].front()) - 1;
346  // then count up, building lane number vector
347  for (std::vector<int>::iterator each = ++laneVec.begin(); each != laneVec.end(); ++each) {
348  *each = *(each - 1) + 1;
349  }
350 
352  StringUtils::toInt(myElemData["to_id"].front()),
353  laneVec,
354  StringUtils::toDouble(myElemData["to_pos"].front()),
355  assignedVehicles);
356 
357  NIVissimConnection* connector = new
359  myElemData["name"].front(),
360  from_def, to_def,
361  geom, assignedVehicles, clv);
362 
363  NIVissimConnection::dictionary(id, connector);
364  }
365  // clear the element data
366  myElemData.clear();
367  isConnector = false;
368  //std::cout << "elemData len (clear):" << myElemData.size() << std::endl;
369  //std::cout.flush();
370 
371  }
372  --myHierarchyLevel;
373 }
374 
375 
376 // ---------------------------------------------------------------------------
377 // definitions of NIVissimXMLHandler_Zuflussdefinition-methods
378 // ---------------------------------------------------------------------------
382  "vissim - file") {
383 }
384 
386 
387 void
389  // finding an actual flow
390  if (element == VISSIM_TAG_VEHICLE_INPUT) {
391  //parse all flows
392  bool ok = true;
393  std::string id = attrs.get<std::string>(VISSIM_ATTR_NO, nullptr, ok);
394  std::string edgeid = attrs.get<std::string>(VISSIM_ATTR_LINK, nullptr, ok);
395  std::string name = attrs.get<std::string>(VISSIM_ATTR_NAME, nullptr, ok, false);
396 
398  name,
399  edgeid);
400  }
401 }
402 
403 // ---------------------------------------------------------------------------
404 // definitions of NIVissimXMLHandler_Parkplatzdefinition-methods
405 // ---------------------------------------------------------------------------
409  "vissim - file") {
410 }
411 
413 
414 void
416  // finding an actual parkinglot
417  if (element == VISSIM_TAG_PARKINGLOT) {
418  //parse all parkinglots
419  bool ok = true;
420  int id = attrs.get<int>(VISSIM_ATTR_NO, nullptr, ok);
421  int edgeid = attrs.get<int>(VISSIM_ATTR_INTLINK, nullptr, ok);
422  std::string name = attrs.get<std::string>(VISSIM_ATTR_NAME, nullptr, ok, false);
423  double position = attrs.get<double>(VISSIM_ATTR_POS, nullptr, ok);
424  std::vector<std::pair<int, int> > assignedVehicles; // (vclass, vwunsch)
425  //FIXME: vWunsch + Fahzeugklassen einlesen
426  // There can be s
427  std::vector<int> districts;
428  //FIXME: Parkplatzdefinition für mehrere Zonen implementieren
429  std::vector<double> percentages;
430  districts.push_back(attrs.get<int>(VISSIM_ATTR_DISTRICT, nullptr, ok));
431  percentages.push_back(attrs.get<double>(VISSIM_ATTR_PERCENTAGE, nullptr, ok));
432 
434  name,
435  districts,
436  percentages,
437  edgeid,
438  position,
439  assignedVehicles);
440  }
441 }
442 
443 
444 // ---------------------------------------------------------------------------
445 // definitions of NIVissimXMLHandler_Fahrzeugklassendefinition-methods
446 // ---------------------------------------------------------------------------
450  "vissim - file"),
451  myElemData(elemData),
452  myHierarchyLevel(0) {
453  myElemData.clear();
454 }
455 
457 
458 void
460  myHierarchyLevel++;
461 
462  if (element == VISSIM_TAG_VEHICLE_CLASS) {
463  bool ok = true;
464  myElemData["id"].push_back(attrs.get<std::string>(VISSIM_ATTR_NO, nullptr, ok));
465  myElemData["name"].push_back(attrs.get<std::string>(VISSIM_ATTR_NAME, nullptr, ok, false));
466  std::string colorStr(attrs.get<std::string>(VISSIM_ATTR_COLOR, nullptr, ok));
467  for (int pos = (int)colorStr.size() - 2; pos > 0; pos -= 2) {
468  colorStr.insert(pos, " ");
469  }
470  myElemData["color"].push_back(colorStr);
471  }
472  if (element == VISSIM_TAG_INTOBJECTREF) {
473  bool ok = true;
474  myElemData["types"].push_back(attrs.get<std::string>(VISSIM_ATTR_KEY, nullptr, ok));
475 
476 
477  }
478 }
479 
480 void
482  if (element == VISSIM_TAG_VEHICLE_CLASS && myHierarchyLevel == 3) {
483  RGBColor color;
484  std::istringstream iss(myElemData["color"].front());
485  std::vector<std::string> sCol_v(StringTokenizer(
486  myElemData["color"].front(), " ").getVector());
487  std::vector<int> myColorVector(sCol_v.size());
488  std::transform(sCol_v.begin(), sCol_v.end(), myColorVector.begin(), StringUtils::hexToInt);
489 
490  color = RGBColor((unsigned char)myColorVector[0],
491  (unsigned char)myColorVector[1],
492  (unsigned char)myColorVector[2],
493  (unsigned char)myColorVector[3]);
494  std::vector<int> types;
495  while (!myElemData["types"].empty()) {
496  types.push_back(StringUtils::toInt(myElemData["types"].front()));
497  myElemData["types"].pop_front();
498  }
499 
500  NIVissimVehTypeClass::dictionary(StringUtils::toInt(myElemData["id"].front()),
501  myElemData["name"].front(),
502  color,
503  types);
504  myElemData.clear();
505  }
506  --myHierarchyLevel;
507 }
508 
509 // ---------------------------------------------------------------------------
510 // definitions of NIVissimXMLHandler_Geschwindigkeitsverteilungsdefinition-methods
511 // ---------------------------------------------------------------------------
515  "vissim - file"),
516  myElemData(elemData),
517  myHierarchyLevel(0) {
518  myElemData.clear();
519 }
520 
522 
523 void
525  myHierarchyLevel++;
526  if (element == VISSIM_TAG_SPEED_DIST) {
527  bool ok = true;
528  myElemData["id"].push_back(attrs.get<std::string>(VISSIM_ATTR_NO, nullptr, ok));
529  }
530 
531  if (element == VISSIM_TAG_DATAPOINT) {
532  bool ok = true;
533  std::string sep(" ");
534  std::string posS(attrs.get<std::string>(VISSIM_ATTR_X, nullptr, ok));
535  posS += sep;
536  posS.append(attrs.get<std::string>(VISSIM_ATTR_FX, nullptr, ok));
537  myElemData["points"].push_back(posS);
538 
539  }
540 
541 }
542 
543 void
545  if (element == VISSIM_TAG_SPEED_DIST && myHierarchyLevel == 3) {
546  Distribution_Points* points = new Distribution_Points(myElemData["id"].front());
547  while (!myElemData["points"].empty()) {
548  std::vector<std::string> sPos_v(StringTokenizer(
549  myElemData["points"].front(), " ").getVector());
550  myElemData["points"].pop_front();
551  points->add(StringUtils::toDouble(sPos_v[0]), StringUtils::toDouble(sPos_v[1]));
552  }
553  DistributionCont::dictionary("speed", myElemData["id"].front(), points);
554  myElemData.clear();
555  }
556  --myHierarchyLevel;
557 }
558 
559 // ---------------------------------------------------------------------------
560 // definitions of NIVissimXMLHandler_VWunschentscheidungsdefinition-methods
561 // ---------------------------------------------------------------------------
565  "vissim - file"),
566  myElemData(elemData),
567  myHierarchyLevel(0) {
568  myElemData.clear();
569 }
570 
572 
573 void
575  myHierarchyLevel++;
576  if (element == VISSIM_TAG_SPEED_DECISION) {
577  bool ok = true;
578  myElemData["name"].push_back(attrs.get<std::string>(VISSIM_ATTR_NAME, nullptr, ok, false));
579  //FIXME: 2 vWunsch in the xml file, but only 1 of them is set???
580  }
581 
582 }
583 
584 void
586  --myHierarchyLevel;
587 }
588 
589 
590 // ---------------------------------------------------------------------------
591 // definitions of NIVissimXMLHandler_Routenentscheidungsdefinition-methods
592 // ---------------------------------------------------------------------------
596  "vissim - file"),
597  myElemData(elemData),
598  myHierarchyLevel(0) {
599  myElemData.clear();
600 }
601 
603 
604 void
606  myHierarchyLevel++;
607  if (element == VISSIM_TAG_DECISION_STATIC) {
608  bool ok = true;
609  myElemData["startLink"].push_back(attrs.get<std::string>(VISSIM_ATTR_LINK, nullptr, ok));
610  myElemData["startPos"].push_back(attrs.get<std::string>(VISSIM_ATTR_POS, nullptr, ok));
611  }
612  if (element == VISSIM_TAG_ROUTE_STATIC) {
613  bool ok = true;
614  myElemData["destLink"].push_back(attrs.get<std::string>(VISSIM_ATTR_DESTLINK, nullptr, ok));
615  myElemData["destPos"].push_back(attrs.get<std::string>(VISSIM_ATTR_DESTPOS, nullptr, ok));
616  myElemData["id"].push_back(attrs.get<std::string>(VISSIM_ATTR_NO, nullptr, ok));
617  }
618  if (element == VISSIM_TAG_INTOBJECTREF) {
619  // bool ok = true;
620  }
621 
622 }
623 
624 void
626  --myHierarchyLevel;
627 }
628 
629 // ---------------------------------------------------------------------------
630 // definitions of NIVissimXMLHandler_ConflictArea-methods
631 // ---------------------------------------------------------------------------
635  "vissim - file") {}
636 
638 
639 void
641  // finding an actual flow
642  if (element == VISSIM_TAG_CA) {
643  //parse all flows
644  bool ok = true;
645  std::string status = attrs.get<std::string>(VISSIM_ATTR_STATUS, nullptr, ok);
646  //get only the conflict areas which were set in VISSIM
647  if (status != "PASSIVE") {
648  NIVissimConflictArea::dictionary(attrs.get<int>(VISSIM_ATTR_NO, nullptr, ok),
649  attrs.get<std::string>(VISSIM_ATTR_LINK1, nullptr, ok),
650  attrs.get<std::string>(VISSIM_ATTR_LINK2, nullptr, ok),
651  status);
652  }
653 
654  }
655 }
656 
657 
658 /* -------------------------------------------------------------------------
659  * NIImporter_Vissim::VissimSingleTypeParser-methods
660  * ----------------------------------------------------------------------- */
662  : myVissimParent(parent) {}
663 
664 
666 
667 
668 std::string
670  std::string tmp;
671  from >> tmp;
672  return StringUtils::to_lower_case(tmp);
673 }
674 
675 
676 
677 std::string
679  const std::string& excl) {
680  std::string myExcl = StringUtils::to_lower_case(excl);
681  std::string tmp = myRead(from);
682  if (tmp == "") {
683  return "DATAEND";
684  }
685  if (tmp != myExcl
686  &&
687  (tmp.substr(0, 2) == "--" || !myVissimParent.admitContinue(tmp))
688  ) {
689  return "DATAEND";
690  }
691  return StringUtils::to_lower_case(tmp);
692 }
693 
694 
695 std::string
697  const std::vector<std::string>& excl) {
698  std::vector<std::string> myExcl;
699  std::vector<std::string>::const_iterator i;
700  for (i = excl.begin(); i != excl.end(); i++) {
701  std::string mes = StringUtils::to_lower_case(*i);
702  myExcl.push_back(mes);
703  }
704  std::string tmp = myRead(from);
705  if (tmp == "") {
706  return "DATAEND";
707  }
708 
709  bool equals = false;
710  for (i = myExcl.begin(); i != myExcl.end() && !equals; i++) {
711  if ((*i) == tmp) {
712  equals = true;
713  }
714  }
715  if (!equals
716  &&
717  (tmp.substr(0, 2) == "--" || !myVissimParent.admitContinue(tmp))
718  ) {
719  return "DATAEND";
720  }
721  return StringUtils::to_lower_case(tmp);
722 }
723 
724 
725 std::string
727  const std::string& tag) {
728  std::string tmp;
729  if (tag == "") {
730  tmp = myRead(from);
731  } else {
732  tmp = tag;
733  }
734  if (tmp == "beschriftung") {
735  tmp = myRead(from);
736  if (tmp == "keine") {
737  from >> tmp;
738  }
739  tmp = myRead(from);
740  tmp = myRead(from);
741  }
742  return tmp;
743 }
744 
745 
746 Position
748  double x, y;
749  from >> x; // type-checking is missing!
750  from >> y; // type-checking is missing!
751  return Position(x, y);
752 }
753 
754 
755 std::vector<int>
757  std::istream& from, const std::string& next) {
758  std::string tmp = readEndSecure(from);
759  std::vector<int> ret;
760  if (tmp == "alle") {
761  ret.push_back(-1);
762  return ret;
763  }
764  while (tmp != "DATAEND" && tmp != next) {
765  ret.push_back(StringUtils::toInt(tmp));
766  tmp = readEndSecure(from);
767  }
768  return ret;
769 }
770 
771 
774  std::istream& from) {
775  std::string tag;
776  from >> tag; // "Strecke"
777  int edgeid;
778  from >> edgeid; // type-checking is missing!
779  from >> tag; // "Spuren"
780  std::vector<int> lanes;
781  while (tag != "bei") {
782  tag = readEndSecure(from);
783  if (tag != "bei") {
784  int lane = StringUtils::toInt(tag);
785  lanes.push_back(lane - 1);
786  }
787  }
788  double position;
789  from >> position;
790  std::vector<int> dummy;
791  return NIVissimExtendedEdgePoint(edgeid, lanes, position, dummy);
792 }
793 
794 
795 std::string
797  std::string name;
798  from >> name;
799  if (name[0] == '"') {
800  while (name[name.length() - 1] != '"') {
801  std::string tmp;
802  from >> tmp;
803  name = name + " " + tmp;
804  }
805  name = name.substr(1, name.length() - 2);
806  }
807  return StringUtils::convertUmlaute(name);
808 }
809 
810 
811 void
813  const std::string& name) {
814  std::string tag;
815  while (tag != name) {
816  tag = myRead(from);
817  }
818 }
819 
820 bool
822  const std::string& name) {
823  std::string tag;
824  while (tag != name) {
825  tag = myRead(from);
826  }
827  while (tag != "DATAEND") {
828  tag = readEndSecure(from);
829  }
830  return true;
831 }
832 
833 
834 
835 /* -------------------------------------------------------------------------
836  * NIImporter_Vissim-methods
837  * ----------------------------------------------------------------------- */
840  buildParsers();
841  myColorMap["blau"] = RGBColor(77, 77, 255, 255);
842  myColorMap["gelb"] = RGBColor::YELLOW;
843  myColorMap["grau"] = RGBColor::GREY;
844  myColorMap["lila"] = RGBColor::MAGENTA;
845  myColorMap["gruen"] = RGBColor::GREEN;
846  myColorMap["rot"] = RGBColor::RED;
847  myColorMap["schwarz"] = RGBColor::BLACK;
848  myColorMap["tuerkis"] = RGBColor::CYAN;
849  myColorMap["weiss"] = RGBColor::WHITE;
850  myColorMap["keine"] = RGBColor::WHITE;
851 }
852 
853 
854 
855 
875  for (ToParserMap::iterator i = myParsers.begin(); i != myParsers.end(); i++) {
876  delete (*i).second;
877  }
878 }
879 
880 
881 void
883  const std::string file = options.getString("vissim-file");
884  // try to open the file
885  std::ifstream strm(file.c_str());
886  if (!strm.good()) {
887  WRITE_ERRORF(TL("Could not open vissim-file '%'."), file);
888  return;
889  }
890  std::string token;
891  strm >> token;
892  if (StringUtils::endsWith(file, ".inpx") || StringUtils::endsWith(token, "<?xml") || StringUtils::endsWith(token, "<network")) {
893  // Create NIVissimXMLHandlers
894  NIVissimXMLHandler_Streckendefinition XMLHandler_Streckendefinition(elementData);
895  NIVissimXMLHandler_Zuflussdefinition XMLHandler_Zuflussdefinition;
896  //NIVissimXMLHandler_Parkplatzdefinition XMLHandler_Parkplatzdefinition;
897  NIVissimXMLHandler_Fahrzeugklassendefinition XMLHandler_Fahrzeugklassendefinition(elementData);
898  NIVissimXMLHandler_Geschwindigkeitsverteilungsdefinition XMLHandler_Geschwindigkeitsverteilung(elementData);
899  NIVissimXMLHandler_ConflictArea XMLHandler_ConflictAreas;
900 
901  // Strecken + Verbinder
902  XMLHandler_Streckendefinition.setFileName(file);
903  PROGRESS_BEGIN_MESSAGE("Parsing strecken+verbinder from vissim-file '" + file + "'");
904  if (!XMLSubSys::runParser(XMLHandler_Streckendefinition, file)) {
905  return;
906  }
908 
909  // Zuflüsse
910  XMLHandler_Zuflussdefinition.setFileName(file);
911  PROGRESS_BEGIN_MESSAGE("Parsing zuflüsse from vissim-file '" + file + "'");
912  if (!XMLSubSys::runParser(XMLHandler_Zuflussdefinition, file)) {
913  return;
914  }
916 
917  //Geschwindigkeitsverteilungen
918  XMLHandler_Geschwindigkeitsverteilung.setFileName(file);
919  PROGRESS_BEGIN_MESSAGE("Parsing parkplätze from vissim-file '" + file + "'");
920  if (!XMLSubSys::runParser(XMLHandler_Geschwindigkeitsverteilung, file)) {
921  return;
922  }
924 
925 
926  //Fahrzeugklassen
927  XMLHandler_Fahrzeugklassendefinition.setFileName(file);
928  PROGRESS_BEGIN_MESSAGE("Parsing parkplätze from vissim-file '" + file + "'");
929  if (!XMLSubSys::runParser(XMLHandler_Fahrzeugklassendefinition, file)) {
930  return;
931  }
933 
934  //Parkplätze
935  /*XMLHandler_Parkplatzdefinition.setFileName(file);
936  PROGRESS_BEGIN_MESSAGE("Parsing parkplätze from vissim-file '" + file + "'");
937  if (!XMLSubSys::runParser(XMLHandler_Parkplatzdefinition, file)) {
938  return;
939  }
940  PROGRESS_DONE_MESSAGE();*/
941 
942 
943  //Konfliktflächen
944  XMLHandler_ConflictAreas.setFileName(file);
945  PROGRESS_BEGIN_MESSAGE("Parsing conflict areas from vissim-file '" + file + "'");
946  if (!XMLSubSys::runParser(XMLHandler_ConflictAreas, file)) {
947  return;
948  }
950  } else {
951  strm.seekg(strm.beg);
952  if (!readContents(strm)) {
953  return;
954  }
955  }
956  postLoadBuild(options.getFloat("vissim.join-distance"));
957 }
958 
959 
960 bool
961 NIImporter_Vissim::admitContinue(const std::string& tag) {
962  ToElemIDMap::const_iterator i = myKnownElements.find(tag);
963  if (i == myKnownElements.end()) {
964  return true;
965  }
966  myLastSecure = tag;
967  return false;
968 }
969 
970 
971 bool
972 NIImporter_Vissim::readContents(std::istream& strm) {
973  // read contents
974  bool ok = true;
975  while (strm.good() && ok) {
976  std::string tag;
977  if (myLastSecure != "") {
978  tag = myLastSecure;
979  } else {
980  strm >> tag;
981  }
982  myLastSecure = "";
983  bool parsed = false;
984  while (!parsed && strm.good() && ok) {
985  ToElemIDMap::iterator i = myKnownElements.find(StringUtils::to_lower_case(tag));
986  if (i != myKnownElements.end()) {
987  ToParserMap::iterator j = myParsers.find((*i).second);
988  if (j != myParsers.end()) {
989  VissimSingleTypeParser* parser = (*j).second;
990  ok = parser->parse(strm);
991  parsed = true;
992  }
993  }
994  if (!parsed) {
995  std::string line;
996  std::streamoff pos;
997  do {
998  pos = strm.tellg();
999  getline(strm, line);
1000  } while (strm.good() && (line == "" || line[0] == ' ' || line[0] == '-'));
1001  if (!strm.good()) {
1002  return true;
1003  }
1004  strm.seekg(pos);
1005  strm >> tag;
1006  }
1007  }
1008  }
1009  return ok;
1010 }
1011 
1012 
1013 void
1015  // close the loading process
1019  // build district->connections map
1021  // build clusters around nodes
1022 // NIVissimNodeDef::buildNodeClusters();
1023  // build node clusters around traffic lights
1024 // NIVissimTL::buildNodeClusters();
1025 
1026  // when connections or disturbances are left, build nodes around them
1027 
1028  // try to assign connection clusters to nodes
1029  // only left connections will be processed in
1030  // buildConnectionClusters & join
1031 //30.4. brauchen wir noch! NIVissimNodeDef::dict_assignConnectionsToNodes();
1032 
1033  // build clusters of connections with the same direction and a similar position along the streets
1035  // check whether further nodes (connection clusters by now) must be added
1037 
1038  // join clusters when overlapping (different streets are possible)
1041 // NIVissimConnectionCluster::joinByDisturbances(offset);
1042 
1043 // NIVissimConnectionCluster::addTLs(offset);
1044 
1045  // build nodes from clusters
1048 
1049 // NIVissimNodeCluster::dict_recheckEdgeChanges();
1055  if (OptionsCont::getOptions().getBool("vissim.report-unset-speeds")) {
1057  }
1063 }
1064 
1065 
1066 void
1068  myKnownElements["kennung"] = VE_Kennungszeile;
1069  myKnownElements["zufallszahl"] = VE_Startzufallszahl;
1070  myKnownElements["simulationsdauer"] = VE_Simdauer;
1071  myKnownElements["startuhrzeit"] = VE_Startuhrzeit;
1072  myKnownElements["simulationsrate"] = VE_SimRate;
1073  myKnownElements["zeitschritt"] = VE_Zeitschrittfaktor;
1074  myKnownElements["linksverkehr"] = VE_Linksverkehr;
1075  myKnownElements["dynuml"] = VE_DynUml;
1077  myKnownElements["gelbverhalten"] = VE_Gelbverhaltendefinition;
1079  myKnownElements["verbindung"] = VE_Verbindungsdefinition;
1080  myKnownElements["richtungsentscheidung"] = VE_Richtungsentscheidungsdefinition;
1081  myKnownElements["routenentscheidung"] = VE_Routenentscheidungsdefinition;
1082  myKnownElements["vwunschentscheidung"] = VE_VWunschentscheidungsdefinition;
1083  myKnownElements["langsamfahrbereich"] = VE_Langsamfahrbereichdefinition;
1085  myKnownElements["fahrzeugtyp"] = VE_Fahrzeugtypdefinition;
1086  myKnownElements["fahrzeugklasse"] = VE_Fahrzeugklassendefinition;
1096  myKnownElements["wunschbeschleunigung"] = VE_Wunschbeschleunigungskurvedefinition;
1099  myKnownElements["querverkehrsstoerung"] = VE_Querverkehrsstoerungsdefinition;
1101  myKnownElements["signalgruppe"] = VE_Signalgruppendefinition;
1102  myKnownElements["signalgeber"] = VE_Signalgeberdefinition;
1103  myKnownElements["lsakopplung"] = VE_LSAKopplungdefinition;
1105  myKnownElements["haltestelle"] = VE_Haltestellendefinition;
1107  myKnownElements["stopschild"] = VE_Stopschilddefinition;
1111  myKnownElements["querschnittsmessung"] = VE_Querschnittsmessungsdefinition;
1112  myKnownElements["stauzaehler"] = VE_Stauzaehlerdefinition;
1113  myKnownElements["auswertung"] = VE_Auswertungsdefinition;
1116  myKnownElements["parkplatz"] = VE_Parkplatzdefinition;
1119  myKnownElements["netzobjekt"] = VE_Netzobjektdefinition;
1120  myKnownElements["richtungspfeil"] = VE_Richtungspfeildefinition;
1122  myKnownElements["fahrverhalten"] = VE_Fahrverhaltendefinition;
1123  myKnownElements["fahrtverlaufdateien"] = VE_Fahrtverlaufdateien;
1124  myKnownElements["emission"] = VE_Emission;
1126  myKnownElements["streckentyp"] = VE_Streckentypdefinition;
1127  myKnownElements["kantensperrung"] = VE_Kantensperrung;
1129 
1130 
1131  myKnownElements["advance"] = VE_DUMMY;
1132  myKnownElements["temperatur"] = VE_DUMMY;
1133 
1134 }
1135 
1136 
1137 
1138 void
1144  myParsers[VE_DynUml] =
1218 
1261 
1262 }
1263 
1264 
1265 /****************************************************************************/
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define TL(string)
Definition: MsgHandler.h:315
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:300
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:299
std::vector< NIVissimClosedLaneDef * > NIVissimClosedLanesVector
@ VE_Richtungsentscheidungsdefinition
@ VE_Lichtsignalanlagendefinition
@ VE_LSAKopplungdefinition
@ VE_VWunschentscheidungsdefinition
@ VE_Leistungsverteilungsdefinition
@ VE_Fahrverhaltendefinition
@ VE_Auswertungsdefinition
@ VE_Geschwindigkeitsverteilungsdefinition
@ VE_Linksverkehr
@ VE_Messungsdefinition
@ VE_Wunschbeschleunigungskurvedefinition
@ VE_Verlustzeitmessungsdefinition
@ VE_Maxverzoegerungskurvedefinition
@ VE_Streckendefinition
@ VE_Simdauer
@ VE_Kennungszeile
@ VE_Startuhrzeit
@ VE_Querschnittsmessungsdefinition
@ VE_Stauzaehlerdefinition
@ VE_Netzobjektdefinition
@ VE_Stauparameterdefinition
@ VE_Kantensperrung
@ VE_Einheitendefinition
@ VE_Wunschverzoegerungskurvedefinition
@ VE_Liniendefinition
@ VE_TEAPACdefinition
@ VE_Verkehrszusammensetzungsdefinition
@ VE_Zuflussdefinition
@ VE_Detektorendefinition
@ VE_Rautedefinition
@ VE_Fensterdefinition
@ VE_Emission
@ VE_Routenentscheidungsdefinition
@ VE_Streckentypdefinition
@ VE_Baujahrverteilungsdefinition
@ VE_Fahrzeugklassendefinition
@ VE_Maxbeschleunigungskurvedefinition
@ VE_Reisezeitmessungsdefinition
@ VE_Signalgruppendefinition
@ VE_Massenverteilungsdefinition
@ VE_Laufleistungsverteilungsdefinition
@ VE_Gelbverhaltendefinition
@ VE_Querverkehrsstoerungsdefinition
@ VE_Fahrtverlaufdateien
@ VE_Startzufallszahl
@ VE_Verbindungsdefinition
@ VE_Haltestellendefinition
@ VE_Laengenverteilungsdefinition
@ VE_Signalgeberdefinition
@ VE_Fahrzeugtypdefinition
@ VE_Richtungspfeildefinition
@ VE_Stopschilddefinition
@ VE_Parkplatzdefinition
@ VE_Zeitschrittfaktor
@ VE_DynUml
@ VE_DUMMY
@ VE_Zeitenverteilungsdefinition
@ VE_Knotendefinition
@ VE_SimRate
@ VE_Langsamfahrbereichdefinition
@ VE_Gefahrenwarnsystemdefinition
static bool dictionary(const std::string &type, const std::string &id, Distribution *d)
Adds a distribution of the given type and name to the container.
A handler which converts occurring elements and attributes into enums.
void setFileName(const std::string &name)
Sets the current file name.
Instance responsible for building networks.
Definition: NBNetBuilder.h:107
NBDistrictCont & getDistrictCont()
Returns a reference the districts container.
Definition: NBNetBuilder.h:159
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:139
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Definition: NBNetBuilder.h:144
NBTrafficLightLogicCont & getTLLogicCont()
Returns a reference to the traffic light logics container.
Definition: NBNetBuilder.h:154
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
NIVissimXMLHandler_Streckendefinition(nodeMap &elemData)
Constructor.
void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void myEndElement(int element)
Callback method for a closing tag to implement by derived classes.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
VissimSingleTypeParser(NIImporter_Vissim &parent)
Constructor.
Position getPosition(std::istream &from)
returns the 2d-position saved as next within the stream
std::string readEndSecure(std::istream &from, const std::string &excl="")
as myRead, but returns "DATAEND" when the current field has ended
NIVissimExtendedEdgePoint readExtEdgePointDef(std::istream &from)
std::vector< int > parseAssignedVehicleTypes(std::istream &from, const std::string &next)
parses a listof vehicle types assigned to the current data field One should remeber,...
std::string readName(std::istream &from)
Reads the structures name We cannot use the "<<" operator, as names may contain more than one word wh...
virtual bool parse(std::istream &from)=0
Parses a single data type. Returns whether no error occurred.
void readUntil(std::istream &from, const std::string &name)
Reads from the stream until the keywor occurs.
bool skipOverreading(std::istream &from, const std::string &name="")
Overreads the named parameter (if) given and skips the rest until "DATAEND".
std::string overrideOptionalLabel(std::istream &from, const std::string &tag="")
overrides the optional label definition; returns the next tag as done by readEndSecure
std::string myRead(std::istream &from)
reads from the stream and returns the lower case version of the read value
Importer for networks stored in Vissim format.
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads network definition from the assigned option and stores it in the given network builder.
~NIImporter_Vissim()
destructor
std::map< std::string, std::list< std::string > > nodeMap
void buildParsers()
adds id-to-parser - relationships of elements to parse into myParsers
static StringBijection< int >::Entry vissimTags[]
The names of VISSIM-XML elements (for passing to GenericSAXHandler)
bool admitContinue(const std::string &tag)
static StringBijection< int >::Entry vissimAttrs[]
The names of VISSIM-XML attributes (for passing to GenericSAXHandler)
ColorMap myColorMap
a map from color names to color definitions
ToElemIDMap myKnownElements
Map from element names to their numerical representation.
void postLoadBuild(double offset)
void insertKnownElements()
adds name-to-id - relationships of known elements into myKnownElements
std::string myLastSecure
bool readContents(std::istream &strm)
ToParserMap myParsers
Parsers by element id.
NIImporter_Vissim(NBNetBuilder &nb)
constructor
NBNetBuilder & myNetBuilder
void load(const OptionsCont &options)
loads the vissim file
static void clearDict()
static bool dictionary(int id, const std::string &link1, const std::string &link2, const std::string &status)
Adds the described item to the dictionary Builds the conflict area first.
static void setPriorityRegulation(NBEdgeCont &ec)
Sets the priority regulation according to the VISSIM conflict area data.
static void clearDict()
Clears the dictionary.
static void joinBySameEdges(double offset)
Tries to joind clusters participating within a node This is done by joining clusters which overlap.
static void dict_buildNBEdgeConnections(NBEdgeCont &ec)
static void dict_assignToEdges()
static bool dictionary(int id, NIVissimConnection *o)
static void dict_BuildDistricts(NBDistrictCont &dc, NBEdgeCont &ec, NBNodeCont &nc)
Builds the districts.
static void dict_BuildDistrictNodes(NBDistrictCont &dc, NBNodeCont &nc)
Builds the nodes that belong to a district.
static void clearDict()
Clears the dictionary.
static bool dictionary(int id, const std::string &name, const std::vector< int > &districts, const std::vector< double > &percentages, int edgeid, double position, const std::vector< std::pair< int, int > > &assignedVehicles)
Inserts the connection into the dictionary after building it.
static void dict_SetDisturbances()
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:51
static void reportUnsetSpeeds()
Writes edges with unset speeds to the warnings message log instance.
static void dict_checkEdges2Join()
static void buildConnectionClusters()
Clusters connections of each edge.
static void dict_buildNBEdges(NBDistrictCont &dc, NBNodeCont &nc, NBEdgeCont &ec, double offset)
Builds NBEdges from the VissimEdges within the dictionary.
static void dict_propagateSpeeds()
static bool dictionary(int id, const std::string &name, const std::string &type, int noLanes, double zuschlag1, double zuschlag2, double length, const PositionVector &geom, const NIVissimClosedLanesVector &clv)
Adds the described item to the dictionary Builds the edge first.
static void setCurrentVirtID(int id)
static void dict_addDisturbances(NBDistrictCont &dc, NBNodeCont &nc, NBEdgeCont &ec)
static void buildNBNodes(NBNodeCont &nc)
static void clearDict()
static int getMaxID()
static void clearDict()
static bool dictionary(const std::string &id, const std::string &name, const std::string &edgeid)
static bool dict_SetSignals(NBTrafficLightLogicCont &tlc, NBEdgeCont &ec)
Definition: NIVissimTL.cpp:355
static void clearDict()
Definition: NIVissimTL.cpp:343
static bool dictionary(int id, const std::string &name, const RGBColor &color, std::vector< int > &types)
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)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
double length() const
Returns the length.
void push_back_noDoublePos(const Position &p)
insert in back a non double position
static const RGBColor WHITE
Definition: RGBColor.h:192
static const RGBColor GREY
Definition: RGBColor.h:194
static const RGBColor YELLOW
Definition: RGBColor.h:188
static const RGBColor CYAN
Definition: RGBColor.h:189
static const RGBColor GREEN
Definition: RGBColor.h:186
static const RGBColor BLACK
Definition: RGBColor.h:193
static const RGBColor MAGENTA
Definition: RGBColor.h:190
static const RGBColor RED
named colors
Definition: RGBColor.h:185
bool add(T val, double prob, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
Encapsulated SAX-Attributes.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
std::vector< std::string > getVector()
return vector of strings
static std::string to_lower_case(const std::string &str)
Transfers the content to lower case.
Definition: StringUtils.cpp:77
static int hexToInt(const std::string &sData)
converts a string with a hex value into the integer value described by it by calling the char-type co...
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 convertUmlaute(std::string str)
Converts german "Umlaute" to their latin-version.
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 runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false, const bool isExternal=false, const bool catchExceptions=true)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:148