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 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #ifndef OGR_CSV_H_INCLUDED
32 : #define OGR_CSV_H_INCLUDED
33 :
34 : #include "ogrsf_frmts.h"
35 :
36 : #include <set>
37 :
38 : typedef enum
39 : {
40 : OGR_CSV_GEOM_NONE,
41 : OGR_CSV_GEOM_AS_WKT,
42 : OGR_CSV_GEOM_AS_SOME_GEOM_FORMAT,
43 : OGR_CSV_GEOM_AS_XYZ,
44 : OGR_CSV_GEOM_AS_XY,
45 : OGR_CSV_GEOM_AS_YX,
46 : } OGRCSVGeometryFormat;
47 :
48 : class OGRCSVDataSource;
49 :
50 : typedef enum
51 : {
52 : CREATE_FIELD_DO_NOTHING,
53 : CREATE_FIELD_PROCEED,
54 : CREATE_FIELD_ERROR
55 : } OGRCSVCreateFieldAction;
56 :
57 : void OGRCSVDriverRemoveFromMap(const char *pszName, GDALDataset *poDS);
58 :
59 : // Must be kept as a macro with the value fully resolved, as it is used
60 : // by STRINGIFY(x) to generate open option description.
61 : #define OGR_CSV_DEFAULT_MAX_LINE_SIZE 10000000
62 :
63 : /************************************************************************/
64 : /* OGRCSVLayer */
65 : /************************************************************************/
66 :
67 : class IOGRCSVLayer CPL_NON_FINAL
68 : {
69 : public:
70 923 : IOGRCSVLayer() = default;
71 923 : virtual ~IOGRCSVLayer() = default;
72 :
73 : virtual OGRLayer *GetLayer() = 0;
74 :
75 : virtual std::vector<std::string> GetFileList() = 0;
76 : };
77 :
78 : class OGRCSVLayer final : public IOGRCSVLayer, public OGRLayer
79 : {
80 : public:
81 : enum class StringQuoting
82 : {
83 : IF_NEEDED,
84 : IF_AMBIGUOUS,
85 : ALWAYS
86 : };
87 :
88 : private:
89 : GDALDataset *m_poDS = nullptr;
90 : OGRFeatureDefn *poFeatureDefn;
91 : std::set<CPLString> m_oSetFields;
92 :
93 : VSILFILE *fpCSV;
94 : const int m_nMaxLineSize = -1;
95 :
96 : int nNextFID;
97 :
98 : bool bHasFieldNames;
99 :
100 : OGRFeature *GetNextUnfilteredFeature();
101 :
102 : bool bNew;
103 : bool bInWriteMode;
104 : bool bUseCRLF;
105 : bool bNeedRewindBeforeRead;
106 : OGRCSVGeometryFormat eGeometryFormat;
107 :
108 : char *pszFilename;
109 : std::string m_osCSVTFilename{};
110 : bool bCreateCSVT;
111 : bool bWriteBOM;
112 : char szDelimiter[2] = {0};
113 :
114 : int nCSVFieldCount;
115 : int *panGeomFieldIndex;
116 : bool bFirstFeatureAppendedDuringSession;
117 : bool bHiddenWKTColumn;
118 :
119 : // http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm
120 : // specific
121 : int iNfdcLongitudeS;
122 : int iNfdcLatitudeS;
123 : bool bHonourStrings;
124 :
125 : bool m_bIsGNIS =
126 : false; // https://www.usgs.gov/u.s.-board-on-geographic-names/download-gnis-data
127 : int iLongitudeField;
128 : int iLatitudeField;
129 : int iZField;
130 : CPLString osXField;
131 : CPLString osYField;
132 : CPLString osZField;
133 :
134 : bool bIsEurostatTSV;
135 : int nEurostatDims;
136 :
137 : GIntBig nTotalFeatures;
138 :
139 : char **AutodetectFieldTypes(char **papszOpenOptions, int nFieldCount);
140 :
141 : bool bWarningBadTypeOrWidth;
142 : bool bKeepSourceColumns;
143 : bool bKeepGeomColumns;
144 :
145 : bool bMergeDelimiter;
146 :
147 : bool bEmptyStringNull;
148 :
149 : StringQuoting m_eStringQuoting = StringQuoting::IF_AMBIGUOUS;
150 :
151 : char **GetNextLineTokens();
152 :
153 : static bool Matches(const char *pszFieldName, char **papszPossibleNames);
154 :
155 : public:
156 : OGRCSVLayer(GDALDataset *poDS, const char *pszName, VSILFILE *fp,
157 : int nMaxLineSize, const char *pszFilename, int bNew,
158 : int bInWriteMode, char chDelimiter);
159 : virtual ~OGRCSVLayer() override;
160 :
161 626 : OGRLayer *GetLayer() override
162 : {
163 626 : return this;
164 : }
165 :
166 9 : const char *GetFilename() const
167 : {
168 9 : return pszFilename;
169 : }
170 :
171 : std::vector<std::string> GetFileList() override;
172 :
173 9 : char GetDelimiter() const
174 : {
175 9 : return szDelimiter[0];
176 : }
177 :
178 9 : bool GetCRLF() const
179 : {
180 9 : return bUseCRLF;
181 : }
182 :
183 9 : bool GetCreateCSVT() const
184 : {
185 9 : return bCreateCSVT;
186 : }
187 :
188 9 : bool GetWriteBOM() const
189 : {
190 9 : return bWriteBOM;
191 : }
192 :
193 9 : OGRCSVGeometryFormat GetGeometryFormat() const
194 : {
195 9 : return eGeometryFormat;
196 : }
197 :
198 9 : bool HasHiddenWKTColumn() const
199 : {
200 9 : return bHiddenWKTColumn;
201 : }
202 :
203 4 : GIntBig GetTotalFeatureCount() const
204 : {
205 4 : return nTotalFeatures;
206 : }
207 :
208 16 : const CPLString &GetXField() const
209 : {
210 16 : return osXField;
211 : }
212 :
213 10 : const CPLString &GetYField() const
214 : {
215 10 : return osYField;
216 : }
217 :
218 12 : const CPLString &GetZField() const
219 : {
220 12 : return osZField;
221 : }
222 :
223 : void BuildFeatureDefn(const char *pszNfdcGeomField = nullptr,
224 : const char *pszGeonamesGeomFieldPrefix = nullptr,
225 : char **papszOpenOptions = nullptr);
226 :
227 : void ResetReading() override;
228 : OGRFeature *GetNextFeature() override;
229 : virtual OGRFeature *GetFeature(GIntBig nFID) override;
230 :
231 83250 : OGRFeatureDefn *GetLayerDefn() override
232 : {
233 83250 : return poFeatureDefn;
234 : }
235 :
236 : int TestCapability(const char *) override;
237 :
238 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
239 : int bApproxOK = TRUE) override;
240 :
241 : static OGRCSVCreateFieldAction
242 : PreCreateField(OGRFeatureDefn *poFeatureDefn,
243 : const std::set<CPLString> &oSetFields,
244 : const OGRFieldDefn *poNewField, int bApproxOK);
245 : virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomField,
246 : int bApproxOK = TRUE) override;
247 :
248 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
249 :
250 : void SetCRLF(bool bNewValue);
251 : void SetWriteGeometry(OGRwkbGeometryType eGType,
252 : OGRCSVGeometryFormat eGeometryFormat,
253 : const char *pszGeomCol = nullptr);
254 : void SetCreateCSVT(bool bCreateCSVT);
255 : void SetWriteBOM(bool bWriteBOM);
256 :
257 130 : void SetStringQuoting(StringQuoting eVal)
258 : {
259 130 : m_eStringQuoting = eVal;
260 130 : }
261 :
262 9 : StringQuoting GetStringQuoting() const
263 : {
264 9 : return m_eStringQuoting;
265 : }
266 :
267 : virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
268 : virtual OGRErr SyncToDisk() override;
269 :
270 25 : GDALDataset *GetDataset() override
271 : {
272 25 : return m_poDS;
273 : }
274 :
275 : OGRErr WriteHeader();
276 : };
277 :
278 : /************************************************************************/
279 : /* OGRCSVDataSource */
280 : /************************************************************************/
281 :
282 1137 : class OGRCSVDataSource final : public OGRDataSource
283 : {
284 : char *pszName = nullptr;
285 :
286 : std::vector<std::unique_ptr<IOGRCSVLayer>> m_apoLayers{};
287 :
288 : bool bUpdate = false;
289 :
290 : CPLString osDefaultCSVName{};
291 :
292 : bool bEnableGeometryFields = false;
293 :
294 : public:
295 : OGRCSVDataSource();
296 : virtual ~OGRCSVDataSource() override;
297 :
298 : int Open(const char *pszFilename, int bUpdate, int bForceAccept,
299 : char **papszOpenOptions = nullptr);
300 : bool OpenTable(const char *pszFilename, char **papszOpenOptions,
301 : const char *pszNfdcRunwaysGeomField = nullptr,
302 : const char *pszGeonamesGeomFieldPrefix = nullptr);
303 :
304 0 : const char *GetName() override
305 : {
306 0 : return pszName;
307 : }
308 :
309 1340 : int GetLayerCount() override
310 : {
311 1340 : return static_cast<int>(m_apoLayers.size());
312 : }
313 :
314 : OGRLayer *GetLayer(int) override;
315 :
316 : char **GetFileList() override;
317 :
318 : virtual OGRLayer *ICreateLayer(const char *pszName,
319 : const OGRGeomFieldDefn *poGeomFieldDefn,
320 : CSLConstList papszOptions) override;
321 :
322 : virtual OGRErr DeleteLayer(int) override;
323 :
324 : int TestCapability(const char *) 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 : };
335 :
336 : #endif // ndef OGR_CSV_H_INCLUDED
|