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