Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features for OpenDRIVE 4 : * Purpose: Implementation of LaneBorder 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 : OGRXODRLayerLaneBorder::OGRXODRLayerLaneBorder( 19 13 : const RoadElements &xodrRoadElements, const std::string &proj4Defn) 20 13 : : OGRXODRLayer(xodrRoadElements, proj4Defn) 21 : { 22 : m_poFeatureDefn = 23 13 : std::make_unique<OGRFeatureDefn>(FEATURE_CLASS_NAME.c_str()); 24 13 : m_poFeatureDefn->Reference(); 25 13 : SetDescription(FEATURE_CLASS_NAME.c_str()); 26 : 27 13 : OGRwkbGeometryType wkbLineStringWithZ = OGR_GT_SetZ(wkbLineString); 28 13 : m_poFeatureDefn->SetGeomType(wkbLineStringWithZ); 29 13 : if (!m_oSRS.IsEmpty()) 30 12 : m_poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(&m_oSRS); 31 : 32 26 : OGRFieldDefn oFieldID("ID", OFTInteger); 33 13 : m_poFeatureDefn->AddFieldDefn(&oFieldID); 34 : 35 26 : OGRFieldDefn oFieldRoadID("RoadID", OFTString); 36 13 : m_poFeatureDefn->AddFieldDefn(&oFieldRoadID); 37 : 38 26 : OGRFieldDefn oFieldType("Type", OFTString); 39 13 : m_poFeatureDefn->AddFieldDefn(&oFieldType); 40 : 41 26 : OGRFieldDefn oFieldPred("Predecessor", OFTInteger); 42 13 : m_poFeatureDefn->AddFieldDefn(&oFieldPred); 43 : 44 26 : OGRFieldDefn oFieldSuc("Successor", OFTInteger); 45 13 : m_poFeatureDefn->AddFieldDefn(&oFieldSuc); 46 13 : } 47 : 48 36 : int OGRXODRLayerLaneBorder::TestCapability(const char *pszCap) 49 : { 50 36 : int result = FALSE; 51 : 52 36 : if (EQUAL(pszCap, OLCZGeometries)) 53 3 : result = TRUE; 54 : 55 36 : return result; 56 : } 57 : 58 9054 : OGRFeature *OGRXODRLayerLaneBorder::GetNextRawFeature() 59 : { 60 9054 : std::unique_ptr<OGRFeature> feature; 61 : 62 9054 : if (m_laneIter != m_roadElements.lanes.end()) 63 : { 64 9014 : feature = std::make_unique<OGRFeature>(m_poFeatureDefn.get()); 65 : 66 18028 : odr::Lane lane = *m_laneIter; 67 18028 : odr::Line3D laneOuterBorder = *m_laneLinesOuterIter; 68 18028 : std::string laneRoadID = *m_laneRoadIDIter; 69 : 70 : // Populate geometry field 71 18028 : auto lineString = std::make_unique<OGRLineString>(); 72 373655 : for (const auto &borderVertex : laneOuterBorder) 73 : { 74 729282 : lineString->addPoint(borderVertex[0], borderVertex[1], 75 364641 : borderVertex[2]); 76 : } 77 9014 : if (!m_oSRS.IsEmpty()) 78 9014 : lineString->assignSpatialReference(&m_oSRS); 79 9014 : feature->SetGeometryDirectly(lineString.release()); 80 : 81 : // Populate other fields 82 9014 : feature->SetField(m_poFeatureDefn->GetFieldIndex("RoadID"), 83 : laneRoadID.c_str()); 84 9014 : feature->SetField(m_poFeatureDefn->GetFieldIndex("ID"), lane.id); 85 9014 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Type"), 86 : lane.type.c_str()); 87 9014 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Predecessor"), 88 : lane.predecessor); 89 9014 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Successor"), 90 : lane.successor); 91 9014 : feature->SetFID(m_nNextFID++); 92 : 93 9014 : ++m_laneIter; 94 9014 : ++m_laneLinesOuterIter; 95 9014 : ++m_laneLinesInnerIter; // For consistency, even though not used here 96 9014 : ++m_laneRoadIDIter; 97 : } 98 : 99 9054 : if (feature) 100 : { 101 9014 : return feature.release(); 102 : } 103 : else 104 : { 105 : // End of features for the given layer reached. 106 40 : return nullptr; 107 : } 108 : }