|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // Some methods for traversing lists of edges 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 #ifndef NBContHelper_h 00023 #define NBContHelper_h 00024 00025 00026 // =========================================================================== 00027 // included modules 00028 // =========================================================================== 00029 #ifdef _MSC_VER 00030 #include <windows_config.h> 00031 #else 00032 #include <config.h> 00033 #endif 00034 00035 #include <vector> 00036 #include <iostream> 00037 #include <cmath> 00038 #include <algorithm> 00039 #include <cassert> 00040 #include "NBHelpers.h" 00041 #include "NBCont.h" 00042 #include "NBEdge.h" 00043 #include "NBNode.h" 00044 #include <utils/common/StdDefs.h> 00045 #include <utils/geom/GeomHelper.h> 00046 00047 00048 // =========================================================================== 00049 // class definitions 00050 // =========================================================================== 00056 class NBContHelper { 00057 public: 00060 static void nextCW(const EdgeVector& edges, 00061 EdgeVector::const_iterator& from); 00062 00065 static void nextCCW(const EdgeVector& edges, 00066 EdgeVector::const_iterator& from); 00067 00068 static SUMOReal getMaxSpeed(const EdgeVector& edges); 00069 00070 static SUMOReal getMinSpeed(const EdgeVector& edges); 00071 00073 static std::ostream& out(std::ostream& os, const std::vector<bool> &v); 00074 00079 class edge_by_junction_angle_sorter { 00080 public: 00082 explicit edge_by_junction_angle_sorter(NBNode* n) : myNode(n) {} 00083 00085 int operator()(NBEdge* e1, NBEdge* e2) const; 00086 00087 private: 00089 SUMOReal getConvAngle(NBEdge* e) const; 00090 00091 private: 00093 NBNode* myNode; 00094 00095 }; 00096 00105 class relative_edge_sorter { 00106 public: 00108 explicit relative_edge_sorter(NBEdge* e, NBNode* n) 00109 : myEdge(e), myNode(n) {} 00110 00111 public: 00113 int operator()(NBEdge* e1, NBEdge* e2) const { 00114 if (e1 == 0 || e2 == 0) { 00115 return -1; 00116 } 00117 SUMOReal relAngle1 = NBHelpers::normRelAngle( 00118 myEdge->getAngle(), e1->getAngle()); 00119 SUMOReal relAngle2 = NBHelpers::normRelAngle( 00120 myEdge->getAngle(), e2->getAngle()); 00121 return relAngle1 > relAngle2; 00122 } 00123 00124 private: 00126 NBEdge* myEdge; 00127 00129 NBNode* myNode; 00130 00131 }; 00132 00133 00138 class edge_by_priority_sorter { 00139 public: 00141 int operator()(NBEdge* e1, NBEdge* e2) const { 00142 if (e1->getPriority() != e2->getPriority()) { 00143 return e1->getPriority() > e2->getPriority(); 00144 } 00145 if (e1->getSpeed() != e2->getSpeed()) { 00146 return e1->getSpeed() > e2->getSpeed(); 00147 } 00148 return e1->getNumLanes() > e2->getNumLanes(); 00149 } 00150 }; 00151 00152 // --------------------------- 00153 00161 class edge_opposite_direction_sorter { 00162 public: 00167 explicit edge_opposite_direction_sorter(const NBEdge* const e, const NBNode* const n) 00168 : myNode(n) { 00169 myAngle = getEdgeAngleAt(e, n); 00170 } 00171 00177 int operator()(NBEdge* e1, NBEdge* e2) const { 00178 SUMOReal d1 = getDiff(e1); 00179 SUMOReal d2 = getDiff(e2); 00180 return d1 > d2; 00181 } 00182 00183 protected: 00188 SUMOReal getDiff(const NBEdge* const e) const { 00189 SUMOReal d = getEdgeAngleAt(e, myNode); 00190 return GeomHelper::getMinAngleDiff(d, myAngle); 00191 } 00192 00199 SUMOReal getEdgeAngleAt(const NBEdge* const e, const NBNode* const n) const { 00200 if (e->getFromNode() == n) { 00201 return e->getGeometry().getBegLine().atan2DegreeAngle(); 00202 } else { 00203 return e->getGeometry().getEndLine().reverse().atan2DegreeAngle(); 00204 } 00205 } 00206 00207 private: 00209 SUMOReal myAngle; 00210 00212 const NBNode* const myNode; 00213 00214 }; 00215 00216 // --------------------------- 00217 00224 class edge_similar_direction_sorter { 00225 public: 00227 explicit edge_similar_direction_sorter(const NBEdge* const e) 00228 : myAngle(e->getAngle()) {} 00229 00231 int operator()(NBEdge* e1, NBEdge* e2) const { 00232 SUMOReal d1 = GeomHelper::getMinAngleDiff(e1->getAngle(), myAngle); 00233 SUMOReal d2 = GeomHelper::getMinAngleDiff(e2->getAngle(), myAngle); 00234 return d1 < d2; 00235 } 00236 00237 private: 00239 SUMOReal myAngle; 00240 }; 00241 00242 00246 class node_with_incoming_finder { 00247 public: 00249 node_with_incoming_finder(const NBEdge* const e); 00250 00251 bool operator()(const NBNode* const n) const; 00252 00253 private: 00254 const NBEdge* const myEdge; 00255 00256 private: 00258 node_with_incoming_finder& operator=(const node_with_incoming_finder& s); 00259 00260 }; 00261 00262 00266 class node_with_outgoing_finder { 00267 public: 00269 node_with_outgoing_finder(const NBEdge* const e); 00270 00271 bool operator()(const NBNode* const n) const; 00272 00273 private: 00274 const NBEdge* const myEdge; 00275 00276 private: 00278 node_with_outgoing_finder& operator=(const node_with_outgoing_finder& s); 00279 00280 }; 00281 00282 00283 00284 00285 class edge_with_destination_finder { 00286 public: 00288 edge_with_destination_finder(NBNode* dest); 00289 00290 bool operator()(NBEdge* e) const; 00291 00292 private: 00293 NBNode* myDestinationNode; 00294 00295 private: 00297 edge_with_destination_finder& operator=(const edge_with_destination_finder& s); 00298 00299 }; 00300 00301 00304 static NBEdge* findConnectingEdge(const EdgeVector& edges, 00305 NBNode* from, NBNode* to); 00306 00307 00309 static SUMOReal maxSpeed(const EdgeVector& ev); 00310 00317 class same_connection_edge_sorter { 00318 public: 00320 explicit same_connection_edge_sorter() { } 00321 00323 int operator()(NBEdge* e1, NBEdge* e2) const { 00324 std::pair<SUMOReal, SUMOReal> mm1 = getMinMaxRelAngles(e1); 00325 std::pair<SUMOReal, SUMOReal> mm2 = getMinMaxRelAngles(e2); 00326 if (mm1.first == mm2.first && mm1.second == mm2.second) { 00327 // ok, let's simply sort them arbitrarily 00328 return e1->getID() < e2->getID(); 00329 } 00330 00331 assert( 00332 (mm1.first <= mm2.first && mm1.second <= mm2.second) 00333 || 00334 (mm1.first >= mm2.first && mm1.second >= mm2.second)); 00335 return (mm1.first >= mm2.first && mm1.second >= mm2.second); 00336 } 00337 00341 std::pair<SUMOReal, SUMOReal> getMinMaxRelAngles(NBEdge* e) const { 00342 SUMOReal min = 360; 00343 SUMOReal max = 360; 00344 const EdgeVector& ev = e->getConnectedEdges(); 00345 for (EdgeVector::const_iterator i = ev.begin(); i != ev.end(); ++i) { 00346 SUMOReal angle = NBHelpers::normRelAngle( 00347 e->getAngle(), (*i)->getAngle()); 00348 if (min == 360 || min > angle) { 00349 min = angle; 00350 } 00351 if (max == 360 || max < angle) { 00352 max = angle; 00353 } 00354 } 00355 return std::pair<SUMOReal, SUMOReal>(min, max); 00356 } 00357 }; 00358 00359 00360 friend std::ostream& operator<<(std::ostream& os, const EdgeVector& ev); 00361 00362 class opposite_finder { 00363 public: 00365 opposite_finder(NBEdge* edge, const NBNode* n) 00366 : myReferenceEdge(edge), myAtNode(n) { } 00367 00368 bool operator()(NBEdge* e) const { 00369 return e->isTurningDirectionAt(myAtNode, myReferenceEdge) || 00370 myReferenceEdge->isTurningDirectionAt(myAtNode, e); 00371 } 00372 00373 private: 00374 NBEdge* myReferenceEdge; 00375 const NBNode* myAtNode; 00376 00377 }; 00378 00379 00380 }; 00381 00382 00383 #endif 00384 00385 /****************************************************************************/ 00386