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