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: 2026-06-19 21:24:00 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             : #include <utility>
      36             : 
      37             : class OGRFlatGeobufDataset;
      38             : 
      39             : static constexpr uint8_t magicbytes[8] = {0x66, 0x67, 0x62, 0x03,
      40             :                                           0x66, 0x67, 0x62, 0x01};
      41             : 
      42             : static constexpr uint32_t header_max_buffer_size = 1048576 * 10;
      43             : 
      44             : // Cannot be larger than that, due to a x2 logic done in ensureFeatureBuf()
      45             : static constexpr uint32_t feature_max_buffer_size =
      46             :     static_cast<uint32_t>(std::numeric_limits<int32_t>::max());
      47             : 
      48             : // holds feature meta needed to build spatial index
      49             : struct FeatureItem : FlatGeobuf::Item
      50             : {
      51             :     uint32_t size;
      52             :     uint64_t offset;
      53             : };
      54             : 
      55         334 : class OGRFlatGeobufBaseLayerInterface CPL_NON_FINAL
      56             : {
      57             :   public:
      58             :     virtual ~OGRFlatGeobufBaseLayerInterface();
      59             : 
      60             :     virtual const std::string &GetFilename() const = 0;
      61             :     virtual OGRLayer *GetLayer() = 0;
      62             :     virtual CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) = 0;
      63             : };
      64             : 
      65             : class OGRFlatGeobufLayer final : public OGRLayer,
      66             :                                  public OGRFlatGeobufBaseLayerInterface
      67             : {
      68             :   private:
      69             :     std::string m_osFilename;
      70             :     std::string m_osLayerName;
      71             : 
      72             :     VSILFILE *m_poFp = nullptr;
      73             :     vsi_l_offset m_nFileSize = 0;
      74             : 
      75             :     const FlatGeobuf::Header *m_poHeader = nullptr;
      76             :     GByte *m_headerBuf = nullptr;
      77             :     OGRwkbGeometryType m_eGType;
      78             :     FlatGeobuf::GeometryType m_geometryType;
      79             :     bool m_hasM = false;
      80             :     bool m_hasZ = false;
      81             :     bool m_hasT = false;
      82             :     bool m_hasTM = false;
      83             :     uint64_t m_featuresCount = 0;
      84             :     OGREnvelope m_sExtent;
      85             :     OGRFeatureDefn *m_poFeatureDefn = nullptr;
      86             :     OGRSpatialReference *m_poSRS = nullptr;
      87             : 
      88             :     // iteration
      89             :     bool m_bEOF = false;
      90             :     size_t m_featuresPos = 0;       // current iteration position
      91             :     uint64_t m_offset = 0;          // current read offset
      92             :     uint64_t m_offsetFeatures = 0;  // offset of feature data
      93             :     std::vector<FlatGeobuf::SearchResultItem>
      94             :         m_foundItems;  // found node items in spatial index search
      95             :     bool m_queriedSpatialIndex = false;
      96             :     bool m_ignoreSpatialFilter = false;
      97             :     bool m_ignoreAttributeFilter = false;
      98             : 
      99             :     // creation
     100             :     GDALDataset *m_poDS = nullptr;  // parent dataset to get metadata from it
     101             :     bool m_create = false;
     102             :     std::deque<FeatureItem> m_featureItems;  // feature item description used to
     103             :                                              // create spatial index
     104             :     bool m_bCreateSpatialIndexAtClose = true;
     105             :     bool m_bVerifyBuffers = true;
     106             :     VSILFILE *m_poFpWrite = nullptr;
     107             :     CPLStringList m_aosCreationOption{};  // layer creation options
     108             :     uint64_t m_writeOffset = 0;           // current write offset
     109             :     uint64_t m_offsetAfterHeader =
     110             :         0;  // offset after dummy header writing (when creating a file without
     111             :             // spatial index)
     112             :     uint16_t m_indexNodeSize = 0;
     113             :     std::string
     114             :         m_osTempFile;  // holds generated temp file name for two pass writing
     115             :     uint32_t m_maxFeatureSize = 0;
     116             :     std::vector<uint8_t> m_writeProperties{};
     117             : 
     118             :     // shared
     119             :     GByte *m_featureBuf = nullptr;  // reusable/resizable feature data buffer
     120             :     uint32_t m_featureBufSize = 0;  // current feature buffer size
     121             : 
     122             :     // deserialize
     123             :     void ensurePadfBuffers(size_t count);
     124             :     OGRErr ensureFeatureBuf(uint32_t featureSize);
     125             :     OGRErr parseFeature(OGRFeature *poFeature);
     126             :     const std::vector<flatbuffers::Offset<FlatGeobuf::Column>>
     127             :     writeColumns(flatbuffers::FlatBufferBuilder &fbb);
     128             :     void readColumns();
     129             :     OGRErr readIndex();
     130             :     OGRErr readFeatureOffset(uint64_t index, uint64_t &featureOffset);
     131             : 
     132             :     // serialize
     133             :     bool CreateFinalFile();
     134             :     void writeHeader(VSILFILE *poFp, uint64_t featuresCount,
     135             :                      std::vector<double> *extentVector);
     136             : 
     137             :     // construction
     138             :     OGRFlatGeobufLayer(const FlatGeobuf::Header *, GByte *headerBuf,
     139             :                        const char *pszFilename, VSILFILE *poFp,
     140             :                        uint64_t offset);
     141             :     OGRFlatGeobufLayer(GDALDataset *poDS, const char *pszLayerName,
     142             :                        const char *pszFilename,
     143             :                        const OGRSpatialReference *poSpatialRef,
     144             :                        OGRwkbGeometryType eGType,
     145             :                        bool bCreateSpatialIndexAtClose, VSILFILE *poFpWrite,
     146             :                        std::string &osTempFile, CSLConstList papszOptions);
     147             : 
     148             :   protected:
     149             :     virtual int GetNextArrowArray(struct ArrowArrayStream *,
     150             :                                   struct ArrowArray *out_array) override;
     151             : 
     152             :     CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) override;
     153             : 
     154             :   public:
     155             :     ~OGRFlatGeobufLayer() override;
     156             : 
     157             :     static OGRFlatGeobufLayer *Open(const FlatGeobuf::Header *,
     158             :                                     GByte *headerBuf, const char *pszFilename,
     159             :                                     VSILFILE *poFp, uint64_t offset);
     160             :     static OGRFlatGeobufLayer *Open(const char *pszFilename, VSILFILE *fp,
     161             :                                     bool bVerifyBuffers);
     162             :     static OGRFlatGeobufLayer *
     163             :     Create(GDALDataset *poDS, const char *pszLayerName, const char *pszFilename,
     164             :            const OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType,
     165             :            bool bCreateSpatialIndexAtClose, CSLConstList papszOptions);
     166             : 
     167             :     OGRFeature *GetFeature(GIntBig nFeatureId) override;
     168             :     OGRFeature *GetNextFeature() override;
     169             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     170             :                                int bApproxOK = true) override;
     171             :     OGRErr ICreateFeature(OGRFeature *poFeature) override;
     172             :     int TestCapability(const char *) const override;
     173             : 
     174             :     void ResetReading() override;
     175             : 
     176        1508 :     const OGRFeatureDefn *GetLayerDefn() const override
     177             :     {
     178        1508 :         return m_poFeatureDefn;
     179             :     }
     180             : 
     181             :     GIntBig GetFeatureCount(int bForce) override;
     182             :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     183             :                       bool bForce) override;
     184             : 
     185         154 :     void VerifyBuffers(int bFlag)
     186             :     {
     187         154 :         m_bVerifyBuffers = CPL_TO_BOOL(bFlag);
     188         154 :     }
     189             : 
     190          39 :     GDALDataset *GetDataset() override
     191             :     {
     192          39 :         return m_poDS;
     193             :     }
     194             : 
     195           5 :     const std::string &GetFilename() const override
     196             :     {
     197           5 :         return m_osFilename;
     198             :     }
     199             : 
     200         766 :     OGRLayer *GetLayer() override
     201             :     {
     202         766 :         return this;
     203             :     }
     204             : 
     205             :     static std::pair<VSILFILE *, std::string>
     206             :     CreateOutputFile(const CPLString &pszFilename, CSLConstList papszOptions,
     207             :                      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             :     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) const override;
     238             : 
     239           1 :     CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) 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(GDALProgressFunc = nullptr, void * = nullptr) override;
     256             : 
     257             :   public:
     258             :     OGRFlatGeobufDataset(const char *pszName, bool bIsDir, bool bCreate,
     259             :                          bool bUpdate);
     260             :     ~OGRFlatGeobufDataset() override;
     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             :                                CSLConstList papszOptions);
     267             :     using GDALDataset::GetLayer;
     268             :     const OGRLayer *GetLayer(int) const override;
     269             :     int TestCapability(const char *pszCap) const override;
     270             : 
     271             :     OGRLayer *ICreateLayer(const char *pszName,
     272             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     273             :                            CSLConstList papszOptions) override;
     274             : 
     275        2041 :     int GetLayerCount() const override
     276             :     {
     277        2041 :         return static_cast<int>(m_apoLayers.size());
     278             :     }
     279             : 
     280             :     char **GetFileList() override;
     281             : };
     282             : 
     283             : #endif /* ndef OGR_FLATGEOBUF_H_INCLUDED */

Generated by: LCOV version 1.14