LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/xodr - ogrxodrlayerlane.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 61 62 98.4 %
Date: 2024-11-21 22:18:42 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features for OpenDRIVE
       4             :  * Purpose:  Implementation of Lane layer.
       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_api.h"
      15             : #include "ogr_geometry.h"
      16             : #include "ogr_xodr.h"
      17             : 
      18          13 : OGRXODRLayerLane::OGRXODRLayerLane(const RoadElements &xodrRoadElements,
      19             :                                    const std::string &proj4Defn,
      20          13 :                                    const bool dissolveTriangulatedSurface)
      21          13 :     : OGRXODRLayer(xodrRoadElements, proj4Defn, dissolveTriangulatedSurface)
      22             : {
      23             :     m_poFeatureDefn =
      24          13 :         std::make_unique<OGRFeatureDefn>(FEATURE_CLASS_NAME.c_str());
      25          13 :     m_poFeatureDefn->Reference();
      26          13 :     SetDescription(FEATURE_CLASS_NAME.c_str());
      27             : 
      28          13 :     if (m_bDissolveTIN)
      29             :     {
      30           2 :         OGRwkbGeometryType wkbPolygonWithZ = OGR_GT_SetZ(wkbPolygon);
      31           2 :         m_poFeatureDefn->SetGeomType(wkbPolygonWithZ);
      32             :     }
      33             :     else
      34             :     {
      35          11 :         m_poFeatureDefn->SetGeomType(wkbTINZ);
      36             :     }
      37          13 :     if (!m_oSRS.IsEmpty())
      38             :     {
      39          12 :         m_poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(&m_oSRS);
      40             :     }
      41             : 
      42          26 :     OGRFieldDefn oFieldLaneID("LaneID", OFTInteger);
      43          13 :     m_poFeatureDefn->AddFieldDefn(&oFieldLaneID);
      44             : 
      45          26 :     OGRFieldDefn oFieldRoadID("RoadID", OFTString);
      46          13 :     m_poFeatureDefn->AddFieldDefn(&oFieldRoadID);
      47             : 
      48          26 :     OGRFieldDefn oFieldType("Type", OFTString);
      49          13 :     m_poFeatureDefn->AddFieldDefn(&oFieldType);
      50             : 
      51          26 :     OGRFieldDefn oFieldPred("Predecessor", OFTInteger);
      52          13 :     m_poFeatureDefn->AddFieldDefn(&oFieldPred);
      53             : 
      54          26 :     OGRFieldDefn oFieldSuc("Successor", OFTInteger);
      55          13 :     m_poFeatureDefn->AddFieldDefn(&oFieldSuc);
      56          13 : }
      57             : 
      58          36 : int OGRXODRLayerLane::TestCapability(const char *pszCap)
      59             : {
      60          36 :     int result = FALSE;
      61             : 
      62          36 :     if (EQUAL(pszCap, OLCZGeometries))
      63           3 :         result = TRUE;
      64             : 
      65          36 :     return result;
      66             : }
      67             : 
      68        6868 : OGRFeature *OGRXODRLayerLane::GetNextRawFeature()
      69             : {
      70       13736 :     std::unique_ptr<OGRFeature> feature;
      71             : 
      72        9058 :     while (m_laneIter != m_roadElements.lanes.end() && (*m_laneIter).id == 0)
      73             :     {
      74             :         // Skip lane(s) with id 0 because these "center lanes" don't have any width
      75        2190 :         ++m_laneIter;
      76        2190 :         ++m_laneMeshIter;
      77        2190 :         ++m_laneRoadIDIter;
      78             :     }
      79             : 
      80        6868 :     if (m_laneIter != m_roadElements.lanes.end())
      81             :     {
      82             : 
      83        6828 :         feature = std::make_unique<OGRFeature>(m_poFeatureDefn.get());
      84             : 
      85       13656 :         odr::Lane lane = *m_laneIter;
      86       13656 :         odr::Mesh3D laneMesh = *m_laneMeshIter;
      87       13656 :         std::string laneRoadID = *m_laneRoadIDIter;
      88             : 
      89             :         // Populate geometry field
      90             :         std::unique_ptr<OGRTriangulatedSurface> tin =
      91       13656 :             triangulateSurface(laneMesh);
      92        6828 :         if (m_bDissolveTIN)
      93             :         {
      94         175 :             OGRGeometry *dissolvedPolygon = tin->UnaryUnion();
      95         175 :             if (dissolvedPolygon != nullptr)
      96             :             {
      97         175 :                 if (!m_oSRS.IsEmpty())
      98         175 :                     dissolvedPolygon->assignSpatialReference(&m_oSRS);
      99         175 :                 feature->SetGeometryDirectly(dissolvedPolygon);
     100             :             }
     101             :             else
     102             :             {
     103           0 :                 CPLError(CE_Warning, CPLE_AppDefined,
     104             :                          "Lane feature with FID %d has no geometry because its "
     105             :                          "triangulated surface could not be dissolved.",
     106             :                          m_nNextFID);
     107             :             }
     108             :         }
     109             :         else
     110             :         {
     111        6653 :             if (!m_oSRS.IsEmpty())
     112        6653 :                 tin->assignSpatialReference(&m_oSRS);
     113        6653 :             feature->SetGeometryDirectly(tin.release());
     114             :         }
     115             : 
     116             :         // Populate other fields
     117        6828 :         feature->SetFID(m_nNextFID++);
     118        6828 :         feature->SetField(m_poFeatureDefn->GetFieldIndex("RoadID"),
     119             :                           laneRoadID.c_str());
     120        6828 :         feature->SetField(m_poFeatureDefn->GetFieldIndex("LaneID"), lane.id);
     121        6828 :         feature->SetField(m_poFeatureDefn->GetFieldIndex("Type"),
     122             :                           lane.type.c_str());
     123        6828 :         feature->SetField(m_poFeatureDefn->GetFieldIndex("Predecessor"),
     124             :                           lane.predecessor);
     125        6828 :         feature->SetField(m_poFeatureDefn->GetFieldIndex("Successor"),
     126             :                           lane.successor);
     127             : 
     128        6828 :         ++m_laneIter;
     129        6828 :         ++m_laneMeshIter;
     130        6828 :         ++m_laneRoadIDIter;
     131             :     }
     132             : 
     133        6868 :     if (feature)
     134             :     {
     135        6828 :         return feature.release();
     136             :     }
     137             :     else
     138             :     {
     139             :         // End of features for the given layer reached.
     140          40 :         return nullptr;
     141             :     }
     142             : }

Generated by: LCOV version 1.14