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 992 : class IOGRCSVLayer CPL_NON_FINAL
51 : {
52 : public:
53 993 : 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 : virtual ~OGRCSVLayer() override;
148 :
149 736 : OGRLayer *GetLayer() override
150 : {
151 736 : 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 : virtual OGRFeature *GetFeature(GIntBig nFID) override;
218 :
219 89894 : OGRFeatureDefn *GetLayerDefn() override
220 : {
221 89894 : return poFeatureDefn;
222 : }
223 :
224 : int TestCapability(const char *) override;
225 :
226 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
227 : int bApproxOK = TRUE) override;
228 :
229 : static OGRCSVCreateFieldAction
230 : PreCreateField(OGRFeatureDefn *poFeatureDefn,
231 : const std::set<CPLString> &oSetFields,
232 : const OGRFieldDefn *poNewField, int bApproxOK);
233 : virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomField,
234 : int bApproxOK = TRUE) override;
235 :
236 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
237 :
238 : void SetCRLF(bool bNewValue);
239 : void SetWriteGeometry(OGRwkbGeometryType eGType,
240 : OGRCSVGeometryFormat eGeometryFormat,
241 : const char *pszGeomCol = nullptr);
242 : void SetCreateCSVT(bool bCreateCSVT);
243 : void SetWriteBOM(bool bWriteBOM);
244 :
245 123 : void SetWriteHeader(bool b)
246 : {
247 123 : m_bWriteHeader = b;
248 123 : }
249 :
250 134 : void SetStringQuoting(StringQuoting eVal)
251 : {
252 134 : m_eStringQuoting = eVal;
253 134 : }
254 :
255 9 : StringQuoting GetStringQuoting() const
256 : {
257 9 : return m_eStringQuoting;
258 : }
259 :
260 : virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
261 : virtual OGRErr SyncToDisk() override;
262 :
263 25 : GDALDataset *GetDataset() override
264 : {
265 25 : return m_poDS;
266 : }
267 :
268 : OGRErr WriteHeader();
269 : };
270 :
271 : /************************************************************************/
272 : /* OGRCSVDataSource */
273 : /************************************************************************/
274 :
275 1312 : class OGRCSVDataSource final : public GDALDataset
276 : {
277 : char *pszName = nullptr;
278 :
279 : std::vector<std::unique_ptr<IOGRCSVLayer>> m_apoLayers{};
280 :
281 : bool bUpdate = false;
282 :
283 : CPLString osDefaultCSVName{};
284 :
285 : bool bEnableGeometryFields = false;
286 :
287 : bool DealWithOgrSchemaOpenOption(CSLConstList papszOpenOptions);
288 :
289 : /* When OGR_SCHEMA and schemaType=Full, this will contain the list
290 : * of removed field (if any).
291 : */
292 : std::vector<int> m_oDeletedFieldIndexes{};
293 :
294 : CPL_DISALLOW_COPY_ASSIGN(OGRCSVDataSource)
295 :
296 : public:
297 : OGRCSVDataSource();
298 : virtual ~OGRCSVDataSource() override;
299 :
300 : bool Open(const char *pszFilename, bool bUpdate, bool bForceOpen,
301 : CSLConstList papszOpenOptions, bool bSingleDriver);
302 : bool OpenTable(const char *pszFilename, CSLConstList papszOpenOptions,
303 : const char *pszNfdcRunwaysGeomField = nullptr,
304 : const char *pszGeonamesGeomFieldPrefix = nullptr);
305 :
306 1520 : int GetLayerCount() override
307 : {
308 1520 : return static_cast<int>(m_apoLayers.size());
309 : }
310 :
311 : OGRLayer *GetLayer(int) override;
312 :
313 : char **GetFileList() override;
314 :
315 : virtual OGRLayer *ICreateLayer(const char *pszName,
316 : const OGRGeomFieldDefn *poGeomFieldDefn,
317 : CSLConstList papszOptions) override;
318 :
319 : virtual OGRErr DeleteLayer(int) override;
320 :
321 : int TestCapability(const char *) override;
322 :
323 : void CreateForSingleFile(const char *pszDirname, const char *pszFilename);
324 :
325 10 : void EnableGeometryFields()
326 : {
327 10 : bEnableGeometryFields = true;
328 10 : }
329 :
330 : static CPLString GetRealExtension(CPLString osFilename);
331 : const std::vector<int> &DeletedFieldIndexes() const;
332 : };
333 :
334 : #endif // ndef OGR_CSV_H_INCLUDED
|