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