Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features for OpenDRIVE 4 : * Purpose: Implementation of RoadSignal 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 : OGRXODRLayerRoadSignal::OGRXODRLayerRoadSignal( 19 : const RoadElements &xodrRoadElements, 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 wkbPointWithZ = OGR_GT_SetZ(wkbPoint); 31 2 : m_poFeatureDefn->SetGeomType(wkbPointWithZ); 32 : } 33 : else 34 : { 35 11 : m_poFeatureDefn->SetGeomType(wkbTINZ); 36 : } 37 13 : if (!m_oSRS.IsEmpty()) 38 12 : m_poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(&m_oSRS); 39 : 40 26 : OGRFieldDefn oFieldSignalID("SignalID", OFTString); 41 13 : m_poFeatureDefn->AddFieldDefn(&oFieldSignalID); 42 : 43 26 : OGRFieldDefn oFieldRoadID("RoadID", OFTString); 44 13 : m_poFeatureDefn->AddFieldDefn(&oFieldRoadID); 45 : 46 26 : OGRFieldDefn oFieldType("Type", OFTString); 47 13 : m_poFeatureDefn->AddFieldDefn(&oFieldType); 48 : 49 26 : OGRFieldDefn oFieldSubType("SubType", OFTString); 50 13 : m_poFeatureDefn->AddFieldDefn(&oFieldSubType); 51 : 52 26 : OGRFieldDefn oFieldHOffset("HOffset", OFTReal); 53 13 : m_poFeatureDefn->AddFieldDefn(&oFieldHOffset); 54 : 55 26 : OGRFieldDefn oFieldPitch("Pitch", OFTReal); 56 13 : m_poFeatureDefn->AddFieldDefn(&oFieldPitch); 57 : 58 26 : OGRFieldDefn oFieldRoll("Roll", OFTReal); 59 13 : m_poFeatureDefn->AddFieldDefn(&oFieldRoll); 60 : 61 26 : OGRFieldDefn oFieldOrientation("Orientation", OFTString); 62 13 : m_poFeatureDefn->AddFieldDefn(&oFieldOrientation); 63 : 64 26 : OGRFieldDefn oFieldName("Name", OFTString); 65 13 : m_poFeatureDefn->AddFieldDefn(&oFieldName); 66 : 67 26 : OGRFieldDefn oFieldObjectDynamic("Dynamic", OFTInteger); 68 13 : oFieldObjectDynamic.SetSubType(OFSTBoolean); 69 13 : m_poFeatureDefn->AddFieldDefn(&oFieldObjectDynamic); 70 13 : } 71 : 72 36 : int OGRXODRLayerRoadSignal::TestCapability(const char *pszCap) 73 : { 74 36 : int result = FALSE; 75 : 76 36 : if (EQUAL(pszCap, OLCZGeometries)) 77 3 : result = TRUE; 78 : 79 36 : return result; 80 : } 81 : 82 2032 : OGRFeature *OGRXODRLayerRoadSignal::GetNextRawFeature() 83 : { 84 2032 : std::unique_ptr<OGRFeature> feature; 85 : 86 2032 : if (m_roadSignalIter != m_roadElements.roadSignals.end()) 87 : { 88 1992 : feature = std::make_unique<OGRFeature>(m_poFeatureDefn.get()); 89 : 90 3984 : odr::RoadSignal roadSignal = *m_roadSignalIter; 91 3984 : odr::Mesh3D roadSignalMesh = *m_roadSignalMeshesIter; 92 : 93 : // Populate geometry field 94 1992 : if (m_bDissolveTIN) 95 : { 96 : // Use simplified centroid, directly provided by libOpenDRIVE 97 102 : std::string roadId = roadSignal.road_id; 98 102 : odr::Road road = m_roadElements.roads.at(roadId); 99 : 100 51 : double s = roadSignal.s0; 101 51 : double t = roadSignal.t0; 102 51 : double h = roadSignal.zOffset; 103 51 : odr::Vec3D xyz = road.get_xyz(s, t, h); 104 : 105 102 : auto point = std::make_unique<OGRPoint>(xyz[0], xyz[1], xyz[2]); 106 51 : if (!m_oSRS.IsEmpty()) 107 51 : point->assignSpatialReference(&m_oSRS); 108 51 : feature->SetGeometryDirectly(point.release()); 109 : } 110 : else 111 : { 112 : std::unique_ptr<OGRTriangulatedSurface> tin = 113 3882 : triangulateSurface(roadSignalMesh); 114 1941 : if (!m_oSRS.IsEmpty()) 115 1941 : tin->assignSpatialReference(&m_oSRS); 116 1941 : feature->SetGeometryDirectly(tin.release()); 117 : } 118 : 119 : // Populate other fields 120 1992 : feature->SetField(m_poFeatureDefn->GetFieldIndex("SignalID"), 121 : roadSignal.id.c_str()); 122 1992 : feature->SetField(m_poFeatureDefn->GetFieldIndex("RoadID"), 123 : roadSignal.road_id.c_str()); 124 1992 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Type"), 125 : roadSignal.type.c_str()); 126 1992 : feature->SetField(m_poFeatureDefn->GetFieldIndex("SubType"), 127 : roadSignal.subtype.c_str()); 128 1992 : feature->SetField(m_poFeatureDefn->GetFieldIndex("HOffset"), 129 : roadSignal.hOffset); 130 1992 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Pitch"), 131 : roadSignal.pitch); 132 1992 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Roll"), 133 : roadSignal.roll); 134 1992 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Orientation"), 135 : roadSignal.orientation.c_str()); 136 1992 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Name"), 137 : roadSignal.name.c_str()); 138 3984 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Dynamic"), 139 1992 : roadSignal.is_dynamic); 140 1992 : feature->SetFID(m_nNextFID++); 141 : 142 1992 : ++m_roadSignalIter; 143 1992 : ++m_roadSignalMeshesIter; 144 : } 145 : 146 2032 : if (feature) 147 : { 148 1992 : return feature.release(); 149 : } 150 : else 151 : { 152 : // End of features for the given layer reached. 153 40 : return nullptr; 154 : } 155 : }