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