Coverage Report

Created: 2026-02-14 09:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogrsf_frmts/gml/ogr_gml.h
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GML Reader
4
 * Purpose:  Declarations for OGR wrapper classes for GML, and GML<->OGR
5
 *           translation of geometry.
6
 * Author:   Frank Warmerdam, warmerdam@pobox.com
7
 *
8
 ******************************************************************************
9
 * Copyright (c) 2002, Frank Warmerdam
10
 * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
11
 *
12
 * SPDX-License-Identifier: MIT
13
 ****************************************************************************/
14
15
#ifndef OGR_GML_H_INCLUDED
16
#define OGR_GML_H_INCLUDED
17
18
#include "ogrsf_frmts.h"
19
#include "gmlreader.h"
20
#include "gmlutils.h"
21
22
#include <memory>
23
#include <set>
24
#include <vector>
25
26
class OGRGMLDataSource;
27
28
typedef enum
29
{
30
    STANDARD,
31
    SEQUENTIAL_LAYERS,
32
    INTERLEAVED_LAYERS
33
} ReadMode;
34
35
/************************************************************************/
36
/*                             OGRGMLLayer                              */
37
/************************************************************************/
38
39
class OGRGMLLayer final : public OGRLayer
40
{
41
    OGRFeatureDefn *poFeatureDefn;
42
43
    GIntBig m_iNextGMLId = 0;
44
    bool m_bInvalidFIDFound = false;
45
    char *m_pszFIDPrefix = nullptr;
46
    std::set<GIntBig> m_oSetFIDs{};
47
48
    bool bWriter;
49
50
    OGRGMLDataSource *poDS;
51
52
    GMLFeatureClass *poFClass;
53
54
    std::unique_ptr<OGRGML_SRSCache, decltype(&OGRGML_SRSCache_Destroy)>
55
        m_srsCache{OGRGML_SRSCache_Create(), OGRGML_SRSCache_Destroy};
56
57
    bool bUseOldFIDFormat;
58
59
    bool bFaceHoleNegative;
60
61
    CPL_DISALLOW_COPY_ASSIGN(OGRGMLLayer)
62
63
  public:
64
    OGRGMLLayer(const char *pszName, bool bWriter, OGRGMLDataSource *poDS);
65
66
    ~OGRGMLLayer() override;
67
68
    GDALDataset *GetDataset() override;
69
70
    void ResetReading() override;
71
    OGRFeature *GetNextFeature() override;
72
73
    GIntBig GetFeatureCount(int bForce = TRUE) override;
74
    OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
75
                      bool bForce) override;
76
77
    OGRErr ICreateFeature(OGRFeature *poFeature) override;
78
79
    const OGRFeatureDefn *GetLayerDefn() const override
80
595k
    {
81
595k
        return poFeatureDefn;
82
595k
    }
83
84
    virtual OGRErr CreateField(const OGRFieldDefn *poField,
85
                               int bApproxOK = TRUE) override;
86
    virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poField,
87
                                   int bApproxOK = TRUE) override;
88
89
    int TestCapability(const char *) const override;
90
};
91
92
/************************************************************************/
93
/*                           OGRGMLDataSource                           */
94
/************************************************************************/
95
96
class OGRGMLDataSource final : public GDALDataset
97
{
98
    OGRLayer **papoLayers;
99
    int nLayers;
100
101
    OGRLayer *TranslateGMLSchema(GMLFeatureClass *);
102
103
    char **papszCreateOptions;
104
105
    // output related parameters
106
    VSILFILE *fpOutput;
107
    bool bFpOutputIsNonSeekable;
108
    bool bFpOutputSingleFile;
109
    bool m_bWriteError = false;
110
    OGREnvelope3D sBoundingRect{};
111
    bool bBBOX3D;
112
    int nBoundedByLocation;
113
114
    int nSchemaInsertLocation;
115
    bool bIsOutputGML3;
116
    bool bIsOutputGML3Deegree; /* if TRUE, then bIsOutputGML3 is also TRUE */
117
    bool bIsOutputGML32;       /* if TRUE, then bIsOutputGML3 is also TRUE */
118
    OGRGMLSRSNameFormat eSRSNameFormat;
119
    bool bWriteSpaceIndentation;
120
121
    //! Whether all geometry fields of all layers have the same SRS (or no SRS at all)
122
    bool m_bWriteGlobalSRS = true;
123
124
    //! The global SRS (may be null), that is valid only if m_bWriteGlobalSRS == true
125
    std::unique_ptr<OGRSpatialReference> m_poWriteGlobalSRS{};
126
127
    //! Whether at least one geometry field has been created
128
    bool m_bWriteGlobalSRSInit = false;
129
130
    // input related parameters.
131
    CPLString osFilename{};
132
    CPLString osXSDFilename{};
133
    bool m_bUnlinkXSDFilename = false;
134
135
    IGMLReader *poReader;
136
    bool bOutIsTempFile;
137
138
    void InsertHeader();
139
140
    bool bExposeGMLId;
141
    bool bExposeFid;
142
    bool bIsWFS;
143
144
    bool bUseGlobalSRSName;
145
146
    bool m_bInvertAxisOrderIfLatLong;
147
    bool m_bConsiderEPSGAsURN;
148
    GMLSwapCoordinatesEnum m_eSwapCoordinates;
149
    bool m_bGetSecondaryGeometryOption;
150
151
    ReadMode eReadMode;
152
    GMLFeature *poStoredGMLFeature;
153
    OGRGMLLayer *poLastReadLayer;
154
155
    bool bEmptyAsNull;
156
157
    OGRSpatialReference m_oStandaloneGeomSRS{};
158
    std::unique_ptr<OGRGeometry> m_poStandaloneGeom{};
159
160
    std::vector<std::string> m_aosGMLExtraElements{};
161
162
    void FindAndParseTopElements(VSILFILE *fp);
163
    void SetExtents(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY);
164
165
    void BuildJointClassFromXSD();
166
    void BuildJointClassFromScannedSchema();
167
168
    void WriteTopElements();
169
170
    // Analyze the OGR_SCHEMA open options and apply changes to the GML reader, return false in case of a critical error
171
    bool DealWithOgrSchemaOpenOption(const GDALOpenInfo *poOpenInfo);
172
173
    CPL_DISALLOW_COPY_ASSIGN(OGRGMLDataSource)
174
175
  public:
176
    OGRGMLDataSource();
177
    ~OGRGMLDataSource() override;
178
179
    bool Open(GDALOpenInfo *poOpenInfo);
180
    CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) override;
