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: 2024-11-21 22:18:42 Functions: 18 18 100.0 %

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

Generated by: LCOV version 1.14