LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/flatgeobuf - ogr_flatgeobuf.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 20 23 87.0 %
Date: 2025-07-08 21:33:46 Functions: 10 12 83.3 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  FlatGeobuf driver
       4             :  * Purpose:  Declaration of classes for OGR FlatGeobuf driver.
       5             :  * Author:   Björn Harrtell <bjorn at wololo dot org>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2018-2020, Björn Harrtell <bjorn at wololo dot org>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #ifndef OGR_FLATGEOBUF_H_INCLUDED
      14             : #define OGR_FLATGEOBUF_H_INCLUDED
      15             : 
      16             : #include "ogrsf_frmts.h"
      17             : #include "ogr_p.h"
      18             : #include "ogreditablelayer.h"
      19             : 
      20             : #if defined(__clang__)
      21             : #pragma clang diagnostic push
      22             : #pragma clang diagnostic ignored "-Wweak-vtables"
      23             : #endif
      24             : 
      25             : #include "header_generated.h"
      26             : #include "feature_generated.h"
      27             : #include "packedrtree.h"
      28             : 
      29             : #if defined(__clang__)
      30             : #pragma clang diagnostic pop
      31             : #endif
      32             : 
      33             : #include <deque>
      34             : #include <limits>
      35             : 
      36             : class OGRFlatGeobufDataset;
      37             : 
      38             : static constexpr uint8_t magicbytes[8] = {0x66, 0x67, 0x62, 0x03,
      39             :                                           0x66, 0x67, 0x62, 0x01};
      40             : 
      41             : static constexpr uint32_t header_max_buffer_size = 1048576 * 10;
      42             : 
      43             : // Cannot be larger than that, due to a x2 logic done in ensureFeatureBuf()
      44             : static constexpr uint32_t feature_max_buffer_size =
      45             :     static_cast<uint32_t>(std::numeric_limits<int32_t>::max());
      46             : 
      47             : // holds feature meta needed to build spatial index
      48             : struct FeatureItem : FlatGeobuf::Item
      49             : {
      50             :     uint32_t size;
      51             :     uint64_t offset;
      52             : };
      53             : 
      54         322 : class OGRFlatGeobufBaseLayerInterface CPL_NON_FINAL
      55             : {
      56             :   public:
      57             :     virtual ~OGRFlatGeobufBaseLayerInterface();
      58             : 
      59             :     virtual const std::string &GetFilename() const = 0;
      60             :     virtual OGRLayer *GetLayer() = 0;
      61             :     virtual CPLErr Close() = 0;
      62             : };
      63             : 
      64             : class OGRFlatGeobufLayer final : public OGRLayer,
      65             :                                  public OGRFlatGeobufBaseLayerInterface
      66             : {
      67             :   private:
      68             :     std::string m_osFilename;
      69             :     std::string m_osLayerName;
      70             : 
      71             :     VSILFILE *m_poFp = nullptr;
      72             :     vsi_l_offset m_nFileSize = 0;
      73             : 
      74             :     const FlatGeobuf::Header *m_poHeader = nullptr;
      75             :     GByte *m_headerBuf = nullptr;
      76             :     OGRwkbGeometryType m_eGType;
      77             :     FlatGeobuf::GeometryType m_geometryType;
      78             :     bool m_hasM = false;
      79             :     bool m_hasZ = false;
      80             :     bool m_hasT = false;
      81             :     bool m_hasTM = false;
      82             :     uint64_t m_featuresCount = 0;
      83             :     OGREnvelope m_sExtent;
      84             :     OGRFeatureDefn *m_poFeatureDefn = nullptr;
      85             :     OGRSpatialReference *m_poSRS = nullptr;
      86             : 
      87             :     // iteration
      88             :     bool m_bEOF = false;
      89             :     size_t m_featuresPos = 0;       // current iteration position
      90             :     uint64_t m_offset = 0;          // current read offset
      91             :     uint64_t m_offsetFeatures = 0;  // offset of feature data
      92             :     std::vector<FlatGeobuf::SearchResultItem>
      93             :         m_foundItems;  // found node items in spatial index search
      94             :     bool m_queriedSpatialIndex = false;
      95             :     bool m_ignoreSpatialFilter = false;
      96             :     bool m_ignoreAttributeFilter = false;
      97             : 
      98             :     // creation
      99             :     GDALDataset *m_poDS = nullptr;  // parent dataset to get metadata from it
     100             :     bool m_create = false;
     101             :     std::deque<FeatureItem> m_featureItems;  // feature item description used to
     102             :                                              // create spatial index
     103             :     bool m_bCreateSpatialIndexAtClose = true;
     104             :     bool m_bVerifyBuffers = true;
     105             :     VSILFILE *m_poFpWrite = nullptr;
     106             :     CPLStringList m_aosCreationOption{};  // layer creation options
     107             :     uint64_t m_writeOffset = 0;           // current write offset
     108             :     uint64_t m_offsetAfterHeader =
     109             :         0;  // offset after dummy header writing (when creating a file without
     110             :             // spatial index)
     111             :     uint16_t m_indexNodeSize = 0;
     112             :     std::string
     113             :         m_osTempFile;  // holds generated temp file name for two pass writing
     114             :     uint32_t m_maxFeatureSize = 0;
     115             :     std::vector<uint8_t> m_writeProperties{};
     116             : 
     117             :     // shared
     118             :     GByte *m_featureBuf = nullptr;  // reusable/resizable feature data buffer
     119             :     uint32_t m_featureBufSize = 0;  // current feature buffer size
     120             : 
     121             :     // deserialize
     122             :     void ensurePadfBuffers(size_t count);
     123             :     OGRErr ensureFeatureBuf(uint32_t featureSize);
     124             :     OGRErr parseFeature(OGRFeature *poFeature);
     125             :     const std::vector<flatbuffers::Offset<FlatGeobuf::Column>>
     126             :     writeColumns(flatbuffers::FlatBufferBuilder &fbb);
     127             :     void readColumns();
     128             :     OGRErr readIndex();
     129             :     OGRErr readFeatureOffset(uint64_t index, uint64_t &featureOffset);
     130             : 
     131             :     // serialize
     132             :     bool CreateFinalFile();
     133             :     void writeHeader(VSILFILE *poFp, uint64_t featuresCount,
     134             :                      std::vector<double> *extentVector);
     135             : 
     136             :     // construction
     137             :     OGRFlatGeobufLayer(const FlatGeobuf::Header *, GByte *headerBuf,
     138             :                        const char *pszFilename, VSILFILE *poFp,
     139             :                        uint64_t offset);
     140             :     OGRFlatGeobufLayer(GDALDataset *poDS, const char *pszLayerName,
     141             :                        const char *pszFilename,
     142             :                        const OGRSpatialReference *poSpatialRef,
     143             :                        OGRwkbGeometryType eGType,
     144             :                        bool bCreateSpatialIndexAtClose, VSILFILE *poFpWrite,
     145             :                        std::string &osTempFile, CSLConstList papszOptions);
     146             : 
     147             :   protected:
     148             :     virtual int GetNextArrowArray(struct ArrowArrayStream *,
     149             :                                   struct ArrowArray *out_array) override;
     150             : 
     151             :     CPLErr Close() override;
     152             : 
     153             :   public:
     154             :     virtual ~OGRFlatGeobufLayer();
     155             : 
     156             :     static OGRFlatGeobufLayer *Open(const FlatGeobuf::Header *,
     157             :                                     GByte *headerBuf, const char *pszFilename,
     158             :                                     VSILFILE *poFp, uint64_t offset);
     159             :     static OGRFlatGeobufLayer *Open(const char *pszFilename, VSILFILE *fp,
     160             :                                     bool bVerifyBuffers);
     161             :     static OGRFlatGeobufLayer *
     162             :     Create(GDALDataset *poDS, const char *pszLayerName, const char *pszFilename,
     163             :            const OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType,
     164             :            bool bCreateSpatialIndexAtClose, CSLConstList papszOptions);
     165             : 
     166             :     virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
     167             :     virtual OGRFeature *GetNextFeature() override;
     168             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     169             :                                int bApproxOK = true) override;
     170             :     virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
     171             :     virtual int TestCapability(const char *) override;
     172             : 
     173             :     virtual void ResetReading() override;
     174             : 
     175        1513 :     virtual OGRFeatureDefn *GetLayerDefn() override
     176             :     {
     177        1513 :         return m_poFeatureDefn;
     178             :     }
     179             : 
     180             :     virtual GIntBig GetFeatureCount(int bForce) override;
     181             :     virtual OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     182             :                               bool bForce) override;
     183             : 
     184         150 :     void VerifyBuffers(int bFlag)
     185             :     {
     186         150 :         m_bVerifyBuffers = CPL_TO_BOOL(bFlag);
     187         150 :     }
     188             : 
     189          39 :     GDALDataset *GetDataset() override
     190             :     {
     191          39 :         return m_poDS;
     192             :     }
     193             : 
     194           4 :     const std::string &GetFilename() const override
     195             :     {
     196           4 :         return m_osFilename;
     197             :     }
     198             : 
     199         740 :     OGRLayer *GetLayer() override
     200             :     {
     201         740 :         return this;
     202             :     }
     203             : 
     204             :     static std::string GetTempFilePath(const CPLString &fileName,
     205             :                                        CSLConstList papszOptions);
     206             :     static VSILFILE *CreateOutputFile(const CPLString &pszFilename,
     207             :                                       CSLConstList papszOptions, bool isTemp);
     208             : 
     209           1 :     uint16_t GetIndexNodeSize() const
     210             :     {
     211           1 :         return m_indexNodeSize;
     212             :     }
     213             : 
     214             :     OGRwkbGeometryType getOGRwkbGeometryType();
     215             : };
     216             : 
     217             : class OGRFlatGeobufEditableLayer final : public OGREditableLayer,
     218             :                                          public OGRFlatGeobufBaseLayerInterface
     219             : {
     220             :   public:
     221             :     OGRFlatGeobufEditableLayer(OGRFlatGeobufLayer *poFlatGeobufLayer,
     222             :                                char **papszOpenOptions);
     223             : 
     224             :     virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
     225             : 
     226           0 :     const std::string &GetFilename() const override
     227             :     {
     228           0 :         return static_cast<OGRFlatGeobufLayer *>(m_poDecoratedLayer)
     229           0 :             ->GetFilename();
     230             :     }
     231             : 
     232           2 :     OGRLayer *GetLayer() override
     233             :     {
     234           2 :         return this;
     235             :     }
     236             : 
     237             :     int TestCapability(const char *pszCap) override;
     238             : 
     239           1 :     CPLErr Close() override
     240             :     {
     241           1 :         return CE_None;
     242             :     }
     243             : };
     244             : 
     245             : class OGRFlatGeobufDataset final : public GDALDataset
     246             : {
     247             :   private:
     248             :     std::vector<std::unique_ptr<OGRFlatGeobufBaseLayerInterface>> m_apoLayers;
     249             :     bool m_bCreate = false;
     250             :     bool m_bUpdate = false;
     251             :     bool m_bIsDir = false;
     252             : 
     253             :     bool OpenFile(const char *pszFilename, VSILFILE *fp, bool bVerifyBuffers);
     254             : 
     255             :     CPLErr Close() override;
     256             : 
     257             :   public:
     258             :     OGRFlatGeobufDataset(const char *pszName, bool bIsDir, bool bCreate,
     259             :                          bool bUpdate);
     260             :     ~OGRFlatGeobufDataset();
     261             : 
     262             :     static GDALDataset *Open(GDALOpenInfo *);
     263             :     static GDALDataset *Create(const char *pszName, CPL_UNUSED int nBands,
     264             :                                CPL_UNUSED int nXSize, CPL_UNUSED int nYSize,
     265             :                                CPL_UNUSED GDALDataType eDT,
     266             :                                char **papszOptions);
     267             :     virtual OGRLayer *GetLayer(int) override;
     268             :     int TestCapability(const char *pszCap) override;
     269             : 
     270             :     OGRLayer *ICreateLayer(const char *pszName,
     271             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     272             :                            CSLConstList papszOptions) override;
     273             : 
     274        1844 :     virtual int GetLayerCount() override
     275             :     {
     276        1844 :         return static_cast<int>(m_apoLayers.size());
     277             :     }
     278             : 
     279             :     char **GetFileList() override;
     280             : };
     281             : 
     282             : #endif /* ndef OGR_FLATGEOBUF_H_INCLUDED */

Generated by: LCOV version 1.14