SUMO - Simulation of Urban MObility
NIVissimEdge.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // A temporary storage for edges imported from Vissim
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <string>
34 #include <algorithm>
35 #include <map>
36 #include <cassert>
37 #include <iomanip>
38 #include <cmath>
39 #include <iostream>
40 #include <sstream>
41 #include <iterator>
42 #include <utils/common/ToString.h>
44 #include <utils/geom/GeomHelper.h>
46 #include <netbuild/NBNode.h>
47 #include <netbuild/NBNodeCont.h>
49 #include "NIVissimNodeCluster.h"
52 #include "NIVissimConnection.h"
53 #include "NIVissimDisturbance.h"
54 #include "NIVissimEdge.h"
56 
57 
58 // ===========================================================================
59 // static members
60 // ===========================================================================
62 int NIVissimEdge::myMaxID = 0;
63 std::vector<std::string> NIVissimEdge::myLanesWithMissingSpeeds;
64 
65 
66 // ===========================================================================
67 // method definitions
68 // ===========================================================================
70  : myEdgeID(edgeid) {}
71 
72 
73 int
75  int c2id) const {
78  double pos1 =
79  c1->getFromEdgeID() == myEdgeID
80  ? c1->getFromPosition() : c1->getToPosition();
81  double pos2 =
82  c2->getFromEdgeID() == myEdgeID
83  ? c2->getFromPosition() : c2->getToPosition();
84  return pos1 < pos2;
85 }
86 
87 
88 
89 
90 
91 
92 
93 
95  : myEdgeID(edgeid) {}
96 
97 
98 int
101  NIVissimConnectionCluster* cc2) const {
102  double pos1 = cc1->getPositionForEdge(myEdgeID);
103  double pos2 = cc2->getPositionForEdge(myEdgeID);
104  if (pos2 < 0 || pos1 < 0) {
107  }
108  assert(pos1 >= 0 && pos2 >= 0);
109  return pos1 < pos2;
110 }
111 
112 
113 
114 
115 NIVissimEdge::NIVissimEdge(int id, const std::string& name,
116  const std::string& type, int noLanes,
117  double zuschlag1, double zuschlag2,
118  double /*length*/, const PositionVector& geom,
119  const NIVissimClosedLanesVector& clv)
120  : NIVissimAbstractEdge(id, geom),
121  myName(name), myType(type), myNoLanes(noLanes),
122  myZuschlag1(zuschlag1), myZuschlag2(zuschlag2),
123  myClosedLanes(clv), myAmWithinJunction(false) { //, mySpeed(-1)
124  assert(noLanes >= 0);
125  if (myMaxID < myID) {
126  myMaxID = myID;
127  }
128  for (int i = 0; i < noLanes; i++) {
129  myLaneSpeeds.push_back(-1);
130  }
131 }
132 
133 
135  for (NIVissimClosedLanesVector::iterator i = myClosedLanes.begin(); i != myClosedLanes.end(); i++) {
136  delete(*i);
137  }
138  myClosedLanes.clear();
139 }
140 
141 
142 bool
143 NIVissimEdge::dictionary(int id, const std::string& name,
144  const std::string& type, int noLanes,
145  double zuschlag1, double zuschlag2, double length,
146  const PositionVector& geom,
147  const NIVissimClosedLanesVector& clv) {
148  NIVissimEdge* o = new NIVissimEdge(id, name, type, noLanes, zuschlag1,
149  zuschlag2, length, geom, clv);
150  if (!dictionary(id, o)) {
151  delete o;
152  return false;
153  }
154  return true;
155 }
156 
157 
158 
159 bool
161  DictType::iterator i = myDict.find(id);
162  if (i == myDict.end()) {
163  myDict[id] = o;
164  return true;
165  }
166  return false;
167 }
168 
169 
170 
173  DictType::iterator i = myDict.find(id);
174  if (i == myDict.end()) {
175  return 0;
176  }
177  return (*i).second;
178 }
179 
180 
181 void
183  const double MAX_CLUSTER_DISTANCE = 10;
184  // build clusters for all edges made up from not previously assigne
185  // connections
186  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
187  int edgeid = (*i).first;
188  NIVissimEdge* edge = (*i).second;
189  // get all connectors using this edge
190  std::vector<int> connectors = edge->myIncomingConnections;
191  copy(edge->myOutgoingConnections.begin(), edge->myOutgoingConnections.end(), back_inserter(connectors));
192  if (connectors.size() == 0) {
193  continue;
194  }
195  // sort the connectors by the place on the edge
196  sort(connectors.begin(), connectors.end(), connection_position_sorter(edgeid));
197  // try to cluster the connections participating within the current edge
198  std::vector<int> currentCluster;
199  std::vector<int>::iterator j = connectors.begin();
200  bool outgoing = NIVissimConnection::dictionary(*j)->getFromEdgeID() == (*i).first;
201  double position = outgoing
202  ? NIVissimConnection::dictionary(*j)->getFromPosition()
203  : NIVissimConnection::dictionary(*j)->getToPosition();
204 
205  // skip connections already in a cluster
206  // !!! (?)
207  while (j != connectors.end() && NIVissimConnection::dictionary(*j)->hasNodeCluster()) {
208  ++j;
209  }
210  if (j == connectors.end()) {
211  continue;
212  }
213  currentCluster.push_back(*j);
214  do {
215  if (j + 1 != connectors.end() && !NIVissimConnection::dictionary(*j)->hasNodeCluster()) {
216  bool n_outgoing = NIVissimConnection::dictionary(*(j + 1))->getFromEdgeID() == edgeid;
217  double n_position = n_outgoing
218  ? NIVissimConnection::dictionary(*(j + 1))->getFromPosition()
219  : NIVissimConnection::dictionary(*(j + 1))->getToPosition();
220  if (n_outgoing == outgoing && fabs(n_position - position) < MAX_CLUSTER_DISTANCE) {
221  // ok, in same cluster as prior
222  currentCluster.push_back(*(j + 1));
223  } else {
224  // start new cluster
225  VectorHelper<int>::removeDouble(currentCluster);
226  edge->myConnectionClusters.push_back(new NIVissimConnectionCluster(currentCluster, -1, edgeid));
227  currentCluster.clear();
228  currentCluster.push_back(*(j + 1));
229  }
230  outgoing = n_outgoing;
231  position = n_position;
232  }
233  j++;
234  } while (j != connectors.end());
235  // add last connection
236  if (currentCluster.size() > 0) {
237  VectorHelper<int>::removeDouble(currentCluster);
238  edge->myConnectionClusters.push_back(new NIVissimConnectionCluster(currentCluster, -1, edgeid));
239  }
240  }
241 }
242 
243 
244 void
246  NBEdgeCont& ec, double offset) {
247  for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
248  NIVissimEdge* edge = (*i).second;
249  edge->buildNBEdge(dc, nc, ec, offset);
250  }
251 }
252 
253 
254 void
256  DictType::iterator i;
257  for (i = myDict.begin(); i != myDict.end(); i++) {
258  NIVissimEdge* edge = (*i).second;
259  edge->setDistrictSpeed();
260  }
261  for (i = myDict.begin(); i != myDict.end(); i++) {
262  NIVissimEdge* edge = (*i).second;
263  edge->propagateSpeed(-1, std::vector<int>());
264  }
265  for (int j = 0; j < 3; j++) {
266  for (i = myDict.begin(); i != myDict.end(); i++) {
267  NIVissimEdge* edge = (*i).second;
268  edge->propagateOwn();
269  }
270  for (i = myDict.begin(); i != myDict.end(); i++) {
271  NIVissimEdge* edge = (*i).second;
273  }
274  }
275 }
276 
277 
278 void
280  for (int i = 0; i < (int) myLaneSpeeds.size(); i++) {
281  if (myLaneSpeeds[i] == -1) {
282  double speed = -1;
283  int j1 = i - 1; // !!! recheck - j1 may become negative?
284  int j2 = i;
285  while (j2 != (int) myLaneSpeeds.size() && myLaneSpeeds[j2] == -1) {
286  j2++;
287  }
288  if (j1 < 0) {
289  if (j2 < (int) myLaneSpeeds.size()) {
290  speed = myLaneSpeeds[j2];
291  }
292  } else {
293  if (j2 >= (int) myLaneSpeeds.size()) {
294  speed = myLaneSpeeds[j1];
295  } else {
296  speed = (myLaneSpeeds[j1] + myLaneSpeeds[j2]) / (double) 2.0;
297  }
298  }
299  if (speed == -1) {
300  continue;
301  }
302  myLaneSpeeds[i] = speed;
303  std::vector<NIVissimConnection*> connected = getOutgoingConnected(i);
304  for (std::vector<NIVissimConnection*>::iterator j = connected.begin(); j != connected.end(); j++) {
305  NIVissimConnection* c = *j;
307  // propagate
308  e->propagateSpeed(/*dc, */speed, c->getToLanes());
309  }
310  }
311  }
312 }
313 
314 
315 void
317  for (int i = 0; i < (int) myLaneSpeeds.size(); i++) {
318  if (myLaneSpeeds[i] == -1) {
319  continue;
320  }
321  std::vector<NIVissimConnection*> connected = getOutgoingConnected(i);
322  for (std::vector<NIVissimConnection*>::iterator j = connected.begin(); j != connected.end(); j++) {
323  NIVissimConnection* c = *j;
325  // propagate
326  e->propagateSpeed(/*dc, */myLaneSpeeds[i], c->getToLanes());
327  }
328  }
329 }
330 
331 
332 void
333 NIVissimEdge::propagateSpeed(double speed, std::vector<int> forLanes) {
334  // if no lane is given, all set be set
335  if (forLanes.size() == 0) {
336  for (int i = 0; i < myNoLanes; i++) {
337  forLanes.push_back((int) i);
338  }
339  }
340  // for the case of a first call
341  // go through the lanes
342  for (std::vector<int>::const_iterator i = forLanes.begin(); i < forLanes.end(); i++) {
343  // check whether a speed was set before
344  if (myLaneSpeeds[*i] != -1) {
345  // do not reset it from incoming
346  continue;
347  }
348  // check whether the lane has a new speed to set
349  if ((int) myPatchedSpeeds.size() > *i && myPatchedSpeeds[*i] != -1) {
350  // use it
351  speed = getRealSpeed(/*dc, */myPatchedSpeeds[*i]);
352  }
353  // check whether a speed is given
354  if (speed == -1) {
355  // do nothing if not
356  continue;
357  }
358  // set the lane's speed to the given
359  myLaneSpeeds[*i] = speed;
360  // propagate the speed further
361  // get the list of connected edges
362  std::vector<NIVissimConnection*> connected = getOutgoingConnected(*i);
363  // go throught the list
364  for (std::vector<NIVissimConnection*>::iterator j = connected.begin(); j != connected.end(); j++) {
365  NIVissimConnection* c = *j;
367  // propagate
368  e->propagateSpeed(/*dc, */speed, c->getToLanes());
369  }
370  }
371 }
372 
373 
374 
375 void
377  if (myDistrictConnections.size() > 0) {
378  double pos = *(myDistrictConnections.begin());
379  if (pos < getLength() - pos) {
382  if (d != 0) {
383  double speed = d->getMeanSpeed(/*dc*/);
384  if (speed == -1) {
385  return;
386  }
387  for (int i = 0; i < myNoLanes; i++) {
388  myLaneSpeeds[i] = speed;
389  // propagate the speed further
390  // get the list of connected edges
391  std::vector<NIVissimConnection*> connected = getOutgoingConnected(i);
392  // go throught the list
393  for (std::vector<NIVissimConnection*>::iterator j = connected.begin(); j != connected.end(); j++) {
394  NIVissimConnection* c = *j;
396  // propagate
397  e->propagateSpeed(/*dc, */speed, c->getToLanes());
398  }
399  }
400  }
401  }
402  }
403 }
404 
405 
406 std::vector<NIVissimConnection*>
408  std::vector<NIVissimConnection*> ret;
409  for (std::vector<int>::const_iterator i = myOutgoingConnections.begin(); i != myOutgoingConnections.end(); i++) {
411  const std::vector<int>& lanes = c->getFromLanes();
412  if (find(lanes.begin(), lanes.end(), lane) != lanes.end()) {
414  if (e != 0) {
415  ret.push_back(c);
416  }
417  }
418  }
419  return ret;
420 }
421 
422 
423 void
425  double sameNodesOffset) {
426  // build the edge
427  std::pair<NIVissimConnectionCluster*, NBNode*> fromInf, toInf;
428  NBNode* fromNode, *toNode;
429  fromNode = toNode = 0;
431  sort(myDistrictConnections.begin(), myDistrictConnections.end());
433  if (tmpClusters.size() != 0) {
434  sort(tmpClusters.begin(), tmpClusters.end(), connection_cluster_position_sorter(myID));
435  // get or build the from-node
436  // A node may have to be build when the edge starts or ends at
437  // a parking place or something like this
438  fromInf = getFromNode(nc, tmpClusters);
439  fromNode = fromInf.second;
440  // get or build the to-node
441  //if(tmpClusters.size()>0) {
442  toInf = getToNode(nc, tmpClusters);
443  toNode = toInf.second;
444  if (fromInf.first != 0 && toNode != 0 && fromInf.first->around(toNode->getPosition())) {
445  WRITE_WARNING("Will not build edge '" + toString(myID) + "'.");
446  myAmWithinJunction = true;
447  return;
448  }
449  //}
450  // if both nodes are the same, resolve the problem otherwise
451  if (fromNode == toNode) {
452  std::pair<NBNode*, NBNode*> tmp = resolveSameNode(nc, sameNodesOffset, fromNode, toNode);
453  if (fromNode != tmp.first) {
454  fromInf.first = 0;
455  }
456  if (toNode != tmp.second) {
457  toInf.first = 0;
458  }
459  fromNode = tmp.first;
460  toNode = tmp.second;
461  }
462  }
463 
464  //
465  if (fromNode == 0) {
466  fromInf.first = 0;
467  Position pos = myGeom[0];
468  fromNode = new NBNode(toString<int>(myID) + "-SourceNode", pos, NODETYPE_NOJUNCTION);
469  if (!nc.insert(fromNode)) {
470  throw ProcessError("Could not insert node '" + fromNode->getID() + "' to nodes container.");
471  }
472  }
473  if (toNode == 0) {
474  toInf.first = 0;
475  Position pos = myGeom[-1];
476  toNode = new NBNode(toString<int>(myID) + "-DestinationNode", pos, NODETYPE_NOJUNCTION);
477  if (!nc.insert(toNode)) {
478  throw ProcessError("Could not insert node '" + toNode->getID() + "' to nodes container.");
479  }
480  }
481 
482  // build the edge
483  double avgSpeed = 0;
484  for (int i = 0; i < myNoLanes; i++) {
485  if ((int)myLaneSpeeds.size() <= i || myLaneSpeeds[i] == -1) {
486  myLanesWithMissingSpeeds.push_back(toString(myID) + "_" + toString(i));
487  avgSpeed += OptionsCont::getOptions().getFloat("vissim.default-speed");
488  } else {
489  avgSpeed += myLaneSpeeds[i];
490  }
491  }
492  avgSpeed /= (double) myLaneSpeeds.size();
493  avgSpeed *= OptionsCont::getOptions().getFloat("vissim.speed-norm");
494 
495  if (fromNode == toNode) {
496  WRITE_WARNING("Could not build edge '" + toString(myID) + "'; would connect same node.");
497  return;
498  }
499 
500  NBEdge* buildEdge = new NBEdge(toString<int>(myID), fromNode, toNode, myType,
501  avgSpeed / (double) 3.6, myNoLanes, -1,
503  myGeom, myName, "", LANESPREAD_CENTER, true);
504  for (int i = 0; i < myNoLanes; i++) {
505  if ((int) myLaneSpeeds.size() <= i || myLaneSpeeds[i] == -1) {
506  buildEdge->setSpeed(i, OptionsCont::getOptions().getFloat("vissim.default-speed") / (double) 3.6);
507  } else {
508  buildEdge->setSpeed(i, myLaneSpeeds[i] / (double) 3.6);
509  }
510  }
511  ec.insert(buildEdge);
512  // check whether the edge contains any other clusters
513  if (tmpClusters.size() > 0) {
514  bool cont = true;
515  for (ConnectionClusters::iterator j = tmpClusters.begin(); cont && j != tmpClusters.end(); ++j) {
516  // split the edge at the previously build node
517  std::string nextID = buildEdge->getID() + "[1]";
518  cont = ec.splitAt(dc, buildEdge, (*j)->getNBNode());
519  // !!! what to do if the edge could not be split?
520  buildEdge = ec.retrieve(nextID);
521  }
522  }
523 }
524 
525 
526 double
528  std::string id = toString<int>(distNo);
529  Distribution* dist = DistributionCont::dictionary("speed", id);
530  if (dist == 0) {
531  WRITE_WARNING("The referenced speed distribution '" + id + "' is not known.");
532  return -1;
533  }
534  assert(dist != 0);
535  double speed = dist->getMax();
536  if (speed < 0 || speed > 1000) {
537  WRITE_WARNING("What about distribution '" + toString<int>(distNo) + "' ");
538  }
539  return speed;
540 }
541 
542 /*
543 bool
544 NIVissimEdge::recheckSpeedPatches()
545 {
546 // int speed_idx = -1;
547  // check set speeds
548  if(myPatchedSpeeds.size()!=0) {
549  std::vector<double>::iterator i =
550  find(myPatchedSpeeds.begin(), myPatchedSpeeds.end(), -1);
551  if(myPatchedSpeeds.size()!=myNoLanes||i!=myPatchedSpeeds.end()) {
552  cot << "Warning! Not all lanes are patched! (edge:" << myID << ")." << endl;
553  }
554  //
555  if(std::vector<double>Helper::maxValue(myPatchedSpeeds)!=std::vector<double>Helper::minValue(myPatchedSpeeds)) {
556  cot << "Warning! Not all lanes have the same speed!! (edge:" << myID << ")." << endl;
557  }
558  //
559 / // !!! ist natuerlich Quatsch - erst recht, wenn Edges zusammengefasst werden
560  speed = std::vector<double>Helper::sum(myPatchedSpeeds);
561  speed /= (double) myPatchedSpeeds.size();*/
562 /* return true;
563  }
564  if(myDistrictConnections.size()>0) {
565  double pos = *(myDistrictConnections.begin());
566 // if(pos<10) {
567  NIVissimDistrictConnection *d =
568  NIVissimDistrictConnection::dict_findForEdge(myID);
569  if(d!=0) {
570  return true;
571 // speed = d->getMeanSpeed();
572  }
573 // }
574 // return true;
575  }
576  return false;
577 }
578 */
579 
580 std::pair<NIVissimConnectionCluster*, NBNode*>
582  // changed MAX_DISTANCE from 10 to 3.5, because 3.5 is the default lane width in VISSIM
583  const double MAX_DISTANCE = 3.5;
584  assert(clusters.size() >= 1);
585  const Position& beg = myGeom.front();
586  NIVissimConnectionCluster* c = *(clusters.begin());
587  // check whether the edge starts within a already build node
588  if (c->around(beg, MAX_DISTANCE)) {
589  clusters.erase(clusters.begin());
590  return std::pair<NIVissimConnectionCluster*, NBNode*>
591  (c, c->getNBNode());
592  }
593  // check for a parking place at the begin
594  if (myDistrictConnections.size() > 0) {
595  double pos = *(myDistrictConnections.begin());
596  if (pos < 10) {
597  NBNode* node = new NBNode(toString<int>(myID) + "-begin", beg, NODETYPE_NOJUNCTION);
598  if (!nc.insert(node)) {
599  throw 1;
600  }
601  while (myDistrictConnections.size() > 0 && *(myDistrictConnections.begin()) < 10) {
603  }
604  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node);
605  }
606  }
607  // build a new node for the edge's begin otherwise
608  NBNode* node = new NBNode(toString<int>(myID) + "-begin", beg, NODETYPE_NOJUNCTION);
609  if (!nc.insert(node)) {
610  throw 1;
611  }
612  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node);
613 }
614 
615 
616 std::pair<NIVissimConnectionCluster*, NBNode*>
618  const Position& end = myGeom.back();
619  if (clusters.size() > 0) {
620  const double MAX_DISTANCE = 10.;
621  assert(clusters.size() >= 1);
622  NIVissimConnectionCluster* c = *(clusters.end() - 1);
623  // check whether the edge ends within a already build node
624  if (c->around(end, MAX_DISTANCE)) {
625  clusters.erase(clusters.end() - 1);
626  return std::pair<NIVissimConnectionCluster*, NBNode*>(c, c->getNBNode());
627  }
628  }
629  // check for a parking place at the end
630  if (myDistrictConnections.size() > 0) {
631  double pos = *(myDistrictConnections.end() - 1);
632  if (pos > myGeom.length() - 10) {
633  NBNode* node = new NBNode(toString<int>(myID) + "-end", end, NODETYPE_NOJUNCTION);
634  if (!nc.insert(node)) {
635  throw 1;
636  }
637  while (myDistrictConnections.size() > 0 && *(myDistrictConnections.end() - 1) < myGeom.length() - 10) {
639  }
640  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node);
641  }
642  }
643 
644  // build a new node for the edge's end otherwise
645  NBNode* node = new NBNode(toString<int>(myID) + "-end", end, NODETYPE_NOJUNCTION);
646  if (!nc.insert(node)) {
647  throw 1;
648  }
649  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node);
650  /*
651  if (clusters.size()>0) {
652  NIVissimConnectionCluster *c = *(clusters.end()-1);
653  clusters.erase(clusters.end()-1);
654  return std::pair<NIVissimConnectionCluster*, NBNode*>(c, c->getNBNode());
655  } else {
656  // !!! self-loop edge?!
657  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), (*(myConnectionClusters.begin()))->getNBNode());
658  }
659  */
660 }
661 
662 
663 std::pair<NBNode*, NBNode*>
666  NBNode* fromNode, NBNode* toNode) {
667  std::string nid = "ParkingPlace" + toString<int>(d->getID());
668  if (d->geomPosition().distanceTo(fromNode->getPosition())
669  <
670  d->geomPosition().distanceTo(toNode->getPosition())) {
671 
672  NBNode* newNode = new NBNode(nid,
673  fromNode->getPosition(),
675  nc.erase(fromNode);
676  nc.insert(newNode);
677  return std::pair<NBNode*, NBNode*>(newNode, toNode);
678  } else {
679  NBNode* newNode = new NBNode(nid,
680  toNode->getPosition(),
682  nc.erase(toNode);
683  nc.insert(newNode);
684  return std::pair<NBNode*, NBNode*>(fromNode, newNode);
685  }
686 }
687 
688 
689 
690 std::pair<NBNode*, NBNode*>
692  NBNode* prevFrom, NBNode* prevTo) {
693  // check whether the edge is connected to a district
694  // use it if so
697  if (d != 0) {
698  Position pos = d->geomPosition();
699  double position = d->getPosition();
700  // the district is at the begin of the edge
701  if (myGeom.length() - position > position) {
702  std::string nid = "ParkingPlace" + toString<int>(d->getID());
703  NBNode* node = nc.retrieve(nid);
704  if (node == 0) {
705  node = new NBNode(nid,
706  pos, NODETYPE_NOJUNCTION);
707  if (!nc.insert(node)) {
708  throw 1;
709  }
710  }
711  return std::pair<NBNode*, NBNode*>(node, prevTo);
712  }
713  // the district is at the end of the edge
714  else {
715  std::string nid = "ParkingPlace" + toString<int>(d->getID());
716  NBNode* node = nc.retrieve(nid);
717  if (node == 0) {
718  node = new NBNode(nid, pos, NODETYPE_NOJUNCTION);
719  if (!nc.insert(node)) {
720  throw 1;
721  }
722  }
723  assert(node != 0);
724  return std::pair<NBNode*, NBNode*>(prevFrom, node);
725  }
726  }
727  // otherwise, check whether the edge is some kind of
728  // a dead end...
729  // check which end is nearer to the node centre
730  if (myConnectionClusters.size() == 1) {
731  NBNode* node = prevFrom; // it is the same as getToNode()
732 
734  // no end node given
735  if (c->around(myGeom.front(), offset) && !c->around(myGeom.back(), offset)) {
736  NBNode* end = new NBNode(
737  toString<int>(myID) + "-End",
738  myGeom.back(),
740  if (!nc.insert(end)) {
741  throw 1;
742  }
743  return std::pair<NBNode*, NBNode*>(node, end);
744  }
745 
746  // no begin node given
747  if (!c->around(myGeom.front(), offset) && c->around(myGeom.back(), offset)) {
748  NBNode* beg = new NBNode(
749  toString<int>(myID) + "-Begin",
750  myGeom.front(),
752  if (!nc.insert(beg)) {
753  std::cout << "nope, NIVissimDisturbance" << std::endl;
754  throw 1;
755  }
756  return std::pair<NBNode*, NBNode*>(beg, node);
757  }
758 
759  // self-loop edge - both points lie within the same cluster
760  if (c->around(myGeom.front()) && c->around(myGeom.back())) {
761  return std::pair<NBNode*, NBNode*>(node, node);
762  }
763  }
764  // what to do in other cases?
765  // It simply is a self-looping edge....
766  return std::pair<NBNode*, NBNode*>(prevFrom, prevTo);
767 }
768 
769 
770 
771 
772 void
774  myNode = nodeid;
775 }
776 
777 
778 void
780 
781 
782 void
784  myIncomingConnections.push_back(id);
785 }
786 
787 
788 void
790  myOutgoingConnections.push_back(id);
791 }
792 
793 
794 
795 void
798  ConnectionClusters::iterator i =
799  find(myConnectionClusters.begin(), myConnectionClusters.end(), old);
800  if (i != myConnectionClusters.end()) {
801  myConnectionClusters.erase(i);
802  }
803  i = find(myConnectionClusters.begin(), myConnectionClusters.end(), act);
804  if (i == myConnectionClusters.end()) {
805  myConnectionClusters.push_back(act);
806  }
807 }
808 
809 
810 
811 void
813  ConnectionClusters::iterator i =
814  find(myConnectionClusters.begin(), myConnectionClusters.end(), c);
815  assert(i != myConnectionClusters.end());
816  myConnectionClusters.erase(i);
817 }
818 
819 
820 void
822  ConnectionClusters::iterator i =
823  find(myConnectionClusters.begin(), myConnectionClusters.end(), c);
824  if (i == myConnectionClusters.end()) {
825  myConnectionClusters.push_back(c);
826  }
827 }
828 
829 
830 Position // !!! reference?
832  return myGeom[0];
833 }
834 
835 
836 Position // !!! reference?
838  return myGeom[-1];
839 }
840 
841 
842 double
844  return myGeom.length();
845 }
846 
847 
848 void
850  if (find(myDistrictConnections.begin(), myDistrictConnections.end(), pos) == myDistrictConnections.end()) {
851  myDistrictConnections.push_back(pos);
852  /* int id = NIVissimConnection::getMaxID() + 1;
853  std::vector<int> currentCluster;
854  currentCluster.push_back(id);
855  myConnectionClusters.push_back(
856  new NIVissimConnectionCluster(currentCluster, -1, myID));*/
857  }
858 }
859 
860 
861 void
862 NIVissimEdge::setSpeed(int lane, int speedDist) {
863  while ((int)myPatchedSpeeds.size() <= lane) {
864  myPatchedSpeeds.push_back(-1);
865  }
866  myPatchedSpeeds[lane] = speedDist;
867 }
868 
869 
870 void
872  // go through the edges
873  for (DictType::iterator i1 = myDict.begin(); i1 != myDict.end(); i1++) {
874  // retrieve needed values from the first edge
875  NIVissimEdge* e1 = (*i1).second;
876  const PositionVector& g1 = e1->getGeometry();
877  // check all other edges
878  DictType::iterator i2 = i1;
879  i2++;
880  for (; i2 != myDict.end(); i2++) {
881  // retrieve needed values from the second edge
882  NIVissimEdge* e2 = (*i2).second;
883  const PositionVector& g2 = e2->getGeometry();
884  // get the connection description
885  NIVissimConnection* c = e1->getConnectionTo(e2);
886  if (c == 0) {
887  c = e2->getConnectionTo(e1);
888  }
889  // the edge must not be a direct contiuation of the other
890  if (c != 0) {
891  if ((c->getFromEdgeID() == e1->getID() && fabs(c->getFromPosition() - e1->getGeometry().length()) < 5)
892  ||
893  (c->getFromEdgeID() == e2->getID() && fabs(c->getFromPosition() - e2->getGeometry().length()) < 5)) {
894 
895  continue;
896  }
897  }
898  // only parallel edges which do end at the same node
899  // should be joined
900  // check for parallelity
901  // !!! the usage of an explicit value is not very fine
902  if (fabs(GeomHelper::angleDiff(g1.beginEndAngle(), g2.beginEndAngle())) > DEG2RAD(2.0)) {
903  // continue if the lines are not parallel
904  continue;
905  }
906 
907  // check whether the same node is approached
908  // (the distance between the ends should not be too large)
909  // !!! the usage of an explicit value is not very fine
910  if (g1.back().distanceTo(g2.back()) > 10) {
911  // continue if the lines do not end at the same length
912  continue;
913  }
914  // ok, seem to be different lanes for the same edge
915  // mark as possibly joined later
916  e1->addToTreatAsSame(e2);
917  e2->addToTreatAsSame(e1);
918  }
919  }
920 }
921 
922 
923 bool
925  if (e == this) {
926  return false;
927  }
928  // check whether this edge already knows about the other
929  if (find(myToTreatAsSame.begin(), myToTreatAsSame.end(), e) == myToTreatAsSame.end()) {
930  myToTreatAsSame.push_back(e);
931  return true;
932  } else {
933  return false; // !!! check this
934  }
935  /*
936  //
937  std::vector<NIVissimEdge*>::iterator i;
938  // add to all other that shall be treated as same
939  bool changed = true;
940  while (changed) {
941  changed = false;
942  for (i = myToTreatAsSame.begin(); !changed && i != myToTreatAsSame.end(); i++) {
943  changed |= (*i)->addToTreatAsSame(e);
944  }
945  for (i = myToTreatAsSame.begin(); !changed && i != myToTreatAsSame.end(); i++) {
946  changed |= e->addToTreatAsSame(*i);
947  }
948  }
949  */
950 }
951 
954  std::vector<int>::iterator i;
955  for (i = myIncomingConnections.begin(); i != myIncomingConnections.end(); i++) {
957  if (c->getFromEdgeID() == e->getID()) {
958  return c;
959  }
960  }
961  for (i = myOutgoingConnections.begin(); i != myOutgoingConnections.end(); i++) {
963  if (c->getToEdgeID() == e->getID()) {
964  return c;
965  }
966  }
967  return 0;
968 }
969 
970 
971 const std::vector<NIVissimEdge*>&
973  return myToTreatAsSame;
974 }
975 
976 
977 void
979  if (myLanesWithMissingSpeeds.size() == 0) {
980  return;
981  }
982  std::ostringstream str;
983  str << "The following lanes have no explicit speed information:\n ";
984  for (std::vector<std::string>::iterator i = myLanesWithMissingSpeeds.begin(); i != myLanesWithMissingSpeeds.end(); ++i) {
985  if (i != myLanesWithMissingSpeeds.begin()) {
986  str << ", ";
987  }
988  str << *i;
989  }
990  WRITE_WARNING(str.str());
991 }
992 
993 
996  // @todo seems as this would have been a hard hack!
997  /*
998  for (std::vector<int>::const_iterator i = myIncomingConnections.begin(); i != myIncomingConnections.end(); ++i) {
999  NIVissimConnection* c = NIVissimConnection::dictionary(*i);
1000  return NIVissimEdge::dictionary(c->getFromEdgeID());
1001  }
1002  return 0;
1003  */
1004  if (myIncomingConnections.size() != 0) {
1006  }
1007  return 0;
1008 }
1009 
1010 
1011 NIVissimEdge*
1013  // @todo seems as this would have been a hard hack!
1014  /*
1015  for (std::vector<int>::const_iterator i = myOutgoingConnections.begin(); i != myOutgoingConnections.end(); ++i) {
1016  NIVissimConnection* c = NIVissimConnection::dictionary(*i);
1017  return NIVissimEdge::dictionary(c->getToEdgeID());
1018  }
1019  return 0;
1020  */
1021  if (myOutgoingConnections.size() != 0) {
1023  }
1024  return 0;
1025 }
1026 
1027 
1028 
1029 /****************************************************************************/
1030 
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:106
std::vector< NIVissimConnection * > getOutgoingConnected(int lane) const
static int myMaxID
The current maximum id; needed for further id assignment.
Definition: NIVissimEdge.h:301
NIVissimEdge(int id, const std::string &name, const std::string &type, int noLanes, double zuschlag1, double zuschlag2, double length, const PositionVector &geom, const NIVissimClosedLanesVector &clv)
Constructor.
std::vector< double > myDistrictConnections
Definition: NIVissimEdge.h:282
~NIVissimEdge()
Destructor.
std::string myName
The name of the edge.
Definition: NIVissimEdge.h:259
const std::vector< int > & getFromLanes() const
static void dict_checkEdges2Join()
std::map< int, NIVissimEdge * > DictType
Definition of the dictionary type.
Definition: NIVissimEdge.h:295
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:2862
std::vector< int > myPatchedSpeeds
Definition: NIVissimEdge.h:284
std::pair< NBNode *, NBNode * > remapOneOfNodes(NBNodeCont &nc, NIVissimDistrictConnection *d, NBNode *fromNode, NBNode *toNode)
static void reportUnsetSpeeds()
Writes edges with unset speeds to the warnings message log instance.
std::vector< NIVissimClosedLaneDef * > NIVissimClosedLanesVector
The representation of a single edge during network building.
Definition: NBEdge.h:71
ConnectionClusters myConnectionClusters
List of connection clusters along this edge.
Definition: NIVissimEdge.h:274
std::vector< double > myLaneSpeeds
Definition: NIVissimEdge.h:286
double myZuschlag2
Definition: NIVissimEdge.h:268
A container for districts.
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:258
const PositionVector & getGeometry() const
Position geomPosition() const
Returns the position The position yields from the edge geometry and the place the connection is plaed...
static void dict_buildNBEdges(NBDistrictCont &dc, NBNodeCont &nc, NBEdgeCont &ec, double offset)
Builds NBEdges from the VissimEdges within the dictionary.
void addToConnectionCluster(NIVissimConnectionCluster *c)
void setNodeCluster(int nodeid)
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:416
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.
const std::vector< int > & getToLanes() const
static bool dictionary(int id, NIVissimConnection *o)
const std::string & getID() const
Returns the id.
Definition: Named.h:66
int getID() const
Returns the id of the connection.
NIVissimEdge * getBestIncoming() const
static NIVissimDistrictConnection * dict_findForEdge(int edgeid)
Returns the connection to a district placed at the given node Yep, there onyl should be one...
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:255
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
double getPositionForEdge(int edgeid) const
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
A temporary storage for edges imported from Vissim.
Definition: NIVissimEdge.h:60
Position getBegin2D() const
void propagateSpeed(double speed, std::vector< int > forLanes)
NIVissimEdge * getBestOutgoing() const
int myNoLanes
The number of lanes the edge has.
Definition: NIVissimEdge.h:265
double myZuschlag1
Additional load values for this edge.
Definition: NIVissimEdge.h:268
double getPosition() const
Returns the position of the connection at the edge.
double getRealSpeed(int distNo)
int operator()(NIVissimConnectionCluster *cc1, NIVissimConnectionCluster *cc2) const
comparing operation
bool insert(NBEdge *edge, bool ignorePrunning=false)
Adds an edge to the dictionary.
Definition: NBEdgeCont.cpp:158
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
void setSpeed(int lane, int speedDist)
void addIncomingConnection(int id)
Adds a connection where this edge is the destination.
bool myAmWithinJunction
Information whether this edge was not build due to being within a junction.
Definition: NIVissimEdge.h:291
static void dict_propagateSpeeds()
int operator()(int c1id, int c2id) const
comparing operation
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position ...
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
std::vector< int > myIncomingConnections
List of connections incoming to this edge.
Definition: NIVissimEdge.h:277
double getLength() const
Returns the length of the node.
void checkDistrictConnectionExistanceAt(double pos)
static void removeDouble(std::vector< T > &v)
Definition: VectorHelper.h:77
std::string myType
The type of the edge.
Definition: NIVissimEdge.h:262
void setDistrictSpeed()
bool around(const Position &p, double offset=0) const
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
connection_cluster_position_sorter(int edgeid)
constructor
connection_position_sorter(int edgeid)
constructor
void checkUnconnectedLaneSpeeds()
void addOutgoingConnection(int id)
Adds a connection where this edge is the source.
void buildNBEdge(NBDistrictCont &dc, NBNodeCont &nc, NBEdgeCont &ec, double sameNodesOffset)
Builds the NBEdge from this VissimEdge.
#define DEG2RAD(x)
Definition: GeomHelper.h:45
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.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
NIVissimConnection * getConnectionTo(NIVissimEdge *e)
std::pair< NIVissimConnectionCluster *, NBNode * > getToNode(NBNodeCont &nc, ConnectionClusters &clusters)
Returns the destination node.
double getToPosition() const
static void buildConnectionClusters()
Clusters connections of each edge.
std::vector< NIVissimEdge * > myToTreatAsSame
Definition: NIVissimEdge.h:288
double length() const
Returns the length.
bool addToTreatAsSame(NIVissimEdge *e)
Position getEnd2D() const
Returns the end position of the edge.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:251
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:77
std::pair< NBNode *, NBNode * > resolveSameNode(NBNodeCont &nc, double offset, NBNode *prevFrom, NBNode *prevTo)
Tries to resolve the problem that the same node has been returned as origin and destination node...
static std::vector< std::string > myLanesWithMissingSpeeds
Definition: NIVissimEdge.h:303
NIVissimClosedLanesVector myClosedLanes
List of lanes closed on this edge.
Definition: NIVissimEdge.h:271
std::vector< NIVissimConnectionCluster * > ConnectionClusters
The definition for a container for connection clusters.
Definition: NIVissimEdge.h:169
const Position & getPosition() const
Definition: NBNode.h:232
Represents a single node (junction) during network building.
Definition: NBNode.h:75
void propagateOwn()
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:240
static DictType myDict
The dictionary.
Definition: NIVissimEdge.h:298
const std::vector< NIVissimEdge * > & getToTreatAsSame() const
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:63
void mergedInto(NIVissimConnectionCluster *old, NIVissimConnectionCluster *act)
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
Definition: GeomHelper.cpp:174
bool erase(NBNode *node)
Removes the given node, deleting it.
Definition: NBNodeCont.cpp:136
std::vector< int > myOutgoingConnections
List of connections outgoing from this edge.
Definition: NIVissimEdge.h:280
std::pair< NIVissimConnectionCluster *, NBNode * > getFromNode(NBNodeCont &nc, ConnectionClusters &clusters)
Returns the origin node.
void removeFromConnectionCluster(NIVissimConnectionCluster *c)
double getFromPosition() const