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

Generated by: LCOV version 1.14