1 /****************************************************************************** 2 * $Id: ogrshape.h 74eca1110adf6e47b87fee110ad9bf5f322fef64 2021-03-15 14:38:32 +0100 Even Rouault $ 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 OGRGeometry *SHPReadOGRObject( SHPHandle hSHP, int iShape, SHPObject *psShape ); 59 OGRFeatureDefn *SHPReadOGRFeatureDefn( const char * pszName, 60 SHPHandle hSHP, DBFHandle hDBF, 61 const char *pszSHPEncoding, 62 int bAdjustType ); 63 OGRErr SHPWriteOGRFeature( SHPHandle hSHP, DBFHandle hDBF, 64 OGRFeatureDefn *poFeatureDefn, 65 OGRFeature *poFeature, const char *pszSHPEncoding, 66 bool* pbTruncationWarningEmitted, 67 bool bRewind ); 68 69 /************************************************************************/ 70 /* OGRShapeGeomFieldDefn */ 71 /************************************************************************/ 72 73 class OGRShapeGeomFieldDefn final: public OGRGeomFieldDefn 74 { 75 CPL_DISALLOW_COPY_ASSIGN(OGRShapeGeomFieldDefn) 76 77 char* pszFullName = nullptr; 78 mutable bool bSRSSet = false; 79 mutable CPLString osPrjFile{}; 80 81 public: OGRShapeGeomFieldDefn(const char * pszFullNameIn,OGRwkbGeometryType eType,int bSRSSetIn,OGRSpatialReference * poSRSIn)82 OGRShapeGeomFieldDefn( const char* pszFullNameIn, 83 OGRwkbGeometryType eType, 84 int bSRSSetIn, OGRSpatialReference *poSRSIn) : 85 OGRGeomFieldDefn("", eType), 86 pszFullName(CPLStrdup(pszFullNameIn)), 87 bSRSSet(CPL_TO_BOOL(bSRSSetIn)) 88 { 89 SetSpatialRef(poSRSIn); 90 } 91 ~OGRShapeGeomFieldDefn()92 virtual ~OGRShapeGeomFieldDefn() 93 { 94 CPLFree(pszFullName); 95 } 96 97 OGRSpatialReference* GetSpatialRef() const override; 98 GetPrjFilename()99 const CPLString& GetPrjFilename() const { return osPrjFile; } 100 }; 101 102 /************************************************************************/ 103 /* OGRShapeLayer */ 104 /************************************************************************/ 105 106 class OGRShapeDataSource; 107 108 class OGRShapeLayer final: public OGRAbstractProxiedLayer 109 { 110 CPL_DISALLOW_COPY_ASSIGN(OGRShapeLayer) 111 112 OGRShapeDataSource *poDS; 113 114 OGRFeatureDefn *poFeatureDefn; 115 int iNextShapeId; 116 int nTotalShapeCount; 117 118 char *pszFullName; 119 120 SHPHandle hSHP; 121 DBFHandle hDBF; 122 123 bool bUpdateAccess; 124 125 OGRwkbGeometryType eRequestedGeomType; 126 int ResetGeomType( int nNewType ); 127 128 bool ScanIndices(); 129 130 GIntBig *panMatchingFIDs; 131 int iMatchingFID; 132 void ClearMatchingFIDs(); 133 134 OGRGeometry *m_poFilterGeomLastValid; 135 int nSpatialFIDCount; 136 int *panSpatialFIDs; 137 void ClearSpatialFIDs(); 138 139 bool bHeaderDirty; 140 bool bSHPNeedsRepack; 141 bool bCheckedForQIX; 142 SHPTreeDiskHandle hQIX; 143 bool CheckForQIX(); 144 145 bool bCheckedForSBN; 146 SBNSearchHandle hSBN; 147 bool CheckForSBN(); 148 149 bool bSbnSbxDeleted; 150 151 CPLString ConvertCodePage( const char * ); 152 CPLString osEncoding{}; 153 154 bool bTruncationWarningEmitted; 155 156 bool bHSHPWasNonNULL; // Must try to reopen a .shp? 157 bool bHDBFWasNonNULL; // Must try to reopen a .dbf 158 // Current state of opening of file descriptor to .shp and .dbf. 159 160 typedef enum 161 { 162 FD_OPENED, 163 FD_CLOSED, 164 FD_CANNOT_REOPEN 165 } FileDescriptorState; 166 FileDescriptorState eFileDescriptorsState; 167 168 bool TouchLayer(); 169 bool ReopenFileDescriptors(); 170 171 bool bResizeAtClose; 172 173 void TruncateDBF(); 174 175 bool bCreateSpatialIndexAtClose; 176 bool bRewindOnWrite; 177 178 bool m_bAutoRepack; 179 typedef enum 180 { 181 YES, 182 NO, 183 MAYBE 184 } NormandyState; /* French joke. "Peut'et' ben que oui, peut'et' ben que non." Sorry :-) */ 185 NormandyState m_eNeedRepack; 186 187 // Set of field names (in upper case). Built and invalidated when convenient 188 std::set<CPLString> m_oSetUCFieldName{}; 189 190 bool StartUpdate( const char* pszOperation ); 191 192 void CloseUnderlyingLayer() override; 193 194 // WARNING: Each of the below public methods should start with a call to 195 // TouchLayer() and test its return value, so as to make sure that 196 // the layer is properly re-opened if necessary. 197 198 public: 199 OGRErr CreateSpatialIndex( int nMaxDepth ); 200 OGRErr DropSpatialIndex(); 201 OGRErr Repack(); 202 OGRErr RecomputeExtent(); 203 OGRErr ResizeDBF(); 204 SetResizeAtClose(bool bFlag)205 void SetResizeAtClose( bool bFlag ) 206 { bResizeAtClose = bFlag; } 207 GetFullName()208 const char *GetFullName() { return pszFullName; } 209 void UpdateFollowingDeOrRecompression(); 210 211 OGRFeature * FetchShape( int iShapeId ); 212 int GetFeatureCountWithSpatialFilterOnly(); 213 214 OGRShapeLayer( OGRShapeDataSource* poDSIn, 215 const char * pszName, 216 SHPHandle hSHP, DBFHandle hDBF, 217 const OGRSpatialReference *poSRS, bool bSRSSet, 218 bool bUpdate, 219 OGRwkbGeometryType eReqType, 220 char ** papszCreateOptions = nullptr); 221 virtual ~OGRShapeLayer(); 222 223 void ResetReading() override; 224 OGRFeature * GetNextFeature() override; 225 OGRErr SetNextByIndex( GIntBig nIndex ) override; 226 227 OGRFeature *GetFeature( GIntBig nFeatureId ) override; 228 OGRErr ISetFeature( OGRFeature *poFeature ) override; 229 OGRErr DeleteFeature( GIntBig nFID ) override; 230 OGRErr ICreateFeature( OGRFeature *poFeature ) override; 231 OGRErr SyncToDisk() override; 232 GetLayerDefn()233 OGRFeatureDefn * GetLayerDefn() override { return poFeatureDefn; } 234 235 GIntBig GetFeatureCount( int ) override; 236 OGRErr GetExtent( OGREnvelope *psExtent, int bForce ) override; GetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)237 OGRErr GetExtent( int iGeomField, OGREnvelope *psExtent, 238 int bForce ) override 239 { return OGRLayer::GetExtent(iGeomField, psExtent, bForce); } 240 241 OGRErr CreateField( OGRFieldDefn *poField, 242 int bApproxOK = TRUE ) override; 243 OGRErr DeleteField( int iField ) override; 244 OGRErr ReorderFields( int* panMap ) override; 245 OGRErr AlterFieldDefn( int iField, 246 OGRFieldDefn* poNewFieldDefn, 247 int nFlags ) override; 248 249 int TestCapability( const char * ) override; 250 void SetSpatialFilter( OGRGeometry * ) override; SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)251 void SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override 252 { OGRLayer::SetSpatialFilter(iGeomField, poGeom); } 253 254 OGRErr SetAttributeFilter( const char * ) override; 255 256 void AddToFileList( CPLStringList& oFileList ); CreateSpatialIndexAtClose(int bFlag)257 void CreateSpatialIndexAtClose( int bFlag ) 258 { bCreateSpatialIndexAtClose = CPL_TO_BOOL(bFlag); } 259 void SetModificationDate( const char* pszStr ); SetAutoRepack(bool b)260 void SetAutoRepack(bool b) { m_bAutoRepack = b; } 261 void SetWriteDBFEOFChar(bool b); 262 }; 263 264 /************************************************************************/ 265 /* OGRShapeDataSource */ 266 /************************************************************************/ 267 268 class OGRShapeDataSource final: public OGRDataSource 269 { 270 OGRShapeLayer **papoLayers; 271 int nLayers; 272 char *pszName; 273 bool bDSUpdate; 274 bool bSingleFileDataSource; 275 OGRLayerPool *poPool; 276 277 std::vector<CPLString> oVectorLayerName{}; 278 279 bool b2GBLimit; 280 bool m_bIsZip = false; 281 bool m_bSingleLayerZip = false; 282 CPLString m_osTemporaryUnzipDir{}; 283 CPLMutex *m_poRefreshLockFileMutex = nullptr; 284 CPLCond *m_poRefreshLockFileCond = nullptr; 285 VSILFILE *m_psLockFile = nullptr; 286 CPLJoinableThread *m_hRefreshLockFileThread = nullptr; 287 bool m_bExitRefreshLockFileThread = false; 288 double m_dfRefreshLockDelay = 0; 289 290 std::vector<CPLString> GetLayerNames() const; 291 void AddLayer( OGRShapeLayer* poLayer ); 292 static void RefreshLockFile(void* _self); 293 void RemoveLockFile(); 294 bool RecompressIfNeeded(const std::vector<CPLString>& layerNames); 295 296 CPL_DISALLOW_COPY_ASSIGN(OGRShapeDataSource) 297 298 public: 299 OGRShapeDataSource(); 300 virtual ~OGRShapeDataSource(); 301 GetPool()302 OGRLayerPool *GetPool() const { return poPool; } 303 304 bool Open( GDALOpenInfo* poOpenInfo, bool bTestOpen, 305 bool bForceSingleFileDataSource = false ); 306 bool OpenFile( const char *, bool bUpdate ); 307 bool OpenZip( GDALOpenInfo* poOpenInfo, 308 const char* pszOriFilename ); 309 bool CreateZip(const char* pszOriFilename ); 310 GetName()311 const char *GetName() override { return pszName; } 312 313 int GetLayerCount() override; 314 OGRLayer *GetLayer( int ) override; 315 OGRLayer *GetLayerByName( const char * ) override; 316 317 OGRLayer *ICreateLayer( const char *, 318 OGRSpatialReference * = nullptr, 319 OGRwkbGeometryType = wkbUnknown, 320 char ** = nullptr ) override; 321 322 OGRLayer *ExecuteSQL( const char *pszStatement, 323 OGRGeometry *poSpatialFilter, 324 const char *pszDialect ) override; 325 326 int TestCapability( const char * ) override; 327 OGRErr DeleteLayer( int iLayer ) override; 328 329 char **GetFileList() override; 330 331 void SetLastUsedLayer( OGRShapeLayer* poLayer ); 332 void UnchainLayer( OGRShapeLayer* poLayer ); 333 334 bool UncompressIfNeeded(); 335 336 SHPHandle DS_SHPOpen( const char * pszShapeFile, 337 const char * pszAccess ); 338 DBFHandle DS_DBFOpen( const char * pszDBFFile, 339 const char * pszAccess ); GetOpenOptions()340 char **GetOpenOptions() { return papszOpenOptions; } 341 342 static const char* const* GetExtensionsForDeletion(); IsZip()343 bool IsZip() const { return m_bIsZip; } GetVSIZipPrefixeDir()344 CPLString GetVSIZipPrefixeDir() const { return CPLString("/vsizip/{") + pszName + '}'; } GetTemporaryUnzipDir()345 const CPLString& GetTemporaryUnzipDir() const { return m_osTemporaryUnzipDir; } 346 347 static bool CopyInPlace( VSILFILE* fpTarget, 348 const CPLString& osSourceFilename ); 349 }; 350 351 #endif /* ndef OGRSHAPE_H_INCLUDED */ 352