SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // A temporary storage for edges imported from Vissim 00010 /****************************************************************************/ 00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00013 /****************************************************************************/ 00014 // 00015 // This file is part of SUMO. 00016 // SUMO is free software: you can redistribute it and/or modify 00017 // it under the terms of the GNU General Public License as published by 00018 // the Free Software Foundation, either version 3 of the License, or 00019 // (at your option) any later version. 00020 // 00021 /****************************************************************************/ 00022 00023 00024 // =========================================================================== 00025 // included modules 00026 // =========================================================================== 00027 #ifdef _MSC_VER 00028 #include <windows_config.h> 00029 #else 00030 #include <config.h> 00031 #endif 00032 00033 #include <string> 00034 #include <algorithm> 00035 #include <map> 00036 #include <cassert> 00037 #include <iomanip> 00038 #include <cmath> 00039 #include <iostream> 00040 #include <sstream> 00041 #include <iterator> 00042 #include <utils/common/ToString.h> 00043 #include <utils/geom/PositionVector.h> 00044 #include <utils/geom/GeomHelper.h> 00045 #include <utils/distribution/Distribution.h> 00046 #include <netbuild/NBDistribution.h> 00047 #include <netbuild/NBNode.h> 00048 #include <netbuild/NBNodeCont.h> 00049 #include <utils/options/OptionsCont.h> 00050 #include "NIVissimNodeCluster.h" 00051 #include "NIVissimDistrictConnection.h" 00052 #include "NIVissimClosedLanesVector.h" 00053 #include "NIVissimConnection.h" 00054 #include "NIVissimDisturbance.h" 00055 #include "NIVissimEdge.h" 00056 #include <utils/common/MsgHandler.h> 00057 00058 #ifdef CHECK_MEMORY_LEAKS 00059 #include <foreign/nvwa/debug_new.h> 00060 #endif // CHECK_MEMORY_LEAKS 00061 00062 00063 // =========================================================================== 00064 // static members 00065 // =========================================================================== 00066 NIVissimEdge::DictType NIVissimEdge::myDict; 00067 int NIVissimEdge::myMaxID = 0; 00068 std::vector<std::string> NIVissimEdge::myLanesWithMissingSpeeds; 00069 00070 00071 // =========================================================================== 00072 // method definitions 00073 // =========================================================================== 00074 NIVissimEdge::connection_position_sorter::connection_position_sorter(int edgeid) 00075 : myEdgeID(edgeid) {} 00076 00077 00078 int 00079 NIVissimEdge::connection_position_sorter::operator()(int c1id, 00080 int c2id) const { 00081 NIVissimConnection* c1 = NIVissimConnection::dictionary(c1id); 00082 NIVissimConnection* c2 = NIVissimConnection::dictionary(c2id); 00083 SUMOReal pos1 = 00084 c1->getFromEdgeID() == myEdgeID 00085 ? c1->getFromPosition() : c1->getToPosition(); 00086 SUMOReal pos2 = 00087 c2->getFromEdgeID() == myEdgeID 00088 ? c2->getFromPosition() : c2->getToPosition(); 00089 return pos1 < pos2; 00090 } 00091 00092 00093 00094 00095 00096 00097 00098 00099 NIVissimEdge::connection_cluster_position_sorter::connection_cluster_position_sorter(int edgeid) 00100 : myEdgeID(edgeid) {} 00101 00102 00103 int 00104 NIVissimEdge::connection_cluster_position_sorter::operator()( 00105 NIVissimConnectionCluster* cc1, 00106 NIVissimConnectionCluster* cc2) const { 00107 SUMOReal pos1 = cc1->getPositionForEdge(myEdgeID); 00108 SUMOReal pos2 = cc2->getPositionForEdge(myEdgeID); 00109 if (pos2 < 0 || pos1 < 0) { 00110 cc1->getPositionForEdge(myEdgeID); 00111 cc2->getPositionForEdge(myEdgeID); 00112 } 00113 assert(pos1 >= 0 && pos2 >= 0); 00114 return pos1 < pos2; 00115 } 00116 00117 00118 00119 00120 NIVissimEdge::NIVissimEdge(int id, const std::string& name, 00121 const std::string& type, int noLanes, 00122 SUMOReal zuschlag1, SUMOReal zuschlag2, 00123 SUMOReal /*length*/, const PositionVector& geom, 00124 const NIVissimClosedLanesVector& clv) 00125 : NIVissimAbstractEdge(id, geom), 00126 myName(name), myType(type), myNoLanes(noLanes), 00127 myZuschlag1(zuschlag1), myZuschlag2(zuschlag2), 00128 myClosedLanes(clv), myAmWithinJunction(false) { //, mySpeed(-1) 00129 assert(noLanes >= 0); 00130 if (myMaxID < myID) { 00131 myMaxID = myID; 00132 } 00133 for (int i = 0; i < noLanes; i++) { 00134 myLaneSpeeds.push_back(-1); 00135 } 00136 } 00137 00138 00139 NIVissimEdge::~NIVissimEdge() { 00140 for (NIVissimClosedLanesVector::iterator i = myClosedLanes.begin(); i != myClosedLanes.end(); i++) { 00141 delete(*i); 00142 } 00143 myClosedLanes.clear(); 00144 } 00145 00146 00147 bool 00148 NIVissimEdge::dictionary(int id, const std::string& name, 00149 const std::string& type, int noLanes, 00150 SUMOReal zuschlag1, SUMOReal zuschlag2, SUMOReal length, 00151 const PositionVector& geom, 00152 const NIVissimClosedLanesVector& clv) { 00153 NIVissimEdge* o = new NIVissimEdge(id, name, type, noLanes, zuschlag1, 00154 zuschlag2, length, geom, clv); 00155 if (!dictionary(id, o)) { 00156 delete o; 00157 return false; 00158 } 00159 return true; 00160 } 00161 00162 00163 00164 bool 00165 NIVissimEdge::dictionary(int id, NIVissimEdge* o) { 00166 DictType::iterator i = myDict.find(id); 00167 if (i == myDict.end()) { 00168 myDict[id] = o; 00169 return true; 00170 } 00171 return false; 00172 } 00173 00174 00175 00176 NIVissimEdge* 00177 NIVissimEdge::dictionary(int id) { 00178 DictType::iterator i = myDict.find(id); 00179 if (i == myDict.end()) { 00180 return 0; 00181 } 00182 return (*i).second; 00183 } 00184 00185 00186 void 00187 NIVissimEdge::buildConnectionClusters() { 00188 const SUMOReal MAX_CLUSTER_DISTANCE = 10; 00189 // build clusters for all edges made up from not previously assigne 00190 // connections 00191 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00192 int edgeid = (*i).first; 00193 NIVissimEdge* edge = (*i).second; 00194 // get all connectors using this edge 00195 std::vector<int> connectors = edge->myIncomingConnections; 00196 copy(edge->myOutgoingConnections.begin(), edge->myOutgoingConnections.end(), back_inserter(connectors)); 00197 if (connectors.size() == 0) { 00198 continue; 00199 } 00200 // sort the connectors by the place on the edge 00201 sort(connectors.begin(), connectors.end(), connection_position_sorter(edgeid)); 00202 // try to cluster the connections participating within the current edge 00203 std::vector<int> currentCluster; 00204 std::vector<int>::iterator j = connectors.begin(); 00205 bool outgoing = NIVissimConnection::dictionary(*j)->getFromEdgeID() == (*i).first; 00206 SUMOReal position = outgoing 00207 ? NIVissimConnection::dictionary(*j)->getFromPosition() 00208 : NIVissimConnection::dictionary(*j)->getToPosition(); 00209 00210 // skip connections already in a cluster 00211 // !!! (?) 00212 while (j != connectors.end() && NIVissimConnection::dictionary(*j)->hasNodeCluster()) { 00213 ++j; 00214 } 00215 if (j == connectors.end()) { 00216 continue; 00217 } 00218 currentCluster.push_back(*j); 00219 do { 00220 if (j + 1 != connectors.end() && !NIVissimConnection::dictionary(*j)->hasNodeCluster()) { 00221 bool n_outgoing = NIVissimConnection::dictionary(*(j + 1))->getFromEdgeID() == edgeid; 00222 SUMOReal n_position = n_outgoing 00223 ? NIVissimConnection::dictionary(*(j + 1))->getFromPosition() 00224 : NIVissimConnection::dictionary(*(j + 1))->getToPosition(); 00225 if (n_outgoing == outgoing && fabs(n_position - position) < MAX_CLUSTER_DISTANCE) { 00226 // ok, in same cluster as prior 00227 currentCluster.push_back(*(j + 1)); 00228 } else { 00229 // start new cluster 00230 VectorHelper<int>::removeDouble(currentCluster); 00231 edge->myConnectionClusters.push_back(new NIVissimConnectionCluster(currentCluster, -1, edgeid)); 00232 currentCluster.clear(); 00233 currentCluster.push_back(*(j + 1)); 00234 } 00235 outgoing = n_outgoing; 00236 position = n_position; 00237 } 00238 j++; 00239 } while (j != connectors.end()); 00240 // add last connection 00241 if (currentCluster.size() > 0) { 00242 VectorHelper<int>::removeDouble(currentCluster); 00243 edge->myConnectionClusters.push_back(new NIVissimConnectionCluster(currentCluster, -1, edgeid)); 00244 } 00245 } 00246 } 00247 00248 00249 void 00250 NIVissimEdge::dict_buildNBEdges(NBDistrictCont& dc, NBNodeCont& nc, 00251 NBEdgeCont& ec, SUMOReal offset) { 00252 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00253 NIVissimEdge* edge = (*i).second; 00254 edge->buildNBEdge(dc, nc, ec, offset); 00255 } 00256 } 00257 00258 00259 void 00260 NIVissimEdge::dict_propagateSpeeds(/* NBDistribution &dc */) { 00261 DictType::iterator i; 00262 for (i = myDict.begin(); i != myDict.end(); i++) { 00263 NIVissimEdge* edge = (*i).second; 00264 edge->setDistrictSpeed(/* dc */); 00265 } 00266 for (i = myDict.begin(); i != myDict.end(); i++) { 00267 NIVissimEdge* edge = (*i).second; 00268 edge->propagateSpeed(/* dc */ -1, std::vector<int>()); 00269 } 00270 for (int j = 0; j < 3; j++) { 00271 for (i = myDict.begin(); i != myDict.end(); i++) { 00272 NIVissimEdge* edge = (*i).second; 00273 edge->propagateOwn(/* dc */); 00274 } 00275 for (i = myDict.begin(); i != myDict.end(); i++) { 00276 NIVissimEdge* edge = (*i).second; 00277 edge->checkUnconnectedLaneSpeeds(/* dc */); 00278 } 00279 } 00280 } 00281 00282 00283 void 00284 NIVissimEdge::checkUnconnectedLaneSpeeds(/* NBDistribution &dc */) { 00285 for (int i = 0; i < (int) myLaneSpeeds.size(); i++) { 00286 if (myLaneSpeeds[i] == -1) { 00287 SUMOReal speed = -1; 00288 int j1 = i - 1; // !!! recheck - j1 may become negative? 00289 int j2 = i; 00290 while (j2 != (int) myLaneSpeeds.size() && myLaneSpeeds[j2] == -1) { 00291 j2++; 00292 } 00293 if (j1 < 0) { 00294 if (j2 < (int) myLaneSpeeds.size()) { 00295 speed = myLaneSpeeds[j2]; 00296 } 00297 } else { 00298 if (j2 >= (int) myLaneSpeeds.size()) { 00299 speed = myLaneSpeeds[j1]; 00300 } else { 00301 speed = (myLaneSpeeds[j1] + myLaneSpeeds[j2]) / (SUMOReal) 2.0; 00302 } 00303 } 00304 if (speed == -1) { 00305 continue; 00306 } 00307 myLaneSpeeds[i] = speed; 00308 std::vector<NIVissimConnection*> connected = getOutgoingConnected(i); 00309 for (std::vector<NIVissimConnection*>::iterator j = connected.begin(); j != connected.end(); j++) { 00310 NIVissimConnection* c = *j; 00311 NIVissimEdge* e = NIVissimEdge::dictionary(c->getToEdgeID()); 00312 // propagate 00313 e->propagateSpeed(/*dc, */speed, c->getToLanes()); 00314 } 00315 } 00316 } 00317 } 00318 00319 00320 void 00321 NIVissimEdge::propagateOwn(/* NBDistribution &dc */) { 00322 for (int i = 0; i < (int) myLaneSpeeds.size(); i++) { 00323 if (myLaneSpeeds[i] == -1) { 00324 continue; 00325 } 00326 std::vector<NIVissimConnection*> connected = getOutgoingConnected(i); 00327 for (std::vector<NIVissimConnection*>::iterator j = connected.begin(); j != connected.end(); j++) { 00328 NIVissimConnection* c = *j; 00329 NIVissimEdge* e = NIVissimEdge::dictionary(c->getToEdgeID()); 00330 // propagate 00331 e->propagateSpeed(/*dc, */myLaneSpeeds[i], c->getToLanes()); 00332 } 00333 } 00334 } 00335 00336 00337 void 00338 NIVissimEdge::propagateSpeed(/* NBDistribution &dc */ SUMOReal speed, std::vector<int> forLanes) { 00339 // if no lane is given, all set be set 00340 if (forLanes.size() == 0) { 00341 for (size_t i = 0; i < myNoLanes; i++) { 00342 forLanes.push_back((int) i); 00343 } 00344 } 00345 // for the case of a first call 00346 // go through the lanes 00347 for (std::vector<int>::const_iterator i = forLanes.begin(); i < forLanes.end(); i++) { 00348 // check whether a speed was set before 00349 if (myLaneSpeeds[*i] != -1) { 00350 // do not reset it from incoming 00351 continue; 00352 } 00353 // check whether the lane has a new speed to set 00354 if ((int) myPatchedSpeeds.size() > *i && myPatchedSpeeds[*i] != -1) { 00355 // use it 00356 speed = getRealSpeed(/*dc, */myPatchedSpeeds[*i]); 00357 } 00358 // check whether a speed is given 00359 if (speed == -1) { 00360 // do nothing if not 00361 continue; 00362 } 00363 // set the lane's speed to the given 00364 myLaneSpeeds[*i] = speed; 00365 // propagate the speed further 00366 // get the list of connected edges 00367 std::vector<NIVissimConnection*> connected = getOutgoingConnected(*i); 00368 // go throught the list 00369 for (std::vector<NIVissimConnection*>::iterator j = connected.begin(); j != connected.end(); j++) { 00370 NIVissimConnection* c = *j; 00371 NIVissimEdge* e = NIVissimEdge::dictionary(c->getToEdgeID()); 00372 // propagate 00373 e->propagateSpeed(/*dc, */speed, c->getToLanes()); 00374 } 00375 } 00376 } 00377 00378 00379 00380 void 00381 NIVissimEdge::setDistrictSpeed(/* NBDistribution &dc */) { 00382 if (myDistrictConnections.size() > 0) { 00383 SUMOReal pos = *(myDistrictConnections.begin()); 00384 if (pos < getLength() - pos) { 00385 NIVissimDistrictConnection* d = 00386 NIVissimDistrictConnection::dict_findForEdge(myID); 00387 if (d != 0) { 00388 SUMOReal speed = d->getMeanSpeed(/*dc*/); 00389 if (speed == -1) { 00390 return; 00391 } 00392 for (unsigned int i = 0; i < myNoLanes; i++) { 00393 myLaneSpeeds[i] = speed; 00394 // propagate the speed further 00395 // get the list of connected edges 00396 std::vector<NIVissimConnection*> connected = getOutgoingConnected(i); 00397 // go throught the list 00398 for (std::vector<NIVissimConnection*>::iterator j = connected.begin(); j != connected.end(); j++) { 00399 NIVissimConnection* c = *j; 00400 NIVissimEdge* e = NIVissimEdge::dictionary(c->getToEdgeID()); 00401 // propagate 00402 e->propagateSpeed(/*dc, */speed, c->getToLanes()); 00403 } 00404 } 00405 } 00406 } 00407 } 00408 } 00409 00410 00411 std::vector<NIVissimConnection*> 00412 NIVissimEdge::getOutgoingConnected(int lane) const { 00413 std::vector<NIVissimConnection*> ret; 00414 for (std::vector<int>::const_iterator i = myOutgoingConnections.begin(); i != myOutgoingConnections.end(); i++) { 00415 NIVissimConnection* c = NIVissimConnection::dictionary(*i); 00416 const std::vector<int>& lanes = c->getFromLanes(); 00417 if (find(lanes.begin(), lanes.end(), lane) != lanes.end()) { 00418 NIVissimEdge* e = NIVissimEdge::dictionary(c->getToEdgeID()); 00419 if (e != 0) { 00420 ret.push_back(c); 00421 } 00422 } 00423 } 00424 return ret; 00425 } 00426 00427 00428 void 00429 NIVissimEdge::buildNBEdge(NBDistrictCont& dc, NBNodeCont& nc, NBEdgeCont& ec, 00430 SUMOReal sameNodesOffset) { 00431 // build the edge 00432 std::pair<NIVissimConnectionCluster*, NBNode*> fromInf, toInf; 00433 NBNode* fromNode, *toNode; 00434 fromNode = toNode = 0; 00435 sort(myConnectionClusters.begin(), myConnectionClusters.end(), connection_cluster_position_sorter(myID)); 00436 sort(myDistrictConnections.begin(), myDistrictConnections.end()); 00437 ConnectionClusters tmpClusters = myConnectionClusters; 00438 if (tmpClusters.size() != 0) { 00439 sort(tmpClusters.begin(), tmpClusters.end(), connection_cluster_position_sorter(myID)); 00440 // get or build the from-node 00441 // A node may have to be build when the edge starts or ends at 00442 // a parking place or something like this 00443 fromInf = getFromNode(nc, tmpClusters); 00444 fromNode = fromInf.second; 00445 // get or build the to-node 00446 //if(tmpClusters.size()>0) { 00447 toInf = getToNode(nc, tmpClusters); 00448 toNode = toInf.second; 00449 if (fromInf.first != 0 && toNode != 0 && fromInf.first->around(toNode->getPosition())) { 00450 WRITE_WARNING("Will not build edge '" + toString(myID) + "'."); 00451 myAmWithinJunction = true; 00452 return; 00453 } 00454 //} 00455 // if both nodes are the same, resolve the problem otherwise 00456 if (fromNode == toNode) { 00457 std::pair<NBNode*, NBNode*> tmp = resolveSameNode(nc, sameNodesOffset, fromNode, toNode); 00458 if (fromNode != tmp.first) { 00459 fromInf.first = 0; 00460 } 00461 if (toNode != tmp.second) { 00462 toInf.first = 0; 00463 } 00464 fromNode = tmp.first; 00465 toNode = tmp.second; 00466 } 00467 } 00468 00469 // 00470 if (fromNode == 0) { 00471 fromInf.first = 0; 00472 Position pos = myGeom[0]; 00473 fromNode = new NBNode(toString<int>(myID) + "-SourceNode", pos, NODETYPE_NOJUNCTION); 00474 if (!nc.insert(fromNode)) { 00475 throw ProcessError("Could not insert node '" + fromNode->getID() + "' to nodes container."); 00476 } 00477 } 00478 if (toNode == 0) { 00479 toInf.first = 0; 00480 Position pos = myGeom[-1]; 00481 toNode = new NBNode(toString<int>(myID) + "-DestinationNode", pos, NODETYPE_NOJUNCTION); 00482 if (!nc.insert(toNode)) { 00483 throw ProcessError("Could not insert node '" + toNode->getID() + "' to nodes container."); 00484 } 00485 } 00486 00487 // build the edge 00488 SUMOReal avgSpeed = 0; 00489 int i; 00490 for (i = 0; i < (int) myNoLanes; i++) { 00491 if (myLaneSpeeds.size() <= (size_t) i || myLaneSpeeds[i] == -1) { 00492 myLanesWithMissingSpeeds.push_back(toString(myID) + "_" + toString(i)); 00493 avgSpeed += OptionsCont::getOptions().getFloat("vissim.default-speed"); 00494 } else { 00495 avgSpeed += myLaneSpeeds[i]; 00496 } 00497 } 00498 avgSpeed /= (SUMOReal) myLaneSpeeds.size(); 00499 avgSpeed *= OptionsCont::getOptions().getFloat("vissim.speed-norm"); 00500 00501 if (fromNode == toNode) { 00502 WRITE_WARNING("Could not build edge '" + toString(myID) + "'; would connect same node."); 00503 return; 00504 } 00505 00506 NBEdge* buildEdge = new NBEdge(toString<int>(myID), fromNode, toNode, myType, 00507 avgSpeed / (SUMOReal) 3.6, myNoLanes, -1, -1, -1, myGeom, myName, LANESPREAD_CENTER, true); 00508 for (i = 0; i < (int) myNoLanes; i++) { 00509 if ((int) myLaneSpeeds.size() <= i || myLaneSpeeds[i] == -1) { 00510 buildEdge->setSpeed(i, OptionsCont::getOptions().getFloat("vissim.default-speed") / (SUMOReal) 3.6); 00511 } else { 00512 buildEdge->setSpeed(i, myLaneSpeeds[i] / (SUMOReal) 3.6); 00513 } 00514 } 00515 ec.insert(buildEdge); 00516 // check whether the edge contains any other clusters 00517 if (tmpClusters.size() > 0) { 00518 bool cont = true; 00519 for (ConnectionClusters::iterator j = tmpClusters.begin(); cont && j != tmpClusters.end(); ++j) { 00520 // split the edge at the previously build node 00521 std::string nextID = buildEdge->getID() + "[1]"; 00522 cont = ec.splitAt(dc, buildEdge, (*j)->getNBNode()); 00523 // !!! what to do if the edge could not be split? 00524 buildEdge = ec.retrieve(nextID); 00525 } 00526 } 00527 } 00528 00529 00530 SUMOReal 00531 NIVissimEdge::getRealSpeed(/* NBDistribution &dc */ int distNo) { 00532 std::string id = toString<int>(distNo); 00533 Distribution* dist = NBDistribution::dictionary("speed", id); 00534 if (dist == 0) { 00535 WRITE_WARNING("The referenced speed distribution '" + id + "' is not known."); 00536 return -1; 00537 } 00538 assert(dist != 0); 00539 SUMOReal speed = dist->getMax(); 00540 if (speed < 0 || speed > 1000) { 00541 WRITE_WARNING("What about distribution '" + toString<int>(distNo) + "' "); 00542 } 00543 return speed; 00544 } 00545 00546 /* 00547 bool 00548 NIVissimEdge::recheckSpeedPatches() 00549 { 00550 // size_t speed_idx = -1; 00551 // check set speeds 00552 if(myPatchedSpeeds.size()!=0) { 00553 std::vector<SUMOReal>::iterator i = 00554 find(myPatchedSpeeds.begin(), myPatchedSpeeds.end(), -1); 00555 if(myPatchedSpeeds.size()!=myNoLanes||i!=myPatchedSpeeds.end()) { 00556 cot << "Warning! Not all lanes are patched! (edge:" << myID << ")." << endl; 00557 } 00558 // 00559 if(std::vector<SUMOReal>Helper::maxValue(myPatchedSpeeds)!=std::vector<SUMOReal>Helper::minValue(myPatchedSpeeds)) { 00560 cot << "Warning! Not all lanes have the same speed!! (edge:" << myID << ")." << endl; 00561 } 00562 // 00563 / // !!! ist natuerlich Quatsch - erst recht, wenn Edges zusammengefasst werden 00564 speed = std::vector<SUMOReal>Helper::sum(myPatchedSpeeds); 00565 speed /= (SUMOReal) myPatchedSpeeds.size();*/ 00566 /* return true; 00567 } 00568 if(myDistrictConnections.size()>0) { 00569 SUMOReal pos = *(myDistrictConnections.begin()); 00570 // if(pos<10) { 00571 NIVissimDistrictConnection *d = 00572 NIVissimDistrictConnection::dict_findForEdge(myID); 00573 if(d!=0) { 00574 return true; 00575 // speed = d->getMeanSpeed(); 00576 } 00577 // } 00578 // return true; 00579 } 00580 return false; 00581 } 00582 */ 00583 00584 std::pair<NIVissimConnectionCluster*, NBNode*> 00585 NIVissimEdge::getFromNode(NBNodeCont& nc, ConnectionClusters& clusters) { 00586 const SUMOReal MAX_DISTANCE = 10.; 00587 assert(clusters.size() >= 1); 00588 const Position& beg = myGeom.getBegin(); 00589 NIVissimConnectionCluster* c = *(clusters.begin()); 00590 // check whether the edge starts within a already build node 00591 if (c->around(beg, MAX_DISTANCE)) { 00592 clusters.erase(clusters.begin()); 00593 return std::pair<NIVissimConnectionCluster*, NBNode*> 00594 (c, c->getNBNode()); 00595 } 00596 // check for a parking place at the begin 00597 if (myDistrictConnections.size() > 0) { 00598 SUMOReal pos = *(myDistrictConnections.begin()); 00599 if (pos < 10) { 00600 NBNode* node = new NBNode(toString<int>(myID) + "-begin", beg, NODETYPE_NOJUNCTION); 00601 if (!nc.insert(node)) { 00602 throw 1; 00603 } 00604 while (myDistrictConnections.size() > 0 && *(myDistrictConnections.begin()) < 10) { 00605 myDistrictConnections.erase(myDistrictConnections.begin()); 00606 } 00607 return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node); 00608 } 00609 } 00610 // build a new node for the edge's begin otherwise 00611 NBNode* node = new NBNode(toString<int>(myID) + "-begin", beg, NODETYPE_NOJUNCTION); 00612 if (!nc.insert(node)) { 00613 throw 1; 00614 } 00615 return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node); 00616 } 00617 00618 00619 std::pair<NIVissimConnectionCluster*, NBNode*> 00620 NIVissimEdge::getToNode(NBNodeCont& nc, ConnectionClusters& clusters) { 00621 const Position& end = myGeom.getEnd(); 00622 if (clusters.size() > 0) { 00623 const SUMOReal MAX_DISTANCE = 10.; 00624 assert(clusters.size() >= 1); 00625 NIVissimConnectionCluster* c = *(clusters.end() - 1); 00626 // check whether the edge ends within a already build node 00627 if (c->around(end, MAX_DISTANCE)) { 00628 clusters.erase(clusters.end() - 1); 00629 return std::pair<NIVissimConnectionCluster*, NBNode*>(c, c->getNBNode()); 00630 } 00631 } 00632 // check for a parking place at the end 00633 if (myDistrictConnections.size() > 0) { 00634 SUMOReal pos = *(myDistrictConnections.end() - 1); 00635 if (pos > myGeom.length() - 10) { 00636 NBNode* node = new NBNode(toString<int>(myID) + "-end", end, NODETYPE_NOJUNCTION); 00637 if (!nc.insert(node)) { 00638 throw 1; 00639 } 00640 while (myDistrictConnections.size() > 0 && *(myDistrictConnections.end() - 1) < myGeom.length() - 10) { 00641 myDistrictConnections.erase(myDistrictConnections.end() - 1); 00642 } 00643 return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node); 00644 } 00645 } 00646 00647 // build a new node for the edge's end otherwise 00648 NBNode* node = new NBNode(toString<int>(myID) + "-end", end, NODETYPE_NOJUNCTION); 00649 if (!nc.insert(node)) { 00650 throw 1; 00651 } 00652 return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), node); 00653 /* 00654 if (clusters.size()>0) { 00655 NIVissimConnectionCluster *c = *(clusters.end()-1); 00656 clusters.erase(clusters.end()-1); 00657 return std::pair<NIVissimConnectionCluster*, NBNode*>(c, c->getNBNode()); 00658 } else { 00659 // !!! self-loop edge?! 00660 return std::pair<NIVissimConnectionCluster*, NBNode*>(static_cast<NIVissimConnectionCluster*>(0), (*(myConnectionClusters.begin()))->getNBNode()); 00661 } 00662 */ 00663 } 00664 00665 00666 std::pair<NBNode*, NBNode*> 00667 NIVissimEdge::remapOneOfNodes(NBNodeCont& nc, 00668 NIVissimDistrictConnection* d, 00669 NBNode* fromNode, NBNode* toNode) { 00670 std::string nid = "ParkingPlace" + toString<int>(d->getID()); 00671 if (d->geomPosition().distanceTo(fromNode->getPosition()) 00672 < 00673 d->geomPosition().distanceTo(toNode->getPosition())) { 00674 00675 NBNode* newNode = new NBNode(nid, 00676 fromNode->getPosition(), 00677 NODETYPE_NOJUNCTION); 00678 nc.erase(fromNode); 00679 nc.insert(newNode); 00680 return std::pair<NBNode*, NBNode*>(newNode, toNode); 00681 } else { 00682 NBNode* newNode = new NBNode(nid, 00683 toNode->getPosition(), 00684 NODETYPE_NOJUNCTION); 00685 nc.erase(toNode); 00686 nc.insert(newNode); 00687 return std::pair<NBNode*, NBNode*>(fromNode, newNode); 00688 } 00689 } 00690 00691 00692 00693 std::pair<NBNode*, NBNode*> 00694 NIVissimEdge::resolveSameNode(NBNodeCont& nc, SUMOReal offset, 00695 NBNode* prevFrom, NBNode* prevTo) { 00696 // check whether the edge is connected to a district 00697 // use it if so 00698 NIVissimDistrictConnection* d = 00699 NIVissimDistrictConnection::dict_findForEdge(myID); 00700 if (d != 0) { 00701 Position pos = d->geomPosition(); 00702 SUMOReal position = d->getPosition(); 00703 // the district is at the begin of the edge 00704 if (myGeom.length() - position > position) { 00705 std::string nid = "ParkingPlace" + toString<int>(d->getID()); 00706 NBNode* node = nc.retrieve(nid); 00707 if (node == 0) { 00708 node = new NBNode(nid, 00709 pos, NODETYPE_NOJUNCTION); 00710 if (!nc.insert(node)) { 00711 throw 1; 00712 } 00713 } 00714 return std::pair<NBNode*, NBNode*>(node, prevTo); 00715 } 00716 // the district is at the end of the edge 00717 else { 00718 std::string nid = "ParkingPlace" + toString<int>(d->getID()); 00719 NBNode* node = nc.retrieve(nid); 00720 if (node == 0) { 00721 node = new NBNode(nid, pos, NODETYPE_NOJUNCTION); 00722 if (!nc.insert(node)) { 00723 throw 1; 00724 } 00725 } 00726 assert(node != 0); 00727 return std::pair<NBNode*, NBNode*>(prevFrom, node); 00728 } 00729 } 00730 // otherwise, check whether the edge is some kind of 00731 // a dead end... 00732 // check which end is nearer to the node centre 00733 if (myConnectionClusters.size() == 1) { 00734 NBNode* node = prevFrom; // it is the same as getToNode() 00735 00736 NIVissimConnectionCluster* c = *(myConnectionClusters.begin()); 00737 // no end node given 00738 if (c->around(myGeom.getBegin(), offset) && !c->around(myGeom.getEnd(), offset)) { 00739 NBNode* end = new NBNode( 00740 toString<int>(myID) + "-End", 00741 myGeom.getEnd(), 00742 NODETYPE_NOJUNCTION); 00743 if (!nc.insert(end)) { 00744 throw 1; 00745 } 00746 return std::pair<NBNode*, NBNode*>(node, end); 00747 } 00748 00749 // no begin node given 00750 if (!c->around(myGeom.getBegin(), offset) && c->around(myGeom.getEnd(), offset)) { 00751 NBNode* beg = new NBNode( 00752 toString<int>(myID) + "-Begin", 00753 myGeom.getBegin(), 00754 NODETYPE_NOJUNCTION); 00755 if (!nc.insert(beg)) { 00756 std::cout << "nope, NIVissimDisturbance" << std::endl; 00757 throw 1; 00758 } 00759 return std::pair<NBNode*, NBNode*>(beg, node); 00760 } 00761 00762 // self-loop edge - both points lie within the same cluster 00763 if (c->around(myGeom.getBegin()) && c->around(myGeom.getEnd())) { 00764 return std::pair<NBNode*, NBNode*>(node, node); 00765 } 00766 } 00767 // what to do in other cases? 00768 // It simply is a self-looping edge.... 00769 return std::pair<NBNode*, NBNode*>(prevFrom, prevTo); 00770 } 00771 00772 00773 00774 00775 void 00776 NIVissimEdge::setNodeCluster(int nodeid) { 00777 myNode = nodeid; 00778 } 00779 00780 00781 void 00782 NIVissimEdge::buildGeom() {} 00783 00784 00785 void 00786 NIVissimEdge::addIncomingConnection(int id) { 00787 myIncomingConnections.push_back(id); 00788 } 00789 00790 00791 void 00792 NIVissimEdge::addOutgoingConnection(int id) { 00793 myOutgoingConnections.push_back(id); 00794 } 00795 00796 00797 00798 void 00799 NIVissimEdge::mergedInto(NIVissimConnectionCluster* old, 00800 NIVissimConnectionCluster* act) { 00801 ConnectionClusters::iterator i = 00802 find(myConnectionClusters.begin(), myConnectionClusters.end(), old); 00803 if (i != myConnectionClusters.end()) { 00804 myConnectionClusters.erase(i); 00805 } 00806 i = find(myConnectionClusters.begin(), myConnectionClusters.end(), act); 00807 if (i == myConnectionClusters.end()) { 00808 myConnectionClusters.push_back(act); 00809 } 00810 } 00811 00812 00813 00814 void 00815 NIVissimEdge::removeFromConnectionCluster(NIVissimConnectionCluster* c) { 00816 ConnectionClusters::iterator i = 00817 find(myConnectionClusters.begin(), myConnectionClusters.end(), c); 00818 assert(i != myConnectionClusters.end()); 00819 myConnectionClusters.erase(i); 00820 } 00821 00822 00823 void 00824 NIVissimEdge::addToConnectionCluster(NIVissimConnectionCluster* c) { 00825 ConnectionClusters::iterator i = 00826 find(myConnectionClusters.begin(), myConnectionClusters.end(), c); 00827 if (i == myConnectionClusters.end()) { 00828 myConnectionClusters.push_back(c); 00829 } 00830 } 00831 00832 00833 Position // !!! reference? 00834 NIVissimEdge::getBegin2D() const { 00835 return myGeom[0]; 00836 } 00837 00838 00839 Position // !!! reference? 00840 NIVissimEdge::getEnd2D() const { 00841 return myGeom[-1]; 00842 } 00843 00844 00845 SUMOReal 00846 NIVissimEdge::getLength() const { 00847 return myGeom.length(); 00848 } 00849 00850 00851 void 00852 NIVissimEdge::checkDistrictConnectionExistanceAt(SUMOReal pos) { 00853 if (find(myDistrictConnections.begin(), myDistrictConnections.end(), pos) == myDistrictConnections.end()) { 00854 myDistrictConnections.push_back(pos); 00855 /* int id = NIVissimConnection::getMaxID() + 1; 00856 std::vector<int> currentCluster; 00857 currentCluster.push_back(id); 00858 myConnectionClusters.push_back( 00859 new NIVissimConnectionCluster(currentCluster, -1, myID));*/ 00860 } 00861 } 00862 00863 00864 void 00865 NIVissimEdge::setSpeed(size_t lane, int speedDist) { 00866 while (myPatchedSpeeds.size() <= lane) { 00867 myPatchedSpeeds.push_back(-1); 00868 } 00869 myPatchedSpeeds[lane] = speedDist; 00870 } 00871 00872 00873 void 00874 NIVissimEdge::dict_checkEdges2Join() { 00875 // go through the edges 00876 for (DictType::iterator i1 = myDict.begin(); i1 != myDict.end(); i1++) { 00877 // retrieve needed values from the first edge 00878 NIVissimEdge* e1 = (*i1).second; 00879 const PositionVector& g1 = e1->getGeometry(); 00880 // check all other edges 00881 DictType::iterator i2 = i1; 00882 i2++; 00883 for (; i2 != myDict.end(); i2++) { 00884 // retrieve needed values from the second edge 00885 NIVissimEdge* e2 = (*i2).second; 00886 const PositionVector& g2 = e2->getGeometry(); 00887 // get the connection description 00888 NIVissimConnection* c = e1->getConnectionTo(e2); 00889 if (c == 0) { 00890 c = e2->getConnectionTo(e1); 00891 } 00892 // the edge must not be a direct contiuation of the other 00893 if (c != 0) { 00894 if ((c->getFromEdgeID() == e1->getID() && fabs(c->getFromPosition() - e1->getGeometry().length()) < 5) 00895 || 00896 (c->getFromEdgeID() == e2->getID() && fabs(c->getFromPosition() - e2->getGeometry().length()) < 5)) { 00897 00898 continue; 00899 } 00900 } 00901 // only parallel edges which do end at the same node 00902 // should be joined 00903 // retrieve the "approximating" lines first 00904 Line l1 = Line(g1.getBegin(), g1.getEnd()); 00905 Line l2 = Line(g2.getBegin(), g2.getEnd()); 00906 // check for parallelity 00907 // !!! the usage of an explicit value is not very fine 00908 if (fabs(l1.atan2DegreeAngle() - l2.atan2DegreeAngle()) > 2.0) { 00909 // continue if the lines are not parallel 00910 continue; 00911 } 00912 00913 // check whether the same node is approached 00914 // (the distance between the ends should not be too large) 00915 // !!! the usage of an explicit value is not very fine 00916 if (l1.p2().distanceTo(l2.p2()) > 10) { 00917 // continue if the lines do not end at the same length 00918 continue; 00919 } 00920 // ok, seem to be different lanes for the same edge 00921 // mark as possibly joined later 00922 e1->addToTreatAsSame(e2); 00923 e2->addToTreatAsSame(e1); 00924 } 00925 } 00926 } 00927 00928 00929 bool 00930 NIVissimEdge::addToTreatAsSame(NIVissimEdge* e) { 00931 if (e == this) { 00932 return false; 00933 } 00934 // check whether this edge already knows about the other 00935 if (find(myToTreatAsSame.begin(), myToTreatAsSame.end(), e) == myToTreatAsSame.end()) { 00936 myToTreatAsSame.push_back(e); 00937 return true; 00938 } else { 00939 return false; // !!! check this 00940 } 00941 // 00942 std::vector<NIVissimEdge*>::iterator i; 00943 // add to all other that shall be treated as same 00944 bool changed = true; 00945 while (changed) { 00946 changed = false; 00947 for (i = myToTreatAsSame.begin(); !changed && i != myToTreatAsSame.end(); i++) { 00948 changed |= (*i)->addToTreatAsSame(e); 00949 } 00950 for (i = myToTreatAsSame.begin(); !changed && i != myToTreatAsSame.end(); i++) { 00951 changed |= e->addToTreatAsSame(*i); 00952 } 00953 } 00954 } 00955 00956 NIVissimConnection* 00957 NIVissimEdge::getConnectionTo(NIVissimEdge* e) { 00958 std::vector<int>::iterator i; 00959 for (i = myIncomingConnections.begin(); i != myIncomingConnections.end(); i++) { 00960 NIVissimConnection* c = NIVissimConnection::dictionary(*i); 00961 if (c->getFromEdgeID() == e->getID()) { 00962 return c; 00963 } 00964 } 00965 for (i = myOutgoingConnections.begin(); i != myOutgoingConnections.end(); i++) { 00966 NIVissimConnection* c = NIVissimConnection::dictionary(*i); 00967 if (c->getToEdgeID() == e->getID()) { 00968 return c; 00969 } 00970 } 00971 return 0; 00972 } 00973 00974 00975 const std::vector<NIVissimEdge*> & 00976 NIVissimEdge::getToTreatAsSame() const { 00977 return myToTreatAsSame; 00978 } 00979 00980 00981 void 00982 NIVissimEdge::reportUnsetSpeeds() { 00983 if (myLanesWithMissingSpeeds.size() == 0) { 00984 return; 00985 } 00986 std::ostringstream str; 00987 str << "The following lanes have no explicit speed information:\n "; 00988 for (std::vector<std::string>::iterator i = myLanesWithMissingSpeeds.begin(); i != myLanesWithMissingSpeeds.end(); ++i) { 00989 if (i != myLanesWithMissingSpeeds.begin()) { 00990 str << ", "; 00991 } 00992 str << *i; 00993 } 00994 WRITE_WARNING(str.str()); 00995 } 00996 00997 00998 NIVissimEdge* 00999 NIVissimEdge::getBestIncoming() const { 01000 for (std::vector<int>::const_iterator i = myIncomingConnections.begin(); i != myIncomingConnections.end(); ++i) { 01001 NIVissimConnection* c = NIVissimConnection::dictionary(*i); 01002 return NIVissimEdge::dictionary(c->getFromEdgeID()); 01003 } 01004 return 0; 01005 } 01006 01007 01008 NIVissimEdge* 01009 NIVissimEdge::getBestOutgoing() const { 01010 for (std::vector<int>::const_iterator i = myOutgoingConnections.begin(); i != myOutgoingConnections.end(); ++i) { 01011 NIVissimConnection* c = NIVissimConnection::dictionary(*i); 01012 return NIVissimEdge::dictionary(c->getToEdgeID()); 01013 } 01014 return 0; 01015 } 01016 01017 01018 01019 /****************************************************************************/ 01020