1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others. 4 // This program and the accompanying materials 5 // are made available under the terms of the Eclipse Public License v2.0 6 // which accompanies this distribution, and is available at 7 // http://www.eclipse.org/legal/epl-v20.html 8 // SPDX-License-Identifier: EPL-2.0 9 /****************************************************************************/ 10 /// @file NIVissimEdge.h 11 /// @author Daniel Krajzewicz 12 /// @author Michael Behrisch 13 /// @date End of 2002 14 /// @version $Id$ 15 /// 16 // A temporary storage for edges imported from Vissim 17 /****************************************************************************/ 18 #ifndef NIVissimEdge_h 19 #define NIVissimEdge_h 20 21 22 // =========================================================================== 23 // included modules 24 // =========================================================================== 25 #include <config.h> 26 27 #include "NIVissimConnectionCluster.h" 28 #include <vector> 29 #include <string> 30 #include <map> 31 #include <netbuild/NBEdge.h> 32 #include <utils/geom/PositionVector.h> 33 #include <utils/common/UtilExceptions.h> 34 #include "NIVissimAbstractEdge.h" 35 #include "NIVissimClosedLanesVector.h" 36 37 38 // =========================================================================== 39 // class declarations 40 // =========================================================================== 41 class NBNode; 42 class NBDistrictCont; 43 class NIVissimDistrictConnection; 44 45 46 // =========================================================================== 47 // class definitions 48 // =========================================================================== 49 /** 50 * @class NIVissimEdge 51 * @brief A temporary storage for edges imported from Vissim 52 */ 53 class NIVissimEdge 54 : public NIVissimAbstractEdge { 55 public: 56 /// Constructor 57 NIVissimEdge(int id, const std::string& name, 58 const std::string& type, 59 std::vector<double> laneWidths, 60 double zuschlag1, 61 double zuschlag2, double length, 62 const PositionVector& geom, 63 const NIVissimClosedLanesVector& clv); 64 65 /// Destructor 66 ~NIVissimEdge(); 67 68 void setNodeCluster(int nodeid); 69 void buildGeom(); 70 71 /// Adds a connection where this edge is the destination 72 void addIncomingConnection(int id); 73 74 /// Adds a connection where this edge is the source 75 void addOutgoingConnection(int id); 76 77 /** @brief Returns the node at the given position 78 As this may be ambigous, a second node not to return may be supplied */ 79 NBNode* getNodeAt(const Position& p, NBNode* other = 0); 80 81 /** Returns the begin position of the edge */ 82 Position getBegin2D() const; 83 84 /// Returns the end position of the edge 85 Position getEnd2D() const; 86 87 /// Returns the length of the node 88 double getLength() const; 89 90 void checkDistrictConnectionExistanceAt(double pos); 91 92 void mergedInto(NIVissimConnectionCluster* old, 93 NIVissimConnectionCluster* act); 94 95 void removeFromConnectionCluster(NIVissimConnectionCluster* c); 96 void addToConnectionCluster(NIVissimConnectionCluster* c); 97 void setSpeed(int lane, int speedDist); 98 bool addToTreatAsSame(NIVissimEdge* e); 99 100 NIVissimConnection* getConnectionTo(NIVissimEdge* e); 101 const std::vector<NIVissimEdge*>& getToTreatAsSame() const; 102 103 104 /** @brief Returns whether this edge was found to be within a junction 105 * @return Whether this node is assumed to be within a junction 106 */ wasWithinAJunction()107 bool wasWithinAJunction() const { 108 return myAmWithinJunction; 109 } 110 111 NIVissimEdge* getBestIncoming() const; 112 NIVissimEdge* getBestOutgoing() const; 113 114 friend class NIVissimNodeDef_Edges; 115 friend class NIVissimNodeDef_Poly; 116 117 public: 118 /** @brief Adds the described item to the dictionary 119 Builds the edge first */ 120 static bool dictionary(int id, const std::string& name, 121 const std::string& type, int noLanes, double zuschlag1, 122 double zuschlag2, double length, 123 const PositionVector& geom, 124 const NIVissimClosedLanesVector& clv); 125 126 /// Adds the edge to the dictionary 127 static bool dictionary(int id, NIVissimEdge* o); 128 129 /// Returns the named edge from the dictionary 130 static NIVissimEdge* dictionary(int id); 131 132 /** @brief Clusters connections of each edge 133 * 134 * For every edge stored in this container, its connections are collected and 135 * joined into "clusters" if they have the same "direction" (incoming/outgoing) 136 * and are not further than 10m away from each other. 137 * 138 * @todo Probably the distance (MAX_CLUSTER_DISTANCE=10m) should be made variable 139 */ 140 static void buildConnectionClusters(); 141 142 /// Builds NBEdges from the VissimEdges within the dictionary 143 static void dict_buildNBEdges(NBDistrictCont& dc, NBNodeCont& nc, 144 NBEdgeCont& ec, double offset); 145 146 static void dict_propagateSpeeds(); 147 148 static void dict_checkEdges2Join(); 149 150 151 /** @brief Writes edges with unset speeds to the warnings message log instance 152 * 153 * Vissim has no direct speed definition of edges; still, we try to propagate 154 * speed changes along the streets. If a lane is not covered by such, its id 155 * is put into the static container "myLanesWithMissingSpeeds". 156 * If the option "vissim.report-unset-speeds" is set, all lane ids stored within 157 * this container are written. 158 */ 159 static void reportUnsetSpeeds(); 160 161 162 private: 163 /// The definition for a container for connection clusters 164 typedef std::vector<NIVissimConnectionCluster*> ConnectionClusters; 165 166 private: 167 /** @brief Builds the NBEdge from this VissimEdge 168 * 169 * @param[in] dc The district container used if this edge must be split 170 * @param[in] nc The node container used for (optionally) building this edge's nodes 171 * @param[in] ec The edge control to add this edge to 172 * @param[in] sameNodesOffset Offset used to discriminate nodes 173 * @exception ProcessError If one of the built nodes or edges could not be added to the according container 174 */ 175 void buildNBEdge(NBDistrictCont& dc, NBNodeCont& nc, 176 NBEdgeCont& ec, double sameNodesOffset); 177 178 /// Returns the origin node 179 std::pair<NIVissimConnectionCluster*, NBNode*> 180 getFromNode(NBNodeCont& nc, ConnectionClusters& clusters); 181 182 /// Returns the destination node 183 std::pair<NIVissimConnectionCluster*, NBNode*> 184 getToNode(NBNodeCont& nc, ConnectionClusters& clusters); 185 186 /// Tries to resolve the problem that the same node has been returned as origin and destination node 187 std::pair<NBNode*, NBNode*> resolveSameNode(NBNodeCont& nc, 188 double offset, NBNode* prevFrom, NBNode* prevTo); 189 190 // double recheckSpeedPatches(); 191 192 std::vector<NIVissimConnection*> getOutgoingConnected(int lane) const; 193 194 void propagateSpeed(double speed, std::vector<int> forLanes); 195 196 197 void setDistrictSpeed(); 198 double getRealSpeed(int distNo); 199 void checkUnconnectedLaneSpeeds(); 200 void propagateOwn(); 201 202 203 204 private: 205 static NBNode* getNodeSecure(int nodeid, const Position& pos, 206 const std::string& possibleName); 207 208 std::pair<NBNode*, NBNode*> 209 remapOneOfNodes(NBNodeCont& nc, 210 NIVissimDistrictConnection* d, 211 NBNode* fromNode, NBNode* toNode); 212 213 private: 214 /** 215 * Sorts connections the edge participates in by their position along 216 * the given edge 217 */ 218 class connection_position_sorter { 219 public: 220 /// constructor 221 explicit connection_position_sorter(int edgeid); 222 223 /// comparing operation 224 int operator()(int c1id, int c2id) const; 225 226 private: 227 /// The id of the edge 228 int myEdgeID; 229 230 }; 231 232 233 /** 234 * Sorts connection clusters the edge participates in by their 235 * position along the given edge 236 */ 237 class connection_cluster_position_sorter { 238 public: 239 /// constructor 240 explicit connection_cluster_position_sorter(int edgeid); 241 242 /// comparing operation 243 int operator()(NIVissimConnectionCluster* cc1, 244 NIVissimConnectionCluster* cc2) const; 245 246 private: 247 /// The id of the edge 248 int myEdgeID; 249 250 }; 251 252 private: 253 /// The name of the edge 254 std::string myName; 255 256 /// The type of the edge 257 std::string myType; 258 259 /// The number of lanes the edge has 260 int myNoLanes; 261 std::vector<double> myLaneWidths; 262 263 /// Additional load values for this edge 264 double myZuschlag1, myZuschlag2; 265 266 /// List of lanes closed on this edge 267 NIVissimClosedLanesVector myClosedLanes; 268 269 /// List of connection clusters along this edge 270 ConnectionClusters myConnectionClusters; 271 272 /// List of connections incoming to this edge 273 std::vector<int> myIncomingConnections; 274 275 /// List of connections outgoing from this edge 276 std::vector<int> myOutgoingConnections; 277 278 std::vector<double> myDistrictConnections; 279 280 std::vector<int> myPatchedSpeeds; 281 282 std::vector<double> myLaneSpeeds; 283 284 std::vector<NIVissimEdge*> myToTreatAsSame; 285 286 /// @brief Information whether this edge was not build due to being within a junction 287 bool myAmWithinJunction; 288 289 private: 290 /// @brief Definition of the dictionary type 291 typedef std::map<int, NIVissimEdge*> DictType; 292 293 /// @brief The dictionary 294 static DictType myDict; 295 296 /// @brief The current maximum id; needed for further id assignment 297 static int myMaxID; 298 299 static std::vector<std::string> myLanesWithMissingSpeeds; 300 301 }; 302 303 304 #endif 305 306 /****************************************************************************/ 307 308