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: 22 25 88.0 %
Date: 2024-11-21 22:18:42 Functions: 11 13 84.6 %

          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         316 : 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        1483 :     virtual OGRFeatureDefn *GetLayerDefn() override
     167             :     {
     168        1483 :         return m_poFeatureDefn;
     169             :     }
     170             : 
     171             :     virtual GIntBig GetFeatureCount(int bForce) override;
     172             :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
     173             : 
     174           7 :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     175             :                              int bForce) override
     176             :     {
     177           7 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     178             :     }
     179             : 
     180         147 :     void VerifyBuffers(int bFlag)
     181             :     {
     182         147 :         m_bVerifyBuffers = CPL_TO_BOOL(bFlag);
     183         147 :     }
     184             : 
     185          37 :     GDALDataset *GetDataset() override
     186             :     {
     187          37 :         return m_poDS;
     188             :     }
     189             : 
     190           4 :     const std::string &GetFilename() const override
     191             :     {
     192           4 :         return m_osFilename;
     193             :     }
     194             : 
     195         728 :     OGRLayer *GetLayer() override
     196             :     {
     197         728 :         return this;
     198             :     }
     199             : 
     200             :     static std::string GetTempFilePath(const CPLString &fileName,
     201             :                                        CSLConstList papszOptions);
     202             :     static VSILFILE *CreateOutputFile(const CPLString &pszFilename,
     203             :                                       CSLConstList papszOptions, bool isTemp);
     204             : 
     205           1 :     uint16_t GetIndexNodeSize() const
     206             :     {
     207           1 :         return m_indexNodeSize;
     208             :     }
     209             : 
     210             :     OGRwkbGeometryType getOGRwkbGeometryType();
     211             : };
     212             : 
     213             : class OGRFlatGeobufEditableLayer final : public OGREditableLayer,
     214             :                                          public OGRFlatGeobufBaseLayerInterface
     215             : {
     216             :   public:
     217             :     OGRFlatGeobufEditableLayer(OGRFlatGeobufLayer *poFlatGeobufLayer,
     218             :                                char **papszOpenOptions);
     219             : 
     220             :     virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
     221             : 
     222           0 :     const std::string &GetFilename() const override
     223             :     {
     224           0 :         return static_cast<OGRFlatGeobufLayer *>(m_poDecoratedLayer)
     225           0 :             ->GetFilename();
     226             :     }
     227             : 
     228           2 :     OGRLayer *GetLayer() override
     229             :     {
     230           2 :         return this;
     231             :     }
     232             : 
     233             :     int TestCapability(const char *pszCap) override;
     234             : 
     235           1 :     CPLErr Close() override
     236             :     {
     237           1 :         return CE_None;
     238             :     }
     239             : };
     240             : 
     241             : class OGRFlatGeobufDataset final : public GDALDataset
     242             : {
     243             :   private:
     244             :     std::vector<std::unique_ptr<OGRFlatGeobufBaseLayerInterface>> m_apoLayers;
     245             :     bool m_bCreate = false;
     246             :     bool m_bUpdate = false;
     247             :     bool m_bIsDir = false;
     248             : 
     249             :     bool OpenFile(const char *pszFilename, VSILFILE *fp, bool bVerifyBuffers);
     250             : 
     251             :     CPLErr Close() override;
     252             : 
     253             :   public:
     254             :     OGRFlatGeobufDataset(const char *pszName, bool bIsDir, bool bCreate,
     255             :                          bool bUpdate);
     256             :     ~OGRFlatGeobufDataset();
     257             : 
     258             :     static GDALDataset *Open(GDALOpenInfo *);
     259             :     static GDALDataset *Create(const char *pszName, CPL_UNUSED int nBands,
     260             :                                CPL_UNUSED int nXSize, CPL_UNUSED int nYSize,
     261             :                                CPL_UNUSED GDALDataType eDT,
     262             :                                char **papszOptions);
     263             :     virtual OGRLayer *GetLayer(int) override;
     264             :     int TestCapability(const char *pszCap) override;
     265             : 
     266             :     OGRLayer *ICreateLayer(const char *pszName,
     267             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     268             :                            CSLConstList papszOptions) override;
     269             : 
     270        1757 :     virtual int GetLayerCount() override
     271             :     {
     272        1757 :         return static_cast<int>(m_apoLayers.size());
     273             :     }
     274             : 
     275             :     char **GetFileList() override;
     276             : };
     277             : 
     278             : #endif /* ndef OGR_FLATGEOBUF_H_INCLUDED */

Generated by: LCOV version 1.14