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 : class IOGRCSVLayer CPL_NON_FINAL
51 : {
52 : public:
53 951 : IOGRCSVLayer() = default;
54 950 : virtual ~IOGRCSVLayer() = default;
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;
74 : std::set<CPLString> m_oSetFields;
75 :
76 : VSILFILE *fpCSV;
77 : const int m_nMaxLineSize = -1;
78 :
79 : int nNextFID;
80 :
81 : bool bHasFieldNames;
82 :
83 : OGRFeature *GetNextUnfilteredFeature();
84 :
85 : bool bNew;
86 : bool bInWriteMode;
87 : bool bUseCRLF;
88 : bool bNeedRewindBeforeRead;
89 : OGRCSVGeometryFormat eGeometryFormat;
90 :
91 : char *pszFilename;
92 : std::string m_osCSVTFilename{};
93 : bool bCreateCSVT;
94 : bool bWriteBOM;
95 : char szDelimiter[2] = {0};
96 :
97 : int nCSVFieldCount;
98 : int *panGeomFieldIndex;
99 : bool bFirstFeatureAppendedDuringSession;
100 : bool bHiddenWKTColumn;
101 :
102 : // http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm
103 : // specific
104 : int iNfdcLongitudeS;
105 : int iNfdcLatitudeS;
106 : bool bHonourStrings;
107 :
108 : bool m_bIsGNIS =
109 : false; // https://www.usgs.gov/u.s.-board-on-geographic-names/download-gnis-data
110 : int iLongitudeField;
111 : int iLatitudeField;
112 : int iZField;
113 : CPLString osXField;
114 : CPLString osYField;
115 : CPLString osZField;
116 :
117 : bool bIsEurostatTSV;
118 : int nEurostatDims;
119 :
120 : GIntBig nTotalFeatures;
121 :
122 : char **AutodetectFieldTypes(CSLConstList papszOpenOptions, int nFieldCount);
123 :
124 : bool bWarningBadTypeOrWidth;
125 : bool bKeepSourceColumns;
126 : bool bKeepGeomColumns;
127 :
128 : bool bMergeDelimiter;
129 :
130 : bool bEmptyStringNull;
131 :
132 : StringQuoting m_eStringQuoting = StringQuoting::IF_AMBIGUOUS;
133 :
134 : char **GetNextLineTokens();
135 :
136 : static bool Matches(const char *pszFieldName, char **papszPossibleNames);
137 :
138 : public:
139 : OGRCSVLayer(GDALDataset *poDS, const char *pszName, VSILFILE *fp,
140 : int nMaxLineSize, const char *pszFilename, int bNew,
141 : int bInWriteMode, char chDelimiter);
142 : virtual ~OGRCSVLayer() override;
143 :
144 685 : OGRLayer *GetLayer() override
145 : {
146 685 : return this;
147 : }
148 :
149 9 : const char *GetFilename() const
150 : {
151 9 : return pszFilename;
152 : }
153 :
154 : std::vector<std::string> GetFileList() override;
155 :
156 9 : char GetDelimiter() const
157 : {
158 9 : return szDelimiter[0];
159 : }
160 :
161 9 : bool GetCRLF() const
162 : {
163 9 : return bUseCRLF;
164 : }
165 :
166 9 : bool GetCreateCSVT() const
167 : {
168 9 : return bCreateCSVT;
169 : }
170 :
171 9 : bool GetWriteBOM() const
172 : {
173 9 : return bWriteBOM;
174 : }
175 :
176 9 : OGRCSVGeometryFormat GetGeometryFormat() const
177 : {
178 9 : return eGeometryFormat;
179 : }
180 :
181 9 : bool HasHiddenWKTColumn() const
182 : {
183 9 : return bHiddenWKTColumn;
184 : }
185 :
186 4 : GIntBig GetTotalFeatureCount() const
187 : {
188 4 : return nTotalFeatures;
189 : }
190 :
191 16 : const CPLString &GetXField() const
192 : {
193 16 : return osXField;
194 : }
195 :
196 10 : const CPLString &GetYField() const
197 : {
198 10 : return osYField;
199 : }
200 :
201 12 : const CPLString &GetZField() const
202 : {
203 12 : return osZField;
204 : }
205 :
206 : void BuildFeatureDefn(const char *pszNfdcGeomField = nullptr,
207 : const char *pszGeonamesGeomFieldPrefix = nullptr,
208 : CSLConstList papszOpenOptions = nullptr);
209 :
210 : void ResetReading() override;
211 : OGRFeature *GetNextFeature() override;
212 : virtual OGRFeature *GetFeature(GIntBig nFID) override;
213 :
214 89797 : OGRFeatureDefn *GetLayerDefn() override
215 : {
216 89797 : return poFeatureDefn;
217 : }
218 :
219 : int TestCapability(const char *) override;
220 :
221 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
222 : int bApproxOK = TRUE) override;
223 :
224 : static OGRCSVCreateFieldAction
225 : PreCreateField(OGRFeatureDefn *poFeatureDefn,
226 : const std::set<CPLString> &oSetFields,
227 : const OGRFieldDefn *poNewField, int bApproxOK);
228 : virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomField,
229 : int bApproxOK = TRUE) override;
230 :
231 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
232 :
233 : void SetCRLF(bool bNewValue);
234 : void SetWriteGeometry(OGRwkbGeometryType eGType,
235 : OGRCSVGeometryFormat eGeometryFormat,
236 : const char *pszGeomCol = nullptr);
237 : void SetCreateCSVT(bool bCreateCSVT);
238 : void SetWriteBOM(bool bWriteBOM);
239 :
240 132 : void SetStringQuoting(StringQuoting eVal)
241 : {
242 132 : m_eStringQuoting = eVal;
243 132 : }
244 :
245 9 : StringQuoting GetStringQuoting() const
246 : {
247 9 : return m_eStringQuoting;
248 : }
249 :
250 : virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
251 : virtual OGRErr SyncToDisk() override;
252 :
253 25 : GDALDataset *GetDataset() override
254 : {
255 25 : return m_poDS;
256 : }
257 :
258 : OGRErr WriteHeader();
259 : };
260 :
261 : /************************************************************************/
262 : /* OGRCSVDataSource */
263 : /************************************************************************/
264 :
265 1212 : class OGRCSVDataSource final : public GDALDataset
266 : {
267 : char *pszName = nullptr;
268 :
269 : std::vector<std::unique_ptr<IOGRCSVLayer>> m_apoLayers{};
270 :
271 : bool bUpdate = false;
272 :
273 : CPLString osDefaultCSVName{};
274 :
275 : bool bEnableGeometryFields = false;
276 :
277 : bool DealWithOgrSchemaOpenOption(CSLConstList papszOpenOptions);
278 :
279 : /* When OGR_SCHEMA and schemaType=Full, this will contain the list
280 : * of removed field (if any).
281 : */
282 : std::vector<int> m_oDeletedFieldIndexes;
283 :
284 : public:
285 : OGRCSVDataSource();
286 : virtual ~OGRCSVDataSource() override;
287 :
288 : bool Open(const char *pszFilename, bool bUpdate, bool bForceOpen,
289 : CSLConstList papszOpenOptions, bool bSingleDriver);
290 : bool OpenTable(const char *pszFilename, CSLConstList papszOpenOptions,
291 : const char *pszNfdcRunwaysGeomField = nullptr,
292 : const char *pszGeonamesGeomFieldPrefix = nullptr);
293 :
294 1413 : int GetLayerCount() override
295 : {
296 1413 : return static_cast<int>(m_apoLayers.size());
297 : }
298 :
299 : OGRLayer *GetLayer(int) override;
300 :
301 : char **GetFileList() override;
302 :
303 : virtual OGRLayer *ICreateLayer(const char *pszName,
304 : const OGRGeomFieldDefn *poGeomFieldDefn,
305 : CSLConstList papszOptions) override;
306 :
307 : virtual OGRErr DeleteLayer(int) override;
308 :
309 : int TestCapability(const char *) override;
310 :
311 : void CreateForSingleFile(const char *pszDirname, const char *pszFilename);
312 :
313 10 : void EnableGeometryFields()
314 : {
315 10 : bEnableGeometryFields = true;
316 10 : }
317 :
318 : static CPLString GetRealExtension(CPLString osFilename);
319 : const std::vector<int> &DeletedFieldIndexes() const;
320 : };
321 :
322 : #endif // ndef OGR_CSV_H_INCLUDED
|