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-05-15 13:15:52 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #ifndef OGR_FLATGEOBUF_H_INCLUDED
      30             : #define OGR_FLATGEOBUF_H_INCLUDED
      31             : 
      32             : #include "ogrsf_frmts.h"
      33             : #include "ogr_p.h"
      34             : #include "ogreditablelayer.h"
      35             : 
      36             : #include "header_generated.h"
      37             : #include "feature_generated.h"
      38             : #include "packedrtree.h"
      39             : 
      40             : #include <deque>
      41             : #include <limits>
      42             : 
      43             : class OGRFlatGeobufDataset;
      44             : 
      45             : static constexpr uint8_t magicbytes[8] = {0x66, 0x67, 0x62, 0x03,
      46             :                                           0x66, 0x67, 0x62, 0x01};
      47             : 
      48             : static constexpr uint32_t header_max_buffer_size = 1048576 * 10;
      49             : 
      50             : // Cannot be larger than that, due to a x2 logic done in ensureFeatureBuf()
      51             : static constexpr uint32_t feature_max_buffer_size =
      52             :     static_cast<uint32_t>(std::numeric_limits<int32_t>::max());
      53             : 
      54             : // holds feature meta needed to build spatial index
      55             : struct FeatureItem : FlatGeobuf::Item
      56             : {
      57             :     uint32_t size;
      58             :     uint64_t offset;
      59             : };
      60             : 
      61         313 : class OGRFlatGeobufBaseLayerInterface CPL_NON_FINAL
      62             : {
      63             :   public:
      64             :     virtual ~OGRFlatGeobufBaseLayerInterface();
      65             : 
      66             :     virtual const std::string &GetFilename() const = 0;
      67             :     virtual OGRLayer *GetLayer() = 0;
      68             :     virtual CPLErr Close() = 0;
      69             : };
      70             : 
      71             : class OGRFlatGeobufLayer final : public OGRLayer,
      72             :                                  public OGRFlatGeobufBaseLayerInterface
      73             : {
      74             :   private:
      75             :     std::string m_osFilename;
      76             :     std::string m_osLayerName;
      77             : 
      78             :     VSILFILE *m_poFp = nullptr;
      79             :     vsi_l_offset m_nFileSize = 0;
      80             : 
      81             :     const FlatGeobuf::Header *m_poHeader = nullptr;
      82             :     GByte *m_headerBuf = nullptr;
      83             :     OGRwkbGeometryType m_eGType;
      84             :     FlatGeobuf::GeometryType m_geometryType;
      85             :     bool m_hasM = false;
      86             :     bool m_hasZ = false;
      87             :     bool m_hasT = false;
      88             :     bool m_hasTM = false;
      89             :     uint64_t m_featuresCount = 0;
      90             :     OGREnvelope m_sExtent;
      91             :     OGRFeatureDefn *m_poFeatureDefn = nullptr;
      92             :     OGRSpatialReference *m_poSRS = nullptr;
      93             : 
      94             :     // iteration
      95             :     bool m_bEOF = false;
      96             :     size_t m_featuresPos = 0;       // current iteration position
      97             :     uint64_t m_offset = 0;          // current read offset
      98             :     uint64_t m_offsetFeatures = 0;  // offset of feature data
      99             :     std::vector<FlatGeobuf::SearchResultItem>
     100             :         m_foundItems;  // found node items in spatial index search
     101             :     bool m_queriedSpatialIndex = false;
     102             :     bool m_ignoreSpatialFilter = false;
     103             :     bool m_ignoreAttributeFilter = false;
     104             : 
     105             :     // creation
     106             :     GDALDataset *m_poDS = nullptr;  // parent dataset to get metadata from it
     107             :     bool m_create = false;
     108             :     std::deque<FeatureItem> m_featureItems;  // feature item description used to
     109             :                                              // create spatial index
     110             :     bool m_bCreateSpatialIndexAtClose = true;
     111             :     bool m_bVerifyBuffers = true;
     112             :     VSILFILE *m_poFpWrite = nullptr;
     113             :     CPLStringList m_aosCreationOption{};  // layer creation options
     114             :     uint64_t m_writeOffset = 0;           // current write offset
     115             :     uint64_t m_offsetAfterHeader =
     116             :         0;  // offset after dummy header writing (when creating a file without
     117             :             // spatial index)
     118             :     uint16_t m_indexNodeSize = 0;
     119             :     std::string
     120             :         m_osTempFile;  // holds generated temp file name for two pass writing
     121             :     uint32_t m_maxFeatureSize = 0;
     122             :     std::vector<uint8_t> m_writeProperties{};
     123             : 
     124             :     // shared
     125             :     GByte *m_featureBuf = nullptr;  // reusable/resizable feature data buffer
     126             :     uint32_t m_featureBufSize = 0;  // current feature buffer size
     127             : 
     128             :     // deserialize
     129             :     void ensurePadfBuffers(size_t count);
     130             :     OGRErr ensureFeatureBuf(uint32_t featureSize);
     131             :     OGRErr parseFeature(OGRFeature *poFeature);
     132             :     const std::vector<flatbuffers::Offset<FlatGeobuf::Column>>
     133             :     writeColumns(flatbuffers::FlatBufferBuilder &fbb);
     134             :     void readColumns();
     135             :     OGRErr readIndex();
     136             :     OGRErr readFeatureOffset(uint64_t index, uint64_t &featureOffset);
     137             : 
     138             :     // serialize
     139             :     bool CreateFinalFile();
     140             :     void writeHeader(VSILFILE *poFp, uint64_t featuresCount,
     141             :                      std::vector<double> *extentVector);
     142             : 
     143             :     // construction
     144             :     OGRFlatGeobufLayer(const FlatGeobuf::Header *, GByte *headerBuf,
     145             :                        const char *pszFilename, VSILFILE *poFp,
     146             :                        uint64_t offset);
     147             :     OGRFlatGeobufLayer(GDALDataset *poDS, const char *pszLayerName,
     148             :                        const char *pszFilename,
     149             :                        const OGRSpatialReference *poSpatialRef,
     150             :                        OGRwkbGeometryType eGType,
     151             :                        bool bCreateSpatialIndexAtClose, VSILFILE *poFpWrite,
     152             :                        std::string &osTempFile, CSLConstList papszOptions);
     153             : 
     154             :   protected:
     155             :     virtual int GetNextArrowArray(struct ArrowArrayStream *,
     156             :                                   struct ArrowArray *out_array) override;
     157             : 
     158             :     CPLErr Close() override;
     159             : 
     160             :   public:
     161             :     virtual ~OGRFlatGeobufLayer();
     162             : 
     163             :     static OGRFlatGeobufLayer *Open(const FlatGeobuf::Header *,
     164             :                                     GByte *headerBuf, const char *pszFilename,
     165             :                                     VSILFILE *poFp, uint64_t offset);
     166             :     static OGRFlatGeobufLayer *Open(const char *pszFilename, VSILFILE *fp,
     167             :                                     bool bVerifyBuffers);
     168             :     static OGRFlatGeobufLayer *
     169             :     Create(GDALDataset *poDS, const char *pszLayerName, const char *pszFilename,
     170             :            const OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType,
     171             :            bool bCreateSpatialIndexAtClose, CSLConstList papszOptions);
     172             : 
     173             :     virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
     174             :     virtual OGRFeature *GetNextFeature() override;
     175             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     176             :                                int bApproxOK = true) override;
     177             :     virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
     178             :     virtual int TestCapability(const char *) override;
     179             : 
     180             :     virtual void ResetReading() override;
     181             : 
     182         968 :     virtual OGRFeatureDefn *GetLayerDefn() override
     183             :     {
     184         968 :         return m_poFeatureDefn;
     185             :     }
     186             : 
     187             :     virtual GIntBig GetFeatureCount(int bForce) override;
     188             :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
     189             : 
     190           7 :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     191             :                              int bForce) override
     192             :     {
     193           7 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     194             :     }
     195             : 
     196         145 :     void VerifyBuffers(int bFlag)
     197             :     {
     198         145 :         m_bVerifyBuffers = CPL_TO_BOOL(bFlag);
     199         145 :     }
     200             : 
     201          38 :     GDALDataset *GetDataset() override
     202             :     {
     203          38 :         return m_poDS;
     204             :     }
     205             : 
     206           4 :     const std::string &GetFilename() const override
     207             :     {
     208           4 :         return m_osFilename;
     209             :     }
     210             : 
     211         647 :     OGRLayer *GetLayer() override
     212             :     {
     213         647 :         return this;
     214             :     }
     215             : 
     216             :     static std::string GetTempFilePath(const CPLString &fileName,
     217             :                                        CSLConstList papszOptions);
     218             :     static VSILFILE *CreateOutputFile(const CPLString &pszFilename,
     219             :                                       CSLConstList papszOptions, bool isTemp);
     220             : 
     221           1 :     uint16_t GetIndexNodeSize() const
     222             :     {
     223           1 :         return m_indexNodeSize;
     224             :     }
     225             : 
     226             :     OGRwkbGeometryType getOGRwkbGeometryType();
     227             : };
     228             : 
     229             : class OGRFlatGeobufEditableLayer final : public OGREditableLayer,
     230             :                                          public OGRFlatGeobufBaseLayerInterface
     231             : {
     232             :   public:
     233             :     OGRFlatGeobufEditableLayer(OGRFlatGeobufLayer *poFlatGeobufLayer,
     234             :                                char **papszOpenOptions);
     235             : 
     236             :     virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
     237             : 
     238           0 :     const std::string &GetFilename() const override
     239             :     {
     240           0 :         return static_cast<OGRFlatGeobufLayer *>(m_poDecoratedLayer)
     241           0 :             ->GetFilename();
     242             :     }
     243             : 
     244           2 :     OGRLayer *GetLayer() override
     245             :     {
     246           2 :         return this;
     247             :     }
     248             : 
     249             :     int TestCapability(const char *pszCap) override;
     250             : 
     251           1 :     CPLErr Close() override
     252             :     {
     253           1 :         return CE_None;
     254             :     }
     255             : };
     256             : 
     257             : class OGRFlatGeobufDataset final : public GDALDataset
     258             : {
     259             :   private:
     260             :     std::vector<std::unique_ptr<OGRFlatGeobufBaseLayerInterface>> m_apoLayers;
     261             :     bool m_bCreate = false;
     262             :     bool m_bUpdate = false;
     263             :     bool m_bIsDir = false;
     264             : 
     265             :     bool OpenFile(const char *pszFilename, VSILFILE *fp, bool bVerifyBuffers);
     266             : 
     267             :     CPLErr Close() override;
     268             : 
     269             :   public:
     270             :     OGRFlatGeobufDataset(const char *pszName, bool bIsDir, bool bCreate,
     271             :                          bool bUpdate);
     272             :     ~OGRFlatGeobufDataset();
     273             : 
     274             :     static GDALDataset *Open(GDALOpenInfo *);
     275             :     static GDALDataset *Create(const char *pszName, CPL_UNUSED int nBands,
     276             :                                CPL_UNUSED int nXSize, CPL_UNUSED int nYSize,
     277             :                                CPL_UNUSED GDALDataType eDT,
     278             :                                char **papszOptions);
     279             :     virtual OGRLayer *GetLayer(int) override;
     280             :     int TestCapability(const char *pszCap) override;
     281             : 
     282             :     OGRLayer *ICreateLayer(const char *pszName,
     283             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     284             :                            CSLConstList papszOptions) override;
     285             : 
     286        1560 :     virtual int GetLayerCount() override
     287             :     {
     288        1560 :         return static_cast<int>(m_apoLayers.size());
     289             :     }
     290             : 
     291             :     char **GetFileList() override;
     292             : };
     293             : 
     294             : #endif /* ndef OGR_FLATGEOBUF_H_INCLUDED */

Generated by: LCOV version 1.14