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