181
    bool Create(const char *pszFile, CSLConstList papszOptions);
182
183
    int GetLayerCount() const override
184
45.6k
    {
185
45.6k
        return nLayers;
186
45.6k
    }
187
188
    using GDALDataset::GetLayer;
189
    const OGRLayer *GetLayer(int) const override;
190
    OGRLayer *ICreateLayer(const char *pszName,
191
                           const OGRGeomFieldDefn *poGeomFieldDefn,
192
                           CSLConstList papszOptions) override;
193
    int TestCapability(const char *) const override;
194
195
    VSILFILE *GetOutputFP() const
196
433k
    {
197
433k
        return fpOutput;
198
433k
    }
199
200
    IGMLReader *GetReader() const
201
37.5k
    {
202
37.5k
        return poReader;
203
37.5k
    }
204
205
    void GrowExtents(OGREnvelope3D *psGeomBounds, int nCoordDimension);
206
207
    int ExposeId() const
208
13.0k
    {
209
13.0k
        return bExposeGMLId || bExposeFid;
210
13.0k
    }
211
212
    void PrintLine(VSILFILE *fp, const char *fmt, ...)
213
        CPL_PRINT_FUNC_FORMAT(3, 4);
214
215
    bool IsGML3Output() const
216
940k
    {
217
940k
        return bIsOutputGML3;
218
940k
    }
219
220
    bool IsGML3DeegreeOutput() const
221
322
    {
222
322
        return bIsOutputGML3Deegree;
223
322
    }
224
225
    bool IsGML32Output() const
226
8.13k
    {
227
8.13k
        return bIsOutputGML32;
228
8.13k
    }
229
230
    /** Returns whether a writing error has occurred */
231
    inline bool HasWriteError() const
232
864k
    {
233
864k
        return m_bWriteError;
234
864k
    }
235
236
    OGRGMLSRSNameFormat GetSRSNameFormat() const
237
13.9k
    {
238
13.9k
        return eSRSNameFormat;
239
13.9k
    }
240
241
    bool WriteSpaceIndentation() const
242
433k
    {
243
433k
        return bWriteSpaceIndentation;
244
433k
    }
245
246
    const char *GetGlobalSRSName();
247
248
    bool GetInvertAxisOrderIfLatLong() const
249
3.18k
    {
250
3.18k
        return m_bInvertAxisOrderIfLatLong;
251
3.18k
    }
252
253
    bool GetConsiderEPSGAsURN() const
254
3.18k
    {
255
3.18k
        return m_bConsiderEPSGAsURN;
256
3.18k
    }
257
258
    GMLSwapCoordinatesEnum GetSwapCoordinates() const
259
3.18k
    {
260
3.18k
        return m_eSwapCoordinates;
261
3.18k
    }
262
263
    bool GetSecondaryGeometryOption() const
264
3.18k
    {
265
3.18k
        return m_bGetSecondaryGeometryOption;
266
3.18k
    }
267
268
    ReadMode GetReadMode() const
269
17.9k
    {
270
17.9k
        return eReadMode;
271
17.9k
    }
272
273
    void SetStoredGMLFeature(GMLFeature *poStoredGMLFeatureIn)
274
1.49k
    {
275
1.49k
        poStoredGMLFeature = poStoredGMLFeatureIn;
276
1.49k
    }
277
278
    GMLFeature *PeekStoredGMLFeature() const
279
20.6k
    {
280
20.6k
        return poStoredGMLFeature;
281
20.6k
    }
282
283
    OGRGMLLayer *GetLastReadLayer() const
284
17.4k
    {
285
17.4k
        return poLastReadLayer;
286
17.4k
    }
287
288
    void SetLastReadLayer(OGRGMLLayer *poLayer)
289
4.31k
    {
290
4.31k
        poLastReadLayer = poLayer;
291
4.31k
    }
292
293
    const char *GetAppPrefix() const;
294
    bool RemoveAppPrefix() const;
295
    bool WriteFeatureBoundedBy() const;
296
    const char *GetSRSDimensionLoc() const;
297
    bool GMLFeatureCollection() const;
298
299
    void DeclareNewWriteSRS(const OGRSpatialReference *poSRS);
300
301
    bool HasWriteGlobalSRS() const
302
4.24k
    {
303
4.24k
        return m_bWriteGlobalSRS;
304
4.24k
    }
305
306
    OGRLayer *ExecuteSQL(const char *pszSQLCommand,
307
                         OGRGeometry *poSpatialFilter,
308
                         const char *pszDialect) override;
309
    void ReleaseResultSet(OGRLayer *poResultsSet) override;
310
311
    static bool CheckHeader(const char *pszStr);
312
};
313
314
#endif /* OGR_GML_H_INCLUDED */