Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features for OpenDRIVE 4 : * Purpose: Implementation of OGRXODRDataSource. 5 : * Author: Michael Scholz, German Aerospace Center (DLR) 6 : * Gülsen Bardak, German Aerospace Center (DLR) 7 : * 8 : ****************************************************************************** 9 : * Copyright 2024 German Aerospace Center (DLR), Institute of Transportation Systems 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #include "ogr_xodr.h" 15 : using namespace odr; 16 : using namespace pugi; 17 : using namespace std; 18 : 19 13 : bool OGRXODRDataSource::Open(const char *pszFilename, CSLConstList openOptions) 20 : { 21 39 : odr::OpenDriveMap xodr(pszFilename, false); 22 13 : pugi::xml_parse_result parse_result = xodr.xml_parse_result; 23 26 : if (!parse_result || 24 13 : parse_result.status != pugi::xml_parse_status::status_ok) 25 : { 26 0 : CPLError(CE_Failure, CPLE_AppDefined, 27 : "OpenDRIVE dataset %s could not be parsed: %s.", pszFilename, 28 : parse_result.description()); 29 0 : return FALSE; 30 : } 31 13 : bool parsingFailed = xodr.xml_doc.child("OpenDRIVE").empty(); 32 13 : if (parsingFailed) 33 : { 34 0 : CPLError(CE_Failure, CPLE_AppDefined, 35 : "The provided file does not contain any OpenDRIVE data. Is it " 36 : "empty?"); 37 0 : return false; 38 : } 39 : 40 26 : std::vector<odr::Road> roads = xodr.get_roads(); 41 13 : if (roads.empty()) 42 : { 43 0 : CPLError(CE_Failure, CPLE_AppDefined, 44 : "OpenDRIVE dataset does not contain any roads."); 45 0 : return false; 46 : } 47 : 48 13 : const char *openOptionValue = CSLFetchNameValue(openOptions, "EPSILON"); 49 13 : if (openOptionValue != nullptr) 50 : { 51 2 : double dfEpsilon = CPLAtof(openOptionValue); 52 2 : if (dfEpsilon > 0.0) 53 : { 54 2 : m_dfEpsilon = dfEpsilon; 55 : } 56 : else 57 : { 58 0 : CPLError(CE_Warning, CPLE_AppDefined, 59 : "Invalid value for EPSILON specified. Falling back to " 60 : "default of 1.0."); 61 : } 62 : } 63 13 : openOptionValue = CSLFetchNameValueDef(openOptions, "DISSOLVE_TIN", "NO"); 64 13 : bool bDissolveTIN = CPLTestBool(openOptionValue); 65 : 66 26 : RoadElements roadElements = createRoadElements(roads); 67 13 : std::string &proj4Defn = xodr.proj4; 68 : 69 : auto refLine = 70 26 : std::make_unique<OGRXODRLayerReferenceLine>(roadElements, proj4Defn); 71 : auto laneBorder = 72 26 : std::make_unique<OGRXODRLayerLaneBorder>(roadElements, proj4Defn); 73 : auto roadMark = std::make_unique<OGRXODRLayerRoadMark>( 74 26 : roadElements, proj4Defn, bDissolveTIN); 75 : auto roadObject = 76 26 : std::make_unique<OGRXODRLayerRoadObject>(roadElements, proj4Defn); 77 : auto lane = std::make_unique<OGRXODRLayerLane>(roadElements, proj4Defn, 78 26 : bDissolveTIN); 79 : auto roadSignal = std::make_unique<OGRXODRLayerRoadSignal>( 80 13 : roadElements, proj4Defn, bDissolveTIN); 81 : 82 13 : m_apoLayers.push_back(std::move(refLine)); 83 13 : m_apoLayers.push_back(std::move(laneBorder)); 84 13 : m_apoLayers.push_back(std::move(roadMark)); 85 13 : m_apoLayers.push_back(std::move(roadObject)); 86 13 : m_apoLayers.push_back(std::move(lane)); 87 13 : m_apoLayers.push_back(std::move(roadSignal)); 88 : 89 13 : return true; 90 : } 91 : 92 511 : OGRLayer *OGRXODRDataSource::GetLayer(int iLayer) 93 : { 94 511 : if (iLayer < 0 || static_cast<size_t>(iLayer) >= m_apoLayers.size()) 95 2 : return nullptr; 96 : 97 509 : return m_apoLayers[iLayer].get(); 98 : } 99 : 100 27 : int OGRXODRDataSource::TestCapability(const char *pszCap) 101 : { 102 27 : int result = FALSE; 103 : 104 27 : if (EQUAL(pszCap, ODsCZGeometries)) 105 12 : result = TRUE; 106 : 107 27 : return result; 108 : } 109 : 110 : RoadElements 111 13 : OGRXODRDataSource::createRoadElements(const std::vector<odr::Road> &roads) 112 : { 113 13 : RoadElements elements; 114 : 115 506 : for (const odr::Road &road : roads) 116 : { 117 493 : elements.roads.insert({road.id, road}); 118 : 119 : odr::Line3D referenceLine = 120 986 : road.ref_line.get_line(0.0, road.length, m_dfEpsilon); 121 493 : elements.referenceLines.push_back(referenceLine); 122 : 123 1165 : for (const odr::LaneSection &laneSection : road.get_lanesections()) 124 : { 125 672 : elements.laneSections.push_back(laneSection); 126 : 127 3432 : for (const odr::Lane &lane : laneSection.get_lanes()) 128 : { 129 2760 : elements.laneRoadIDs.push_back(road.id); 130 : 131 2760 : elements.lanes.push_back(lane); 132 : 133 5520 : odr::Mesh3D laneMesh = road.get_lane_mesh(lane, m_dfEpsilon); 134 2760 : elements.laneMeshes.push_back(laneMesh); 135 : 136 : odr::Line3D laneLineOuter = 137 5520 : road.get_lane_border_line(lane, m_dfEpsilon, true); 138 2760 : elements.laneLinesOuter.push_back(laneLineOuter); 139 : 140 : odr::Line3D laneLineInner = 141 5520 : road.get_lane_border_line(lane, m_dfEpsilon, false); 142 2760 : elements.laneLinesInner.push_back(laneLineInner); 143 : 144 2760 : const double sectionStart = laneSection.s0; 145 2760 : const double sectionEnd = road.get_lanesection_end(laneSection); 146 5088 : for (const odr::RoadMark &roadMark : 147 12936 : lane.get_roadmarks(sectionStart, sectionEnd)) 148 : { 149 5088 : elements.roadMarks.push_back(roadMark); 150 : 151 : odr::Mesh3D roadMarkMesh = 152 10176 : road.get_roadmark_mesh(lane, roadMark, m_dfEpsilon); 153 5088 : elements.roadMarkMeshes.push_back(roadMarkMesh); 154 : } 155 : } 156 : } 157 : 158 3769 : for (const odr::RoadObject &roadObject : road.get_road_objects()) 159 : { 160 3276 : elements.roadObjects.push_back(roadObject); 161 : 162 : odr::Mesh3D roadObjectMesh = 163 6552 : road.get_road_object_mesh(roadObject, m_dfEpsilon); 164 3276 : elements.roadObjectMeshes.push_back(roadObjectMesh); 165 : } 166 : 167 1093 : for (const odr::RoadSignal &roadSignal : road.get_road_signals()) 168 : { 169 600 : elements.roadSignals.push_back(roadSignal); 170 : 171 1200 : odr::Mesh3D roadSignalMesh = road.get_road_signal_mesh(roadSignal); 172 600 : elements.roadSignalMeshes.push_back(roadSignalMesh); 173 : } 174 : } 175 13 : return elements; 176 : }