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