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

Generated by: LCOV version 1.14