LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/xodr - ogrxodrdatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 73 80 91.2 %
Date: 2024-11-21 22:18:42 Functions: 4 4 100.0 %

          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             : }

Generated by: LCOV version 1.14