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