Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: S-101 driver 4 : * Purpose: Implements OGRS101Reader 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2026, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "ogr_s101.h" 14 : #include "ogrs101readerconstants.h" 15 : #include "ogrs101readerconstants.h" 16 : 17 : #include <memory> 18 : 19 : /************************************************************************/ 20 : /* CreateInformationTypeFeatureDefn() */ 21 : /************************************************************************/ 22 : 23 : /** Create the feature definition for the informationType layer. 24 : */ 25 362 : bool OGRS101Reader::CreateInformationTypeFeatureDefn() 26 : { 27 362 : if (m_oInformationTypeRecordIndex.GetCount() != 0) 28 : { 29 : m_poFeatureDefnInformationType = 30 220 : OGRFeatureDefnRefCountedPtr::makeInstance("informationType"); 31 220 : m_poFeatureDefnInformationType->SetGeomType(wkbNone); 32 : { 33 440 : OGRFieldDefn oFieldDefn(OGR_FIELD_NAME_RECORD_ID, OFTInteger); 34 220 : m_poFeatureDefnInformationType->AddFieldDefn(&oFieldDefn); 35 : } 36 : { 37 440 : OGRFieldDefn oFieldDefn(OGR_FIELD_NAME_RECORD_VERSION, OFTInteger); 38 220 : m_poFeatureDefnInformationType->AddFieldDefn(&oFieldDefn); 39 : } 40 : { 41 440 : OGRFieldDefn oFieldDefn(OGR_FIELD_NAME_INFORMATION_TYPE, OFTString); 42 220 : m_poFeatureDefnInformationType->AddFieldDefn(&oFieldDefn); 43 : } 44 : 45 : // Scan the properties of the information type record 46 440 : if (!InferFeatureDefn( 47 220 : m_oInformationTypeRecordIndex, IRID_FIELD, ATTR_FIELD, 48 : /* anRecordIdx = */ {}, *m_poFeatureDefnInformationType, 49 220 : m_oMapFieldDomains)) 50 : { 51 9 : return false; 52 : } 53 : 54 : // Scan the properties of the association of one information record to 55 : // another related information type record. 56 422 : if (!InferFeatureDefn( 57 211 : m_oInformationTypeRecordIndex, IRID_FIELD, INAS_FIELD, 58 : /* anRecordIdx = */ {}, *m_poFeatureDefnInformationType, 59 211 : m_oMapFieldDomains)) 60 : { 61 0 : return false; 62 : } 63 : } 64 : 65 353 : return true; 66 : } 67 : 68 : /************************************************************************/ 69 : /* FillFeatureInformationType() */ 70 : /************************************************************************/ 71 : 72 : /** Fill the content of the provided feature from the identified record 73 : * of m_oInformationTypeRecordIndex. 74 : */ 75 568 : bool OGRS101Reader::FillFeatureInformationType(const DDFRecordIndex &oIndex, 76 : int iRecord, 77 : OGRFeature &oFeature) const 78 : { 79 568 : const auto poRecord = oIndex.GetByIndex(iRecord); 80 568 : CPLAssert(poRecord); 81 : 82 : const InfoTypeCode nNITC( 83 568 : poRecord->GetIntSubfield(IRID_FIELD, 0, NITC_SUBFIELD, 0)); 84 568 : const auto oIter = m_informationTypeCodes.find(nNITC); 85 568 : if (oIter != m_informationTypeCodes.end()) 86 : { 87 567 : oFeature.SetField(OGR_FIELD_NAME_INFORMATION_TYPE, 88 567 : oIter->second.c_str()); 89 : } 90 1 : else if (!EMIT_ERROR_OR_WARNING( 91 : CPLSPrintf("Unknown value %d for NITC subfield of IRID field.", 92 : static_cast<int>(nNITC)))) 93 : { 94 0 : return false; 95 : } 96 : else 97 : { 98 1 : oFeature.SetField( 99 : OGR_FIELD_NAME_INFORMATION_TYPE, 100 : CPLSPrintf("informationTypeCode%d", static_cast<int>(nNITC))); 101 : } 102 : 103 : // An IRID record might have a ATTR field, a INAS field (thus pointing 104 : // to another IRID record), both or none... 105 568 : return FillFeatureAttributes(oIndex, iRecord, ATTR_FIELD, oFeature) && 106 1136 : FillFeatureAttributes(oIndex, iRecord, INAS_FIELD, oFeature) && 107 568 : FillFeatureWithNonAttrAssocSubfields(poRecord, iRecord, INAS_FIELD, 108 568 : oFeature); 109 : }