Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: CSV Translator
4 : * Purpose: Definition of classes for OGR .csv driver.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2004, Frank Warmerdam
9 : * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #ifndef OGR_CSV_H_INCLUDED
15 : #define OGR_CSV_H_INCLUDED
16 :
17 : #include "ogrsf_frmts.h"
18 :
19 : #include <set>
20 :
21 : typedef enum
22 : {
23 : OGR_CSV_GEOM_NONE,
24 : OGR_CSV_GEOM_AS_WKT,
25 : OGR_CSV_GEOM_AS_SOME_GEOM_FORMAT,
26 : OGR_CSV_GEOM_AS_XYZ,
27 : OGR_CSV_GEOM_AS_XY,
28 : OGR_CSV_GEOM_AS_YX,
29 : } OGRCSVGeometryFormat;
30 :
31 : class OGRCSVDataSource;
32 :
33 : typedef enum
34 : {
35 : CREATE_FIELD_DO_NOTHING,
36 : CREATE_FIELD_PROCEED,
37 : CREATE_FIELD_ERROR
38 : } OGRCSVCreateFieldAction;
39 :
40 : void OGRCSVDriverRemoveFromMap(const char *pszName, GDALDataset *poDS);
41 :
42 : // Must be kept as a macro with the value fully resolved, as it is used
43 : // by STRINGIFY(x) to generate open option description.
44 : #define OGR_CSV_DEFAULT_MAX_LINE_SIZE 10000000
45 :
46 : /************************************************************************/
47 : /* OGRCSVLayer */
48 : /************************************************************************/
49 :
50 994 : class IOGRCSVLayer CPL_NON_FINAL
51 : {
52 : public:
53 997 : IOGRCSVLayer() = default;
54 : virtual ~IOGRCSVLayer();
55 :
56 : virtual OGRLayer *GetLayer() = 0;
57 :
58 : virtual std::vector<std::string> GetFileList() = 0;
59 : };
60 :
61 : class OGRCSVLayer final : public IOGRCSVLayer, public OGRLayer
62 : {
63 : public:
64 : enum class StringQuoting
65 : {
66 : IF_NEEDED,
67 : IF_AMBIGUOUS,
68 : ALWAYS
69 : };
70 :
71 : private:
72 : GDALDataset *m_poDS = nullptr;
73 : OGRFeatureDefn *poFeatureDefn = nullptr;
74 : std::set<CPLString> m_oSetFields{};
75 :
76 : VSILFILE *fpCSV = nullptr;
77 : const int m_nMaxLineSize = -1;
78 :
79 : static constexpr int64_t FID_INITIAL_VALUE = 1;
80 : int64_t m_nNextFID = FID_INITIAL_VALUE;
81 :
82 : bool bHasFieldNames = false;
83 :
84 : OGRFeature *GetNextUnfilteredFeature();
85 :
86 : bool bNew = false;
87 : bool bInWriteMode = false;
88 : bool bUseCRLF = false;
89 : bool bNeedRewindBeforeRead = false;
90 : OGRCSVGeometryFormat eGeometryFormat = OGR_CSV_GEOM_NONE;
91 :
92 : char *pszFilename = nullptr;
93 : std::string m_osCSVTFilename{};
94 : bool bCreateCSVT = false;
95 : bool bWriteBOM = false;
96 : char szDelimiter[2] = {0};
97 :
98 : int nCSVFieldCount = 0;
99 : int *panGeomFieldIndex = nullptr;
100 : bool bFirstFeatureAppendedDuringSession = true;
101 : bool bHiddenWKTColumn = false;
102 :
103 : // http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm
104 : // specific
105 : int iNfdcLongitudeS = -1;
106 : int iNfdcLatitudeS = 1;
107 : bool bHonourStrings = true;
108 :
109 : // https://www.usgs.gov/u.s.-board-on-geographic-names/download-gnis-data
110 : bool m_bIsGNIS = false;
111 : int iLongitudeField = -1;
112 : int iLatitudeField = -1;
113 : int iZField = -1;
114 : CPLString osXField{};
115 : CPLString osYField{};
116 : CPLString osZField{};
117 :
118 : bool bIsEurostatTSV = false;
119 : int nEurostatDims = 0;
120 :
121 : GIntBig nTotalFeatures = 0;
122 :
123 : char **AutodetectFieldTypes(CSLConstList papszOpenOptions, int nFieldCount);
124 :
125 : bool bWarningBadTypeOrWidth = false;
126 : bool bKeepSourceColumns = false;
127 : bool bKeepGeomColumns = true;
128 :
129 : bool bMergeDelimiter = false;
130 :
131 : bool bEmptyStringNull = false;
132 :
133 : bool m_bWriteHeader = true;
134 :
135 : StringQuoting m_eStringQuoting = StringQuoting::IF_AMBIGUOUS;
136 :
137 : char **GetNextLineTokens();
138 :
139 : static bool Matches(const char *pszFieldName, char **papszPossibleNames);
140 :
141 : CPL_DISALLOW_COPY_ASSIGN(OGRCSVLayer)
142 :
143 : public:
144 : OGRCSVLayer(GDALDataset *poDS, const char *pszName, VSILFILE *fp,
145 : int nMaxLineSize, const char *pszFilename, int bNew,
146 : int bInWriteMode, char chDelimiter);
147 : ~OGRCSVLayer() override;
148 :
149 735 : OGRLayer *GetLayer() override
150 : {
151 735 : return this;
152 : }
153 :
154 9 : const char *GetFilename() const
155 : {
156 9 : return pszFilename;
157 : }
158 :
159 : std::vector<std::string> GetFileList() override;
160 :
161 9 : char GetDelimiter() const
162 : {
163 9 : return szDelimiter[0];
164 : }
165 :
166 9 : bool GetCRLF() const
167 : {
168 9 : return bUseCRLF;
169 : }
170 :
171 9 : bool GetCreateCSVT() const
172 : {
173 9 : return bCreateCSVT;
174 : }
175 :
176 9 : bool GetWriteBOM() const
177 : {
178 9 : return bWriteBOM;
179 : }
180 :
181 9 : OGRCSVGeometryFormat GetGeometryFormat() const
182 : {
183 9 : return eGeometryFormat;
184 : }
185 :
186 9 : bool HasHiddenWKTColumn() const
187 : {
188 9 : return bHiddenWKTColumn;
189 : }
190 :
191 4 : GIntBig GetTotalFeatureCount() const
192 : {
193 4 : return nTotalFeatures;
194 : }
195 :
196 16 : const CPLString &GetXField() const
197 : {
198 16 : return osXField;
199 : }
200 :
201 10 : const CPLString &GetYField() const
202 : {
203 10 : return osYField;
204 : }
205 :
206 12 : const CPLString &GetZField() const
207 : {
208 12 : return osZField;
209 : }
210 :
211 : void BuildFeatureDefn(const char *pszNfdcGeomField = nullptr,
212 : const char *pszGeonamesGeomFieldPrefix = nullptr,
213 : CSLConstList papszOpenOptions = nullptr);
214 :
215 : void ResetReading() override;
216 : OGRFeature *GetNextFeature() override;
217 : OGRFeature *GetFeature(GIntBig nFID) override;
218 :
219 : using OGRLayer::GetLayerDefn;
220 :
221 90490 : const OGRFeatureDefn *GetLayerDefn() const override
222 : {
223 90490 : return poFeatureDefn;
224 : }
225 :
226 : int TestCapability(const char *) const override;
227 :
228 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
229 : int bApproxOK = TRUE) override;
230 :
231 : static OGRCSVCreateFieldAction
232 : PreCreateField(OGRFeatureDefn *poFeatureDefn,
233 : const std::set<CPLString> &oSetFields,
234 : const OGRFieldDefn *poNewField, int bApproxOK);
235 : virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomField,
236 : int bApproxOK = TRUE) override;
237 :
238 : OGRErr ICreateFeature(OGRFeature *poFeature) override;
239 :
240 : void SetCRLF(bool bNewValue);
241 : void SetWriteGeometry(OGRwkbGeometryType eGType,
242 : OGRCSVGeometryFormat eGeometryFormat,
243 : const char *pszGeomCol = nullptr);
244 : void SetCreateCSVT(bool bCreateCSVT);
245 : void SetWriteBOM(bool bWriteBOM);
246 :
247 124 : void SetWriteHeader(bool b)
248 : {
249 124 : m_bWriteHeader = b;
250 124 : }
251 :
252 135 : void SetStringQuoting(StringQuoting eVal)
253 : {
254 135 : m_eStringQuoting = eVal;
255 135 : }
256 :
257 9 : StringQuoting GetStringQuoting() const
258 : {
259 9 : return m_eStringQuoting;
260 : }
261 :
262 : GIntBig GetFeatureCount(int bForce = TRUE) override;
263 : OGRErr SyncToDisk() override;
264 :
265 25 : GDALDataset *GetDataset() override
266 : {
267 25 : return m_poDS;
268 : }
269 :
270 : OGRErr WriteHeader();
271 : };
272 :
273 : /************************************************************************/
274 : /* OGRCSVDataSource */
275 : /************************************************************************/
276 :
277 1316 : class OGRCSVDataSource final : public GDALDataset
278 : {
279 : char *pszName = nullptr;
280 :
281 : std::vector<std::unique_ptr<IOGRCSVLayer>> m_apoLayers{};
282 :
283 : bool bUpdate = false;
284 :
285 : CPLString osDefaultCSVName{};
286 :
287 : bool bEnableGeometryFields = false;
288 :
289 : bool DealWithOgrSchemaOpenOption(CSLConstList papszOpenOptions);
290 :
291 : /* When OGR_SCHEMA and schemaType=Full, this will contain the list
292 : * of removed field (if any).
293 : */
294 : std::vector<int> m_oDeletedFieldIndexes{};
295 :
296 : CPL_DISALLOW_COPY_ASSIGN(OGRCSVDataSource)
297 :
298 : public:
299 : OGRCSVDataSource();
300 : ~OGRCSVDataSource() override;
301 :
302 : bool Open(const char *pszFilename, bool bUpdate, bool bForceOpen,
303 : CSLConstList papszOpenOptions, bool bSingleDriver);
304 : bool OpenTable(const char *pszFilename, CSLConstList papszOpenOptions,
305 : const char *pszNfdcRunwaysGeomField = nullptr,
306 : const char *pszGeonamesGeomFieldPrefix = nullptr);
307 :
308 1550 : int GetLayerCount() const override
309 : {
310 1550 : return static_cast<int>(m_apoLayers.size());
311 : }
312 :
313 : using GDALDataset::GetLayer;
314 : const OGRLayer *GetLayer(int) const override;
315 :
316 : char **GetFileList() override;
317 :
318 : virtual OGRLayer *ICreateLayer(const char *pszName,
319 : const OGRGeomFieldDefn *poGeomFieldDefn,
320 : CSLConstList papszOptions) override;
321 :
322 : OGRErr DeleteLayer(int) override;
323 :
324 : int TestCapability(const char *) const override;
325 :
326 : void CreateForSingleFile(const char *pszDirname, const char *pszFilename);
327 :
328 10 : void EnableGeometryFields()
329 : {
330 10 : bEnableGeometryFields = true;
331 10 : }
332 :
333 : static CPLString GetRealExtension(CPLString osFilename);
334 : const std::vector<int> &DeletedFieldIndexes() const;
335 : };
336 :
337 : #endif // ndef OGR_CSV_H_INCLUDED
|