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 47 95.7 %
Date: 2024-05-04 12:52:34 Functions: 18 19 94.7 %

          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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      14             :  * copy of this software and associated documentation files (the "Software"),
      15             :  * to deal in the Software without restriction, including without limitation
      16             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17             :  * and/or sell copies of the Software, and to permit persons to whom the
      18             :  * Software is furnished to do so, subject to the following conditions:
      19             :  *
      20             :  * The above copyright notice and this permission notice shall be included
      21             :  * in all copies or substantial portions of the Software.
      22             :  *
      23             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29             :  * DEALINGS IN THE SOFTWARE.
      30             :  ****************************************************************************/
      31             : 
      32             : #ifndef OGRSHAPE_H_INCLUDED
      33             : #define OGRSHAPE_H_INCLUDED
      34             : 
      35             : #ifdef RENAME_INTERNAL_SHAPELIB_SYMBOLS
      36             : #include "gdal_shapelib_symbol_rename.h"
      37             : #endif
      38             : 
      39             : #include "ogrsf_frmts.h"
      40             : #include "shapefil.h"
      41             : #include "shp_vsi.h"
      42             : #include "ogrlayerpool.h"
      43             : #include <set>
      44             : #include <vector>
      45             : 
      46             : /* Was limited to 255 until OGR 1.10, but 254 seems to be a more */
      47             : /* conventional limit (http://en.wikipedia.org/wiki/Shapefile, */
      48             : /* http://www.clicketyclick.dk/databases/xbase/format/data_types.html, */
      49             : /* #5052 ) */
      50             : #define OGR_DBF_MAX_FIELD_WIDTH 254
      51             : 
      52             : /* ==================================================================== */
      53             : /*      Functions from Shape2ogr.cpp.                                   */
      54             : /* ==================================================================== */
      55             : OGRFeature *SHPReadOGRFeature(SHPHandle hSHP, DBFHandle hDBF,
      56             :                               OGRFeatureDefn *poDefn, int iShape,
      57             :                               SHPObject *psShape, const char *pszSHPEncoding,
      58             :                               bool &bHasWarnedWrongWindingOrder);
      59             : OGRGeometry *SHPReadOGRObject(SHPHandle hSHP, int iShape, SHPObject *psShape,
      60             :                               bool &bHasWarnedWrongWindingOrder);
      61             : OGRFeatureDefn *SHPReadOGRFeatureDefn(const char *pszName, SHPHandle hSHP,
      62             :                                       DBFHandle hDBF,
      63             :                                       const char *pszSHPEncoding,
      64             :                                       int bAdjustType);
      65             : OGRErr SHPWriteOGRFeature(SHPHandle hSHP, DBFHandle hDBF,
      66             :                           OGRFeatureDefn *poFeatureDefn, OGRFeature *poFeature,
      67             :                           const char *pszSHPEncoding,
      68             :                           bool *pbTruncationWarningEmitted, bool bRewind);
      69             : 
      70             : /************************************************************************/
      71             : /*                         OGRShapeGeomFieldDefn                        */
      72             : /************************************************************************/
      73             : 
      74             : class OGRShapeGeomFieldDefn final : public OGRGeomFieldDefn
      75             : {
      76             :     CPL_DISALLOW_COPY_ASSIGN(OGRShapeGeomFieldDefn)
      77             : 
      78             :     char *pszFullName = nullptr;
      79             :     mutable bool bSRSSet = false;
      80             :     mutable CPLString osPrjFile{};
      81             : 
      82             :   public:
      83        4644 :     OGRShapeGeomFieldDefn(const char *pszFullNameIn, OGRwkbGeometryType eType,
      84             :                           int bSRSSetIn, OGRSpatialReference *poSRSIn)
      85       13932 :         : OGRGeomFieldDefn("", eType), pszFullName(CPLStrdup(pszFullNameIn)),
      86        4644 :           bSRSSet(CPL_TO_BOOL(bSRSSetIn))
      87             :     {
      88        4644 :         SetSpatialRef(poSRSIn);
      89        4644 :     }
      90             : 
      91        9256 :     virtual ~OGRShapeGeomFieldDefn()
      92        4628 :     {
      93        4628 :         CPLFree(pszFullName);
      94        9256 :     }
      95             : 
      96             :     const OGRSpatialReference *GetSpatialRef() const override;
      97             : 
      98           3 :     void SetSRSSet()
      99             :     {
     100           3 :         bSRSSet = true;
     101           3 :     }
     102             : 
     103          23 :     const CPLString &GetPrjFilename() const
     104             :     {
     105          23 :         return osPrjFile;
     106             :     }
     107             : 
     108         159 :     void SetPrjFilename(const std::string &osFilename)
     109             :     {
     110         159 :         osPrjFile = osFilename;
     111         159 :     }
     112             : };
     113             : 
     114             : /************************************************************************/
     115             : /*                            OGRShapeLayer                             */
     116             : /************************************************************************/
     117             : 
     118             : class OGRShapeDataSource;
     119             : 
     120             : class OGRShapeLayer final : public OGRAbstractProxiedLayer
     121             : {
     122             :     CPL_DISALLOW_COPY_ASSIGN(OGRShapeLayer)
     123             : 
     124             :     OGRShapeDataSource *poDS;
     125             : 
     126             :     OGRFeatureDefn *poFeatureDefn;
     127             :     int iNextShapeId;
     128             :     int nTotalShapeCount;
     129             : 
     130             :     char *pszFullName;
     131             : 
     132             :     SHPHandle hSHP;
     133             :     DBFHandle hDBF;
     134             : 
     135             :     bool bUpdateAccess;
     136             : 
     137             :     OGRwkbGeometryType eRequestedGeomType;
     138             :     int ResetGeomType(int nNewType);
     139             : 
     140             :     bool ScanIndices();
     141             : 
     142             :     GIntBig *panMatchingFIDs;
     143             :     int iMatchingFID;
     144             :     void ClearMatchingFIDs();
     145             : 
     146             :     OGRGeometry *m_poFilterGeomLastValid;
     147             :     int nSpatialFIDCount;
     148             :     int *panSpatialFIDs;
     149             :     void ClearSpatialFIDs();
     150             : 
     151             :     bool bHeaderDirty;
     152             :     bool bSHPNeedsRepack;
     153             :     bool bCheckedForQIX;
     154             :     SHPTreeDiskHandle hQIX;
     155             :     bool CheckForQIX();
     156             : 
     157             :     bool bCheckedForSBN;
     158             :     SBNSearchHandle hSBN;
     159             :     bool CheckForSBN();
     160             : 
     161             :     bool bSbnSbxDeleted;
     162             : 
     163             :     CPLString ConvertCodePage(const char *);
     164             :     CPLString osEncoding{};
     165             : 
     166             :     bool bTruncationWarningEmitted;
     167             : 
     168             :     bool bHSHPWasNonNULL;  // Must try to reopen a .shp?
     169             :     bool bHDBFWasNonNULL;  // Must try to reopen a .dbf
     170             : 
     171             :     // Current state of opening of file descriptor to .shp and .dbf.
     172             : 
     173             :     typedef enum
     174             :     {
     175             :         FD_OPENED,
     176             :         FD_CLOSED,
     177             :         FD_CANNOT_REOPEN
     178             :     } FileDescriptorState;
     179             : 
     180             :     FileDescriptorState eFileDescriptorsState;
     181             : 
     182             :     bool TouchLayer();
     183             :     bool ReopenFileDescriptors();
     184             : 
     185             :     bool bResizeAtClose;
     186             : 
     187             :     void TruncateDBF();
     188             : 
     189             :     bool bCreateSpatialIndexAtClose;
     190             :     bool bRewindOnWrite;
     191             :     bool m_bHasWarnedWrongWindingOrder = false;
     192             :     bool m_bLastGetNextArrowArrayUsedOptimizedCodePath = false;
     193             : 
     194             :     bool m_bAutoRepack;
     195             : 
     196             :     typedef enum
     197             :     {
     198             :         YES,
     199             :         NO,
     200             :         MAYBE
     201             :     } NormandyState; /* French joke. "Peut'et' ben que oui, peut'et' ben que
     202             :                         non." Sorry :-) */
     203             : 
     204             :     NormandyState m_eNeedRepack;
     205             : 
     206             :     // Set of field names (in upper case). Built and invalidated when convenient
     207             :     std::set<CPLString> m_oSetUCFieldName{};
     208             : 
     209             :     bool StartUpdate(const char *pszOperation);
     210             : 
     211             :     void CloseUnderlyingLayer() override;
     212             : 
     213             :     // WARNING: Each of the below public methods should start with a call to
     214             :     // TouchLayer() and test its return value, so as to make sure that
     215             :     // the layer is properly re-opened if necessary.
     216             : 
     217             :   public:
     218             :     OGRErr CreateSpatialIndex(int nMaxDepth);
     219             :     OGRErr DropSpatialIndex();
     220             :     OGRErr Repack();
     221             :     OGRErr RecomputeExtent();
     222             :     OGRErr ResizeDBF();
     223             : 
     224        1558 :     void SetResizeAtClose(bool bFlag)
     225             :     {
     226        1558 :         bResizeAtClose = bFlag;
     227        1558 :     }
     228             : 
     229         576 :     const char *GetFullName()
     230             :     {
     231         576 :         return pszFullName;
     232             :     }
     233             : 
     234             :     void UpdateFollowingDeOrRecompression();
     235             : 
     236             :     OGRFeature *FetchShape(int iShapeId);
     237             :     int GetFeatureCountWithSpatialFilterOnly();
     238             : 
     239             :     OGRShapeLayer(OGRShapeDataSource *poDSIn, const char *pszName,
     240             :                   SHPHandle hSHP, DBFHandle hDBF,
     241             :                   const OGRSpatialReference *poSRS, bool bSRSSet,
     242             :                   const std::string &osPrjFilename, bool bUpdate,
     243             :                   OGRwkbGeometryType eReqType,
     244             :                   char **papszCreateOptions = nullptr);
     245             :     virtual ~OGRShapeLayer();
     246             : 
     247             :     GDALDataset *GetDataset() override;
     248             : 
     249             :     void ResetReading() override;
     250             :     OGRFeature *GetNextFeature() override;
     251             :     OGRErr SetNextByIndex(GIntBig nIndex) override;
     252             : 
     253             :     int GetNextArrowArray(struct ArrowArrayStream *,
     254             :                           struct ArrowArray *out_array) override;
     255             :     const char *GetMetadataItem(const char *pszName,
     256             :                                 const char *pszDomain) override;
     257             : 
     258             :     OGRFeature *GetFeature(GIntBig nFeatureId) override;
     259             :     OGRErr ISetFeature(OGRFeature *poFeature) override;
     260             :     OGRErr DeleteFeature(GIntBig nFID) override;
     261             :     OGRErr ICreateFeature(OGRFeature *poFeature) override;
     262             :     OGRErr SyncToDisk() override;
     263             : 
     264     1413480 :     OGRFeatureDefn *GetLayerDefn() override
     265             :     {
     266     1413480 :         return poFeatureDefn;
     267             :     }
     268             : 
     269             :     GIntBig GetFeatureCount(int) override;
     270             :     OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
     271             : 
     272          92 :     OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override
     273             :     {
     274          92 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     275             :     }
     276             : 
     277             :     OGRErr GetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
     278             :                        int bForce) override;
     279             : 
     280             :     OGRErr CreateField(const OGRFieldDefn *poField,
     281             :                        int bApproxOK = TRUE) override;
     282             :     OGRErr DeleteField(int iField) override;
     283             :     OGRErr ReorderFields(int *panMap) override;
     284             :     OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
     285             :                           int nFlags) override;
     286             :     OGRErr AlterGeomFieldDefn(int iGeomField,
     287             :                               const OGRGeomFieldDefn *poNewGeomFieldDefn,
     288             :                               int nFlagsIn) override;
     289             : 
     290             :     int TestCapability(const char *) override;
     291             :     void SetSpatialFilter(OGRGeometry *) override;
     292             : 
     293        1443 :     void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
     294             :     {
     295        1443 :         OGRLayer::SetSpatialFilter(iGeomField, poGeom);
     296        1443 :     }
     297             : 
     298             :     OGRErr SetAttributeFilter(const char *) override;
     299             : 
     300             :     OGRErr Rename(const char *pszNewName) override;
     301             : 
     302             :     void AddToFileList(CPLStringList &oFileList);
     303             : 
     304        1558 :     void CreateSpatialIndexAtClose(int bFlag)
     305             :     {
     306        1558 :         bCreateSpatialIndexAtClose = CPL_TO_BOOL(bFlag);
     307        1558 :     }
     308             : 
     309             :     void SetModificationDate(const char *pszStr);
     310             : 
     311        5010 :     void SetAutoRepack(bool b)
     312             :     {
     313        5010 :         m_bAutoRepack = b;
     314        5010 :     }
     315             : 
     316             :     void SetWriteDBFEOFChar(bool b);
     317             : };
     318             : 
     319             : /************************************************************************/
     320             : /*                          OGRShapeDataSource                          */
     321             : /************************************************************************/
     322             : 
     323             : class OGRShapeDataSource final : public OGRDataSource
     324             : {
     325             :     OGRShapeLayer **papoLayers;
     326             :     int nLayers;
     327             :     char *pszName;
     328             :     bool bSingleFileDataSource;
     329             :     OGRLayerPool *poPool;
     330             : 
     331             :     std::vector<CPLString> oVectorLayerName{};
     332             : 
     333             :     bool b2GBLimit;
     334             :     bool m_bIsZip = false;
     335             :     bool m_bSingleLayerZip = false;
     336             :     CPLString m_osTemporaryUnzipDir{};
     337             :     CPLMutex *m_poRefreshLockFileMutex = nullptr;
     338             :     CPLCond *m_poRefreshLockFileCond = nullptr;
     339             :     VSILFILE *m_psLockFile = nullptr;
     340             :     CPLJoinableThread *m_hRefreshLockFileThread = nullptr;
     341             :     bool m_bExitRefreshLockFileThread = false;
     342             :     double m_dfRefreshLockDelay = 0;
     343             : 
     344             :     std::vector<CPLString> GetLayerNames() const;
     345             :     void AddLayer(OGRShapeLayer *poLayer);
     346             :     static void RefreshLockFile(void *_self);
     347             :     void RemoveLockFile();
     348             :     bool RecompressIfNeeded(const std::vector<CPLString> &layerNames);
     349             : 
     350             :     CPL_DISALLOW_COPY_ASSIGN(OGRShapeDataSource)
     351             : 
     352             :   public:
     353             :     OGRShapeDataSource();
     354             :     virtual ~OGRShapeDataSource();
     355             : 
     356        5010 :     OGRLayerPool *GetPool() const
     357             :     {
     358        5010 :         return poPool;
     359             :     }
     360             : 
     361             :     bool Open(GDALOpenInfo *poOpenInfo, bool bTestOpen,
     362             :               bool bForceSingleFileDataSource = false);
     363             :     bool OpenFile(const char *, bool bUpdate);
     364             :     bool OpenZip(GDALOpenInfo *poOpenInfo, const char *pszOriFilename);
     365             :     bool CreateZip(const char *pszOriFilename);
     366             : 
     367           0 :     const char *GetName() override
     368             :     {
     369           0 :         return pszName;
     370             :     }
     371             : 
     372             :     int GetLayerCount() override;
     373             :     OGRLayer *GetLayer(int) override;
     374             :     OGRLayer *GetLayerByName(const char *) override;
     375             : 
     376             :     OGRLayer *ICreateLayer(const char *pszName,
     377             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     378             :                            CSLConstList papszOptions) override;
     379             : 
     380             :     OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter,
     381             :                          const char *pszDialect) override;
     382             : 
     383             :     int TestCapability(const char *) override;
     384             :     OGRErr DeleteLayer(int iLayer) override;
     385             : 
     386             :     char **GetFileList() override;
     387             : 
     388             :     void SetLastUsedLayer(OGRShapeLayer *poLayer);
     389             :     void UnchainLayer(OGRShapeLayer *poLayer);
     390             : 
     391             :     bool UncompressIfNeeded();
     392             : 
     393             :     SHPHandle DS_SHPOpen(const char *pszShapeFile, const char *pszAccess);
     394             :     DBFHandle DS_DBFOpen(const char *pszDBFFile, const char *pszAccess);
     395             : 
     396       13150 :     char **GetOpenOptions()
     397             :     {
     398       13150 :         return papszOpenOptions;
     399             :     }
     400             : 
     401             :     static const char *const *GetExtensionsForDeletion();
     402             : 
     403        1644 :     bool IsZip() const
     404             :     {
     405        1644 :         return m_bIsZip;
     406             :     }
     407             : 
     408           5 :     CPLString GetVSIZipPrefixeDir() const
     409             :     {
     410          10 :         return CPLString("/vsizip/{") + pszName + '}';
     411             :     }
     412             : 
     413          11 :     const CPLString &GetTemporaryUnzipDir() const
     414             :     {
     415          11 :         return m_osTemporaryUnzipDir;
     416             :     }
     417             : 
     418             :     static bool CopyInPlace(VSILFILE *fpTarget,
     419             :                             const CPLString &osSourceFilename);
     420             : };
     421             : 
     422             : #endif /* ndef OGRSHAPE_H_INCLUDED */

Generated by: LCOV version 1.14