LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/shape - ogrshape.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 36 36 100.0 %
Date: 2025-05-31 00:00:17 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Private definitions within the Shapefile driver to implement
       5             :  *           integration with OGR.
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 1999,  Les Technologies SoftMap Inc.
      10             :  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #ifndef OGRSHAPE_H_INCLUDED
      16             : #define OGRSHAPE_H_INCLUDED
      17             : 
      18             : #ifdef RENAME_INTERNAL_SHAPELIB_SYMBOLS
      19             : #include "gdal_shapelib_symbol_rename.h"
      20             : #endif
      21             : 
      22             : #include "ogrsf_frmts.h"
      23             : #include "shapefil.h"
      24             : #include "shp_vsi.h"
      25             : #include "ogrlayerpool.h"
      26             : #include <set>
      27             : #include <vector>
      28             : 
      29             : /* Was limited to 255 until OGR 1.10, but 254 seems to be a more */
      30             : /* conventional limit (http://en.wikipedia.org/wiki/Shapefile, */
      31             : /* http://www.clicketyclick.dk/databases/xbase/format/data_types.html, */
      32             : /* #5052 ) */
      33             : #define OGR_DBF_MAX_FIELD_WIDTH 254
      34             : 
      35             : /* ==================================================================== */
      36             : /*      Functions from Shape2ogr.cpp.                                   */
      37             : /* ==================================================================== */
      38             : OGRFeature *SHPReadOGRFeature(SHPHandle hSHP, DBFHandle hDBF,
      39             :                               OGRFeatureDefn *poDefn, int iShape,
      40             :                               SHPObject *psShape, const char *pszSHPEncoding,
      41             :                               bool &bHasWarnedWrongWindingOrder);
      42             : OGRGeometry *SHPReadOGRObject(SHPHandle hSHP, int iShape, SHPObject *psShape,
      43             :                               bool &bHasWarnedWrongWindingOrder);
      44             : OGRFeatureDefn *SHPReadOGRFeatureDefn(const char *pszName, SHPHandle hSHP,
      45             :                                       DBFHandle hDBF,
      46             :                                       const char *pszSHPEncoding,
      47             :                                       int bAdjustType);
      48             : OGRErr SHPWriteOGRFeature(SHPHandle hSHP, DBFHandle hDBF,
      49             :                           OGRFeatureDefn *m_poFeatureDefn,
      50             :                           OGRFeature *poFeature, const char *pszSHPEncoding,
      51             :                           bool *pbTruncationWarningEmitted, bool bRewind);
      52             : 
      53             : /************************************************************************/
      54             : /*                         OGRShapeGeomFieldDefn                        */
      55             : /************************************************************************/
      56             : 
      57             : class OGRShapeGeomFieldDefn final : public OGRGeomFieldDefn
      58             : {
      59             :     CPL_DISALLOW_COPY_ASSIGN(OGRShapeGeomFieldDefn)
      60             : 
      61             :     std::string m_osFullName{};
      62             :     mutable bool m_bSRSSet = false;
      63             :     mutable CPLString m_osPrjFile{};
      64             : 
      65             :   public:
      66        5142 :     OGRShapeGeomFieldDefn(const char *pszFullNameIn, OGRwkbGeometryType eType,
      67             :                           int bSRSSetIn, OGRSpatialReference *poSRSIn)
      68        5142 :         : OGRGeomFieldDefn("", eType), m_osFullName(pszFullNameIn),
      69        5142 :           m_bSRSSet(CPL_TO_BOOL(bSRSSetIn))
      70             :     {
      71        5142 :         SetSpatialRef(poSRSIn);
      72        5142 :     }
      73             : 
      74             :     const OGRSpatialReference *GetSpatialRef() const override;
      75             : 
      76           3 :     void SetSRSSet()
      77             :     {
      78           3 :         m_bSRSSet = true;
      79           3 :     }
      80             : 
      81          23 :     const CPLString &GetPrjFilename() const
      82             :     {
      83          23 :         return m_osPrjFile;
      84             :     }
      85             : 
      86         222 :     void SetPrjFilename(const std::string &osFilename)
      87             :     {
      88         222 :         m_osPrjFile = osFilename;
      89         222 :     }
      90             : };
      91             : 
      92             : /************************************************************************/
      93             : /*                            OGRShapeLayer                             */
      94             : /************************************************************************/
      95             : 
      96             : class OGRShapeDataSource;
      97             : 
      98             : class OGRShapeLayer final : public OGRAbstractProxiedLayer
      99             : {
     100             :     CPL_DISALLOW_COPY_ASSIGN(OGRShapeLayer)
     101             : 
     102             :     OGRShapeDataSource *m_poDS = nullptr;
     103             : 
     104             :     OGRFeatureDefn *m_poFeatureDefn = nullptr;
     105             :     int m_iNextShapeId = 0;
     106             :     int m_nTotalShapeCount = 0;
     107             : 
     108             :     std::string m_osFullName{};
     109             : 
     110             :     SHPHandle m_hSHP = nullptr;
     111             :     DBFHandle m_hDBF = nullptr;
     112             : 
     113             :     bool m_bUpdateAccess = false;
     114             : 
     115             :     OGRwkbGeometryType m_eRequestedGeomType = wkbUnknown;
     116             :     int ResetGeomType(int nNewType);
     117             : 
     118             :     bool ScanIndices();
     119             : 
     120             :     GIntBig *m_panMatchingFIDs = nullptr;
     121             :     int m_iMatchingFID = 0;
     122             :     void ClearMatchingFIDs();
     123             : 
     124             :     OGRGeometry *m_poFilterGeomLastValid = nullptr;
     125             :     int m_nSpatialFIDCount = 0;
     126             :     int *m_panSpatialFIDs = nullptr;
     127             :     void ClearSpatialFIDs();
     128             : 
     129             :     bool m_bHeaderDirty = false;
     130             :     bool m_bSHPNeedsRepack = false;
     131             :     bool m_bCheckedForQIX = false;
     132             :     SHPTreeDiskHandle m_hQIX = nullptr;
     133             :     bool CheckForQIX();
     134             : 
     135             :     bool m_bCheckedForSBN = false;
     136             :     SBNSearchHandle m_hSBN = nullptr;
     137             :     bool CheckForSBN();
     138             : 
     139             :     bool m_bSbnSbxDeleted = false;
     140             : 
     141             :     CPLString ConvertCodePage(const char *);
     142             :     CPLString m_osEncoding{};
     143             : 
     144             :     bool m_bTruncationWarningEmitted = false;
     145             : 
     146             :     bool m_bHSHPWasNonNULL = false;  // Must try to reopen a .shp?
     147             :     bool m_bHDBFWasNonNULL = false;  // Must try to reopen a .dbf
     148             : 
     149             :     // Current state of opening of file descriptor to .shp and .dbf.
     150             : 
     151             :     typedef enum
     152             :     {
     153             :         FD_OPENED,
     154             :         FD_CLOSED,
     155             :         FD_CANNOT_REOPEN
     156             :     } FileDescriptorState;
     157             : 
     158             :     FileDescriptorState m_eFileDescriptorsState = FD_OPENED;
     159             : 
     160             :     bool TouchLayer();
     161             :     bool ReopenFileDescriptors();
     162             : 
     163             :     bool m_bResizeAtClose = false;
     164             : 
     165             :     void TruncateDBF();
     166             : 
     167             :     bool m_bCreateSpatialIndexAtClose = false;
     168             :     bool m_bRewindOnWrite = false;
     169             :     bool m_bHasWarnedWrongWindingOrder = false;
     170             :     bool m_bLastGetNextArrowArrayUsedOptimizedCodePath = false;
     171             : 
     172             :     bool m_bAutoRepack = false;
     173             : 
     174             :     typedef enum
     175             :     {
     176             :         YES,
     177             :         NO,
     178             :         MAYBE
     179             :     } NormandyState; /* French joke. "Peut'et' ben que oui, peut'et' ben que
     180             :                         non." Sorry :-) */
     181             : 
     182             :     NormandyState m_eNeedRepack = MAYBE;
     183             : 
     184             :     // Set of field names (in upper case). Built and invalidated when convenient
     185             :     std::set<CPLString> m_oSetUCFieldName{};
     186             : 
     187             :     bool StartUpdate(const char *pszOperation);
     188             : 
     189             :     void CloseUnderlyingLayer() override;
     190             : 
     191             :     // WARNING: Each of the below public methods should start with a call to
     192             :     // TouchLayer() and test its return value, so as to make sure that
     193             :     // the layer is properly re-opened if necessary.
     194             : 
     195             :   public:
     196             :     OGRErr CreateSpatialIndex(int nMaxDepth);
     197             :     OGRErr DropSpatialIndex();
     198             :     OGRErr Repack();
     199             :     OGRErr RecomputeExtent();
     200             :     OGRErr ResizeDBF();
     201             : 
     202        1658 :     void SetResizeAtClose(bool bFlag)
     203             :     {
     204        1658 :         m_bResizeAtClose = bFlag;
     205        1658 :     }
     206             : 
     207         580 :     const char *GetFullName()
     208             :     {
     209         580 :         return m_osFullName.c_str();
     210             :     }
     211             : 
     212             :     void UpdateFollowingDeOrRecompression();
     213             : 
     214             :     OGRFeature *FetchShape(int iShapeId);
     215             :     int GetFeatureCountWithSpatialFilterOnly();
     216             : 
     217             :     OGRShapeLayer(OGRShapeDataSource *poDSIn, const char *pszName,
     218             :                   SHPHandle hSHP, DBFHandle hDBF,
     219             :                   const OGRSpatialReference *poSRS, bool bSRSSet,
     220             :                   const std::string &osPrjFilename, bool bUpdate,
     221             :                   OGRwkbGeometryType eReqType,
     222             :                   CSLConstList papszCreateOptions = nullptr);
     223             :     virtual ~OGRShapeLayer();
     224             : 
     225             :     GDALDataset *GetDataset() override;
     226             : 
     227             :     void ResetReading() override;
     228             :     OGRFeature *GetNextFeature() override;
     229             :     OGRErr SetNextByIndex(GIntBig nIndex) override;
     230             : 
     231             :     int GetNextArrowArray(struct ArrowArrayStream *,
     232             :                           struct ArrowArray *out_array) override;
     233             :     const char *GetMetadataItem(const char *pszName,
     234             :                                 const char *pszDomain) override;
     235             : 
     236             :     OGRFeature *GetFeature(GIntBig nFeatureId) override;
     237             :     OGRErr ISetFeature(OGRFeature *poFeature) override;
     238             :     OGRErr DeleteFeature(GIntBig nFID) override;
     239             :     OGRErr ICreateFeature(OGRFeature *poFeature) override;
     240             :     OGRErr SyncToDisk() override;
     241             : 
     242     1423510 :     OGRFeatureDefn *GetLayerDefn() override
     243             :     {
     244     1423510 :         return m_poFeatureDefn;
     245             :     }
     246             : 
     247             :     GIntBig GetFeatureCount(int) override;
     248             :     OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
     249             :                       bool bForce) override;
     250             : 
     251             :     OGRErr IGetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
     252             :                         bool bForce) override;
     253             : 
     254             :     OGRErr CreateField(const OGRFieldDefn *poField,
     255             :                        int bApproxOK = TRUE) override;
     256             :     OGRErr DeleteField(int iField) override;
     257             :     OGRErr ReorderFields(int *panMap) override;
     258             :     OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
     259             :                           int nFlags) override;
     260             :     OGRErr AlterGeomFieldDefn(int iGeomField,
     261             :                               const OGRGeomFieldDefn *poNewGeomFieldDefn,
     262             :                               int nFlagsIn) override;
     263             : 
     264             :     int TestCapability(const char *) override;
     265             : 
     266             :     OGRErr ISetSpatialFilter(int iGeomField,
     267             :                              const OGRGeometry *poGeom) override;
     268             : 
     269             :     OGRErr SetAttributeFilter(const char *) override;
     270             : 
     271             :     OGRErr Rename(const char *pszNewName) override;
     272             : 
     273             :     void AddToFileList(CPLStringList &oFileList);
     274             : 
     275        1658 :     void CreateSpatialIndexAtClose(int bFlag)
     276             :     {
     277        1658 :         m_bCreateSpatialIndexAtClose = CPL_TO_BOOL(bFlag);
     278        1658 :     }
     279             : 
     280             :     void SetModificationDate(const char *pszStr);
     281             : 
     282        5523 :     void SetAutoRepack(bool b)
     283             :     {
     284        5523 :         m_bAutoRepack = b;
     285        5523 :     }
     286             : 
     287             :     void SetWriteDBFEOFChar(bool b);
     288             : };
     289             : 
     290             : /************************************************************************/
     291             : /*                          OGRShapeDataSource                          */
     292             : /************************************************************************/
     293             : 
     294             : class OGRShapeDataSource final : public GDALDataset
     295             : {
     296             :     std::vector<std::unique_ptr<OGRShapeLayer>> m_apoLayers{};
     297             :     bool m_bSingleFileDataSource = false;
     298             :     std::unique_ptr<OGRLayerPool> m_poPool{};
     299             : 
     300             :     std::vector<CPLString> m_oVectorLayerName{};
     301             : 
     302             :     bool m_b2GBLimit = false;
     303             :     bool m_bIsZip = false;
     304             :     bool m_bSingleLayerZip = false;
     305             :     CPLString m_osTemporaryUnzipDir{};
     306             :     CPLMutex *m_poRefreshLockFileMutex = nullptr;
     307             :     CPLCond *m_poRefreshLockFileCond = nullptr;
     308             :     VSILFILE *m_psLockFile = nullptr;
     309             :     CPLJoinableThread *m_hRefreshLockFileThread = nullptr;
     310             :     bool m_bExitRefreshLockFileThread = false;
     311             :     bool m_bRefreshLockFileThreadStarted = false;
     312             :     double m_dfRefreshLockDelay = 0;
     313             : 
     314             :     std::vector<CPLString> GetLayerNames() const;
     315             :     void AddLayer(std::unique_ptr<OGRShapeLayer> poLayer);
     316             :     static void RefreshLockFile(void *_self);
     317             :     void RemoveLockFile();
     318             :     bool RecompressIfNeeded(const std::vector<CPLString> &layerNames);
     319             : 
     320             :     CPL_DISALLOW_COPY_ASSIGN(OGRShapeDataSource)
     321             : 
     322             :   public:
     323             :     OGRShapeDataSource();
     324             :     virtual ~OGRShapeDataSource();
     325             : 
     326        5523 :     OGRLayerPool *GetPool() const
     327             :     {
     328        5523 :         return m_poPool.get();
     329             :     }
     330             : 
     331             :     bool Open(GDALOpenInfo *poOpenInfo, bool bTestOpen,
     332             :               bool bForceSingleFileDataSource = false);
     333             :     bool OpenFile(const char *, bool bUpdate);
     334             :     bool OpenZip(GDALOpenInfo *poOpenInfo, const char *pszOriFilename);
     335             :     bool CreateZip(const char *pszOriFilename);
     336             : 
     337             :     int GetLayerCount() override;
     338             :     OGRLayer *GetLayer(int) override;
     339             :     OGRLayer *GetLayerByName(const char *) override;
     340             : 
     341             :     OGRLayer *ICreateLayer(const char *pszName,
     342             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     343             :                            CSLConstList papszOptions) override;
     344             : 
     345             :     OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter,
     346             :                          const char *pszDialect) override;
     347             : 
     348             :     int TestCapability(const char *) override;
     349             :     OGRErr DeleteLayer(int iLayer) override;
     350             : 
     351             :     char **GetFileList() override;
     352             : 
     353             :     void SetLastUsedLayer(OGRShapeLayer *poLayer);
     354             :     void UnchainLayer(OGRShapeLayer *poLayer);
     355             : 
     356             :     bool UncompressIfNeeded();
     357             : 
     358             :     SHPHandle DS_SHPOpen(const char *pszShapeFile, const char *pszAccess);
     359             :     DBFHandle DS_DBFOpen(const char *pszDBFFile, const char *pszAccess);
     360             : 
     361       14579 :     char **GetOpenOptions()
     362             :     {
     363       14579 :         return papszOpenOptions;
     364             :     }
     365             : 
     366             :     static const char *const *GetExtensionsForDeletion();
     367             : 
     368        1670 :     bool IsZip() const
     369             :     {
     370        1670 :         return m_bIsZip;
     371             :     }
     372             : 
     373           6 :     CPLString GetVSIZipPrefixeDir() const
     374             :     {
     375          12 :         return CPLString("/vsizip/{").append(GetDescription()).append("}");
     376             :     }
     377             : 
     378          13 :     const CPLString &GetTemporaryUnzipDir() const
     379             :     {
     380          13 :         return m_osTemporaryUnzipDir;
     381             :     }
     382             : 
     383             :     static bool CopyInPlace(VSILFILE *fpTarget,
     384             :                             const CPLString &osSourceFilename);
     385             : };
     386             : 
     387             : #endif /* ndef OGRSHAPE_H_INCLUDED */

Generated by: LCOV version 1.14