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

Generated by: LCOV version 1.14