LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/s101 - ogr_s101.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 70 71 98.6 %
Date: 2026-05-29 23:25:07 Functions: 38 39 97.4 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  S-101 driver
       4             :  * Purpose:  Header file
       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             : #ifndef OGR_S101_H_INCLUDED
      14             : #define OGR_S101_H_INCLUDED
      15             : 
      16             : #include "ogrsf_frmts.h"
      17             : #include "iso8211.h"
      18             : #include "ddfrecordindex.h"
      19             : 
      20             : #include "cpl_int_wrapper.h"
      21             : #include "cpl_string.h"
      22             : 
      23             : #include <map>
      24             : #include <set>
      25             : #include <string_view>
      26             : 
      27             : /************************************************************************/
      28             : /*                            OGRS101Reader                             */
      29             : /************************************************************************/
      30             : 
      31             : class OGRS101FeatureCatalog;
      32             : 
      33             : namespace OGRS101FeatureCatalogTypes
      34             : {
      35             : struct InformationType;
      36             : struct FeatureType;
      37             : }  // namespace OGRS101FeatureCatalogTypes
      38             : 
      39        1002 : class OGRS101Reader
      40             : {
      41             :   public:
      42             :     struct CRSIdTag
      43             :     {
      44             :     };
      45             : 
      46             :     using CRSId = cpl::IntWrapper<CRSIdTag>;
      47             : 
      48             :     static constexpr CRSId INVALID_CRS_ID{-1};
      49             :     static constexpr CRSId HORIZONTAL_CRS_ID{1};
      50             : 
      51             :     struct RecordNameTag
      52             :     {
      53             :     };
      54             : 
      55             :     // Record "name" is a poor naming from the S100 spec. It is actually
      56             :     // a numeric value
      57             :     using RecordName = cpl::IntWrapper<RecordNameTag>;
      58             : 
      59             :     // Type for NATC subfield (numeric attribute code)
      60             :     struct AttrCodeTag
      61             :     {
      62             :     };
      63             : 
      64             :     using AttrCode = cpl::IntWrapper<AttrCodeTag>;
      65             : 
      66             :     // Type for PAIX subfield (parent index)
      67             :     struct AttrIndexTag
      68             :     {
      69             :     };
      70             : 
      71             :     using AttrIndex = cpl::IntWrapper<AttrIndexTag>;
      72             : 
      73             :     // Type for ATIX subfield (attribute index)
      74             :     struct AttrRepeatTag
      75             :     {
      76             :     };
      77             : 
      78             :     using AttrRepeat = cpl::IntWrapper<AttrRepeatTag>;
      79             : 
      80         474 :     inline static void AppendUInt8(std::string &s, uint8_t x)
      81             :     {
      82         474 :         s.append(reinterpret_cast<const char *>(&x), sizeof(x));
      83         474 :     }
      84             : 
      85         321 :     inline static void AppendUInt16(std::string &s, uint16_t x)
      86             :     {
      87         321 :         CPL_LSBPTR16(&x);
      88         321 :         s.append(reinterpret_cast<const char *>(&x), sizeof(x));
      89         321 :     }
      90             : 
      91         192 :     inline static void AppendInt32(std::string &s, int32_t x)
      92             :     {
      93         192 :         CPL_LSBPTR32(&x);
      94         192 :         s.append(reinterpret_cast<const char *>(&x), sizeof(x));
      95         192 :     }
      96             : 
      97             :   private:
      98             :     /////////////////////////////////////////////////////////////////////////
      99             :     // Members
     100             :     /////////////////////////////////////////////////////////////////////////
     101             : 
     102             :     bool m_bStrict = true;
     103             : 
     104             :     //! Whereas we are currently processing an update file (.001, .002, ...)
     105             :     bool m_bInUpdate = false;
     106             : 
     107             :     //! Whether an update file cancels the dataset.
     108             :     bool m_bCancelled = false;
     109             : 
     110             :     std::string m_osFilename{};
     111             :     DDFModule m_oMainModule{};
     112             : 
     113             :     CPLStringList m_aosMetadata{};
     114             : 
     115             :     // DSSI field
     116             :     static constexpr double S101_SHIFT = 0;
     117             :     double m_dfXShift = S101_SHIFT;  // DCOX
     118             :     double m_dfYShift = S101_SHIFT;  // DCOY
     119             :     double m_dfZShift = S101_SHIFT;  // DCOZ
     120             :     static constexpr int S101_XSCALE = 10000000;
     121             :     int m_nXScale = S101_XSCALE;  // CMFX
     122             :     static constexpr int S101_YSCALE = 10000000;
     123             :     int m_nYScale = S101_YSCALE;  // CMFY
     124             :     static constexpr int S101_ZSCALE = 10;
     125             :     int m_nZScale = S101_ZSCALE;  // CMFZ
     126             :     OGRGeomCoordinatePrecision m_coordinatePrecision{};
     127             :     int m_nCountInformationRecord = 0;     // NOIR
     128             :     int m_nCountPointRecord = 0;           // NOPN
     129             :     int m_nCountMultiPointRecord = 0;      // NOMN
     130             :     int m_nCountCurveRecord = 0;           // NOCN
     131             :     int m_nCountCompositeCurveRecord = 0;  // NOXN
     132             :     int m_nCountSurfaceRecord = 0;         // NOSN
     133             :     int m_nCountFeatureTypeRecord = 0;     // NOFR
     134             : 
     135             :     // from ATCS field
     136             :     std::map<AttrCode, std::string> m_attributeCodes{};
     137             : 
     138             :     // Maps the AttrCode of the current update to the consolidated one of
     139             :     // m_attributeCodes
     140             :     std::map<AttrCode, AttrCode> m_attributeCodesRemapping{};
     141             : 
     142             :     struct InfoTypeCodeTag
     143             :     {
     144             :     };
     145             : 
     146             :     using InfoTypeCode = cpl::IntWrapper<InfoTypeCodeTag>;
     147             :     // from ITCS field
     148             :     std::map<InfoTypeCode, std::string> m_informationTypeCodes{};
     149             : 
     150             :     // Maps the AttrCode of the current update to the consolidated one of
     151             :     // m_informationTypeCodes
     152             :     std::map<InfoTypeCode, InfoTypeCode> m_informationTypeCodesRemapping{};
     153             : 
     154             :     struct FeatureTypeCodeTag
     155             :     {
     156             :     };
     157             : 
     158             :     using FeatureTypeCode = cpl::IntWrapper<FeatureTypeCodeTag>;
     159             :     // from FTCS field
     160             :     std::map<FeatureTypeCode, std::string> m_featureTypeCodes{};
     161             : 
     162             :     // Maps the AttrCode of the current update to the consolidated one of
     163             :     // m_featureTypeCodes
     164             :     std::map<FeatureTypeCode, FeatureTypeCode> m_featureTypeCodesRemapping{};
     165             : 
     166             :     struct InfoAssocCodeTag
     167             :     {
     168             :     };
     169             : 
     170             :     using InfoAssocCode = cpl::IntWrapper<InfoAssocCodeTag>;
     171             :     // from IACS field
     172             :     std::map<InfoAssocCode, std::string> m_informationAssociationCodes{};
     173             : 
     174             :     // Maps the AttrCode of the current update to the consolidated one of
     175             :     // m_informationAssociationCodes
     176             :     std::map<InfoAssocCode, InfoAssocCode>
     177             :         m_informationAssociationCodesRemapping{};
     178             : 
     179             :     struct FeatureAssocCodeTag
     180             :     {
     181             :     };
     182             : 
     183             :     using FeatureAssocCode = cpl::IntWrapper<FeatureAssocCodeTag>;
     184             :     // from FACS field
     185             :     std::map<FeatureAssocCode, std::string> m_featureAssociationCodes{};
     186             : 
     187             :     // Maps the AttrCode of the current update to the consolidated one of
     188             :     // m_featureAssociationCodes
     189             :     std::map<FeatureAssocCode, FeatureAssocCode>
     190             :         m_featureAssociationCodesRemapping{};
     191             : 
     192             :     struct AssocRoleCodeTag
     193             :     {
     194             :     };
     195             : 
     196             :     using AssocRoleCode = cpl::IntWrapper<AssocRoleCodeTag>;
     197             :     // from ARCS field
     198             :     std::map<AssocRoleCode, std::string> m_associationRoleCodes{};
     199             : 
     200             :     // Maps the AttrCode of the current update to the consolidated one of
     201             :     // m_featureAssociationCodes
     202             :     std::map<AssocRoleCode, AssocRoleCode> m_associationRoleCodesRemapping{};
     203             : 
     204             :     static constexpr RecordName PSEUDO_RECORD_NAME_NO_GEOM{-1111111111};
     205             : 
     206             :     /** Triple (feature type code, geometry type, CRS Id) */
     207             :     struct FeatureTypeKey
     208             :     {
     209             :         FeatureTypeCode nFeatureTypeCode{0};
     210             :         RecordName nGeometryType{PSEUDO_RECORD_NAME_NO_GEOM};
     211             :         CRSId nCRSId{INVALID_CRS_ID};
     212             : 
     213             :         // I'd wish I could use C++20
     214        2946 :         inline bool operator<(const FeatureTypeKey &other) const
     215             :         {
     216        2946 :             return toTuple() < other.toTuple();
     217             :         }
     218             : 
     219             :       private:
     220        5892 :         inline std::tuple<int, int, int> toTuple() const
     221             :         {
     222           0 :             return std::make_tuple(static_cast<int>(nFeatureTypeCode),
     223        5892 :                                    static_cast<int>(nGeometryType),
     224       17676 :                                    static_cast<int>(nCRSId));
     225             :         }
     226             :     };
     227             : 
     228             :     // key is the crs index (CRIX). 1: Horizontal CRS. >= 2: CompoundCRS
     229             :     std::map<CRSId, OGRSpatialReference> m_oMapSRS{};
     230             : 
     231             :     DDFRecordIndex m_oInformationTypeRecordIndex{};
     232             :     DDFRecordIndex m_oPointRecordIndex{};
     233             :     DDFRecordIndex m_oMultiPointRecordIndex{};
     234             :     DDFRecordIndex m_oCurveRecordIndex{};
     235             :     DDFRecordIndex m_oCompositeCurveRecordIndex{};
     236             :     DDFRecordIndex m_oSurfaceRecordIndex{};
     237             :     DDFRecordIndex m_oFeatureTypeRecordIndex{};
     238             : 
     239             :     OGRFeatureDefnRefCountedPtr m_poFeatureDefnInformationType{};
     240             : 
     241             :     std::map<CRSId, OGRFeatureDefnRefCountedPtr> m_oMapPointFeatureDefn{};
     242             :     std::map<CRSId, std::vector<int>> m_oMapCRSIdToPointRecordIdx{};
     243             : 
     244             :     std::map<CRSId, OGRFeatureDefnRefCountedPtr> m_oMapMultiPointFeatureDefn{};
     245             :     std::map<CRSId, std::vector<int>> m_oMapCRSIdToMultiPointRecordIdx{};
     246             : 
     247             :     OGRFeatureDefnRefCountedPtr m_poFeatureDefnCurve{};
     248             :     OGRFeatureDefnRefCountedPtr m_poFeatureDefnCompositeCurve{};
     249             :     OGRFeatureDefnRefCountedPtr m_poFeatureDefnSurface{};
     250             : 
     251             :     struct LayerDef
     252             :     {
     253             :         OGRFeatureDefnRefCountedPtr poFeatureDefn{};
     254             :         std::string osName{};
     255             :         std::string osDefinition{};
     256             :         std::string osAlias{};
     257             :         std::vector<int> anRecordIndices{};
     258             :     };
     259             : 
     260             :     std::map<FeatureTypeKey, LayerDef> m_oMapFeatureKeyToLayerDef{};
     261             :     std::map<int, const OGRFeatureDefn *> m_oMapFeatureTypeIdToFDefn{};
     262             : 
     263             :     std::map<std::string, std::unique_ptr<OGRFieldDomain>> m_oMapFieldDomains{};
     264             : 
     265             :     const OGRS101FeatureCatalog *m_poFeatureCatalog = nullptr;
     266             : 
     267             :     /////////////////////////////////////////////////////////////////////////
     268             :     // Methods
     269             :     /////////////////////////////////////////////////////////////////////////
     270             : 
     271             :     bool Load(const std::string &osFilename, VSILFILE *fp,
     272             :               DDFModule *poCurModule);
     273             : 
     274             :     bool CheckFieldDefinitions(const DDFModule *poCurModule) const;
     275             :     bool CheckField0000Definition(const DDFModule *poCurModule) const;
     276             : 
     277             :     bool ReadDatasetGeneralInformationRecord(const DDFRecord *poRecord);
     278             :     bool ReadDSID(const DDFRecord *poRecord);
     279             :     bool ReadDSSI(const DDFRecord *poRecord);
     280             : 
     281             :     template <class CodeType>
     282             :     bool ReadGenericCodeAssociation(
     283             :         const DDFRecord *poRecord, const char *pszFieldName,
     284             :         const char *pszSubField0Name, const char *pszSubField1Name,
     285             :         std::map<CodeType, std::string> &map,
     286             :         std::map<CodeType, CodeType> &mapRemapping) const;
     287             : 
     288             :     bool ReadATCS(const DDFRecord *poRecord);
     289             :     bool ReadITCS(const DDFRecord *poRecord);
     290             :     bool ReadFTCS(const DDFRecord *poRecord);
     291             :     bool ReadIACS(const DDFRecord *poRecord);
     292             :     bool ReadFACS(const DDFRecord *poRecord);
     293             :     bool ReadARCS(const DDFRecord *poRecord);
     294             : 
     295             :     bool ReadCSID(const DDFRecord *poRecord);
     296             : 
     297             :     bool IngestInitialRecords(const DDFRecord *poRecordIn);
     298             :     bool IngestUpdateRecords(const DDFRecord *poRecordIn,
     299             :                              DDFModule *poCurModule);
     300             :     bool UpdateCodesInRecord(DDFRecord *poRecord) const;
     301             :     bool ProcessUpdateRecord(const DDFRecord *poUpdateRecord,
     302             :                              DDFRecord *poTargetRecord) const;
     303             :     bool ProcessUpdateATTR(const DDFRecord *poUpdateRecord,
     304             :                            DDFRecord *poTargetRecord) const;
     305             :     bool ProcessUpdateINASOrFASC(const DDFRecord *poUpdateRecord,
     306             :                                  DDFRecord *poTargetRecord,
     307             :                                  const char *pszFieldName) const;
     308             :     bool ProcessUpdateAttributeLikeField(const DDFRecord *poUpdateRecord,
     309             :                                          const DDFField *poUpdateField,
     310             :                                          DDFRecord *poTargetRecord,
     311             :                                          DDFField *poTargetField,
     312             :                                          int iFieldInstance) const;
     313             :     bool ProcessUpdateRecordPoint(const DDFRecord *poUpdateRecord,
     314             :                                   DDFRecord *poTargetRecord) const;
     315             :     bool ProcessUpdatePointList(const DDFRecord *poUpdateRecord,
     316             :                                 DDFRecord *poTargetRecord,
     317             :                                 bool bIs3DAllowed) const;
     318             :     bool ProcessUpdateRecordMultiPoint(const DDFRecord *poUpdateRecord,
     319             :                                        DDFRecord *poTargetRecord) const;
     320             :     bool ProcessUpdateRecordCurve(const DDFRecord *poUpdateRecord,
     321             :                                   DDFRecord *poTargetRecord) const;
     322             :     bool ProcessUpdateRecordCompositeCurve(const DDFRecord *poUpdateRecord,
     323             :                                            DDFRecord *poTargetRecord) const;
     324             :     bool ProcessUpdateRecordSurface(const DDFRecord *poUpdateRecord,
     325             :                                     DDFRecord *poTargetRecord) const;
     326             :     bool ProcessUpdateRecordFeatureType(const DDFRecord *poUpdateRecord,
     327             :                                         DDFRecord *poTargetRecord) const;
     328             : 
     329             :     using PathElement = std::pair<AttrCode, AttrRepeat>;
     330             :     using PathVector = std::vector<PathElement>;
     331             : 
     332             :     // Capture essential information for a repetition of the ATTR field
     333             :     struct S101AttrDef
     334             :     {
     335             :         PathVector oReversedPath{};  // ordered from child to root
     336             :         std::string osVal{};
     337             :         int iField = 0;
     338             :         bool bMultipleFields = false;
     339             :         bool bIsParent = false;
     340             :     };
     341             : 
     342             :     bool ReadFeatureCatalog();
     343             : 
     344             :     std::string BuildFieldName(const PathVector &oReversedPath,
     345             :                                const char *pszAttrFieldName, int iField,
     346             :                                bool bMultipleFields,
     347             :                                const char *pszIDFieldName) const;
     348             : 
     349             :     bool CreateInformationTypeFeatureDefn();
     350             :     bool CreatePointFeatureDefns();
     351             :     bool CreateMultiPointFeatureDefns();
     352             :     bool CreateCurveFeatureDefn();
     353             :     bool CreateCompositeCurveFeatureDefn();
     354             :     bool CreateSurfaceFeatureDefn();
     355             :     bool CreateFeatureTypeFeatureDefns();
     356             : 
     357             :     bool InferFeatureDefn(
     358             :         const DDFRecordIndex &oIndex, const char *pszIDFieldName,
     359             :         const char *pszAttrFieldName, const std::vector<int> &anRecordIndices,
     360             :         OGRFeatureDefn &oFeatureDefn,
     361             :         std::map<std::string, std::unique_ptr<OGRFieldDomain>>
     362             :             &oMapFieldDomains,
     363             :         const OGRS101FeatureCatalogTypes::InformationType *psInformationType =
     364             :             nullptr,
     365             :         const OGRS101FeatureCatalogTypes::FeatureType *psFeatureType =
     366             :             nullptr) const;
     367             : 
     368             :     using NameOccMinOccMax = std::tuple<const char *, int, int>;
     369             :     bool CheckFieldDefinitions(
     370             :         const DDFRecord *poRecord, int iRecord, RecordName nRCNM, int nRCID,
     371             :         const std::map<RecordName, std::vector<std::vector<NameOccMinOccMax>>>
     372             :             &mapExpectedFields) const;
     373             : 
     374             :     bool IngestAttributes(const DDFRecord *poRecord, int iRecord,
     375             :                           const char *pszIDFieldName,
     376             :                           const char *pszAttrFieldName,
     377             :                           const DDFField *poATTRField, int iField,
     378             :                           bool bMultipleFields,
     379             :                           std::vector<S101AttrDef> &asS101AttrDefs) const;
     380             : 
     381             :     bool IngestAttributes(const DDFRecord *poRecord, int iRecord,
     382             :                           const char *pszIDFieldName,
     383             :                           const char *pszAttrFieldName,
     384             :                           std::vector<S101AttrDef> &asS101AttrDefs) const;
     385             : 
     386             :     bool FillFeatureAttributes(const DDFRecordIndex &oIndex, int iRecord,
     387             :                                const char *pszAttrFieldName,
     388             :                                OGRFeature &oFeature) const;
     389             : 
     390             :     CRSId GetCRSIdForPointRecord(const DDFRecord *poRecord, int iRecord,
     391             :                                  int nRecordID) const;
     392             : 
     393             :     std::map<OGRS101Reader::CRSId, std::vector<int>>
     394             :     CreateMapCRSIdToRecordIdxForPoints(bool &bError) const;
     395             : 
     396             :     CRSId GetCRSIdForMultiPointRecord(const DDFRecord *poRecord, int iRecord,
     397             :                                       int nRecordID) const;
     398             : 
     399             :     std::map<OGRS101Reader::CRSId, std::vector<int>>
     400             :     CreateMapCRSIdToRecordIdxForMultiPoints(bool &bError) const;
     401             : 
     402             :     bool FillFeatureWithNonAttrAssocSubfields(const DDFRecord *poRecord,
     403             :                                               int iRecord,
     404             :                                               const char *pszAttrFieldName,
     405             :                                               OGRFeature &oFeature) const;
     406             : 
     407             :     std::unique_ptr<OGRPoint> ReadPointGeometryInternal(
     408             :         const DDFRecord *poRecord, int iRecord, int nRecordID, int iPnt,
     409             :         const OGRSpatialReference *poSRS, const bool bIs3D,
     410             :         const DDFField *poCoordField, const char *pszRecordFieldName) const;
     411             : 
     412             :     std::unique_ptr<OGRPoint>
     413             :     ReadPointGeometry(const DDFRecord *poRecord, int iRecord, int nRecordID,
     414             :                       const OGRSpatialReference *poSRS) const;
     415             : 
     416             :     std::unique_ptr<OGRMultiPoint>
     417             :     ReadMultiPointGeometry(const DDFRecord *poRecord, int iRecord,
     418             :                            int nRecordID,
     419             :                            const OGRSpatialReference *poSRS) const;
     420             : 
     421             :     std::unique_ptr<OGRLineString>
     422             :     ReadCurveGeometry(const DDFRecord *poRecord, int iRecord, int nRecordID,
     423             :                       const OGRSpatialReference *poSRS) const;
     424             : 
     425             :     std::unique_ptr<OGRLineString> ReadCompositeCurveGeometryInternal(
     426             :         const DDFRecord *poRecord, int iRecord, int nRecordID,
     427             :         const OGRSpatialReference *poSRS,
     428             :         std::set<int> &oSetAlreadyVisitedCompositeCurveRecords) const;
     429             : 
     430             :     std::unique_ptr<OGRLineString>
     431             :     ReadCompositeCurveGeometry(const DDFRecord *poRecord, int iRecord,
     432             :                                int nRecordID,
     433             :                                const OGRSpatialReference *poSRS) const;
     434             : 
     435             :     std::unique_ptr<OGRPolygon>
     436             :     ReadSurfaceGeometry(const DDFRecord *poRecord, int iRecord, int nRecordID,
     437             :                         const OGRSpatialReference *poSRS) const;
     438             : 
     439             :     template <typename T, typename GeomReaderMethodType>
     440             :     bool ReadGeometry(const DDFRecordIndex &oIndex, const char *pszErrorContext,
     441             :                       int nGeomRecordID, const char *pszGeomType, bool bReverse,
     442             :                       OGRFeature &oFeature,
     443             :                       std::unique_ptr<OGRGeometryCollection> &poMultiGeom,
     444             :                       GeomReaderMethodType geomReaderMethod,
     445             :                       int iGeomField = 0) const;
     446             : 
     447             :     bool FillFeatureTypeGeometry(const DDFRecord *poRecord, int iRecord,
     448             :                                  OGRFeature &oFeature) const;
     449             : 
     450             :     bool FillFeatureTypeMask(const DDFRecord *poRecord, int iRecord,
     451             :                              OGRFeature &oFeature) const;
     452             : 
     453             :     static std::string LaunderCRSName(const OGRSpatialReference &oSRS);
     454             :     static std::string GetPointLayerName(const OGRSpatialReference &oSRS);
     455             :     static std::string GetMultiPointLayerName(const OGRSpatialReference &oSRS);
     456             : 
     457             :     OGRS101Reader(const OGRS101Reader &) = delete;
     458             :     OGRS101Reader &operator=(const OGRS101Reader &) = delete;
     459             : 
     460             :   protected:
     461             :     friend class OGRS101FeatureCatalog;
     462             :     static bool EmitErrorOrWarning(const char *pszFile, const char *pszFunc,
     463             :                                    int nLine, const char *pszMsg, bool bError,
     464             :                                    bool bRecoverable);
     465             : 
     466             :   public:
     467             :     OGRS101Reader();
     468             :     ~OGRS101Reader();
     469             : 
     470             :     bool Load(GDALOpenInfo *poOpenInfo);
     471             : 
     472             :     /** Return whether the dataset is cancelled. */
     473         338 :     bool IsCancelled() const
     474             :     {
     475         338 :         return m_bCancelled;
     476             :     }
     477             : 
     478             :     /** Return feature catalog, or null. */
     479           2 :     const OGRS101FeatureCatalog *GetFeatureCatalog() const
     480             :     {
     481           2 :         return m_poFeatureCatalog;
     482             :     }
     483             : 
     484             :     /** Return dataset metadata from the DSID field. */
     485         338 :     const CPLStringList &GetMetadata() const
     486             :     {
     487         338 :         return m_aosMetadata;
     488             :     }
     489             : 
     490             :     /** Return InformationType records */
     491         198 :     const DDFRecordIndex &GetInformationTypeRecords() const
     492             :     {
     493         198 :         return m_oInformationTypeRecordIndex;
     494             :     }
     495             : 
     496             :     /** Return Point records */
     497         204 :     const DDFRecordIndex &GetPointRecords() const
     498             :     {
     499         204 :         return m_oPointRecordIndex;
     500             :     }
     501             : 
     502             :     /** Return MultiPoint records */
     503          77 :     const DDFRecordIndex &GetMultiPointRecords() const
     504             :     {
     505          77 :         return m_oMultiPointRecordIndex;
     506             :     }
     507             : 
     508             :     /** Return Curve records */
     509         144 :     const DDFRecordIndex &GetCurveRecords() const
     510             :     {
     511         144 :         return m_oCurveRecordIndex;
     512             :     }
     513             : 
     514             :     /** Return CompositeCurve records */
     515         109 :     const DDFRecordIndex &GetCompositeCurveRecords() const
     516             :     {
     517         109 :         return m_oCompositeCurveRecordIndex;
     518             :     }
     519             : 
     520             :     /** Return Surface records */
     521          78 :     const DDFRecordIndex &GetSurfaceRecords() const
     522             :     {
     523          78 :         return m_oSurfaceRecordIndex;
     524             :     }
     525             : 
     526             :     /** Return FeatureType records */
     527         299 :     const DDFRecordIndex &GetFeatureTypeRecords() const
     528             :     {
     529         299 :         return m_oFeatureTypeRecordIndex;
     530             :     }
     531             : 
     532             :     /** Return (and steal) the layer definition for InformationType features */
     533         333 :     OGRFeatureDefnRefCountedPtr StealInformationTypeFeatureDefn()
     534             :     {
     535         333 :         return std::move(m_poFeatureDefnInformationType);
     536             :     }
     537             : 
     538             :     /** Return a map from a CRSId to the layer definition for Point features */
     539         333 :     std::map<CRSId, OGRFeatureDefnRefCountedPtr> &StealPointFeatureDefns()
     540             :     {
     541         333 :         return m_oMapPointFeatureDefn;
     542             :     }
     543             : 
     544             :     /** Return a map from a CRSId to the layer definition for MultiPoint features */
     545         333 :     std::map<CRSId, OGRFeatureDefnRefCountedPtr> &StealMultiPointFeatureDefns()
     546             :     {
     547         333 :         return m_oMapMultiPointFeatureDefn;
     548             :     }
     549             : 
     550             :     /** Return (and steal) a map from a feature type key to the layer definition */
     551         333 :     std::map<FeatureTypeKey, LayerDef> &StealFeatureTypeLayerDefs()
     552             :     {
     553         333 :         return m_oMapFeatureKeyToLayerDef;
     554             :     }
     555             : 
     556             :     /** Return (and steal) the layer definition for curve records */
     557         333 :     OGRFeatureDefnRefCountedPtr StealCurveFeatureDefn()
     558             :     {
     559         333 :         return std::move(m_poFeatureDefnCurve);
     560             :     }
     561             : 
     562             :     /** Return (and steal) the layer definition for composite curve records */
     563         333 :     OGRFeatureDefnRefCountedPtr StealCompositeCurveFeatureDefn()
     564             :     {
     565         333 :         return std::move(m_poFeatureDefnCompositeCurve);
     566             :     }
     567             : 
     568             :     /** Return (and steal) the layer definition for surface records */
     569         333 :     OGRFeatureDefnRefCountedPtr StealSurfaceFeatureDefn()
     570             :     {
     571         333 :         return std::move(m_poFeatureDefnSurface);
     572             :     }
     573             : 
     574             :     /** Return the map from CRS id to indexes of Point records */
     575             :     const std::map<OGRS101Reader::CRSId, std::vector<int>> &
     576         204 :     GetMapCRSIdToRecordIdxForPoints() const
     577             :     {
     578         204 :         return m_oMapCRSIdToPointRecordIdx;
     579             :     }
     580             : 
     581             :     /** Return the map from CRS id to indexes of MultiPoint records */
     582             :     const std::map<OGRS101Reader::CRSId, std::vector<int>> &
     583          77 :     GetMapCRSIdToRecordIdxForMultiPoints() const
     584             :     {
     585          77 :         return m_oMapCRSIdToMultiPointRecordIdx;
     586             :     }
     587             : 
     588             :     /** Return (and steal) the field domains */
     589         333 :     std::map<std::string, std::unique_ptr<OGRFieldDomain>> &StealFieldDomains()
     590             :     {
     591         333 :         return m_oMapFieldDomains;
     592             :     }
     593             : 
     594             :     bool FillFeatureInformationType(const DDFRecordIndex &oIndex, int iRecord,
     595             :                                     OGRFeature &oFeature) const;
     596             : 
     597             :     bool FillFeaturePoint(const DDFRecordIndex &oIndex, int iRecord,
     598             :                           OGRFeature &oFeature) const;
     599             : 
     600             :     bool FillFeatureMultiPoint(const DDFRecordIndex &oIndex, int iRecord,
     601             :                                OGRFeature &oFeature) const;
     602             : 
     603             :     bool FillFeatureCurve(const DDFRecordIndex &oIndex, int iRecord,
     604             :                           OGRFeature &oFeature) const;
     605             : 
     606             :     bool FillFeatureCompositeCurve(const DDFRecordIndex &oIndex, int iRecord,
     607             :                                    OGRFeature &oFeature) const;
     608             : 
     609             :     bool FillFeatureSurface(const DDFRecordIndex &oIndex, int iRecord,
     610             :                             OGRFeature &oFeature) const;
     611             : 
     612             :     bool FillFeatureFeatureType(const DDFRecordIndex &oIndex, int iRecord,
     613             :                                 OGRFeature &oFeature) const;
     614             : };
     615             : 
     616             : /** Emit an error in strict mode (and return false),
     617             :  * or an error in non-strict mode (and return true) */
     618             : #define EMIT_ERROR_OR_WARNING(msg)                                             \
     619             :     EmitErrorOrWarning(__FILE__, __FUNCTION__, __LINE__, msg, m_bStrict, true)
     620             : 
     621             : /** Emit an error */
     622             : #define EMIT_ERROR(msg)                                                        \
     623             :     EmitErrorOrWarning(__FILE__, __FUNCTION__, __LINE__, msg, true, false)
     624             : 
     625             : /************************************************************************/
     626             : /*                            OGRS101Dataset                            */
     627             : /************************************************************************/
     628             : 
     629             : class OGRS101Dataset final : public GDALDataset
     630             : {
     631             :     std::unique_ptr<OGRS101Reader> m_poReader{};
     632             :     std::vector<std::unique_ptr<OGRLayer>> m_apoLayers{};
     633             : 
     634             :   public:
     635         501 :     OGRS101Dataset() = default;
     636             : 
     637             :     int GetLayerCount() const override;
     638             :     OGRLayer *GetLayer(int) const override;
     639             : 
     640        4421 :     const OGRS101Reader &GetReader() const
     641             :     {
     642        4421 :         return *m_poReader;
     643             :     }
     644             : 
     645             :     int TestCapability(const char *) const override;
     646             : 
     647             :     static GDALDataset *Open(GDALOpenInfo *poOpenInfo);
     648             :     static void UnloadDriver(GDALDriver *);
     649             : };
     650             : 
     651             : /************************************************************************/
     652             : /*                            OGRS101Layer()                            */
     653             : /************************************************************************/
     654             : 
     655        1109 : class OGRS101Layer /* non final */ : public OGRLayer
     656             : {
     657             :   public:
     658             :     OGRS101Layer(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     659             :                  OGRFeatureDefnRefCountedPtr poFeatureDefn);
     660             :     ~OGRS101Layer() override;
     661             : 
     662       20467 :     const OGRFeatureDefn *GetLayerDefn() const override
     663             :     {
     664       20467 :         return m_poFeatureDefn.get();
     665             :     }
     666             : 
     667             :     void ResetReading() override;
     668             : 
     669             :     int TestCapability(const char *) const override;
     670             : 
     671             :     GIntBig GetFeatureCount(int bForce) override;
     672             : 
     673             :   protected:
     674             :     const OGRS101Dataset &m_oDS;
     675             :     const DDFRecordIndex &m_oIndex;
     676             :     const OGRFeatureDefnRefCountedPtr m_poFeatureDefn{};
     677             :     int m_nRecordIdx = 0;
     678             : 
     679             :   private:
     680             :     CPL_DISALLOW_COPY_ASSIGN(OGRS101Layer)
     681             : };
     682             : 
     683             : /************************************************************************/
     684             : /*                    OGRS101LayerInformationType()                     */
     685             : /************************************************************************/
     686             : 
     687             : class OGRS101LayerInformationType final
     688             :     : public OGRS101Layer,
     689             :       OGRGetNextFeatureThroughRaw<OGRS101LayerInformationType>
     690             : {
     691             :   public:
     692             :     OGRS101LayerInformationType(OGRS101Dataset &oDS,
     693             :                                 const DDFRecordIndex &oIndex,
     694             :                                 OGRFeatureDefnRefCountedPtr poFeatureDefn);
     695             : 
     696             :     OGRFeature *GetNextRawFeature();
     697             : 
     698             :     OGRFeature *GetFeature(GIntBig nFID) override;
     699             : 
     700         796 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerInformationType)
     701             : };
     702             : 
     703             : /************************************************************************/
     704             : /*                         OGRS101LayerPoint()                          */
     705             : /************************************************************************/
     706             : 
     707             : class OGRS101LayerPoint final : public OGRS101Layer,
     708             :                                 OGRGetNextFeatureThroughRaw<OGRS101LayerPoint>
     709             : {
     710             :   public:
     711             :     OGRS101LayerPoint(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     712             :                       const std::vector<int> &anRecordIndices,
     713             :                       OGRFeatureDefnRefCountedPtr poFeatureDefn);
     714             : 
     715             :     OGRFeature *GetNextRawFeature();
     716             : 
     717             :     GIntBig GetFeatureCount(int bForce) override;
     718             : 
     719             :     OGRFeature *GetFeature(GIntBig nFID) override;
     720             : 
     721        1393 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerPoint)
     722             : 
     723             :   private:
     724             :     const std::vector<int> &m_anRecordIndices;
     725             : };
     726             : 
     727             : /************************************************************************/
     728             : /*                       OGRS101LayerMultiPoint()                       */
     729             : /************************************************************************/
     730             : 
     731             : class OGRS101LayerMultiPoint final
     732             :     : public OGRS101Layer,
     733             :       OGRGetNextFeatureThroughRaw<OGRS101LayerMultiPoint>
     734             : {
     735             :   public:
     736             :     OGRS101LayerMultiPoint(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     737             :                            const std::vector<int> &anRecordIndices,
     738             :                            OGRFeatureDefnRefCountedPtr poFeatureDefn);
     739             : 
     740             :     OGRFeature *GetNextRawFeature();
     741             : 
     742             :     GIntBig GetFeatureCount(int bForce) override;
     743             : 
     744             :     OGRFeature *GetFeature(GIntBig nFID) override;
     745             : 
     746         488 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerMultiPoint)
     747             : 
     748             :   private:
     749             :     const std::vector<int> &m_anRecordIndices;
     750             : };
     751             : 
     752             : /************************************************************************/
     753             : /*                         OGRS101LayerCurve()                          */
     754             : /************************************************************************/
     755             : 
     756             : class OGRS101LayerCurve final : public OGRS101Layer,
     757             :                                 OGRGetNextFeatureThroughRaw<OGRS101LayerCurve>
     758             : {
     759             :   public:
     760             :     OGRS101LayerCurve(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     761             :                       OGRFeatureDefnRefCountedPtr poFeatureDefn);
     762             : 
     763             :     OGRFeature *GetNextRawFeature();
     764             : 
     765             :     OGRFeature *GetFeature(GIntBig nFID) override;
     766             : 
     767        1005 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerCurve)
     768             : };
     769             : 
     770             : /************************************************************************/
     771             : /*                     OGRS101LayerCompositeCurve()                     */
     772             : /************************************************************************/
     773             : 
     774             : class OGRS101LayerCompositeCurve final
     775             :     : public OGRS101Layer,
     776             :       OGRGetNextFeatureThroughRaw<OGRS101LayerCompositeCurve>
     777             : {
     778             :   public:
     779             :     OGRS101LayerCompositeCurve(OGRS101Dataset &oDS,
     780             :                                const DDFRecordIndex &oIndex,
     781             :                                OGRFeatureDefnRefCountedPtr poFeatureDefn);
     782             : 
     783             :     OGRFeature *GetNextRawFeature();
     784             : 
     785             :     OGRFeature *GetFeature(GIntBig nFID) override;
     786             : 
     787         570 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerCompositeCurve)
     788             : };
     789             : 
     790             : /************************************************************************/
     791             : /*                        OGRS101LayerSurface()                         */
     792             : /************************************************************************/
     793             : 
     794             : class OGRS101LayerSurface final
     795             :     : public OGRS101Layer,
     796             :       OGRGetNextFeatureThroughRaw<OGRS101LayerSurface>
     797             : {
     798             :   public:
     799             :     OGRS101LayerSurface(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     800             :                         OGRFeatureDefnRefCountedPtr poFeatureDefn);
     801             : 
     802             :     OGRFeature *GetNextRawFeature();
     803             : 
     804             :     OGRFeature *GetFeature(GIntBig nFID) override;
     805             : 
     806         332 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerSurface)
     807             : };
     808             : 
     809             : /************************************************************************/
     810             : /*                      OGRS101LayerFeatureType()                       */
     811             : /************************************************************************/
     812             : 
     813             : class OGRS101LayerFeatureType final
     814             :     : public OGRS101Layer,
     815             :       OGRGetNextFeatureThroughRaw<OGRS101LayerFeatureType>
     816             : {
     817             :   public:
     818             :     OGRS101LayerFeatureType(OGRS101Dataset &oDS, const DDFRecordIndex &oIndex,
     819             :                             const std::vector<int> &anRecordIndices,
     820             :                             OGRFeatureDefnRefCountedPtr poFeatureDefn);
     821             : 
     822             :     OGRFeature *GetNextRawFeature();
     823             : 
     824             :     GIntBig GetFeatureCount(int bForce) override;
     825             : 
     826             :     OGRFeature *GetFeature(GIntBig nFID) override;
     827             : 
     828        1116 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRS101LayerFeatureType)
     829             : 
     830             :   private:
     831             :     const std::vector<int> &m_anRecordIndices;
     832             : };
     833             : 
     834             : #endif  // OGR_S101_H_INCLUDED

Generated by: LCOV version 1.14