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 (int 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 (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  for (int i = 0; i < myNoLanes; i++) {
490  if ((int)myLaneSpeeds.size() <= i || myLaneSpeeds[i] == -1) {
491  myLanesWithMissingSpeeds.push_back(toString(myID) + "_" + toString(i));
492  avgSpeed += OptionsCont::getOptions().getFloat("vissim.default-speed");
493  } else {
494  avgSpeed += myLaneSpeeds[i];
495  }
496  }
497  avgSpeed /= (SUMOReal) myLaneSpeeds.size();
498  avgSpeed *= OptionsCont::getOptions().getFloat("vissim.speed-norm");
499 
500  if (fromNode == toNode) {
501  WRITE_WARNING("Could not build edge '" + toString(myID) + "'; would connect same node.");
502  return;
503  }
504 
505  NBEdge* buildEdge = new NBEdge(toString<int>(myID), fromNode, toNode, myType,
506  avgSpeed / (SUMOReal) 3.6, myNoLanes, -1,
508  myGeom, myName, "", LANESPREAD_CENTER, true);
509  for (int i = 0; i < myNoLanes; i++) {
510  if ((int) myLaneSpeeds.size() <= i || myLaneSpeeds[i] == -1) {
511  buildEdge->setSpeed(i, OptionsCont::getOptions().getFloat("vissim.default-speed") / (SUMOReal) 3.6);
512  } else {
513  buildEdge->setSpeed(i, myLaneSpeeds[i] / (SUMOReal) 3.6);
514  }
515  }
516  ec.insert(buildEdge);
517  // check whether the edge contains any other clusters
518  if (tmpClusters.size() > 0) {
519  bool cont = true;
520  for (ConnectionClusters::iterator j = tmpClusters.begin(); cont && j != tmpClusters.end(); ++j) {
521  // split the edge at the previously build node
522  std::string nextID = buildEdge->getID() + "[1]";
523  cont = ec.splitAt(dc, buildEdge, (*j)->getNBNode());
524  // !!! what to do if the edge could not be split?
525  buildEdge = ec.retrieve(nextID);
526  }
527  }
528 }
529 
530 
531 SUMOReal
532 NIVissimEdge::getRealSpeed(/* NBDistribution &dc */ int distNo) {
533  std::string id = toString<int>(distNo);
534  Distribution* dist = NBDistribution::dictionary("speed", id);
535  if (dist == 0) {
536  WRITE_WARNING("The referenced speed distribution '" + id + "' is not known.");
537  return -1;
538  }
539  assert(dist != 0);
540  SUMOReal speed = dist->getMax();
541  if (speed < 0 || speed > 1000) {
542  WRITE_WARNING("What about distribution '" + toString<int>(distNo) + "' ");
543  }
544  return speed;
545 }
546 
547 /*
548 bool
549 NIVissimEdge::recheckSpeedPatches()
550 {
551 // int speed_idx = -1;
552  // check set speeds
553  if(myPatchedSpeeds.size()!=0) {
554  std::vector<SUMOReal>::iterator i =
555  find(myPatchedSpeeds.begin(), myPatchedSpeeds.end(), -1);
556  if(myPatchedSpeeds.size()!=myNoLanes||i!=myPatchedSpeeds.end()) {
557  cot << "Warning! Not all lanes are patched! (edge:" << myID << ")." << endl;
558  }
559  //
560  if(std::vector<SUMOReal>Helper::maxValue(myPatchedSpeeds)!=std::vector<SUMOReal>Helper::minValue(myPatchedSpeeds)) {
561  cot << "Warning! Not all lanes have the same speed!! (edge:" << myID << ")." << endl;
562  }
563  //
564 / // !!! ist natuerlich Quatsch - erst recht, wenn Edges zusammengefasst werden
565  speed = std::vector<SUMOReal>Helper::sum(myPatchedSpeeds);
566  speed /= (SUMOReal) myPatchedSpeeds.size();*/
567 /* return true;
568  }
569  if(myDistrictConnections.size()>0) {
570  SUMOReal pos = *(myDistrictConnections.begin());
571 // if(pos<10) {
572  NIVissimDistrictConnection *d =
573  NIVissimDistrictConnection::dict_findForEdge(myID);
574  if(d!=0) {
575  return true;
576 // speed = d->getMeanSpeed();
577  }
578 // }
579 // return true;
580  }
581  return false;
582 }
583 */
584 
585 std::pair<NIVissimConnectionCluster*, NBNode*>
587  // changed MAX_DISTANCE from 10 to 3.5, because 3.5 is the default lane width in VISSIM
588  const SUMOReal MAX_DISTANCE = 3.5;
589  assert(clusters.size() >= 1);
590  const Position& beg = myGeom.front();
591  NIVissimConnectionCluster* c = *(clusters.begin());
592  // check whether the edge starts within a already build node
593  if (c->around(beg, MAX_DISTANCE)) {
594  clusters.erase(clusters.begin());
595  return std::pair<NIVissimConnectionCluster*, NBNode*>
596  (c, c->getNBNode());
597  }
598  // check for a parking place at the begin
599  if (myDistrictConnections.size() > 0) {
600  SUMOReal pos = *(myDistrictConnections.begin());
601  if (pos < 10) {
602  NBNode* node = new NBNode(toString<int>(myID) + "-begin", beg, NODETYPE_NOJUNCTION);
603  if (!nc.insert(node)) {
604  throw 1;
605  }
606  while (myDistrictConnections.size() > 0 && *(myDistrictConnections.begin()) < 10) {
608  }
609  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node);
610  }
611  }
612  // build a new node for the edge's begin otherwise
613  NBNode* node = new NBNode(toString<int>(myID) + "-begin", beg, NODETYPE_NOJUNCTION);
614  if (!nc.insert(node)) {
615  throw 1;
616  }
617  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node);
618 }
619 
620 
621 std::pair<NIVissimConnectionCluster*, NBNode*>
623  const Position& end = myGeom.back();
624  if (clusters.size() > 0) {
625  const SUMOReal MAX_DISTANCE = 10.;
626  assert(clusters.size() >= 1);
627  NIVissimConnectionCluster* c = *(clusters.end() - 1);
628  // check whether the edge ends within a already build node
629  if (c->around(end, MAX_DISTANCE)) {
630  clusters.erase(clusters.end() - 1);
631  return std::pair<NIVissimConnectionCluster*, NBNode*>(c, c->getNBNode());
632  }
633  }
634  // check for a parking place at the end
635  if (myDistrictConnections.size() > 0) {
636  SUMOReal pos = *(myDistrictConnections.end() - 1);
637  if (pos > myGeom.length() - 10) {
638  NBNode* node = new NBNode(toString<int>(myID) + "-end", end, NODETYPE_NOJUNCTION);
639  if (!nc.insert(node)) {
640  throw 1;
641  }
642  while (myDistrictConnections.size() > 0 && *(myDistrictConnections.end() - 1) < myGeom.length() - 10) {
644  }
645  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node);
646  }
647  }
648 
649  // build a new node for the edge's end otherwise
650  NBNode* node = new NBNode(toString<int>(myID) + "-end", end, NODETYPE_NOJUNCTION);
651  if (!nc.insert(node)) {
652  throw 1;
653  }
654  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node);
655  /*
656  if (clusters.size()>0) {
657  NIVissimConnectionCluster *c = *(clusters.end()-1);
658  clusters.erase(clusters.end()-1);
659  return std::pair<NIVissimConnectionCluster*, NBNode*>(c, c->getNBNode());
660  } else {
661  // !!! self-loop edge?!
662  return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), (*(myConnectionClusters.begin()))->getNBNode());
663  }
664  */
665 }
666 
667 
668 std::pair<NBNode*, NBNode*>
671  NBNode* fromNode, NBNode* toNode) {
672  std::string nid = "ParkingPlace" + toString<int>(d->getID());
673  if (d->geomPosition().distanceTo(fromNode->getPosition())
674  <
675  d->geomPosition().distanceTo(toNode->getPosition())) {
676 
677  NBNode* newNode = new NBNode(nid,
678  fromNode->getPosition(),
680  nc.erase(fromNode);
681  nc.insert(newNode);
682  return std::pair<NBNode*, NBNode*>(newNode, toNode);
683  } else {
684  NBNode* newNode = new NBNode(nid,
685  toNode->getPosition(),
687  nc.erase(toNode);
688  nc.insert(newNode);
689  return std::pair<NBNode*, NBNode*>(fromNode, newNode);
690  }
691 }
692 
693 
694 
695 std::pair<NBNode*, NBNode*>
697  NBNode* prevFrom, NBNode* prevTo) {
698  // check whether the edge is connected to a district
699  // use it if so
702  if (d != 0) {
703  Position pos = d->geomPosition();
704  SUMOReal position = d->getPosition();
705  // the district is at the begin of the edge
706  if (myGeom.length() - position > position) {
707  std::string nid = "ParkingPlace" + toString<int>(d->getID());
708  NBNode* node = nc.retrieve(nid);
709  if (node == 0) {
710  node = new NBNode(nid,
711  pos, NODETYPE_NOJUNCTION);
712  if (!nc.insert(node)) {
713  throw 1;
714  }
715  }
716  return std::pair<NBNode*, NBNode*>(node, prevTo);
717  }
718  // the district is at the end of the edge
719  else {
720  std::string nid = "ParkingPlace" + toString<int>(d->getID());
721  NBNode* node = nc.retrieve(nid);
722  if (node == 0) {
723  node = new NBNode(nid, pos, NODETYPE_NOJUNCTION);
724  if (!nc.insert(node)) {
725  throw 1;
726  }
727  }
728  assert(node != 0);
729  return std::pair<NBNode*, NBNode*>(prevFrom, node);
730  }
731  }
732  // otherwise, check whether the edge is some kind of
733  // a dead end...
734  // check which end is nearer to the node centre
735  if (myConnectionClusters.size() == 1) {
736  NBNode* node = prevFrom; // it is the same as getToNode()
737 
739  // no end node given
740  if (c->around(myGeom.front(), offset) && !c->around(myGeom.back(), offset)) {
741  NBNode* end = new NBNode(
742  toString<int>(myID) + "-End",
743  myGeom.back(),
745  if (!nc.insert(end)) {
746  throw 1;
747  }
748  return std::pair<NBNode*, NBNode*>(node, end);
749  }
750 
751  // no begin node given
752  if (!c->around(myGeom.front(), offset) && c->around(myGeom.back(), offset)) {
753  NBNode* beg = new NBNode(
754  toString<int>(myID) + "-Begin",
755  myGeom.front(),
757  if (!nc.insert(beg)) {
758  std::cout << "nope, NIVissimDisturbance" << std::endl;
759  throw 1;
760  }
761  return std::pair<NBNode*, NBNode*>(beg, node);
762  }
763 
764  // self-loop edge - both points lie within the same cluster
765  if (c->around(myGeom.front()) && c->around(myGeom.back())) {
766  return std::pair<NBNode*, NBNode*>(node, node);
767  }
768  }
769  // what to do in other cases?
770  // It simply is a self-looping edge....
771  return std::pair<NBNode*, NBNode*>(prevFrom, prevTo);
772 }
773 
774 
775 
776 
777 void
779  myNode = nodeid;
780 }
781 
782 
783 void
785 
786 
787 void
789  myIncomingConnections.push_back(id);
790 }
791 
792 
793 void
795  myOutgoingConnections.push_back(id);
796 }
797 
798 
799 
800 void
803  ConnectionClusters::iterator i =
804  find(myConnectionClusters.begin(), myConnectionClusters.end(), old);
805  if (i != myConnectionClusters.end()) {
806  myConnectionClusters.erase(i);
807  }
808  i = find(myConnectionClusters.begin(), myConnectionClusters.end(), act);
809  if (i == myConnectionClusters.end()) {
810  myConnectionClusters.push_back(act);
811  }
812 }
813 
814 
815 
816 void
818  ConnectionClusters::iterator i =
819  find(myConnectionClusters.begin(), myConnectionClusters.end(), c);
820  assert(i != myConnectionClusters.end());
821  myConnectionClusters.erase(i);
822 }
823 
824 
825 void
827  ConnectionClusters::iterator i =
828  find(myConnectionClusters.begin(), myConnectionClusters.end(), c);
829  if (i == myConnectionClusters.end()) {
830  myConnectionClusters.push_back(c);
831  }
832 }
833 
834 
835 Position // !!! reference?
837  return myGeom[0];
838 }
839 
840 
841 Position // !!! reference?
843  return myGeom[-1];
844 }
845 
846 
847 SUMOReal
849  return myGeom.length();
850 }
851 
852 
853 void
855  if (find(myDistrictConnections.begin(), myDistrictConnections.end(), pos) == myDistrictConnections.end()) {
856  myDistrictConnections.push_back(pos);
857  /* int id = NIVissimConnection::getMaxID() + 1;
858  std::vector<int> currentCluster;
859  currentCluster.push_back(id);
860  myConnectionClusters.push_back(
861  new NIVissimConnectionCluster(currentCluster, -1, myID));*/
862  }
863 }
864 
865 
866 void
867 NIVissimEdge::setSpeed(int lane, int speedDist) {
868  while ((int)myPatchedSpeeds.size() <= lane) {
869  myPatchedSpeeds.push_back(-1);
870  }
871  myPatchedSpeeds[lane] = speedDist;
872 }
873 
874 
875 void
877  // go through the edges
878  for (DictType::iterator i1 = myDict.begin(); i1 != myDict.end(); i1++) {
879  // retrieve needed values from the first edge
880  NIVissimEdge* e1 = (*i1).second;
881  const PositionVector& g1 = e1->getGeometry();
882  // check all other edges
883  DictType::iterator i2 = i1;
884  i2++;
885  for (; i2 != myDict.end(); i2++) {
886  // retrieve needed values from the second edge
887  NIVissimEdge* e2 = (*i2).second;
888  const PositionVector& g2 = e2->getGeometry();
889  // get the connection description
890  NIVissimConnection* c = e1->getConnectionTo(e2);
891  if (c == 0) {
892  c = e2->getConnectionTo(e1);
893  }
894  // the edge must not be a direct contiuation of the other
895  if (c != 0) {
896  if ((c->getFromEdgeID() == e1->getID() && fabs(c->getFromPosition() - e1->getGeometry().length()) < 5)
897  ||
898  (c->getFromEdgeID() == e2->getID() && fabs(c->getFromPosition() - e2->getGeometry().length()) < 5)) {
899 
900  continue;
901  }
902  }
903  // only parallel edges which do end at the same node
904  // should be joined
905  // check for parallelity
906  // !!! the usage of an explicit value is not very fine
907  if (fabs(GeomHelper::angleDiff(g1.beginEndAngle(), g2.beginEndAngle())) > DEG2RAD(2.0)) {
908  // continue if the lines are not parallel
909  continue;
910  }
911 
912  // check whether the same node is approached
913  // (the distance between the ends should not be too large)
914  // !!! the usage of an explicit value is not very fine
915  if (g1.back().distanceTo(g2.back()) > 10) {
916  // continue if the lines do not end at the same length
917  continue;
918  }
919  // ok, seem to be different lanes for the same edge
920  // mark as possibly joined later
921  e1->addToTreatAsSame(e2);
922  e2->addToTreatAsSame(e1);
923  }
924  }
925 }
926 
927 
928 bool
930  if (e == this) {
931  return false;
932  }
933  // check whether this edge already knows about the other
934  if (find(myToTreatAsSame.begin(), myToTreatAsSame.end(), e) == myToTreatAsSame.end()) {
935  myToTreatAsSame.push_back(e);
936  return true;
937  } else {
938  return false; // !!! check this
939  }
940  /*
941  //
942  std::vector<NIVissimEdge*>::iterator i;
943  // add to all other that shall be treated as same
944  bool changed = true;
945  while (changed) {
946  changed = false;
947  for (i = myToTreatAsSame.begin(); !changed && i != myToTreatAsSame.end(); i++) {
948  changed |= (*i)->addToTreatAsSame(e);
949  }
950  for (i = myToTreatAsSame.begin(); !changed && i != myToTreatAsSame.end(); i++) {
951  changed |= e->addToTreatAsSame(*i);
952  }
953  }
954  */
955 }
956 
959  std::vector<int>::iterator i;
960  for (i = myIncomingConnections.begin(); i != myIncomingConnections.end(); i++) {
962  if (c->getFromEdgeID() == e->getID()) {
963  return c;
964  }
965  }
966  for (i = myOutgoingConnections.begin(); i != myOutgoingConnections.end(); i++) {
968  if (c->getToEdgeID() == e->getID()) {
969  return c;
970  }
971  }
972  return 0;
973 }
974 
975 
976 const std::vector<NIVissimEdge*>&
978  return myToTreatAsSame;
979 }
980 
981 
982 void
984  if (myLanesWithMissingSpeeds.size() == 0) {
985  return;
986  }
987  std::ostringstream str;
988  str << "The following lanes have no explicit speed information:\n ";
989  for (std::vector<std::string>::iterator i = myLanesWithMissingSpeeds.begin(); i != myLanesWithMissingSpeeds.end(); ++i) {
990  if (i != myLanesWithMissingSpeeds.begin()) {
991  str << ", ";
992  }
993  str << *i;
994  }
995  WRITE_WARNING(str.str());
996 }
997 
998 
1001  // @todo seems as this would have been a hard hack!
1002  /*
1003  for (std::vector<int>::const_iterator i = myIncomingConnections.begin(); i != myIncomingConnections.end(); ++i) {
1004  NIVissimConnection* c = NIVissimConnection::dictionary(*i);
1005  return NIVissimEdge::dictionary(c->getFromEdgeID());
1006  }
1007  return 0;
1008  */
1009  if (myIncomingConnections.size() != 0) {
1011  }
1012  return 0;
1013 }
1014 
1015 
1016 NIVissimEdge*
1018  // @todo seems as this would have been a hard hack!
1019  /*
1020  for (std::vector<int>::const_iterator i = myOutgoingConnections.begin(); i != myOutgoingConnections.end(); ++i) {
1021  NIVissimConnection* c = NIVissimConnection::dictionary(*i);
1022  return NIVissimEdge::dictionary(c->getToEdgeID());
1023  }
1024  return 0;
1025  */
1026  if (myOutgoingConnections.size() != 0) {
1028  }
1029  return 0;
1030 }
1031 
1032 
1033 
1034 /****************************************************************************/
1035 
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:203
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:2531
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:412
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:205
SUMOReal beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position ...
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.
int myNoLanes
The number of lanes the edge has.
Definition: NIVissimEdge.h:266
const std::string & getID() const
Returns the id.
Definition: Named.h:66
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:162
void setSpeed(int lane, int speedDist)
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:55
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:247
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:81
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:110
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:63
void mergedInto(NIVissimConnectionCluster *old, NIVissimConnectionCluster *act)
bool erase(NBNode *node)
Removes the given node, deleting it.
Definition: NBNodeCont.cpp:140
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