Coverage Report

Created: 2025-08-11 09:23

/src/gdal/ogr/ogrsf_frmts/gmlutils/gmlfeature.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  GML Reader
4
 * Purpose:  Public Declarations for OGR free GML Reader code.
5
 * Author:   Frank Warmerdam, warmerdam@pobox.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2002, 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 GMLFEATURE_H_INCLUDED
15
#define GMLFEATURE_H_INCLUDED
16
17
#include "cpl_port.h"
18
#include "cpl_vsi.h"
19
#include "cpl_minixml.h"
20
#include "ogr_core.h"
21
#include "ogr_geomcoordinateprecision.h"
22
23
#include <map>
24
#include <vector>
25
26
typedef enum
27
{
28
    GMLPT_Untyped = 0,
29
    GMLPT_String = 1,
30
    GMLPT_Integer = 2,
31
    GMLPT_Real = 3,
32
    GMLPT_Complex = 4,
33
    GMLPT_StringList = 5,
34
    GMLPT_IntegerList = 6,
35
    GMLPT_RealList = 7,
36
    GMLPT_FeatureProperty = 8,
37
    GMLPT_FeaturePropertyList = 9,
38
    GMLPT_Boolean = 10,
39
    GMLPT_BooleanList = 11,
40
    GMLPT_Short = 12,
41
    GMLPT_Float = 13,
42
    GMLPT_Integer64 = 14,
43
    GMLPT_Integer64List = 15,
44
    GMLPT_DateTime = 16,
45
    GMLPT_Date = 17,
46
    GMLPT_Time = 18,
47
} GMLPropertyType;
48
49
/************************************************************************/
50
/*                           GMLPropertyDefn                            */
51
/************************************************************************/
52
53
typedef struct
54
{
55
    int nSubProperties;
56
    char **papszSubProperties;
57
    char *aszSubProperties[2]; /* Optimization in the case of nSubProperties ==
58
                                  1 */
59
} GMLProperty;
60
61
class CPL_DLL GMLPropertyDefn
62
{
63
    char *m_pszName = nullptr;
64
    GMLPropertyType m_eType = GMLPT_Untyped;
65
    OGRFieldSubType m_eSubType = OFSTNone;
66
    int m_nWidth = 0;
67
    int m_nPrecision = 0;
68
    char *m_pszSrcElement = nullptr;
69
    size_t m_nSrcElementLen = 0;
70
    char *m_pszCondition = nullptr;
71
    bool m_bNullable = true;
72
    bool m_bUnique = false;
73
    std::string m_osDocumentation{};
74
75
    CPL_DISALLOW_COPY_ASSIGN(GMLPropertyDefn)
76
77
  public:
78
    explicit GMLPropertyDefn(const char *pszName,
79
                             const char *pszSrcElement = nullptr);
80
    ~GMLPropertyDefn();
81
82
    const char *GetName() const
83
569k
    {
84
569k
        return m_pszName;
85
569k
    }
86
87
    void SetName(const char *pszName)
88
0
    {
89
0
        CPLFree(m_pszName);
90
0
        m_pszName = CPLStrdup(pszName);
91
0
    }
92
93
    GMLPropertyType GetType() const
94
771k
    {
95
771k
        return m_eType;
96
771k
    }
97
98
    void SetType(GMLPropertyType eType)
99
184k
    {
100
184k
        m_eType = eType;
101
184k
    }
102
103
    OGRFieldSubType GetSubType() const
104
151k
    {
105
151k
        return m_eSubType;
106
151k
    }
107
108
    void SetSubType(OGRFieldSubType eSubType)
109
0
    {
110
0
        m_eSubType = eSubType;
111
0
    }
112
113
    void SetWidth(int nWidth)
114
190k
    {
115
190k
        m_nWidth = nWidth;
116
190k
    }
117
118
    int GetWidth() const
119
158k
    {
120
158k
        return m_nWidth;
121
158k
    }
122
123
    void SetPrecision(int nPrecision)
124
182k
    {
125
182k
        m_nPrecision = nPrecision;
126
182k
    }
127
128
    int GetPrecision() const
129
153k
    {
130
153k
        return m_nPrecision;
131
153k
    }
132
133
    void SetSrcElement(const char *pszSrcElement);
134
135
    const char *GetSrcElement() const
136
1.19M
    {
137
1.19M
        return m_pszSrcElement;
138
1.19M
    }
139
140
    size_t GetSrcElementLen() const
141
0
    {
142
0
        return m_nSrcElementLen;
143
0
    }
144
145
    void SetCondition(const char *pszCondition);
146
147
    const char *GetCondition() const
148
9
    {
149
9
        return m_pszCondition;
150
9
    }
151
152
    void SetNullable(bool bNullable)
153
182k
    {
154
182k
        m_bNullable = bNullable;
155
182k
    }
156
157
    bool IsNullable() const
158
1.58k
    {
159
1.58k
        return m_bNullable;
160
1.58k
    }
161
162
    void SetUnique(bool bUnique)
163
0
    {
164
0
        m_bUnique = bUnique;
165
0
    }
166
167
    bool IsUnique() const
168
151k
    {
169
151k
        return m_bUnique;
170
151k
    }
171
172
    void SetDocumentation(const std::string &osDocumentation)
173
0
    {
174
0
        m_osDocumentation = osDocumentation;
175
0
    }
176
177
    const std::string &GetDocumentation() const
178
151k
    {
179
151k
        return m_osDocumentation;
180
151k
    }
181
182
    void AnalysePropertyValue(const GMLProperty *psGMLProperty,
183
                              bool bSetWidth = true);
184
185
    static bool IsSimpleType(GMLPropertyType eType)
186
0
    {
187
0
        return eType == GMLPT_String || eType == GMLPT_Integer ||
188
0
               eType == GMLPT_Real;
189
0
    }
190
};
191
192
/************************************************************************/
193
/*                    GMLGeometryPropertyDefn                           */
194
/************************************************************************/
195
196
class CPL_DLL GMLGeometryPropertyDefn
197
{
198
    char *m_pszName = nullptr;
199
    char *m_pszSrcElement = nullptr;
200
    OGRwkbGeometryType m_nGeometryType = wkbUnknown;
201
    const int m_nAttributeIndex = -1;
202
    const bool m_bNullable = true;
203
    bool m_bSRSNameConsistent = true;
204
    std::string m_osSRSName{};
205
    OGRGeomCoordinatePrecision m_oCoordPrecision{};
206
207
    CPL_DISALLOW_COPY_ASSIGN(GMLGeometryPropertyDefn)
208
209
  public:
210
    GMLGeometryPropertyDefn(const char *pszName, const char *pszSrcElement,
211
                            OGRwkbGeometryType nType, int nAttributeIndex,
212
                            bool bNullable,
213
                            const OGRGeomCoordinatePrecision &oCoordPrec =
214
                                OGRGeomCoordinatePrecision());
215
    ~GMLGeometryPropertyDefn();
216
217
    const char *GetName() const
218
92.7k
    {
219
92.7k
        return m_pszName;
220
92.7k
    }
221
222
    OGRwkbGeometryType GetType() const
223
196k
    {
224
196k
        return m_nGeometryType;
225
196k
    }
226
227
    void SetType(OGRwkbGeometryType nType)
228
18.2k
    {
229
18.2k
        m_nGeometryType = nType;
230
18.2k
    }
231
232
    const char *GetSrcElement() const
233
719k
    {
234
719k
        return m_pszSrcElement;
235
719k
    }
236
237
    int GetAttributeIndex() const
238
0
    {
239
0
        return m_nAttributeIndex;
240
0
    }
241
242
    bool IsNullable() const
243
90.8k
    {
244
90.8k
        return m_bNullable;
245
90.8k
    }
246
247
    const OGRGeomCoordinatePrecision &GetCoordinatePrecision() const
248
87.6k
    {
249
87.6k
        return m_oCoordPrecision;
250
87.6k
    }
251
252
    void SetSRSName(const std::string &srsName)
253
112k
    {
254
112k
        m_bSRSNameConsistent = true;
255
112k
        m_osSRSName = srsName;
256
112k
    }
257
258
    void MergeSRSName(const std::string &osSRSName);
259
260
    const std::string &GetSRSName() const
261
87.6k
    {
262
87.6k
        return m_osSRSName;
263
87.6k
    }
264
};
265
266
/************************************************************************/
267
/*                           GMLFeatureClass                            */
268
/************************************************************************/
269
270
class CPL_DLL GMLFeatureClass
271
{
272
    char *m_pszName;
273
    char *m_pszElementName;
274
    int n_nNameLen;
275
    int n_nElementNameLen;
276
    int m_nPropertyCount;
277
    GMLPropertyDefn **m_papoProperty;
278
    std::map<CPLString, int> m_oMapPropertyNameToIndex{};
279
    std::map<CPLString, int> m_oMapPropertySrcElementToIndex{};
280
281
    int m_nGeometryPropertyCount;
282
    GMLGeometryPropertyDefn **m_papoGeometryProperty;
283
284
    bool m_bSchemaLocked;
285
286
    GIntBig m_nFeatureCount;
287
288
    char *m_pszExtraInfo;
289
290
    bool m_bHaveExtents;
291
    double m_dfXMin;
292
    double m_dfXMax;
293
    double m_dfYMin;
294
    double m_dfYMax;
295
296
    char *m_pszSRSName;
297
    bool m_bSRSNameConsistent;
298
299
    bool m_bIsConsistentSingleGeomElemPath = true;
300
    std::string m_osSingleGeomElemPath{};
301
302
    CPL_DISALLOW_COPY_ASSIGN(GMLFeatureClass)
303
304
  public:
305
    explicit GMLFeatureClass(const char *pszName = "");
306
    ~GMLFeatureClass();
307
308
    const char *GetElementName() const;
309
    size_t GetElementNameLen() const;
310
    void SetElementName(const char *pszElementName);
311
312
    const char *GetName() const
313
6.97M
    {
314
6.97M
        return m_pszName;
315
6.97M
    }
316
317
    void SetName(const char *pszNewName);
318
319
    int GetPropertyCount() const
320
436k
    {
321
436k
        return m_nPropertyCount;
322
436k
    }
323
324
    GMLPropertyDefn *GetProperty(int iIndex) const;
325
    int GetPropertyIndex(const char *pszName) const;
326
327
    GMLPropertyDefn *GetProperty(const char *pszName) const
328
227k
    {
329
227k
        return GetProperty(GetPropertyIndex(pszName));
330
227k
    }
331
332
    int GetPropertyIndexBySrcElement(const char *pszElement, int nLen) const;
333
    void StealProperties();
334
335
    int GetGeometryPropertyCount() const
336
761k
    {
337
761k
        return m_nGeometryPropertyCount;
338
761k
    }
339
340
    GMLGeometryPropertyDefn *GetGeometryProperty(int iIndex) const;
341
    int GetGeometryPropertyIndexBySrcElement(const char *pszElement) const;
342
    void StealGeometryProperties();
343
344
    bool HasFeatureProperties();
345
346
    int AddProperty(GMLPropertyDefn *, int iPos = -1);
347
    int AddGeometryProperty(GMLGeometryPropertyDefn *);
348
    void ClearGeometryProperties();
349
350
    void SetConsistentSingleGeomElemPath(bool b)
351
620
    {
352
620
        m_bIsConsistentSingleGeomElemPath = b;
353
620
    }
354
355
    bool IsConsistentSingleGeomElemPath() const
356
49.1k
    {
357
49.1k
        return m_bIsConsistentSingleGeomElemPath;
358
49.1k
    }
359
360
    void SetSingleGeomElemPath(const std::string &s)
361
21.6k
    {
362
21.6k
        m_osSingleGeomElemPath = s;
363
21.6k
    }
364
365
    const std::string &GetSingleGeomElemPath() const
366
31.8k
    {
367
31.8k
        return m_osSingleGeomElemPath;
368
31.8k
    }
369
370
    bool IsSchemaLocked() const
371
1.57M
    {
372
1.57M
        return m_bSchemaLocked;
373
1.57M
    }
374
375
    void SetSchemaLocked(bool bLock)
376
113k
    {
377
113k
        m_bSchemaLocked = bLock;
378
113k
    }
379
380
    const char *GetExtraInfo();
381
    void SetExtraInfo(const char *);
382
383
    GIntBig GetFeatureCount();
384
    void SetFeatureCount(GIntBig);
385
386
    bool HasExtents() const
387
100k
    {
388
100k
        return m_bHaveExtents;
389
100k
    }
390
391
    void SetExtents(double dfXMin, double dfXMax, double dFYMin, double dfYMax);
392
    bool GetExtents(double *pdfXMin, double *pdfXMax, double *pdFYMin,
393
                    double *pdfYMax);
394
395
    void SetSRSName(const char *pszSRSName);
396
    void MergeSRSName(const char *pszSRSName);
397
398
    const char *GetSRSName()
399
105k
    {
400
105k
        return m_pszSRSName;
401
105k
    }
402
403
    CPLXMLNode *SerializeToXML();
404
    bool InitializeFromXML(CPLXMLNode *);
405
};
406
407
/************************************************************************/
408
/*                              GMLFeature                              */
409
/************************************************************************/
410
411
class CPL_DLL GMLFeature
412
{
413
    GMLFeatureClass *m_poClass;
414
    char *m_pszFID;
415
416
    int m_nPropertyCount;
417
    GMLProperty *m_pasProperties;
418
419
    int m_nGeometryCount;
420
    CPLXMLNode **m_papsGeometry;  /* NULL-terminated. Alias to m_apsGeometry if
421
                                     m_nGeometryCount <= 1 */
422
    CPLXMLNode *m_apsGeometry[2]; /* NULL-terminated */
423
424
    CPLXMLNode *m_psBoundedByGeometry = nullptr;
425
426
    CPL_DISALLOW_COPY_ASSIGN(GMLFeature)
427
428
  public:
429
    explicit GMLFeature(GMLFeatureClass *);
430
    ~GMLFeature();
431
432
    GMLFeatureClass *GetClass() const
433
1.57M
    {
434
1.57M
        return m_poClass;
435
1.57M
    }
436
437
    void SetGeometryDirectly(CPLXMLNode *psGeom);
438
    void SetGeometryDirectly(int nIdx, CPLXMLNode *psGeom);
439
    void AddGeometry(CPLXMLNode *psGeom);
440
441
    int GetGeometryCount() const
442
148k
    {
443
148k
        return m_nGeometryCount;
444
148k
    }
445
446
    const CPLXMLNode *const *GetGeometryList() const
447
184k
    {
448
184k
        return m_papsGeometry;
449
184k
    }
450
451
    const CPLXMLNode *GetGeometryRef(int nIdx) const;
452
453
    void SetBoundedByGeometry(CPLXMLNode *psGeom);
454
455
    const CPLXMLNode *GetBoundedByGeometry() const
456
184k
    {
457
184k
        return m_psBoundedByGeometry;
458
184k
    }
459
460
    void SetPropertyDirectly(int i, char *pszValue);
461
462
    const GMLProperty *GetProperty(int i) const
463
140k
    {
464
140k
        return (i >= 0 && i < m_nPropertyCount) ? &m_pasProperties[i] : nullptr;
465
140k
    }
466
467
    const char *GetFID() const
468
35.7k
    {
469
35.7k
        return m_pszFID;
470
35.7k
    }
471
472
    void SetFID(const char *pszFID);
473
474
    void Dump(FILE *fp);
475
};
476
477
OGRFieldType CPL_DLL GML_GetOGRFieldType(GMLPropertyType eType,
478
                                         OGRFieldSubType &eSubType);
479
480
//! Map OGRFieldType to GMLPropertyType
481
GMLPropertyType CPL_DLL GML_FromOGRFieldType(OGRFieldType eType,
482
                                             OGRFieldSubType eSubType);
483
484
#endif