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 4805 : OGRShapeGeomFieldDefn(const char *pszFullNameIn, OGRwkbGeometryType eType,
67 : int bSRSSetIn, OGRSpatialReference *poSRSIn)
68 14415 : : OGRGeomFieldDefn("", eType), pszFullName(CPLStrdup(pszFullNameIn)),
69 4805 : bSRSSet(CPL_TO_BOOL(bSRSSetIn))
70 : {
71 4805 : SetSpatialRef(poSRSIn);
72 4805 : }
73 :
74 9578 : virtual ~OGRShapeGeomFieldDefn()
75 4789 : {
76 4789 : CPLFree(pszFullName);
77 9578 : }
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 179 : void SetPrjFilename(const std::string &osFilename)
92 : {
93 179 : osPrjFile = osFilename;
94 179 : }
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 1586 : void SetResizeAtClose(bool bFlag)
208 : {
209 1586 : bResizeAtClose = bFlag;
210 1586 : }
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 1412990 : OGRFeatureDefn *GetLayerDefn() override
248 : {
249 1412990 : return poFeatureDefn;
250 : }
251 :
252 : GIntBig GetFeatureCount(int) override;
253 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
254 : bool bForce) override;
255 :
256 : OGRErr IGetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
257 : bool bForce) override;
258 :
259 : OGRErr CreateField(const OGRFieldDefn *poField,
260 : int bApproxOK = TRUE) override;
261 : OGRErr DeleteField(int iField) override;
262 : OGRErr ReorderFields(int *panMap) override;
263 : OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
264 : int nFlags) override;
265 : OGRErr AlterGeomFieldDefn(int iGeomField,
266 : const OGRGeomFieldDefn *poNewGeomFieldDefn,
267 : int nFlagsIn) override;
268 :
269 : int TestCapability(const char *) override;
270 :
271 : OGRErr ISetSpatialFilter(int iGeomField,
272 : const OGRGeometry *poGeom) override;
273 :
274 : OGRErr SetAttributeFilter(const char *) override;
275 :
276 : OGRErr Rename(const char *pszNewName) override;
277 :
278 : void AddToFileList(CPLStringList &oFileList);
279 :
280 1586 : void CreateSpatialIndexAtClose(int bFlag)
281 : {
282 1586 : bCreateSpatialIndexAtClose = CPL_TO_BOOL(bFlag);
283 1586 : }
284 :
285 : void SetModificationDate(const char *pszStr);
286 :
287 5182 : void SetAutoRepack(bool b)
288 : {
289 5182 : m_bAutoRepack = b;
290 5182 : }
291 :
292 : void SetWriteDBFEOFChar(bool b);
293 : };
294 :
295 : /************************************************************************/
296 : /* OGRShapeDataSource */
297 : /************************************************************************/
298 :
299 : class OGRShapeDataSource final : public GDALDataset
300 : {
301 : OGRShapeLayer **papoLayers;
302 : int nLayers;
303 : bool bSingleFileDataSource;
304 : OGRLayerPool *poPool;
305 :
306 : std::vector<CPLString> oVectorLayerName{};
307 :
308 : bool b2GBLimit;
309 : bool m_bIsZip = false;
310 : bool m_bSingleLayerZip = false;
311 : CPLString m_osTemporaryUnzipDir{};
312 : CPLMutex *m_poRefreshLockFileMutex = nullptr;
313 : CPLCond *m_poRefreshLockFileCond = nullptr;
314 : VSILFILE *m_psLockFile = nullptr;
315 : CPLJoinableThread *m_hRefreshLockFileThread = nullptr;
316 : bool m_bExitRefreshLockFileThread = false;
317 : bool m_bRefreshLockFileThreadStarted = false;
318 : double m_dfRefreshLockDelay = 0;
319 :
320 : std::vector<CPLString> GetLayerNames() const;
321 : void AddLayer(OGRShapeLayer *poLayer);
322 : static void RefreshLockFile(void *_self);
323 : void RemoveLockFile();
324 : bool RecompressIfNeeded(const std::vector<CPLString> &layerNames);
325 :
326 : CPL_DISALLOW_COPY_ASSIGN(OGRShapeDataSource)
327 :
328 : public:
329 : OGRShapeDataSource();
330 : virtual ~OGRShapeDataSource();
331 :
332 5182 : OGRLayerPool *GetPool() const
333 : {
334 5182 : return poPool;
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() override;
344 : OGRLayer *GetLayer(int) 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 *) 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 13631 : char **GetOpenOptions()
368 : {
369 13631 : return papszOpenOptions;
370 : }
371 :
372 : static const char *const *GetExtensionsForDeletion();
373 :
374 1647 : bool IsZip() const
375 : {
376 1647 : return m_bIsZip;
377 : }
378 :
379 5 : CPLString GetVSIZipPrefixeDir() const
380 : {
381 10 : return CPLString("/vsizip/{").append(GetDescription()).append("}");
382 : }
383 :
384 11 : const CPLString &GetTemporaryUnzipDir() const
385 : {
386 11 : return m_osTemporaryUnzipDir;
387 : }
388 :
389 : static bool CopyInPlace(VSILFILE *fpTarget,
390 : const CPLString &osSourceFilename);
391 : };
392 :
393 : #endif /* ndef OGRSHAPE_H_INCLUDED */
|