Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features for OpenDRIVE 4 : * Purpose: Implementation of RoadMark 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 : OGRXODRLayerRoadMark::OGRXODRLayerRoadMark( 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 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 12 : m_poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(&m_oSRS); 39 : 40 26 : OGRFieldDefn oFieldRoadID("RoadID", OFTString); 41 13 : m_poFeatureDefn->AddFieldDefn(&oFieldRoadID); 42 : 43 26 : OGRFieldDefn oFieldLaneID("LaneID", OFTInteger); 44 13 : m_poFeatureDefn->AddFieldDefn(&oFieldLaneID); 45 : 46 26 : OGRFieldDefn oFieldType("Type", OFTString); 47 13 : m_poFeatureDefn->AddFieldDefn(&oFieldType); 48 13 : } 49 : 50 36 : int OGRXODRLayerRoadMark::TestCapability(const char *pszCap) 51 : { 52 36 : int result = FALSE; 53 : 54 36 : if (EQUAL(pszCap, OLCZGeometries)) 55 3 : result = TRUE; 56 : 57 36 : return result; 58 : } 59 : 60 16618 : OGRFeature *OGRXODRLayerRoadMark::GetNextRawFeature() 61 : { 62 16618 : std::unique_ptr<OGRFeature> feature; 63 : 64 16618 : if (m_roadMarkIter != m_roadElements.roadMarks.end()) 65 : { 66 16578 : feature = std::make_unique<OGRFeature>(m_poFeatureDefn.get()); 67 : 68 33156 : odr::RoadMark roadMark = *m_roadMarkIter; 69 33156 : odr::Mesh3D roadMarkMesh = *m_roadMarkMeshIter; 70 : 71 : // Populate geometry field 72 : std::unique_ptr<OGRTriangulatedSurface> tin = 73 33156 : triangulateSurface(roadMarkMesh); 74 16578 : if (m_bDissolveTIN) 75 : { 76 425 : OGRGeometry *dissolvedPolygon = tin->UnaryUnion(); 77 425 : if (dissolvedPolygon != nullptr) 78 : { 79 425 : if (!m_oSRS.IsEmpty()) 80 425 : dissolvedPolygon->assignSpatialReference(&m_oSRS); 81 425 : feature->SetGeometryDirectly(dissolvedPolygon); 82 : } 83 : else 84 : { 85 0 : CPLError(CE_Warning, CPLE_AppDefined, 86 : "RoadMark feature with FID %d has no geometry because " 87 : "its triangulated surface could not be dissolved.", 88 : m_nNextFID); 89 : } 90 : } 91 : else 92 : { 93 16153 : if (!m_oSRS.IsEmpty()) 94 16153 : tin->assignSpatialReference(&m_oSRS); 95 16153 : feature->SetGeometryDirectly(tin.release()); 96 : } 97 : 98 : // Populate other fields 99 16578 : feature->SetField(m_poFeatureDefn->GetFieldIndex("RoadID"), 100 : roadMark.road_id.c_str()); 101 16578 : feature->SetField(m_poFeatureDefn->GetFieldIndex("LaneID"), 102 : roadMark.lane_id); 103 16578 : feature->SetField(m_poFeatureDefn->GetFieldIndex("Type"), 104 : roadMark.type.c_str()); 105 16578 : feature->SetFID(m_nNextFID++); 106 : 107 16578 : ++m_roadMarkIter; 108 16578 : ++m_roadMarkMeshIter; 109 : } 110 : 111 16618 : if (feature) 112 : { 113 16578 : return feature.release(); 114 : } 115 : else 116 : { 117 : // End of features for the given layer reached. 118 40 : return nullptr; 119 : } 120 : }