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    NIImporter_OpenStreetMap.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Jakob Erdmann
13 /// @author  Michael Behrisch
14 /// @author  Walter Bamberger
15 /// @author  Gregor Laemmel
16 /// @date    Mon, 14.04.2008
17 /// @version $Id$
18 ///
19 // Importer for networks stored in OpenStreetMap format
20 /****************************************************************************/
21 #ifndef NIImporter_OpenStreetMap_h
22 #define NIImporter_OpenStreetMap_h
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #include <config.h>
29 
30 #include <string>
31 #include <map>
32 #include <utils/xml/SUMOSAXHandler.h>
33 #include <utils/common/UtilExceptions.h>
34 #include <utils/common/Parameterised.h>
35 #include <netbuild/NBPTPlatform.h>
36 
37 
38 // ===========================================================================
39 // class declarations
40 // ===========================================================================
41 class NBEdge;
42 class NBEdgeCont;
43 class NBNetBuilder;
44 class NBNode;
45 class NBNodeCont;
46 class NBTrafficLightLogicCont;
47 class NBTypeCont;
48 class OptionsCont;
49 
50 
51 // ===========================================================================
52 // class definitions
53 // ===========================================================================
54 /**
55  * @class NIImporter_OpenStreetMap
56  * @brief Importer for networks stored in OpenStreetMap format
57  *
58  */
59 class NIImporter_OpenStreetMap {
60 public:
61     /** @brief Loads content of the optionally given OSM file
62      *
63      * If the option "osm-files" is set, the file(s) stored therein is read and
64      *  the network definition stored therein is stored within the given network
65      *  builder.
66      *
67      * If the option "osm-files" is not set, this method simply returns.
68      *
69      * @param[in] oc The options to use
70      * @param[in, out] nb The network builder to fill
71      */
72     static void loadNetwork(const OptionsCont& oc, NBNetBuilder& nb);
73 
74 
75 protected:
76     /** @brief An internal representation of an OSM-node
77      */
78     struct NIOSMNode {
NIOSMNodeNIOSMNode79         NIOSMNode(long long int _id, double _lon, double _lat)
80             :
81             id(_id), lon(_lon), lat(_lat), ele(0),
82             tlsControlled(false),
83             railwayCrossing(false),
84             railwaySignal(false),
85             railwayBufferStop(false),
86             ptStopPosition(false), ptStopLength(0), name(""),
87             permissions(SVC_RAIL | SVC_BUS | SVC_TRAM),
88             node(0) { }
89 
90         /// @brief The node's id
91         const long long int id;
92         /// @brief The longitude the node is located at
93         const double lon;
94         /// @brief The latitude the node is located at
95         const double lat;
96         /// @brief The elevation of this node
97         double ele;
98         /// @brief Whether this is a tls controlled junction
99         bool tlsControlled;
100         /// @brief Whether this is a railway crossing
101         bool railwayCrossing;
102         /// @brief Whether this is a railway (main) signal
103         bool railwaySignal;
104         /// @brief Whether this is a railway buffer stop
105         bool railwayBufferStop;
106         /// @brief Whether this is a public transport stop position
107         bool ptStopPosition;
108         /// @brief The length of the pt stop
109         double ptStopLength;
110         /// @brief The name of the node
111         std::string name;
112         /// @brief type of pt stop
113         SVCPermissions permissions;
114         /// @brief the NBNode that was instantiated
115         NBNode* node;
116 
117     private:
118         /// invalidated assignment operator
119         NIOSMNode& operator=(const NIOSMNode& s) = delete;
120 
121 
122     };
123 
124     /** @enum CycleWayType
125      * @brief details on the kind of cycleway along this road
126      */
127     enum WayType {
128         WAY_NONE = 0,
129         WAY_FORWARD = 1,
130         WAY_BACKWARD = 2,
131         WAY_BOTH = WAY_FORWARD | WAY_BACKWARD,
132         WAY_UNKNOWN = 4
133     };
134 
135     enum ParkingType {
136         PARKING_NONE = 0,
137         PARKING_LEFT = 1,
138         PARKING_RIGHT = 2,
139         PARKING_BOTH = WAY_FORWARD | WAY_BACKWARD,
140         PARKING_UNKNOWN = 4,
141         PARKING_FORBIDDEN = 8,
142         PARKING_PERPENDICULAR = 16,
143         PARKING_DIAGONAL = 32
144     };
145 
146 
147     /** @brief An internal definition of a loaded edge
148      */
149     struct Edge : public Parameterised {
150 
EdgeEdge151         explicit Edge(long long int _id)
152             :
153             id(_id), myNoLanes(-1), myNoLanesForward(0), myMaxSpeed(MAXSPEED_UNGIVEN),
154             myCyclewayType(WAY_UNKNOWN), // building of extra lane depends on bikelaneWidth of loaded typemap
155             myBuswayType(WAY_NONE), // buslanes are always built when declared
156             mySidewalkType(WAY_UNKNOWN), // building of extra lanes depends on sidewalkWidth of loaded typemap
157             myParkingType(PARKING_NONE), // parking areas exported optionally
158             myLayer(0), // layer is non-zero only in conflict areas
159             myCurrentIsRoad(false),
160             myCurrentIsPlatform(false) { }
161 
162 
163         /// @brief The edge's id
164         const long long int id;
165         /// @brief The edge's street name
166         std::string streetName;
167         /// @brief The edge's track name
168         std::string ref;
169         /// @brief number of lanes, or -1 if unknown
170         int myNoLanes;
171         /// @brief number of lanes in forward direction or 0 if unknown, negative if backwards lanes are meant
172         int myNoLanesForward;
173         /// @brief maximum speed in km/h, or MAXSPEED_UNGIVEN
174         double myMaxSpeed;
175         /// @brief The type, stored in "highway" key
176         std::string myHighWayType;
177         /// @brief Information whether this is an one-way road
178         std::string myIsOneWay;
179         /// @brief Information about the kind of cycleway along this road
180         WayType myCyclewayType;
181         /// @brief Information about the kind of busway along this road
182         WayType myBuswayType;
183         /// @brief Information about the kind of sidwalk along this road
184         WayType mySidewalkType;
185         /// @brief Information about road-side parking
186         int myParkingType;
187         /// @brief Information about the relative z-ordering of ways
188         int myLayer;
189         /// @brief The list of nodes this edge is made of
190         std::vector<long long int> myCurrentNodes;
191         /// @brief Information whether this is a road
192         bool myCurrentIsRoad;
193         /// @brief Information whether this is a pt platform
194         bool myCurrentIsPlatform;
195 
196     private:
197         /// invalidated assignment operator
198         Edge& operator=(const Edge& s) = delete;
199 
200 
201     };
202 
203 
204     NIImporter_OpenStreetMap();
205 
206     ~NIImporter_OpenStreetMap();
207 
208     void load(const OptionsCont& oc, NBNetBuilder& nb);
209 
210 private:
211     /** @brief Functor which compares two NIOSMNodes according
212      * to their coordinates
213      */
214     class CompareNodes {
215     public:
operator()216         bool operator()(const NIOSMNode* n1, const NIOSMNode* n2) const {
217             return (n1->lat > n2->lat) || (n1->lat == n2->lat && n1->lon > n2->lon);
218         }
219     };
220 
221 
222     /// @brief The separator within newly created compound type names
223     static const std::string compoundTypeSeparator;
224 
225     class CompareEdges;
226 
227     /** @brief the map from OSM node ids to actual nodes
228      * @note: NIOSMNodes may appear multiple times due to substition
229      */
230     std::map<long long int, NIOSMNode*> myOSMNodes;
231 
232     /// @brief the set of unique nodes used in NodesHandler, used when freeing memory
233     std::set<NIOSMNode*, CompareNodes> myUniqueNodes;
234 
235 
236     /** @brief the map from OSM way ids to edge objects */
237     std::map<long long int, Edge*> myEdges;
238 
239     /** @brief the map from OSM way ids to platform shapes */
240     std::map<long long int, Edge*> myPlatformShapes;
241 
242     /// @brief The compounds types that do not contain known types
243     std::set<std::string> myUnusableTypes;
244 
245     /// @brief The compound types that have already been mapped to other known types
246     std::map<std::string, std::string> myKnownCompoundTypes;
247 
248     /** @brief Builds an NBNode
249      *
250      * If a node with the given id is already known, nothing is done.
251      *  Otherwise, the position and other information of the node is retrieved from the
252      *  given node map, the node is built and added to the given node container.
253      * If the node is controlled by a tls, the according tls is built and added
254      *  to the tls container.
255      * @param[in] id The id of the node to build
256      * @param[in] osmNodes Map of node ids to information about these
257      * @param[in, out] nc The node container to add the built node to
258      * @param[in, out] tlsc The traffic lights logic container to add the built tls to
259      * @return The built/found node
260      * @exception ProcessError If the tls could not be added to the container
261      */
262     NBNode* insertNodeChecking(long long int id, NBNodeCont& nc, NBTrafficLightLogicCont& tlsc);
263 
264 
265     /** @brief Builds an NBEdge
266      *
267      * @param[in] e The definition of the edge
268      * @param[in] index The index of the edge (in the case it is split along her nodes)
269      * @param[in] from The origin node of the edge
270      * @param[in] to The destination node of the edge
271      * @param[in] passed The list of passed nodes (geometry information)
272      * @param[in] osmNodes Container of node definitions for getting information about nodes from
273      * @param[in, out] The NetBuilder instance
274      * @return the new index if the edge is split
275      * @exception ProcessError If the edge could not be added to the container
276      */
277     int insertEdge(Edge* e, int index, NBNode* from, NBNode* to,
278                    const std::vector<long long int>& passed, NBNetBuilder& nb);
279 
280     /// @brief reconstruct elevation from layer info
281     void reconstructLayerElevation(double layerElevation, NBNetBuilder& nb);
282 
283     /// @brief collect neighboring nodes with their road distance and maximum between-speed. Search does not continue beyond knownElevation-nodes
284     std::map<NBNode*, std::pair<double, double> >
285     getNeighboringNodes(NBNode* node, double maxDist, const std::set<NBNode*>& knownElevation);
286 
287 protected:
288     static const double MAXSPEED_UNGIVEN;
289     static const long long int INVALID_ID;
290 
291     /**
292      * @class NodesHandler
293      * @brief A class which extracts OSM-nodes from a parsed OSM-file
294      */
295     friend class NodesHandler;
296     class NodesHandler : public SUMOSAXHandler {
297     public:
298         /** @brief Contructor
299          * @param[in, out] toFill The nodes container to fill
300          * @param[in, out] uniqueNodes The nodes container for ensuring uniqueness
301          * @param[in] options The options to use
302          */
303         NodesHandler(std::map<long long int, NIOSMNode*>& toFill, std::set<NIOSMNode*,
304                      CompareNodes>& uniqueNodes,
305                      const OptionsCont& cont);
306 
307 
308         /// @brief Destructor
309         ~NodesHandler() override;
310 
311 
312     protected:
313         /// @name inherited from GenericSAXHandler
314         //@{
315 
316         /** @brief Called on the opening of a tag;
317          *
318          * @param[in] element ID of the currently opened element
319          * @param[in] attrs Attributes within the currently opened element
320          * @exception ProcessError If something fails
321          * @see GenericSAXHandler::myStartElement
322          */
323         void myStartElement(int element, const SUMOSAXAttributes& attrs) override;
324 
325 
326         /** @brief Called when a closing tag occurs
327          *
328          * @param[in] element ID of the currently opened element
329          * @exception ProcessError If something fails
330          * @see GenericSAXHandler::myEndElement
331          */
332         void myEndElement(int element) override;
333         //@}
334 
335 
336     private:
337 
338         /// @brief The nodes container to fill
339         std::map<long long int, NIOSMNode*>& myToFill;
340 
341         /// @brief ID of the currently parsed node, for reporting mainly
342         long long int myLastNodeID;
343 
344         /// @brief Hierarchy helper for parsing a node's tags
345         bool myIsInValidNodeTag;
346 
347         /// @brief The current hierarchy level
348         int myHierarchyLevel;
349 
350         /// @brief the set of unique nodes (used for duplicate detection/substitution)
351         std::set<NIOSMNode*, CompareNodes>& myUniqueNodes;
352 
353         /// @brief whether elevation data should be imported
354         const bool myImportElevation;
355 
356         /// @brief the options
357         const OptionsCont& myOptionsCont;
358 
359 
360     private:
361         /** @brief invalidated copy constructor */
362         NodesHandler(const NodesHandler& s);
363 
364         /** @brief invalidated assignment operator */
365         NodesHandler& operator=(const NodesHandler& s);
366 
367     };
368 
369 
370     /**
371      * @class EdgesHandler
372      * @brief A class which extracts OSM-edges from a parsed OSM-file
373      */
374     class EdgesHandler : public SUMOSAXHandler {
375     public:
376         /** @brief Constructor
377          *
378          * @param[in] osmNodes The previously parsed (osm-)nodes
379          * @param[in, out] toFill The edges container to fill with read edges
380          */
381         EdgesHandler(const std::map<long long int, NIOSMNode*>& osmNodes,
382                      std::map<long long int, Edge*>& toFill, std::map<long long int, Edge*>& platformShapes);
383 
384 
385         /// @brief Destructor
386         ~EdgesHandler() override;
387 
388 
389     protected:
390         /// @name inherited from GenericSAXHandler
391         //@{
392 
393         /** @brief Called on the opening of a tag;
394          *
395          * @param[in] element ID of the currently opened element
396          * @param[in] attrs Attributes within the currently opened element
397          * @exception ProcessError If something fails
398          * @see GenericSAXHandler::myStartElement
399          */
400         void myStartElement(int element, const SUMOSAXAttributes& attrs) override;
401 
402 
403         /** @brief Called when a closing tag occurs
404          *
405          * @param[in] element ID of the currently opened element
406          * @exception ProcessError If something fails
407          * @see GenericSAXHandler::myEndElement
408          */
409         void myEndElement(int element) override;
410         //@}
411 
412 
413     private:
414         /// @brief The previously parsed nodes
415         const std::map<long long int, NIOSMNode*>& myOSMNodes;
416 
417         /// @brief A map of built edges
418         std::map<long long int, Edge*>& myEdgeMap;
419 
420         /// @brief A map of built edges
421         std::map<long long int, Edge*>& myPlatformShapesMap;
422 
423         /// @brief The currently built edge
424         Edge* myCurrentEdge;
425 
426         /// @brief The element stack
427         std::vector<int> myParentElements;
428 
429         /// @brief A map of non-numeric speed descriptions to their numeric values
430         std::map<std::string, double> mySpeedMap;
431 
432         /// @brief whether additional way attributes shall be added to the edge
433         bool myAllAttributes;
434 
435     private:
436         /** @brief invalidated copy constructor */
437         EdgesHandler(const EdgesHandler& s);
438 
439         /** @brief invalidated assignment operator */
440         EdgesHandler& operator=(const EdgesHandler& s);
441 
442     };
443 
444     /**
445      * @class RelationHandler
446      * @brief A class which extracts relevant relation information from a parsed OSM-file
447      *   - turn restrictions
448      */
449     class RelationHandler : public SUMOSAXHandler {
450     public:
451         /** @brief Constructor
452          *
453          * @param[in] osmNodes The previously parsed OSM-nodes
454          * @param[in] osmEdges The previously parse OSM-edges
455          */
456         RelationHandler(const std::map<long long int, NIOSMNode*>& osmNodes,
457                         const std::map<long long int, Edge*>& osmEdges, NBPTStopCont* nbptStopCont,
458                         const std::map<long long int, Edge*>& platfromShapes, NBPTLineCont* nbptLineCont,
459                         const OptionsCont& oc);
460 
461 
462         /// @brief Destructor
463         ~RelationHandler() override;
464 
465 
466     protected:
467         /// @name inherited from GenericSAXHandler
468         //@{
469 
470         /** @brief Called on the opening of a tag;
471          *
472          * @param[in] element ID of the currently opened element
473          * @param[in] attrs Attributes within the currently opened element
474          * @exception ProcessError If something fails
475          * @see GenericSAXHandler::myStartElement
476          */
477         void myStartElement(int element, const SUMOSAXAttributes& attrs) override;
478 
479 
480         /** @brief Called when a closing tag occurs
481          *
482          * @param[in] element ID of the currently opened element
483          * @exception ProcessError If something fails
484          * @see GenericSAXHandler::myEndElement
485          */
486         void myEndElement(int element) override;
487         //@}
488 
489 
490     private:
491         /// @brief The previously parsed nodes
492         const std::map<long long int, NIOSMNode*>& myOSMNodes;
493 
494         /// @brief The previously parsed edges
495         const std::map<long long int, Edge*>& myOSMEdges;
496 
497         /// @brief The previously parsed platform shapes
498         const std::map<long long int, Edge*>& myPlatformShapes;
499 
500         /// @brief The previously filled pt stop container
501         NBPTStopCont* myNBPTStopCont;
502 
503         /// @brief PT Line container to be filled
504         NBPTLineCont* myNBPTLineCont;
505 
506         /// @brief The currently parsed relation
507         long long int myCurrentRelation;
508 
509         /// @brief The element stack
510         std::vector<int> myParentElements;
511 
512         /// @brief whether the currently parsed relation is a restriction
513         bool myIsRestriction;
514 
515         /// @brief the origination way for the current restriction
516         long long int myFromWay;
517 
518         /// @brief the destination way for the current restriction
519         long long int myToWay;
520 
521         /// @brief the via node/way for the current restriction
522         long long int myViaNode;
523         long long int myViaWay;
524 
525 
526         /// @brief the options cont
527         const OptionsCont& myOptionsCont;
528 
529         /** @enum RestrictionType
530          * @brief whether the only allowed or the only forbidden connection is defined
531          */
532         enum RestrictionType {
533             /// @brief The only valid connection is declared
534             RESTRICTION_ONLY,
535             /// @brief The only invalid connection is declared
536             RESTRICTION_NO,
537             /// @brief The relation tag was missing
538             RESTRICTION_UNKNOWN
539         };
540         RestrictionType myRestrictionType;
541 
542         /// @brief reset members to their defaults for parsing a new relation
543         void resetValues();
544 
545         /// @brief check whether a referenced way has a corresponding edge
546         bool checkEdgeRef(long long int ref) const;
547 
548         /// @brief try to apply the parsed restriction and return whether successful
549         bool applyRestriction() const;
550 
551         /// @brief try to find the way segment among candidates
552         NBEdge* findEdgeRef(long long int wayRef, const std::vector<NBEdge*>& candidates) const;
553 
554     private:
555         /** @brief invalidated copy constructor */
556         RelationHandler(const RelationHandler& s);
557 
558         /** @brief invalidated assignment operator */
559         RelationHandler& operator=(const RelationHandler& s);
560 
561         /// @brief bus stop references
562         std::vector<long long int> myStops;
563 
564 
565         struct NIIPTPlatform {
566             long long int ref;
567             bool isWay;
568         };
569 
570         /// @brief bus stop platforms
571         std::vector<NIIPTPlatform> myPlatforms;
572 
573         /// @brief ways in pt line references
574         std::vector<long long int> myWays;
575 
576         /// @brief indicates whether current relation is a pt stop area
577         bool myIsStopArea;
578 
579         /// @brief indicates whether current relation is a route
580         bool myIsRoute;
581 
582         /// @brief indicates whether current relation is a pt route
583         std::string myPTRouteType;
584 
585         /// @brief name of the relation
586         std::string myName;
587 
588         /// @brief ref of the pt line
589         std::string myRef;
590 
591         /// @brief service interval of the pt line in seconds
592         int myInterval;
593 
594         /// @brief night service information of the pt line
595         std::string myNightService;
596     };
597 
598 };
599 
600 
601 #endif
602 
603 /****************************************************************************/
604 
605