LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/shape - ogrshape.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 45 45 100.0 %
Date: 2025-01-18 12:42:00 Functions: 18 18 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 *poFeatureDefn, OGRFeature *poFeature,
      50             :                           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             :     char *pszFullName = nullptr;
      62             :     mutable bool bSRSSet = false;
      63             :     mutable CPLString osPrjFile{};
      64             : 
      65             :   public:
      66        4753 :     OGRShapeGeomFieldDefn(const char *pszFullNameIn, OGRwkbGeometryType eType,
      67             :                           int bSRSSetIn, OGRSpatialReference *poSRSIn)
      68       14259 :         : OGRGeomFieldDefn("", eType), pszFullName(CPLStrdup(pszFullNameIn)),
      69        4753 :           bSRSSet(CPL_TO_BOOL(bSRSSetIn))
      70             :     {
      71        4753 :         SetSpatialRef(poSRSIn);
      72        4753 :     }
      73             : 
      74        9474 :     virtual ~OGRShapeGeomFieldDefn()
      75        4737 :     {
      76        4737 :         CPLFree(pszFullName);
      77        9474 :     }
      78             : 
      79             :     const OGRSpatialReference *GetSpatialRef() const override;
      80             : 
      81           3 :     void SetSRSSet()
      82             :     {
      83           3 :         bSRSSet = true;
      84           3 :     }
      85             : 
      86          23 :     const CPLString &GetPrjFilename() const
      87             :     {
      88          23 :         return osPrjFile;
      89             :     }
      90             : 
      91         169 :     void SetPrjFilename(const std::string &osFilename)
      92             :     {
      93         169 :         osPrjFile = osFilename;
      94         169 :     }
      95             : };
      96             : 
      97             : /************************************************************************/
      98             : /*                            OGRShapeLayer                             */
      99             : /************************************************************************/
     100             : 
     101             : class OGRShapeDataSource;
     102             : 
     103             : class OGRShapeLayer final : public OGRAbstractProxiedLayer
     104             : {
     105             :     CPL_DISALLOW_COPY_ASSIGN(OGRShapeLayer)
     106             : 
     107             :     OGRShapeDataSource *poDS;
     108             : 
     109             :     OGRFeatureDefn *poFeatureDefn;
     110             :     int iNextShapeId;
     111             :     int nTotalShapeCount;
     112             : 
     113             :     char *pszFullName;
     114             : 
     115             :     SHPHandle hSHP;
     116             :     DBFHandle hDBF;
     117             : 
     118             :     bool bUpdateAccess;
     119             : 
     120             :     OGRwkbGeometryType eRequestedGeomType;
     121             :     int ResetGeomType(int nNewType);
     122             : 
     123             :     bool ScanIndices();
     124             : 
     125             :     GIntBig *panMatchingFIDs;
     126             :     int iMatchingFID;
     127             :     void ClearMatchingFIDs();
     128             : 
     129             :     OGRGeometry *m_poFilterGeomLastValid;
     130             :     int nSpatialFIDCount;
     131             :     int *panSpatialFIDs;
     132             :     void ClearSpatialFIDs();
     133             : 
     134             :     bool bHeaderDirty;
     135             :     bool bSHPNeedsRepack;
     136             :     bool bCheckedForQIX;
     137             :     SHPTreeDiskHandle hQIX;
     138             :     bool CheckForQIX();
     139             : 
     140             :     bool bCheckedForSBN;
     141             :     SBNSearchHandle hSBN;
     142             :     bool CheckForSBN();
     143             : 
     144             :     bool bSbnSbxDeleted;
     145             : 
     146             :     CPLString ConvertCodePage(const char *);
     147             :     CPLString osEncoding{};
     148             : 
     149             :     bool bTruncationWarningEmitted;
     150             : 
     151             :     bool bHSHPWasNonNULL;  // Must try to reopen a .shp?
     152             :     bool bHDBFWasNonNULL;  // Must try to reopen a .dbf
     153             : 
     154             :     // Current state of opening of file descriptor to .shp and .dbf.
     155             : 
     156             :     typedef enum
     157             :     {
     158             :         FD_OPENED,
     159             :         FD_CLOSED,
     160             :         FD_CANNOT_REOPEN
     161             :     } FileDescriptorState;
     162             : 
     163             :     FileDescriptorState eFileDescriptorsState;
     164             : 
     165             :     bool TouchLayer();
     166             :     bool ReopenFileDescriptors();
     167             : 
     168             :     bool bResizeAtClose;
     169             : 
     170             :     void TruncateDBF();
     171             : 
     172             :     bool bCreateSpatialIndexAtClose;
     173             :     bool bRewindOnWrite;
     174             :     bool m_bHasWarnedWrongWindingOrder = false;
     175             :     bool m_bLastGetNextArrowArrayUsedOptimizedCodePath = false;
     176             : 
     177             :     bool m_bAutoRepack;
     178             : 
     179             :     typedef enum
     180             :     {
     181             :         YES,
     182             :         NO,
     183             :         MAYBE
     184             :     } NormandyState; /* French joke. "Peut'et' ben que oui, peut'et' ben que
     185             :                         non." Sorry :-) */
     186             : 
     187             :     NormandyState m_eNeedRepack;
     188             : 
     189             :     // Set of field names (in upper case). Built and invalidated when convenient
     190             :     std::set<CPLString> m_oSetUCFieldName{};
     191             : 
     192             :     bool StartUpdate(const char *pszOperation);
     193             : 
     194             :     void CloseUnderlyingLayer() override;
     195             : 
     196             :     // WARNING: Each of the below public methods should start with a call to
     197             :     // TouchLayer() and test its return value, so as to make sure that
     198             :     // the layer is properly re-opened if necessary.
     199             : 
     200             :   public:
     201             :     OGRErr CreateSpatialIndex(int nMaxDepth);
     202             :     OGRErr DropSpatialIndex();
     203             :     OGRErr Repack();
     204             :     OGRErr RecomputeExtent();
     205             :     OGRErr ResizeDBF();
     206             : 
     207        1572 :     void SetResizeAtClose(bool bFlag)
     208             :     {
     209        1572 :         bResizeAtClose = bFlag;
     210        1572 :     }
     211             : 
     212         577 :     const char *GetFullName()
     213             :     {
     214         577 :         return pszFullName;
     215             :     }
     216             : 
     217             :     void UpdateFollowingDeOrRecompression();
     218             : 
     219             :     OGRFeature *FetchShape(int iShapeId);
     220             :     int GetFeatureCountWithSpatialFilterOnly();
     221             : 
     222             :     OGRShapeLayer(OGRShapeDataSource *poDSIn, const char *pszName,
     223             :                   SHPHandle hSHP, DBFHandle hDBF,
     224             :                   const OGRSpatialReference *poSRS, bool bSRSSet,
     225             :                   const std::string &osPrjFilename, bool bUpdate,
     226             :                   OGRwkbGeometryType eReqType,
     227             :                   char **papszCreateOptions = nullptr);
     228             :     virtual ~OGRShapeLayer();
     229             : 
     230             :     GDALDataset *GetDataset() override;
     231             : 
     232             :     void ResetReading() override;
     233             :     OGRFeature *GetNextFeature() override;
     234             :     OGRErr SetNextByIndex(GIntBig nIndex) override;
     235             : 
     236             :     int GetNextArrowArray(struct ArrowArrayStream *,
     237             :                           struct ArrowArray *out_array) override;
     238             :     const char *GetMetadataItem(const char *pszName,
     239             :                                 const char *pszDomain) override;
     240             : 
     241             :     OGRFeature *GetFeature(GIntBig nFeatureId) override;
     242             :     OGRErr ISetFeature(OGRFeature *poFeature) override;
     243             :     OGRErr DeleteFeature(GIntBig nFID) override;
     244             :     OGRErr ICreateFeature(OGRFeature *poFeature) override;
     245             :     OGRErr SyncToDisk() override;
     246             : 
     247     1386320 :     OGRFeatureDefn *GetLayerDefn() override
     248             :     {
     249     1386320 :         return poFeatureDefn;
     250             :     }
     251             : 
     252             :     GIntBig GetFeatureCount(int) override;
     253             :     OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
     254             : 
     255         100 :     OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override
     256             :     {
     257         100 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     258             :     }
     259             : 
     260             :     OGRErr GetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
     261             :                        int bForce) override;
     262             : 
     263             :     OGRErr CreateField(const OGRFieldDefn *poField,
     264             :                        int bApproxOK = TRUE) override;
     265             :     OGRErr DeleteField(int iField) override;
     266             :     OGRErr ReorderFields(int *panMap) override;
     267             :     OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
     268             :                           int nFlags) override;
     269             :     OGRErr AlterGeomFieldDefn(int iGeomField,
     270             :                               const OGRGeomFieldDefn *poNewGeomFieldDefn,
     271             :                               int nFlagsIn) override;
     272             : 
     273             :     int TestCapability(const char *) override;
     274             :     void SetSpatialFilter(OGRGeometry *) override;
     275             : 
     276        1494 :     void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
     277             :     {
     278        1494 :         OGRLayer::SetSpatialFilter(iGeomField, poGeom);
     279        1494 :     }
     280             : 
     281             :     OGRErr SetAttributeFilter(const char *) override;
     282             : 
     283             :     OGRErr Rename(const char *pszNewName) override;
     284             : 
     285             :     void AddToFileList(CPLStringList &oFileList);
     286             : 
     287        1572 :     void CreateSpatialIndexAtClose(int bFlag)
     288             :     {
     289        1572 :         bCreateSpatialIndexAtClose = CPL_TO_BOOL(bFlag);
     290        1572 :     }
     291             : 
     292             :     void SetModificationDate(const char *pszStr);
     293             : 
     294        5126 :     void SetAutoRepack(bool b)
     295             :     {
     296        5126 :         m_bAutoRepack = b;
     297        5126 :     }
     298             : 
     299             :     void SetWriteDBFEOFChar(bool b);
     300             : };
     301             : 
     302             : /************************************************************************/
     303             : /*                          OGRShapeDataSource                          */
     304             : /************************************************************************/
     305             : 
     306             : class OGRShapeDataSource final : public GDALDataset
     307             : {
     308             :     OGRShapeLayer **papoLayers;
     309             :     int nLayers;
     310             :     bool bSingleFileDataSource;
     311             :     OGRLayerPool *poPool;
     312             : 
     313             :     std::vector<CPLString> oVectorLayerName{};
     314             : 
     315             :     bool b2GBLimit;
     316             :     bool m_bIsZip = false;
     317             :     bool m_bSingleLayerZip = false;
     318             :     CPLString m_osTemporaryUnzipDir{};
     319             :     CPLMutex *m_poRefreshLockFileMutex = nullptr;
     320             :     CPLCond *m_poRefreshLockFileCond = nullptr;
     321             :     VSILFILE *m_psLockFile = nullptr;
     322             :     CPLJoinableThread *m_hRefreshLockFileThread = nullptr;
     323             :     bool m_bExitRefreshLockFileThread = false;
     324             :     bool m_bRefreshLockFileThreadStarted = false;
     325             :     double m_dfRefreshLockDelay = 0;
     326             : 
     327             :     std::vector<CPLString> GetLayerNames() const;
     328             :     void AddLayer(OGRShapeLayer *poLayer);
     329             :     static void RefreshLockFile(void *_self);
     330             :     void RemoveLockFile();
     331             :     bool RecompressIfNeeded(const std::vector<CPLString> &layerNames);
     332             : 
     333             :     CPL_DISALLOW_COPY_ASSIGN(OGRShapeDataSource)
     334             : 
     335             :   public:
     336             :     OGRShapeDataSource();
     337             :     virtual ~OGRShapeDataSource();
     338             : 
     339        5126 :     OGRLayerPool *GetPool() const
     340             :     {
     341        5126 :         return poPool;
     342             :     }
     343             : 
     344             :     bool Open(GDALOpenInfo *poOpenInfo, bool bTestOpen,
     345             :               bool bForceSingleFileDataSource = false);
     346             :     bool OpenFile(const char *, bool bUpdate);
     347             :     bool OpenZip(GDALOpenInfo *poOpenInfo, const char *pszOriFilename);
     348             :     bool CreateZip(const char *pszOriFilename);
     349             : 
     350             :     int GetLayerCount() override;
     351             :     OGRLayer *GetLayer(int) override;
     352             :     OGRLayer *GetLayerByName(const char *) override;
     353             : 
     354             :     OGRLayer *ICreateLayer(const char *pszName,
     355             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     356             :                            CSLConstList papszOptions) override;
     357             : 
     358             :     OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter,
     359             :                          const char *pszDialect) override;
     360             : 
     361             :     int TestCapability(const char *) override;
     362             :     OGRErr DeleteLayer(int iLayer) override;
     363             : 
     364             :     char **GetFileList() override;
     365             : 
     366             :     void SetLastUsedLayer(OGRShapeLayer *poLayer);
     367             :     void UnchainLayer(OGRShapeLayer *poLayer);
     368             : 
     369             :     bool UncompressIfNeeded();
     370             : 
     371             :     SHPHandle DS_SHPOpen(const char *pszShapeFile, const char *pszAccess);
     372             :     DBFHandle DS_DBFOpen(const char *pszDBFFile, const char *pszAccess);
     373             : 
     374       13479 :     char **GetOpenOptions()
     375             :     {
     376       13479 :         return papszOpenOptions;
     377             :     }
     378             : 
     379             :     static const char *const *GetExtensionsForDeletion();
     380             : 
     381        1645 :     bool IsZip() const
     382             :     {
     383        1645 :         return m_bIsZip;
     384             :     }
     385             : 
     386           5 :     CPLString GetVSIZipPrefixeDir() const
     387             :     {
     388          10 :         return CPLString("/vsizip/{").append(GetDescription()).append("}");
     389             :     }
     390             : 
     391          11 :     const CPLString &GetTemporaryUnzipDir() const
     392             :     {
     393          11 :         return m_osTemporaryUnzipDir;
     394             :     }
     395             : 
     396             :     static bool CopyInPlace(VSILFILE *fpTarget,
     397             :                             const CPLString &osSourceFilename);
     398             : };
     399             : 
     400             : #endif /* ndef OGRSHAPE_H_INCLUDED */

Generated by: LCOV version 1.14