Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Class for representing a whole feature, and layer schemas.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 1999, Les Technologies SoftMap Inc.
9 : * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #ifndef OGR_FEATURE_H_INCLUDED
15 : #define OGR_FEATURE_H_INCLUDED
16 :
17 : #include "cpl_atomic_ops.h"
18 : #include "gdal_fwd.h"
19 : #include "ogr_featurestyle.h"
20 : #include "ogr_geometry.h"
21 : #include "ogr_geomcoordinateprecision.h"
22 :
23 : #include <cstddef>
24 :
25 : #include <exception>
26 : #include <memory>
27 : #include <string>
28 : #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
29 : #include <string_view>
30 : #endif
31 : #include <vector>
32 :
33 : /**
34 : * \file ogr_feature.h
35 : *
36 : * Simple feature classes.
37 : */
38 :
39 : class OGRStyleTable;
40 :
41 : /************************************************************************/
42 : /* OGRFieldDefn */
43 : /************************************************************************/
44 :
45 : /**
46 : * Definition of an attribute of an OGRFeatureDefn. A field is described by :
47 : * <ul>
48 : * <li>a name. See SetName() / GetNameRef()</li>
49 : * <li>an alternative name (optional): alternative descriptive name for the
50 : * field (sometimes referred to as an "alias"). See SetAlternativeName() /
51 : * GetAlternativeNameRef()</li> <li>a type: OFTString, OFTInteger, OFTReal, ...
52 : * See SetType() / GetType()</li> <li>a subtype (optional): OFSTBoolean, ... See
53 : * SetSubType() / GetSubType()</li> <li>a width (optional): maximal number of
54 : * characters. See SetWidth() / GetWidth()</li> <li>a precision (optional):
55 : * number of digits after decimal point. See SetPrecision() /
56 : * GetPrecision()</li> <li>a NOT NULL constraint (optional). See SetNullable() /
57 : * IsNullable()</li> <li>a UNIQUE constraint (optional). See SetUnique() /
58 : * IsUnique()</li> <li>a default value (optional). See SetDefault() /
59 : * GetDefault()</li> <li>a boolean to indicate whether it should be ignored when
60 : * retrieving features. See SetIgnored() / IsIgnored()</li> <li>a field domain
61 : * name (optional). See SetDomainName() / Get DomainName()</li>
62 : * </ul>
63 : *
64 : * Note that once a OGRFieldDefn has been added to a layer definition with
65 : * OGRLayer::AddFieldDefn(), its setter methods should not be called on the
66 : * object returned with OGRLayer::GetLayerDefn()->GetFieldDefn(). Instead,
67 : * OGRLayer::AlterFieldDefn() should be called on a new instance of
68 : * OGRFieldDefn, for drivers that support AlterFieldDefn().
69 : */
70 :
71 : class CPL_DLL OGRFieldDefn
72 : {
73 : private:
74 : char *pszName;
75 : char *pszAlternativeName;
76 : OGRFieldType eType;
77 : OGRJustification eJustify;
78 : int nWidth; // Zero is variable.
79 : int nPrecision;
80 : char *pszDefault;
81 :
82 : int bIgnore;
83 : OGRFieldSubType eSubType;
84 :
85 : int bNullable;
86 : int bUnique;
87 :
88 : // Used by drivers (GPKG) to track generated fields
89 : bool m_bGenerated = false;
90 :
91 : std::string m_osDomainName{}; // field domain name. Might be empty
92 :
93 : std::string m_osComment{}; // field comment. Might be empty
94 :
95 : int m_nTZFlag = OGR_TZFLAG_UNKNOWN;
96 : bool m_bSealed = false;
97 :
98 : public:
99 : OGRFieldDefn(const char *, OGRFieldType);
100 : explicit OGRFieldDefn(const OGRFieldDefn *);
101 : ~OGRFieldDefn();
102 :
103 : // Copy constructor
104 : OGRFieldDefn(const OGRFieldDefn &oOther);
105 :
106 : // Copy assignment operator
107 : OGRFieldDefn &operator=(const OGRFieldDefn &oOther);
108 :
109 : void SetName(const char *);
110 :
111 22649111 : const char *GetNameRef() const
112 : {
113 22649111 : return pszName;
114 : }
115 :
116 : void SetAlternativeName(const char *);
117 :
118 935810 : const char *GetAlternativeNameRef() const
119 : {
120 935810 : return pszAlternativeName;
121 : }
122 :
123 37765422 : OGRFieldType GetType() const
124 : {
125 37765422 : return eType;
126 : }
127 :
128 : void SetType(OGRFieldType eTypeIn);
129 : static const char *GetFieldTypeName(OGRFieldType);
130 : static OGRFieldType GetFieldTypeByName(const char *);
131 :
132 9964344 : OGRFieldSubType GetSubType() const
133 : {
134 9964344 : return eSubType;
135 : }
136 :
137 : void SetSubType(OGRFieldSubType eSubTypeIn);
138 : static const char *GetFieldSubTypeName(OGRFieldSubType);
139 : static OGRFieldSubType GetFieldSubTypeByName(const char *);
140 :
141 774581 : OGRJustification GetJustify() const
142 : {
143 774581 : return eJustify;
144 : }
145 :
146 87051 : void SetJustify(OGRJustification eJustifyIn)
147 : {
148 87051 : eJustify = eJustifyIn;
149 87051 : }
150 :
151 5609539 : int GetWidth() const
152 : {
153 5609539 : return nWidth;
154 : }
155 :
156 : void SetWidth(int nWidthIn);
157 :
158 931130 : int GetPrecision() const
159 : {
160 931130 : return nPrecision;
161 : }
162 :
163 : void SetPrecision(int nPrecisionIn);
164 :
165 788243 : int GetTZFlag() const
166 : {
167 788243 : return m_nTZFlag;
168 : }
169 :
170 : void SetTZFlag(int nTZFlag);
171 :
172 : void Set(const char *, OGRFieldType, int = 0, int = 0,
173 : OGRJustification = OJUndefined);
174 :
175 : void SetDefault(const char *);
176 : const char *GetDefault() const;
177 : int IsDefaultDriverSpecific() const;
178 :
179 983600 : int IsIgnored() const
180 : {
181 983600 : return bIgnore;
182 : }
183 :
184 59954 : void SetIgnored(int bIgnoreIn)
185 : {
186 59954 : bIgnore = bIgnoreIn;
187 59954 : }
188 :
189 977537 : int IsNullable() const
190 : {
191 977537 : return bNullable;
192 : }
193 :
194 : void SetNullable(int bNullableIn);
195 :
196 934686 : int IsUnique() const
197 : {
198 934686 : return bUnique;
199 : }
200 :
201 : /**
202 : * @brief Return whether the field is a generated field.
203 : *
204 : * At time of writing, only the GeoPackage and PG drivers fill that information. Consequently,
205 : * only a returned value equal to TRUE can be fully trusted.
206 : * @return TRUE if the field is a generated field, FALSE otherwise.
207 : * @since GDAL 3.11
208 : */
209 5256811 : bool IsGenerated() const
210 : {
211 5256811 : return m_bGenerated;
212 : }
213 :
214 : /**
215 : * @brief SetGenerated set the field generated status.
216 : * @param bGeneratedIn TRUE if the field is a generated field, FALSE otherwise.
217 : * @since GDAL 3.11
218 : */
219 2610 : void SetGenerated(bool bGeneratedIn)
220 : {
221 2610 : m_bGenerated = bGeneratedIn;
222 2610 : }
223 :
224 : void SetUnique(int bUniqueIn);
225 :
226 69494 : const std::string &GetDomainName() const
227 : {
228 69494 : return m_osDomainName;
229 : }
230 :
231 : void SetDomainName(const std::string &osDomainName);
232 :
233 934767 : const std::string &GetComment() const
234 : {
235 934767 : return m_osComment;
236 : }
237 :
238 : void SetComment(const std::string &osComment);
239 :
240 : int IsSame(const OGRFieldDefn *) const;
241 :
242 : /** Convert a OGRFieldDefn* to a OGRFieldDefnH.
243 : */
244 486326 : static inline OGRFieldDefnH ToHandle(OGRFieldDefn *poFieldDefn)
245 : {
246 486326 : return reinterpret_cast<OGRFieldDefnH>(poFieldDefn);
247 : }
248 :
249 : /** Convert a OGRFieldDefnH to a OGRFieldDefn*.
250 : */
251 569721 : static inline OGRFieldDefn *FromHandle(OGRFieldDefnH hFieldDefn)
252 : {
253 569721 : return reinterpret_cast<OGRFieldDefn *>(hFieldDefn);
254 : }
255 :
256 : void Seal();
257 :
258 : void Unseal();
259 :
260 : /*! @cond Doxygen_Suppress */
261 : struct CPL_DLL TemporaryUnsealer
262 : {
263 : private:
264 : OGRFieldDefn *m_poFieldDefn = nullptr;
265 : CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
266 : public:
267 252 : explicit TemporaryUnsealer(OGRFieldDefn *poFieldDefn)
268 252 : : m_poFieldDefn(poFieldDefn)
269 : {
270 252 : m_poFieldDefn->Unseal();
271 252 : }
272 :
273 : TemporaryUnsealer(TemporaryUnsealer &&) = default;
274 : TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
275 :
276 252 : ~TemporaryUnsealer()
277 252 : {
278 252 : m_poFieldDefn->Seal();
279 252 : }
280 :
281 98 : OGRFieldDefn *operator->()
282 : {
283 98 : return m_poFieldDefn;
284 : }
285 : };
286 :
287 : /*! @endcond */
288 :
289 : TemporaryUnsealer GetTemporaryUnsealer();
290 : };
291 :
292 : #ifdef GDAL_COMPILATION
293 : /** Return an object that temporary unseals the OGRFieldDefn.
294 : *
295 : * The returned object calls Unseal() initially, and when it is destroyed
296 : * it calls Seal().
297 : *
298 : * This method should only be called by driver implementations.
299 : *
300 : * Usage: whileUnsealing(poFieldDefn)->some_method();
301 : *
302 : * @since GDAL 3.9
303 : */
304 98 : inline OGRFieldDefn::TemporaryUnsealer whileUnsealing(OGRFieldDefn *object)
305 : {
306 98 : return object->GetTemporaryUnsealer();
307 : }
308 : #endif
309 :
310 : /************************************************************************/
311 : /* OGRGeomFieldDefn */
312 : /************************************************************************/
313 :
314 : /**
315 : * Definition of a geometry field of an OGRFeatureDefn. A geometry field is
316 : * described by :
317 : * <ul>
318 : * <li>a name. See SetName() / GetNameRef()</li>
319 : * <li>a type: wkbPoint, wkbLineString, ... See SetType() / GetType()</li>
320 : * <li>a spatial reference system (optional). See SetSpatialRef() /
321 : * GetSpatialRef()</li> <li>a NOT NULL constraint (optional). See SetNullable()
322 : * / IsNullable()</li> <li>a boolean to indicate whether it should be ignored
323 : * when retrieving features. See SetIgnored() / IsIgnored()</li>
324 : * </ul>
325 : *
326 : * Note that once a OGRGeomFieldDefn has been added to a layer definition with
327 : * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
328 : * object returned with OGRLayer::GetLayerDefn()->GetGeomFieldDefn(). Instead,
329 : * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
330 : * OGRFieldDefn, for drivers that support AlterFieldDefn().
331 : *
332 : */
333 :
334 : class CPL_DLL OGRGeomFieldDefn
335 : {
336 : protected:
337 : //! @cond Doxygen_Suppress
338 : char *pszName = nullptr;
339 : OGRwkbGeometryType eGeomType =
340 : wkbUnknown; /* all values possible except wkbNone */
341 : mutable OGRSpatialReferenceRefCountedPtr poSRS = nullptr;
342 :
343 : int bIgnore = false;
344 : mutable int bNullable = true;
345 : bool m_bSealed = false;
346 : OGRGeomCoordinatePrecision m_oCoordPrecision{};
347 :
348 : void Initialize(const char *, OGRwkbGeometryType);
349 : //! @endcond
350 :
351 : public:
352 : OGRGeomFieldDefn(const char *pszNameIn, OGRwkbGeometryType eGeomTypeIn);
353 : explicit OGRGeomFieldDefn(const OGRGeomFieldDefn *);
354 : virtual ~OGRGeomFieldDefn();
355 :
356 : // Copy constructor
357 : OGRGeomFieldDefn(const OGRGeomFieldDefn &oOther);
358 :
359 : // Move constructor
360 : OGRGeomFieldDefn(OGRGeomFieldDefn &&oOther);
361 :
362 : // Copy assignment operator
363 : OGRGeomFieldDefn &operator=(const OGRGeomFieldDefn &oOther);
364 :
365 : // Move assignment operator
366 : OGRGeomFieldDefn &operator=(OGRGeomFieldDefn &&oOther);
367 :
368 : void SetName(const char *);
369 :
370 170046 : const char *GetNameRef() const
371 : {
372 170046 : return pszName;
373 : }
374 :
375 866085 : OGRwkbGeometryType GetType() const
376 : {
377 866085 : return eGeomType;
378 : }
379 :
380 : void SetType(OGRwkbGeometryType eTypeIn);
381 :
382 : virtual const OGRSpatialReference *GetSpatialRef() const;
383 : void SetSpatialRef(const OGRSpatialReference *poSRSIn);
384 : void SetSpatialRef(OGRSpatialReferenceRefCountedPtr poSRSIn);
385 :
386 200768 : int IsIgnored() const
387 : {
388 200768 : return bIgnore;
389 : }
390 :
391 11493 : void SetIgnored(int bIgnoreIn)
392 : {
393 11493 : bIgnore = bIgnoreIn;
394 11493 : }
395 :
396 14701 : int IsNullable() const
397 : {
398 14701 : return bNullable;
399 : }
400 :
401 : void SetNullable(int bNullableIn);
402 :
403 3924 : const OGRGeomCoordinatePrecision &GetCoordinatePrecision() const
404 : {
405 3924 : return m_oCoordPrecision;
406 : }
407 :
408 : void SetCoordinatePrecision(const OGRGeomCoordinatePrecision &prec);
409 :
410 : int IsSame(const OGRGeomFieldDefn *) const;
411 :
412 : /** Convert a OGRGeomFieldDefn* to a OGRGeomFieldDefnH.
413 : */
414 885 : static inline OGRGeomFieldDefnH ToHandle(OGRGeomFieldDefn *poGeomFieldDefn)
415 : {
416 885 : return reinterpret_cast<OGRGeomFieldDefnH>(poGeomFieldDefn);
417 : }
418 :
419 : /** Convert a OGRGeomFieldDefnH to a OGRGeomFieldDefn*.
420 : */
421 1255 : static inline OGRGeomFieldDefn *FromHandle(OGRGeomFieldDefnH hGeomFieldDefn)
422 : {
423 1255 : return reinterpret_cast<OGRGeomFieldDefn *>(hGeomFieldDefn);
424 : }
425 :
426 : void Seal();
427 :
428 : void Unseal();
429 :
430 : /*! @cond Doxygen_Suppress */
431 : struct CPL_DLL TemporaryUnsealer
432 : {
433 : private:
434 : OGRGeomFieldDefn *m_poFieldDefn = nullptr;
435 : CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
436 : public:
437 761 : explicit TemporaryUnsealer(OGRGeomFieldDefn *poFieldDefn)
438 761 : : m_poFieldDefn(poFieldDefn)
439 : {
440 761 : m_poFieldDefn->Unseal();
441 761 : }
442 :
443 : TemporaryUnsealer(TemporaryUnsealer &&) = default;
444 : TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
445 :
446 761 : ~TemporaryUnsealer()
447 761 : {
448 761 : m_poFieldDefn->Seal();
449 761 : }
450 :
451 729 : OGRGeomFieldDefn *operator->()
452 : {
453 729 : return m_poFieldDefn;
454 : }
455 : };
456 :
457 : /*! @endcond */
458 :
459 : TemporaryUnsealer GetTemporaryUnsealer();
460 :
461 : private:
462 19035 : OGRSpatialReferenceRefCountedPtr &GetRefCountedSRS() const
463 : {
464 19035 : GetSpatialRef();
465 19035 : return poSRS;
466 : }
467 : };
468 :
469 : #ifdef GDAL_COMPILATION
470 : /** Return an object that temporary unseals the OGRGeomFieldDefn.
471 : *
472 : * The returned object calls Unseal() initially, and when it is destroyed
473 : * it calls Seal().
474 : *
475 : * This method should only be called by driver implementations.
476 : *
477 : * Usage: whileUnsealing(poGeomFieldDefn)->some_method();
478 : *
479 : * @since GDAL 3.9
480 : */
481 : inline OGRGeomFieldDefn::TemporaryUnsealer
482 729 : whileUnsealing(OGRGeomFieldDefn *object)
483 : {
484 729 : return object->GetTemporaryUnsealer();
485 : }
486 : #endif
487 :
488 : /************************************************************************/
489 : /* OGRFeatureDefn */
490 : /************************************************************************/
491 :
492 : /**
493 : * Definition of a feature class or feature layer.
494 : *
495 : * This object contains schema information for a set of OGRFeatures. In
496 : * table based systems, an OGRFeatureDefn is essentially a layer. In more
497 : * object oriented approaches (such as SF CORBA) this can represent a class
498 : * of features but doesn't necessarily relate to all of a layer, or just one
499 : * layer.
500 : *
501 : * This object also can contain some other information such as a name and
502 : * potentially other metadata.
503 : *
504 : * It is essentially a collection of field descriptions (OGRFieldDefn class).
505 : * In addition to attribute fields, it can also
506 : * contain multiple geometry fields (OGRGeomFieldDefn class).
507 : *
508 : * It is reasonable for different translators to derive classes from
509 : * OGRFeatureDefn with additional translator specific information.
510 : *
511 : * Note that adding, modifying, removing, reordering a OGRFieldDefn (or a
512 : * OGRGeomFieldDefn) from/to a OGRFeatureDefn that belongs to a OGRLayer should
513 : * not be done through the OGRFeatureDefn::AddFieldDefn(),
514 : * OGRFeatureDefn::DeleteFieldDefn() or OGRFeatureDefn::ReorderFieldDefns()
515 : * methods, but rather through OGRLayer::CreateField(),
516 : * OGRLayer::AlterFieldDefn() or OGRLayer::ReorderFields(), for drivers that
517 : * support those operations.
518 : */
519 :
520 : class CPL_DLL OGRFeatureDefn
521 : {
522 : protected:
523 : //! @cond Doxygen_Suppress
524 : volatile int nRefCount = 0;
525 :
526 : mutable std::vector<std::unique_ptr<OGRFieldDefn>> apoFieldDefn{};
527 : mutable std::vector<std::unique_ptr<OGRGeomFieldDefn>> apoGeomFieldDefn{};
528 :
529 : char *pszFeatureClassName = nullptr;
530 :
531 : bool bIgnoreStyle = false;
532 :
533 : friend class TemporaryUnsealer;
534 : bool m_bSealed = false;
535 : int m_nTemporaryUnsealCount = 0;
536 : //! @endcond
537 :
538 : public:
539 : explicit OGRFeatureDefn(const char *pszName = nullptr);
540 : virtual ~OGRFeatureDefn();
541 :
542 : void SetName(const char *pszName);
543 : virtual const char *GetName() const;
544 :
545 : virtual int GetFieldCount() const;
546 : virtual OGRFieldDefn *GetFieldDefn(int i);
547 : virtual const OGRFieldDefn *GetFieldDefn(int i) const;
548 : virtual int GetFieldIndex(const char *) const;
549 : int GetFieldIndexCaseSensitive(const char *) const;
550 :
551 : //! @cond Doxygen_Suppress
552 : /** Helper class to iterate over non-geometry fields.
553 : *
554 : * Note: fields should not be added or removed while iterating over them.
555 : */
556 : template <class OwnerT, class ChildT> struct CPL_DLL Fields
557 : {
558 : private:
559 : OwnerT m_poFDefn;
560 :
561 : public:
562 362 : inline explicit Fields(OwnerT poFDefn) : m_poFDefn(poFDefn)
563 : {
564 362 : }
565 :
566 : struct CPL_DLL Iterator
567 : {
568 : private:
569 : OwnerT m_poFDefn;
570 : const int m_nFieldCount;
571 : int m_nIdx;
572 : ChildT m_curValue{};
573 :
574 : public:
575 718 : inline Iterator(OwnerT poFDefn, int nIdx)
576 : : m_poFDefn(poFDefn), m_nFieldCount(poFDefn->GetFieldCount()),
577 718 : m_nIdx(nIdx)
578 : {
579 718 : if (m_nIdx < m_nFieldCount)
580 292 : m_curValue = m_poFDefn->GetFieldDefn(m_nIdx);
581 718 : }
582 :
583 10 : inline const ChildT &operator*() const
584 : {
585 10 : return m_curValue;
586 : }
587 :
588 1346 : inline ChildT &operator*()
589 : {
590 1346 : return m_curValue;
591 : }
592 :
593 1355 : inline Iterator &operator++()
594 : {
595 1355 : m_nIdx++;
596 1355 : if (m_nIdx < m_nFieldCount)
597 1064 : m_curValue = m_poFDefn->GetFieldDefn(m_nIdx);
598 : else
599 291 : m_curValue = nullptr;
600 1355 : return *this;
601 : }
602 :
603 1714 : inline bool operator!=(const Iterator &it) const
604 : {
605 1714 : return m_nIdx != it.m_nIdx;
606 : }
607 : };
608 :
609 359 : inline Iterator begin() const
610 : {
611 359 : return Iterator(m_poFDefn, 0);
612 : }
613 :
614 359 : inline Iterator end() const
615 : {
616 359 : return Iterator(m_poFDefn, m_poFDefn->GetFieldCount());
617 : }
618 :
619 1 : inline size_t size() const
620 : {
621 1 : return static_cast<std::size_t>(m_poFDefn->GetFieldCount());
622 : }
623 :
624 2 : inline ChildT operator[](size_t i)
625 : {
626 2 : return m_poFDefn->GetFieldDefn(static_cast<int>(i));
627 : }
628 : };
629 :
630 : //! @endcond
631 :
632 : /** Return type of GetFields() */
633 : using NonConstFields = Fields<OGRFeatureDefn *, OGRFieldDefn *>;
634 :
635 : /** Return an object that can be used to iterate over non-geometry fields.
636 : \verbatim
637 : for( const auto* poFieldDefn: poFeatureDefn->GetFields() )
638 : {
639 : // do something
640 : }
641 : \endverbatim
642 :
643 : @since GDAL 3.7
644 : */
645 106 : inline NonConstFields GetFields()
646 : {
647 106 : return NonConstFields(this);
648 : }
649 :
650 : /** Return type of GetFields() const */
651 : using ConstFields = Fields<const OGRFeatureDefn *, const OGRFieldDefn *>;
652 :
653 : /** Return an object that can be used to iterate over non-geometry fields.
654 : \verbatim
655 : for( const auto* poFieldDefn: poFeatureDefn->GetFields() )
656 : {
657 : // do something
658 : }
659 : \endverbatim
660 :
661 : @since GDAL 3.12
662 : */
663 256 : inline ConstFields GetFields() const
664 : {
665 256 : return ConstFields(this);
666 : }
667 :
668 : //! @cond Doxygen_Suppress
669 : // That method should only be called if there's a guarantee that
670 : // GetFieldCount() has been called before
671 4177232 : int GetFieldCountUnsafe() const
672 : {
673 4177232 : return static_cast<int>(apoFieldDefn.size());
674 : }
675 :
676 : // Those methods don't check i is n range.
677 1491152 : OGRFieldDefn *GetFieldDefnUnsafe(int i)
678 : {
679 1491152 : if (apoFieldDefn.empty())
680 0 : GetFieldDefn(i);
681 1491152 : return apoFieldDefn[static_cast<std::size_t>(i)].get();
682 : }
683 :
684 15831900 : const OGRFieldDefn *GetFieldDefnUnsafe(int i) const
685 : {
686 15831900 : if (apoFieldDefn.empty())
687 0 : GetFieldDefn(i);
688 15831900 : return apoFieldDefn[static_cast<std::size_t>(i)].get();
689 : }
690 :
691 : //! @endcond
692 :
693 : virtual void AddFieldDefn(const OGRFieldDefn *);
694 : virtual OGRErr DeleteFieldDefn(int iField);
695 :
696 : /**
697 : * @brief StealFieldDefn takes ownership of the field definition at index detaching
698 : * it from the feature definition.
699 : * This is an advanced method designed to be only used for driver implementations.
700 : * @param iField index of the field definition to detach.
701 : * @return a unique pointer to the detached field definition or nullptr if the index is out of range.
702 : * @since GDAL 3.11
703 : */
704 : virtual std::unique_ptr<OGRFieldDefn> StealFieldDefn(int iField);
705 :
706 : virtual void AddFieldDefn(std::unique_ptr<OGRFieldDefn> &&poFieldDefn);
707 :
708 : virtual OGRErr ReorderFieldDefns(const int *panMap);
709 :
710 : /**
711 : * @brief StealGeomFieldDefn takes ownership of the geometry field definition at index
712 : * detaching it from the feature definition.
713 : * This is an advanced method designed to be only used for driver implementations.
714 : * @param iField index of the geometry field definition to detach.
715 : * @return a unique pointer to the detached geometry field definition or nullptr if the index is out of range.
716 : * @since GDAL 3.11
717 : */
718 : virtual std::unique_ptr<OGRGeomFieldDefn> StealGeomFieldDefn(int iField);
719 :
720 : virtual int GetGeomFieldCount() const;
721 : virtual OGRGeomFieldDefn *GetGeomFieldDefn(int i);
722 : virtual const OGRGeomFieldDefn *GetGeomFieldDefn(int i) const;
723 : virtual int GetGeomFieldIndex(const char *) const;
724 :
725 : //! @cond Doxygen_Suppress
726 : /** Helper class to iterate over geometry fields.
727 : *
728 : * Note: fields should not be added or removed while iterating over them.
729 : */
730 : template <class OwnerT, class ChildT> struct CPL_DLL GeomFields
731 : {
732 : private:
733 : OwnerT m_poFDefn;
734 :
735 : public:
736 16403 : inline explicit GeomFields(OwnerT poFDefn) : m_poFDefn(poFDefn)
737 : {
738 16403 : }
739 :
740 : struct CPL_DLL Iterator
741 : {
742 : private:
743 : OwnerT m_poFDefn;
744 : int m_nIdx;
745 :
746 : public:
747 32798 : inline Iterator(OwnerT poFDefn, int nIdx)
748 32798 : : m_poFDefn(poFDefn), m_nIdx(nIdx)
749 : {
750 32798 : }
751 :
752 16376 : inline ChildT operator*() const
753 : {
754 16376 : return m_poFDefn->GetGeomFieldDefn(m_nIdx);
755 : }
756 :
757 16370 : inline Iterator &operator++()
758 : {
759 16370 : m_nIdx++;
760 16370 : return *this;
761 : }
762 :
763 32769 : inline bool operator!=(const Iterator &it) const
764 : {
765 32769 : return m_nIdx != it.m_nIdx;
766 : }
767 : };
768 :
769 16399 : inline Iterator begin()
770 : {
771 16399 : return Iterator(m_poFDefn, 0);
772 : }
773 :
774 16399 : inline Iterator end()
775 : {
776 16399 : return Iterator(m_poFDefn, m_poFDefn->GetGeomFieldCount());
777 : }
778 :
779 1 : inline size_t size() const
780 : {
781 1 : return static_cast<std::size_t>(m_poFDefn->GetGeomFieldCount());
782 : }
783 :
784 3 : inline ChildT operator[](size_t i) const
785 : {
786 3 : return m_poFDefn->GetGeomFieldDefn(static_cast<int>(i));
787 : }
788 : };
789 :
790 : //! @endcond
791 :
792 : /** Return type of GetGeomFields() */
793 : using NonConstGeomFields = GeomFields<OGRFeatureDefn *, OGRGeomFieldDefn *>;
794 :
795 : /** Return an object that can be used to iterate over geometry fields.
796 : \verbatim
797 : for( const auto* poGeomFieldDefn: poFeatureDefn->GetGeomFields() )
798 : {
799 : // do something
800 : }
801 : \endverbatim
802 :
803 : @since GDAL 3.7
804 : */
805 10 : inline NonConstGeomFields GetGeomFields()
806 : {
807 10 : return NonConstGeomFields(this);
808 : }
809 :
810 : /** Return type of GetGeomFields() const */
811 : using ConstGeomFields =
812 : GeomFields<const OGRFeatureDefn *, const OGRGeomFieldDefn *>;
813 :
814 : /** Return an object that can be used to iterate over geometry fields.
815 : \verbatim
816 : for( const auto* poGeomFieldDefn: poFeatureDefn->GetGeomFields() )
817 : {
818 : // do something
819 : }
820 : \endverbatim
821 :
822 : @since GDAL 3.12
823 : */
824 16393 : inline ConstGeomFields GetGeomFields() const
825 : {
826 16393 : return ConstGeomFields(this);
827 : }
828 :
829 : virtual void AddGeomFieldDefn(const OGRGeomFieldDefn *);
830 : virtual void AddGeomFieldDefn(std::unique_ptr<OGRGeomFieldDefn> &&);
831 : virtual OGRErr DeleteGeomFieldDefn(int iGeomField);
832 :
833 : virtual OGRwkbGeometryType GetGeomType() const;
834 : virtual void SetGeomType(OGRwkbGeometryType);
835 :
836 : virtual OGRFeatureDefn *Clone() const;
837 :
838 : #ifdef DEPRECATE_OGRFEATUREDEFN_REF_COUNTING
839 0 : int Reference()
840 : CPL_WARN_DEPRECATED("Use OGRFeatureDefnRefCountedPtr instead")
841 : {
842 0 : return CPLAtomicInc(&nRefCount);
843 : }
844 :
845 : int Dereference()
846 : CPL_WARN_DEPRECATED("Use OGRFeatureDefnRefCountedPtr instead")
847 : {
848 : return CPLAtomicDec(&nRefCount);
849 : }
850 :
851 : int GetReferenceCount() const
852 : CPL_WARN_DEPRECATED("Use OGRFeatureDefnRefCountedPtr instead")
853 : {
854 : return nRefCount;
855 : }
856 :
857 : void Release()
858 : CPL_WARN_DEPRECATED("Use OGRFeatureDefnRefCountedPtr instead");
859 : #else
860 2360307 : int Reference()
861 : {
862 2360307 : return CPLAtomicInc(&nRefCount);
863 : }
864 :
865 2360140 : int Dereference()
866 : #if defined(GDAL_COMPILATION) && !defined(DOXYGEN_XML)
867 : CPL_WARN_DEPRECATED("Use Release() instead")
868 : #endif
869 : {
870 2360140 : return CPLAtomicDec(&nRefCount);
871 : }
872 :
873 16 : int GetReferenceCount() const
874 : {
875 16 : return nRefCount;
876 : }
877 :
878 : void Release();
879 : #endif
880 :
881 : virtual int IsGeometryIgnored() const;
882 : virtual void SetGeometryIgnored(int bIgnore);
883 :
884 13 : virtual bool IsStyleIgnored() const
885 : {
886 13 : return bIgnoreStyle;
887 : }
888 :
889 8616 : virtual void SetStyleIgnored(bool bIgnore)
890 : {
891 8616 : bIgnoreStyle = bIgnore;
892 8616 : }
893 :
894 : virtual int IsSame(const OGRFeatureDefn *poOtherFeatureDefn) const;
895 :
896 : //! @cond Doxygen_Suppress
897 : void ReserveSpaceForFields(int nFieldCountIn);
898 : //! @endcond
899 :
900 : std::vector<int> ComputeMapForSetFrom(const OGRFeatureDefn *poSrcFDefn,
901 : bool bForgiving = true) const;
902 :
903 : static OGRFeatureDefn *CreateFeatureDefn(const char *pszName = nullptr);
904 : static void DestroyFeatureDefn(OGRFeatureDefn *);
905 :
906 : /** Convert a OGRFeatureDefn* to a OGRFeatureDefnH.
907 : */
908 185170 : static inline OGRFeatureDefnH ToHandle(OGRFeatureDefn *poFeatureDefn)
909 : {
910 185170 : return reinterpret_cast<OGRFeatureDefnH>(poFeatureDefn);
911 : }
912 :
913 : /** Convert a OGRFeatureDefnH to a OGRFeatureDefn*.
914 : */
915 763105 : static inline OGRFeatureDefn *FromHandle(OGRFeatureDefnH hFeatureDefn)
916 : {
917 763105 : return reinterpret_cast<OGRFeatureDefn *>(hFeatureDefn);
918 : }
919 :
920 : void Seal(bool bSealFields);
921 :
922 : void Unseal(bool bUnsealFields);
923 :
924 : /*! @cond Doxygen_Suppress */
925 : struct CPL_DLL TemporaryUnsealer
926 : {
927 : private:
928 : OGRFeatureDefn *m_poFeatureDefn = nullptr;
929 : bool m_bSealFields = false;
930 : CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
931 : public:
932 : explicit TemporaryUnsealer(OGRFeatureDefn *poFeatureDefn,
933 : bool bSealFields);
934 :
935 : TemporaryUnsealer(TemporaryUnsealer &&) = default;
936 : TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
937 :
938 : ~TemporaryUnsealer();
939 :
940 28178 : OGRFeatureDefn *operator->()
941 : {
942 28178 : return m_poFeatureDefn;
943 : }
944 : };
945 :
946 : /*! @endcond */
947 :
948 : TemporaryUnsealer GetTemporaryUnsealer(bool bSealFields = true);
949 :
950 : private:
951 : CPL_DISALLOW_COPY_ASSIGN(OGRFeatureDefn)
952 : };
953 :
954 : /*! @cond Doxygen_Suppress */
955 :
956 : #include "ogr_refcountedptr.h"
957 :
958 : template <>
959 : struct OGRRefCountedPtr<OGRFeatureDefn>
960 : : public OGRRefCountedPtrBase<OGRFeatureDefn>
961 : {
962 : /** Constructs from a raw OGRFeatureDefn instance.
963 : */
964 27828 : inline explicit OGRRefCountedPtr(OGRFeatureDefn *poFDefn = nullptr,
965 : bool add_ref = true)
966 27828 : : OGRRefCountedPtrBase<OGRFeatureDefn>(poFDefn, add_ref)
967 : {
968 27828 : }
969 :
970 : /** Constructs with a null OGRFeatureDefn instance.
971 : */
972 22 : inline explicit OGRRefCountedPtr(std::nullptr_t)
973 22 : {
974 22 : }
975 :
976 : /** Constructs with a new OGRFeatureDefn instance with the provided name
977 : */
978 16002 : inline static OGRRefCountedPtr makeInstance(const char *pszName)
979 : {
980 : // Initial ref_count of OGRFeatureDefn is 0, so do add a ref
981 16002 : return OGRRefCountedPtr(new OGRFeatureDefn(pszName),
982 16002 : /* add_ref = */ true);
983 : }
984 : };
985 :
986 : /** Smart pointer around OGRFeatureDefn.
987 : *
988 : * It uses OGRFeatureDefn built-in reference counting, to increase the reference
989 : * count when assigning a raw pointer to the smart pointer, and decrease it
990 : * when releasing it.
991 : * Somewhat similar to https://www.boost.org/doc/libs/latest/libs/smart_ptr/doc/html/smart_ptr.html#intrusive_ptr
992 : */
993 : using OGRFeatureDefnRefCountedPtr = OGRRefCountedPtr<OGRFeatureDefn>;
994 :
995 : /*! @endcond */
996 :
997 : #ifdef GDAL_COMPILATION
998 : /** Return an object that temporary unseals the OGRFeatureDefn
999 : *
1000 : * The returned object calls Unseal() initially, and when it is destroyed
1001 : * it calls Seal().
1002 : * This method should be called on a OGRFeatureDefn that has been sealed
1003 : * previously.
1004 : * GetTemporaryUnsealer() calls may be nested, in which case only the first
1005 : * one has an effect (similarly to a recursive mutex locked in a nested way
1006 : * from the same thread).
1007 : *
1008 : * This method should only be called by driver implementations.
1009 : *
1010 : * Usage: whileUnsealing(poFeatureDefn)->some_method();
1011 : *
1012 : * @param bSealFields Whether fields and geometry fields should be unsealed and
1013 : * resealed.
1014 : * This is generally desirable, but in case of deferred
1015 : * resolution of them, this parameter should be set to false.
1016 : * @since GDAL 3.9
1017 : */
1018 9222 : inline OGRFeatureDefn::TemporaryUnsealer whileUnsealing(OGRFeatureDefn *object,
1019 : bool bSealFields = true)
1020 : {
1021 9222 : return object->GetTemporaryUnsealer(bSealFields);
1022 : }
1023 :
1024 : inline OGRFeatureDefn::TemporaryUnsealer
1025 18956 : whileUnsealing(OGRFeatureDefnRefCountedPtr &object, bool bSealFields = true)
1026 : {
1027 18956 : return object->GetTemporaryUnsealer(bSealFields);
1028 : }
1029 :
1030 : #endif
1031 :
1032 : /************************************************************************/
1033 : /* OGRFeature */
1034 : /************************************************************************/
1035 :
1036 : /**
1037 : * A simple feature, including geometry and attributes.
1038 : */
1039 :
1040 : class CPL_DLL OGRFeature
1041 : {
1042 : private:
1043 : GIntBig nFID;
1044 : const OGRFeatureDefn *poDefn;
1045 : OGRGeometry **papoGeometries;
1046 : OGRField *pauFields;
1047 : char *m_pszNativeData;
1048 : char *m_pszNativeMediaType;
1049 :
1050 : bool SetFieldInternal(int i, const OGRField *puValue);
1051 :
1052 : protected:
1053 : //! @cond Doxygen_Suppress
1054 : mutable char *m_pszStyleString;
1055 : mutable OGRStyleTable *m_poStyleTable;
1056 : mutable char *m_pszTmpFieldValue;
1057 : //! @endcond
1058 :
1059 : bool CopySelfTo(OGRFeature *poNew) const;
1060 :
1061 : public:
1062 : explicit OGRFeature(const OGRFeatureDefn *);
1063 : virtual ~OGRFeature();
1064 :
1065 : /** Field value. */
1066 51 : class CPL_DLL FieldValue
1067 : {
1068 : friend class OGRFeature;
1069 : struct Private;
1070 : std::unique_ptr<Private> m_poPrivate;
1071 :
1072 : FieldValue(OGRFeature *poFeature, int iFieldIndex);
1073 : FieldValue(const OGRFeature *poFeature, int iFieldIndex);
1074 : FieldValue(const FieldValue &oOther) = delete;
1075 : FieldValue &Assign(const FieldValue &oOther);
1076 :
1077 : public:
1078 : //! @cond Doxygen_Suppress
1079 : ~FieldValue();
1080 :
1081 : FieldValue &operator=(FieldValue &&oOther);
1082 : //! @endcond
1083 :
1084 : /** Set a field value from another one. */
1085 : FieldValue &operator=(const FieldValue &oOther);
1086 : /** Set an integer value to the field. */
1087 : FieldValue &operator=(int nVal);
1088 : /** Set an integer value to the field. */
1089 : FieldValue &operator=(GIntBig nVal);
1090 : /** Set a real value to the field. */
1091 : FieldValue &operator=(double dfVal);
1092 : /** Set a string value to the field. */
1093 : FieldValue &operator=(const char *pszVal);
1094 : /** Set a string value to the field. */
1095 : FieldValue &operator=(const std::string &osVal);
1096 : /** Set an array of integer to the field. */
1097 : FieldValue &operator=(const std::vector<int> &oArray);
1098 : /** Set an array of big integer to the field. */
1099 : FieldValue &operator=(const std::vector<GIntBig> &oArray);
1100 : /** Set an array of double to the field. */
1101 : FieldValue &operator=(const std::vector<double> &oArray);
1102 : /** Set an array of strings to the field. */
1103 : FieldValue &operator=(const std::vector<std::string> &oArray);
1104 : /** Set an array of strings to the field. */
1105 : FieldValue &operator=(CSLConstList papszValues);
1106 : /** Set a null value to the field. */
1107 : void SetNull();
1108 : /** Unset the field. */
1109 : void clear();
1110 :
1111 : /** Unset the field. */
1112 2 : void Unset()
1113 : {
1114 2 : clear();
1115 2 : }
1116 :
1117 : /** Set date time value/ */
1118 : void SetDateTime(int nYear, int nMonth, int nDay, int nHour = 0,
1119 : int nMinute = 0, float fSecond = 0.f, int nTZFlag = 0);
1120 :
1121 : /** Return field index. */
1122 : int GetIndex() const;
1123 : /** Return field definition. */
1124 : const OGRFieldDefn *GetDefn() const;
1125 :
1126 : /** Return field name. */
1127 11 : const char *GetName() const
1128 : {
1129 11 : return GetDefn()->GetNameRef();
1130 : }
1131 :
1132 : /** Return field type. */
1133 23 : OGRFieldType GetType() const
1134 : {
1135 23 : return GetDefn()->GetType();
1136 : }
1137 :
1138 : /** Return field subtype. */
1139 11 : OGRFieldSubType GetSubType() const
1140 : {
1141 11 : return GetDefn()->GetSubType();
1142 : }
1143 :
1144 : /** Return whether the field value is unset/empty. */
1145 : // cppcheck-suppress functionStatic
1146 1 : bool empty() const
1147 : {
1148 1 : return IsUnset();
1149 : }
1150 :
1151 : /** Return whether the field value is unset/empty. */
1152 : // cppcheck-suppress functionStatic
1153 : bool IsUnset() const;
1154 :
1155 : /** Return whether the field value is null. */
1156 : // cppcheck-suppress functionStatic
1157 : bool IsNull() const;
1158 :
1159 : /** Return the raw field value */
1160 : const OGRField *GetRawValue() const;
1161 :
1162 : /** Return the integer value.
1163 : * Only use that method if and only if GetType() == OFTInteger.
1164 : */
1165 : // cppcheck-suppress functionStatic
1166 3 : int GetInteger() const
1167 : {
1168 3 : return GetRawValue()->Integer;
1169 : }
1170 :
1171 : /** Return the 64-bit integer value.
1172 : * Only use that method if and only if GetType() == OFTInteger64.
1173 : */
1174 : // cppcheck-suppress functionStatic
1175 3 : GIntBig GetInteger64() const
1176 : {
1177 3 : return GetRawValue()->Integer64;
1178 : }
1179 :
1180 : /** Return the double value.
1181 : * Only use that method if and only if GetType() == OFTReal.
1182 : */
1183 : // cppcheck-suppress functionStatic
1184 2 : double GetDouble() const
1185 : {
1186 2 : return GetRawValue()->Real;
1187 : }
1188 :
1189 : /** Return the string value.
1190 : * Only use that method if and only if GetType() == OFTString.
1191 : */
1192 : // cppcheck-suppress functionStatic
1193 6 : const char *GetString() const
1194 : {
1195 6 : return GetRawValue()->String;
1196 : }
1197 :
1198 : /** Return the date/time/datetime value. */
1199 : bool GetDateTime(int *pnYear, int *pnMonth, int *pnDay, int *pnHour,
1200 : int *pnMinute, float *pfSecond, int *pnTZFlag) const;
1201 :
1202 : /** Return the field value as integer, with potential conversion */
1203 2 : operator int() const
1204 : {
1205 2 : return GetAsInteger();
1206 : }
1207 :
1208 : /** Return the field value as 64-bit integer, with potential conversion
1209 : */
1210 1 : operator GIntBig() const
1211 : {
1212 1 : return GetAsInteger64();
1213 : }
1214 :
1215 : /** Return the field value as double, with potential conversion */
1216 1 : operator double() const
1217 : {
1218 1 : return GetAsDouble();
1219 : }
1220 :
1221 : /** Return the field value as string, with potential conversion */
1222 1 : operator const char *() const
1223 : {
1224 1 : return GetAsString();
1225 : }
1226 :
1227 : /** Return the field value as integer list, with potential conversion */
1228 1 : operator const std::vector<int> &() const
1229 : {
1230 1 : return GetAsIntegerList();
1231 : }
1232 :
1233 : /** Return the field value as 64-bit integer list, with potential
1234 : * conversion */
1235 1 : operator const std::vector<GIntBig> &() const
1236 : {
1237 1 : return GetAsInteger64List();
1238 : }
1239 :
1240 : /** Return the field value as double list, with potential conversion */
1241 1 : operator const std::vector<double> &() const
1242 : {
1243 1 : return GetAsDoubleList();
1244 : }
1245 :
1246 : /** Return the field value as string list, with potential conversion */
1247 1 : operator const std::vector<std::string> &() const
1248 : {
1249 1 : return GetAsStringList();
1250 : }
1251 :
1252 : /** Return the field value as string list, with potential conversion */
1253 : operator CSLConstList() const;
1254 :
1255 : /** Return the field value as integer, with potential conversion */
1256 : int GetAsInteger() const;
1257 : /** Return the field value as 64-bit integer, with potential conversion
1258 : */
1259 : GIntBig GetAsInteger64() const;
1260 : /** Return the field value as double, with potential conversion */
1261 : double GetAsDouble() const;
1262 : /** Return the field value as string, with potential conversion */
1263 : const char *GetAsString() const;
1264 : /** Return the field value as integer list, with potential conversion */
1265 : const std::vector<int> &GetAsIntegerList() const;
1266 : /** Return the field value as 64-bit integer list, with potential
1267 : * conversion */
1268 : const std::vector<GIntBig> &GetAsInteger64List() const;
1269 : /** Return the field value as double list, with potential conversion */
1270 : const std::vector<double> &GetAsDoubleList() const;
1271 : /** Return the field value as string list, with potential conversion */
1272 : const std::vector<std::string> &GetAsStringList() const;
1273 : };
1274 :
1275 : /** Field value iterator class. */
1276 4 : class CPL_DLL ConstFieldIterator
1277 : {
1278 : friend class OGRFeature;
1279 : struct Private;
1280 : std::unique_ptr<Private> m_poPrivate;
1281 :
1282 : ConstFieldIterator(const OGRFeature *poSelf, int nPos);
1283 :
1284 : public:
1285 : //! @cond Doxygen_Suppress
1286 : ConstFieldIterator(
1287 : ConstFieldIterator &&oOther) noexcept; // declared but not defined.
1288 : // Needed for gcc 5.4 at least
1289 : ~ConstFieldIterator();
1290 : const FieldValue &operator*() const;
1291 : ConstFieldIterator &operator++();
1292 : bool operator!=(const ConstFieldIterator &it) const;
1293 : //! @endcond
1294 : };
1295 :
1296 : /** Return begin of field value iterator.
1297 : *
1298 : * Using this iterator for standard range-based loops is safe, but
1299 : * due to implementation limitations, you shouldn't try to access
1300 : * (dereference) more than one iterator step at a time, since you will get
1301 : * a reference to the same object (FieldValue) at each iteration step.
1302 : *
1303 : * \code{.cpp}
1304 : * for( auto&& oField: poFeature )
1305 : * {
1306 : * std::cout << oField.GetIndex() << "," << oField.GetName()<< ": " <<
1307 : * oField.GetAsString() << std::endl;
1308 : * }
1309 : * \endcode
1310 : *
1311 : */
1312 : ConstFieldIterator begin() const;
1313 : /** Return end of field value iterator. */
1314 : ConstFieldIterator end() const;
1315 :
1316 : const FieldValue operator[](int iField) const;
1317 : FieldValue operator[](int iField);
1318 :
1319 : #if defined(__clang__)
1320 : #pragma clang diagnostic push
1321 : #pragma clang diagnostic ignored "-Wweak-vtables"
1322 : #endif
1323 :
1324 : /** Exception raised by operator[](const char*) when a field is not found.
1325 : */
1326 : class FieldNotFoundException final : public std::exception
1327 : {
1328 : };
1329 :
1330 : #if defined(__clang__)
1331 : #pragma clang diagnostic pop
1332 : #endif
1333 :
1334 : const FieldValue operator[](const char *pszFieldName) const;
1335 : FieldValue operator[](const char *pszFieldName);
1336 :
1337 1197912 : const OGRFeatureDefn *GetDefnRef() const
1338 : {
1339 1197912 : return poDefn;
1340 : }
1341 :
1342 : //! @cond Doxygen_Suppress
1343 : void SetFDefnUnsafe(OGRFeatureDefn *poNewFDefn);
1344 : //! @endcond
1345 :
1346 : OGRErr SetGeometryDirectly(OGRGeometry *);
1347 : OGRErr SetGeometry(const OGRGeometry *);
1348 : OGRErr SetGeometry(std::unique_ptr<OGRGeometry>);
1349 : OGRGeometry *GetGeometryRef();
1350 : const OGRGeometry *GetGeometryRef() const;
1351 : OGRGeometry *StealGeometry() CPL_WARN_UNUSED_RESULT;
1352 :
1353 7609980 : int GetGeomFieldCount() const
1354 : {
1355 7609980 : return poDefn->GetGeomFieldCount();
1356 : }
1357 :
1358 9714 : const OGRGeomFieldDefn *GetGeomFieldDefnRef(int iField) const
1359 : {
1360 9714 : return poDefn->GetGeomFieldDefn(iField);
1361 : }
1362 :
1363 9427 : int GetGeomFieldIndex(const char *pszName) const
1364 : {
1365 9427 : return poDefn->GetGeomFieldIndex(pszName);
1366 : }
1367 :
1368 : OGRGeometry *GetGeomFieldRef(int iField);
1369 : const OGRGeometry *GetGeomFieldRef(int iField) const;
1370 : OGRGeometry *StealGeometry(int iField);
1371 : OGRGeometry *GetGeomFieldRef(const char *pszFName);
1372 : const OGRGeometry *GetGeomFieldRef(const char *pszFName) const;
1373 : OGRErr SetGeomFieldDirectly(int iField, OGRGeometry *);
1374 : OGRErr SetGeomField(int iField, const OGRGeometry *);
1375 : OGRErr SetGeomField(int iField, std::unique_ptr<OGRGeometry>);
1376 :
1377 : void Reset();
1378 :
1379 : OGRFeature *Clone() const CPL_WARN_UNUSED_RESULT;
1380 : virtual bool Equal(const OGRFeature *poFeature) const;
1381 :
1382 : static bool IsSameFieldValue(const OGRFeature *poFeature1, int nIdxField1,
1383 : const OGRFeature *poFeature2, int nIdxField2);
1384 :
1385 550976 : int GetFieldCount() const
1386 : {
1387 550976 : return poDefn->GetFieldCount();
1388 : }
1389 :
1390 682417 : const OGRFieldDefn *GetFieldDefnRef(int iField) const
1391 : {
1392 682417 : return poDefn->GetFieldDefn(iField);
1393 : }
1394 :
1395 2641224 : int GetFieldIndex(const char *pszName) const
1396 : {
1397 2641224 : return poDefn->GetFieldIndex(pszName);
1398 : }
1399 :
1400 : int IsFieldSet(int iField) const;
1401 :
1402 : void UnsetField(int iField);
1403 :
1404 : bool IsFieldNull(int iField) const;
1405 :
1406 : void SetFieldNull(int iField);
1407 :
1408 : bool IsFieldSetAndNotNull(int iField) const;
1409 :
1410 425504 : OGRField *GetRawFieldRef(int i)
1411 : {
1412 425504 : return pauFields + i;
1413 : }
1414 :
1415 53803 : const OGRField *GetRawFieldRef(int i) const
1416 : {
1417 53803 : return pauFields + i;
1418 : }
1419 :
1420 : int GetFieldAsInteger(int i) const;
1421 : GIntBig GetFieldAsInteger64(int i) const;
1422 : double GetFieldAsDouble(int i) const;
1423 : const char *GetFieldAsString(int i) const;
1424 : const char *GetFieldAsISO8601DateTime(int i,
1425 : CSLConstList papszOptions) const;
1426 : const int *GetFieldAsIntegerList(int i, int *pnCount) const;
1427 : const GIntBig *GetFieldAsInteger64List(int i, int *pnCount) const;
1428 : const double *GetFieldAsDoubleList(int i, int *pnCount) const;
1429 : char **GetFieldAsStringList(int i) const;
1430 : GByte *GetFieldAsBinary(int i, int *pnCount) const;
1431 : int GetFieldAsDateTime(int i, int *pnYear, int *pnMonth, int *pnDay,
1432 : int *pnHour, int *pnMinute, int *pnSecond,
1433 : int *pnTZFlag) const;
1434 : int GetFieldAsDateTime(int i, int *pnYear, int *pnMonth, int *pnDay,
1435 : int *pnHour, int *pnMinute, float *pfSecond,
1436 : int *pnTZFlag) const;
1437 : char *GetFieldAsSerializedJSon(int i) const;
1438 :
1439 : //! @cond Doxygen_Suppress
1440 31253149 : bool IsFieldSetUnsafe(int i) const
1441 : {
1442 40123167 : return !(pauFields[i].Set.nMarker1 == OGRUnsetMarker &&
1443 8870088 : pauFields[i].Set.nMarker2 == OGRUnsetMarker &&
1444 40123167 : pauFields[i].Set.nMarker3 == OGRUnsetMarker);
1445 : }
1446 :
1447 13435731 : bool IsFieldNullUnsafe(int i) const
1448 : {
1449 13496747 : return (pauFields[i].Set.nMarker1 == OGRNullMarker &&
1450 13496747 : pauFields[i].Set.nMarker2 == OGRNullMarker &&
1451 13496747 : pauFields[i].Set.nMarker3 == OGRNullMarker);
1452 : }
1453 :
1454 17730449 : bool IsFieldSetAndNotNullUnsafe(int i) const
1455 : {
1456 17730449 : return IsFieldSetUnsafe(i) && !IsFieldNullUnsafe(i);
1457 : }
1458 :
1459 : // Those methods should only be called on a field that is of the type
1460 : // consistent with the value, and that is set.
1461 51824 : int GetFieldAsIntegerUnsafe(int i) const
1462 : {
1463 51824 : return pauFields[i].Integer;
1464 : }
1465 :
1466 16742 : GIntBig GetFieldAsInteger64Unsafe(int i) const
1467 : {
1468 16742 : return pauFields[i].Integer64;
1469 : }
1470 :
1471 38862 : double GetFieldAsDoubleUnsafe(int i) const
1472 : {
1473 38862 : return pauFields[i].Real;
1474 : }
1475 :
1476 4469150 : const char *GetFieldAsStringUnsafe(int i) const
1477 : {
1478 4469150 : return pauFields[i].String;
1479 : }
1480 :
1481 : //! @endcond
1482 :
1483 30860 : int GetFieldAsInteger(const char *pszFName) const
1484 : {
1485 30860 : return GetFieldAsInteger(GetFieldIndex(pszFName));
1486 : }
1487 :
1488 6937 : GIntBig GetFieldAsInteger64(const char *pszFName) const
1489 : {
1490 6937 : return GetFieldAsInteger64(GetFieldIndex(pszFName));
1491 : }
1492 :
1493 358 : double GetFieldAsDouble(const char *pszFName) const
1494 : {
1495 358 : return GetFieldAsDouble(GetFieldIndex(pszFName));
1496 : }
1497 :
1498 28042 : const char *GetFieldAsString(const char *pszFName) const
1499 : {
1500 28042 : return GetFieldAsString(GetFieldIndex(pszFName));
1501 : }
1502 :
1503 : const char *GetFieldAsISO8601DateTime(const char *pszFName,
1504 : CSLConstList papszOptions) const
1505 : {
1506 : return GetFieldAsISO8601DateTime(GetFieldIndex(pszFName), papszOptions);
1507 : }
1508 :
1509 120 : const int *GetFieldAsIntegerList(const char *pszFName, int *pnCount) const
1510 : {
1511 120 : return GetFieldAsIntegerList(GetFieldIndex(pszFName), pnCount);
1512 : }
1513 :
1514 : const GIntBig *GetFieldAsInteger64List(const char *pszFName,
1515 : int *pnCount) const
1516 : {
1517 : return GetFieldAsInteger64List(GetFieldIndex(pszFName), pnCount);
1518 : }
1519 :
1520 21 : const double *GetFieldAsDoubleList(const char *pszFName, int *pnCount) const
1521 : {
1522 21 : return GetFieldAsDoubleList(GetFieldIndex(pszFName), pnCount);
1523 : }
1524 :
1525 491 : char **GetFieldAsStringList(const char *pszFName) const
1526 : {
1527 491 : return GetFieldAsStringList(GetFieldIndex(pszFName));
1528 : }
1529 :
1530 : void SetField(int i, int nValue);
1531 : void SetField(int i, GIntBig nValue);
1532 : void SetField(int i, double dfValue);
1533 : void SetField(int i, const char *pszValue);
1534 : #if defined(DOXYGEN_SKIP) || __cplusplus >= 201703L || \
1535 : (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
1536 : void SetField(int i, std::string_view svValue);
1537 :
1538 : //! @cond Doxygen_Suppress
1539 2253 : inline void SetField(int i, const std::string &osValue)
1540 : {
1541 2253 : SetField(i, osValue.c_str());
1542 2253 : }
1543 :
1544 : //! @endcond
1545 : #endif
1546 : void SetField(int i, int nCount, const int *panValues);
1547 : void SetField(int i, int nCount, const GIntBig *panValues);
1548 : void SetField(int i, int nCount, const double *padfValues);
1549 : void SetField(int i, const char *const *papszValues);
1550 : void SetField(int i, const OGRField *puValue);
1551 : void SetField(int i, int nCount, const void *pabyBinary);
1552 : void SetField(int i, int nYear, int nMonth, int nDay, int nHour = 0,
1553 : int nMinute = 0, float fSecond = 0.f, int nTZFlag = 0);
1554 :
1555 : //! @cond Doxygen_Suppress
1556 : // Those methods should only be called on a field that is of the type
1557 : // consistent with the value, and in a unset state.
1558 55119 : void SetFieldSameTypeUnsafe(int i, int nValue)
1559 : {
1560 55119 : pauFields[i].Integer = nValue;
1561 55119 : pauFields[i].Set.nMarker2 = 0;
1562 55119 : pauFields[i].Set.nMarker3 = 0;
1563 55119 : }
1564 :
1565 13653 : void SetFieldSameTypeUnsafe(int i, GIntBig nValue)
1566 : {
1567 13653 : pauFields[i].Integer64 = nValue;
1568 13653 : }
1569 :
1570 19491 : void SetFieldSameTypeUnsafe(int i, double dfValue)
1571 : {
1572 19491 : pauFields[i].Real = dfValue;
1573 19491 : }
1574 :
1575 1431952 : void SetFieldSameTypeUnsafe(int i, char *pszValueTransferred)
1576 : {
1577 1431952 : pauFields[i].String = pszValueTransferred;
1578 1431952 : }
1579 :
1580 : //! @endcond
1581 :
1582 956115 : void SetField(const char *pszFName, int nValue)
1583 : {
1584 956115 : SetField(GetFieldIndex(pszFName), nValue);
1585 956115 : }
1586 :
1587 1288 : void SetField(const char *pszFName, GIntBig nValue)
1588 : {
1589 1288 : SetField(GetFieldIndex(pszFName), nValue);
1590 1288 : }
1591 :
1592 4892 : void SetField(const char *pszFName, double dfValue)
1593 : {
1594 4892 : SetField(GetFieldIndex(pszFName), dfValue);
1595 4892 : }
1596 :
1597 1536532 : void SetField(const char *pszFName, const char *pszValue)
1598 : {
1599 1536532 : SetField(GetFieldIndex(pszFName), pszValue);
1600 1536532 : }
1601 :
1602 1065 : void SetField(const char *pszFName, int nCount, const int *panValues)
1603 : {
1604 1065 : SetField(GetFieldIndex(pszFName), nCount, panValues);
1605 1065 : }
1606 :
1607 1 : void SetField(const char *pszFName, int nCount, const GIntBig *panValues)
1608 : {
1609 1 : SetField(GetFieldIndex(pszFName), nCount, panValues);
1610 1 : }
1611 :
1612 45 : void SetField(const char *pszFName, int nCount, const double *padfValues)
1613 : {
1614 45 : SetField(GetFieldIndex(pszFName), nCount, padfValues);
1615 45 : }
1616 :
1617 1081 : void SetField(const char *pszFName, const char *const *papszValues)
1618 : {
1619 1081 : SetField(GetFieldIndex(pszFName), papszValues);
1620 1081 : }
1621 :
1622 86 : void SetField(const char *pszFName, const OGRField *puValue)
1623 : {
1624 86 : SetField(GetFieldIndex(pszFName), puValue);
1625 86 : }
1626 :
1627 3 : void SetField(const char *pszFName, int nYear, int nMonth, int nDay,
1628 : int nHour = 0, int nMinute = 0, float fSecond = 0.f,
1629 : int nTZFlag = 0)
1630 : {
1631 3 : SetField(GetFieldIndex(pszFName), nYear, nMonth, nDay, nHour, nMinute,
1632 : fSecond, nTZFlag);
1633 3 : }
1634 :
1635 3730488 : GIntBig GetFID() const
1636 : {
1637 3730488 : return nFID;
1638 : }
1639 :
1640 : virtual OGRErr SetFID(GIntBig nFIDIn);
1641 :
1642 : void DumpReadable(FILE *, CSLConstList papszOptions = nullptr) const;
1643 : std::string DumpReadableAsString(CSLConstList papszOptions = nullptr) const;
1644 :
1645 : OGRErr SetFrom(const OGRFeature *, int bForgiving = TRUE);
1646 : OGRErr SetFrom(const OGRFeature *, const int *panMap, int bForgiving = TRUE,
1647 : bool bUseISO8601ForDateTimeAsString = false);
1648 : OGRErr SetFieldsFrom(const OGRFeature *, const int *panMap,
1649 : int bForgiving = TRUE,
1650 : bool bUseISO8601ForDateTimeAsString = false);
1651 :
1652 : //! @cond Doxygen_Suppress
1653 : OGRErr RemapFields(const OGRFeatureDefn *poNewDefn,
1654 : const int *panRemapSource);
1655 : void AppendField();
1656 : OGRErr RemapGeomFields(const OGRFeatureDefn *poNewDefn,
1657 : const int *panRemapSource);
1658 : //! @endcond
1659 :
1660 : int Validate(int nValidateFlags, int bEmitError) const;
1661 : void FillUnsetWithDefault(int bNotNullableOnly, CSLConstList papszOptions);
1662 :
1663 : bool SerializeToBinary(std::vector<GByte> &abyBuffer) const;
1664 : bool DeserializeFromBinary(const GByte *pabyBuffer, size_t nSize);
1665 :
1666 : virtual const char *GetStyleString() const;
1667 : virtual void SetStyleString(const char *);
1668 : virtual void SetStyleStringDirectly(char *);
1669 :
1670 : /** Return style table.
1671 : * @return style table.
1672 : */
1673 199 : virtual OGRStyleTable *GetStyleTable() const
1674 : {
1675 199 : return m_poStyleTable;
1676 : } /* f.i.x.m.e: add a const qualifier for return type */
1677 :
1678 : virtual void SetStyleTable(OGRStyleTable *poStyleTable);
1679 : virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable);
1680 :
1681 15654 : const char *GetNativeData() const
1682 : {
1683 15654 : return m_pszNativeData;
1684 : }
1685 :
1686 18813 : const char *GetNativeMediaType() const
1687 : {
1688 18813 : return m_pszNativeMediaType;
1689 : }
1690 :
1691 : void SetNativeData(const char *pszNativeData);
1692 : void SetNativeMediaType(const char *pszNativeMediaType);
1693 :
1694 : static OGRFeature *CreateFeature(const OGRFeatureDefn *);
1695 : static void DestroyFeature(OGRFeature *);
1696 :
1697 : /** Convert a OGRFeature* to a OGRFeatureH.
1698 : */
1699 228845 : static inline OGRFeatureH ToHandle(OGRFeature *poFeature)
1700 : {
1701 228845 : return reinterpret_cast<OGRFeatureH>(poFeature);
1702 : }
1703 :
1704 : /** Convert a OGRFeatureH to a OGRFeature*.
1705 : */
1706 1816512 : static inline OGRFeature *FromHandle(OGRFeatureH hFeature)
1707 : {
1708 1816512 : return reinterpret_cast<OGRFeature *>(hFeature);
1709 : }
1710 :
1711 : private:
1712 : CPL_DISALLOW_COPY_ASSIGN(OGRFeature)
1713 : };
1714 :
1715 : //! @cond Doxygen_Suppress
1716 : struct CPL_DLL OGRFeatureUniquePtrDeleter
1717 : {
1718 : void operator()(OGRFeature *) const;
1719 : };
1720 :
1721 : //! @endcond
1722 :
1723 : /** Unique pointer type for OGRFeature.
1724 : */
1725 : typedef std::unique_ptr<OGRFeature, OGRFeatureUniquePtrDeleter>
1726 : OGRFeatureUniquePtr;
1727 :
1728 : //! @cond Doxygen_Suppress
1729 : /** @see OGRFeature::begin() const */
1730 : inline OGRFeature::ConstFieldIterator begin(const OGRFeature *poFeature)
1731 : {
1732 : return poFeature->begin();
1733 : }
1734 :
1735 : /** @see OGRFeature::end() const */
1736 : inline OGRFeature::ConstFieldIterator end(const OGRFeature *poFeature)
1737 : {
1738 : return poFeature->end();
1739 : }
1740 :
1741 : /** @see OGRFeature::begin() const */
1742 : inline OGRFeature::ConstFieldIterator
1743 : begin(const OGRFeatureUniquePtr &poFeature)
1744 : {
1745 : return poFeature->begin();
1746 : }
1747 :
1748 : /** @see OGRFeature::end() const */
1749 : inline OGRFeature::ConstFieldIterator end(const OGRFeatureUniquePtr &poFeature)
1750 : {
1751 : return poFeature->end();
1752 : }
1753 :
1754 : //! @endcond
1755 :
1756 : /************************************************************************/
1757 : /* OGRFieldDomain */
1758 : /************************************************************************/
1759 :
1760 : /* clang-format off */
1761 : /**
1762 : * Definition of a field domain.
1763 : *
1764 : * A field domain is a set of constraints that apply to one or several fields.
1765 : *
1766 : * This is a concept found in
1767 : * <a href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/geodatabases/an-overview-of-attribute-domains.htm">File
1768 : * Geodatabase</a> or GeoPackage (using the <a href="http://www.geopackage.org/spec/#extension_schema">schema extension</a>)
1769 : * for example.
1770 : *
1771 : * A field domain can be:
1772 : * <ul>
1773 : * <li>OGRCodedFieldDomain: an enumerated list of (code, value) tuples.</li>
1774 : * <li>OGRRangeFieldDomain: a range constraint (min, max).</li>
1775 : * <li>OGRGlobFieldDomain: a glob expression.</li>
1776 : * </ul>
1777 : *
1778 : * @since GDAL 3.3
1779 : */
1780 : /* clang-format on */
1781 :
1782 1382 : class CPL_DLL OGRFieldDomain
1783 : {
1784 : protected:
1785 : /*! @cond Doxygen_Suppress */
1786 : std::string m_osName;
1787 : std::string m_osDescription;
1788 : OGRFieldDomainType m_eDomainType;
1789 : OGRFieldType m_eFieldType;
1790 : OGRFieldSubType m_eFieldSubType;
1791 : OGRFieldDomainSplitPolicy m_eSplitPolicy = OFDSP_DEFAULT_VALUE;
1792 : OGRFieldDomainMergePolicy m_eMergePolicy = OFDMP_DEFAULT_VALUE;
1793 :
1794 : OGRFieldDomain(const std::string &osName, const std::string &osDescription,
1795 : OGRFieldDomainType eDomainType, OGRFieldType eFieldType,
1796 : OGRFieldSubType eFieldSubType);
1797 : /*! @endcond */
1798 :
1799 : public:
1800 : /** Destructor.
1801 : *
1802 : * This is the same as the C function OGR_FldDomain_Destroy().
1803 : */
1804 : virtual ~OGRFieldDomain();
1805 :
1806 : /** Clone.
1807 : *
1808 : * Return a cloned object, or nullptr in case of error.
1809 : */
1810 : virtual OGRFieldDomain *Clone() const = 0;
1811 :
1812 : /** Get the name of the field domain.
1813 : *
1814 : * This is the same as the C function OGR_FldDomain_GetName().
1815 : */
1816 1353 : const std::string &GetName() const
1817 : {
1818 1353 : return m_osName;
1819 : }
1820 :
1821 : /** Get the description of the field domain.
1822 : * Empty string if there is none.
1823 : *
1824 : * This is the same as the C function OGR_FldDomain_GetDescription().
1825 : */
1826 109 : const std::string &GetDescription() const
1827 : {
1828 109 : return m_osDescription;
1829 : }
1830 :
1831 : /** Get the type of the field domain.
1832 : *
1833 : * This is the same as the C function OGR_FldDomain_GetDomainType().
1834 : */
1835 231 : OGRFieldDomainType GetDomainType() const
1836 : {
1837 231 : return m_eDomainType;
1838 : }
1839 :
1840 : /** Get the field type.
1841 : *
1842 : * This is the same as the C function OGR_FldDomain_GetFieldType().
1843 : */
1844 205 : OGRFieldType GetFieldType() const
1845 : {
1846 205 : return m_eFieldType;
1847 : }
1848 :
1849 : /** Get the field subtype.
1850 : *
1851 : * This is the same as the C function OGR_FldDomain_GetFieldSubType().
1852 : */
1853 101 : OGRFieldSubType GetFieldSubType() const
1854 : {
1855 101 : return m_eFieldSubType;
1856 : }
1857 :
1858 : /** Convert a OGRFieldDomain* to a OGRFieldDomainH. */
1859 226 : static inline OGRFieldDomainH ToHandle(OGRFieldDomain *poFieldDomain)
1860 : {
1861 226 : return reinterpret_cast<OGRFieldDomainH>(poFieldDomain);
1862 : }
1863 :
1864 : /** Convert a OGRFieldDomainH to a OGRFieldDomain*. */
1865 554 : static inline OGRFieldDomain *FromHandle(OGRFieldDomainH hFieldDomain)
1866 : {
1867 554 : return reinterpret_cast<OGRFieldDomain *>(hFieldDomain);
1868 : }
1869 :
1870 : /** Get the split policy.
1871 : *
1872 : * This is the same as the C function OGR_FldDomain_GetSplitPolicy().
1873 : */
1874 32 : OGRFieldDomainSplitPolicy GetSplitPolicy() const
1875 : {
1876 32 : return m_eSplitPolicy;
1877 : }
1878 :
1879 : /** Set the split policy.
1880 : *
1881 : * This is the same as the C function OGR_FldDomain_SetSplitPolicy().
1882 : */
1883 1196 : void SetSplitPolicy(OGRFieldDomainSplitPolicy policy)
1884 : {
1885 1196 : m_eSplitPolicy = policy;
1886 1196 : }
1887 :
1888 : /** Get the merge policy.
1889 : *
1890 : * This is the same as the C function OGR_FldDomain_GetMergePolicy().
1891 : */
1892 32 : OGRFieldDomainMergePolicy GetMergePolicy() const
1893 : {
1894 32 : return m_eMergePolicy;
1895 : }
1896 :
1897 : /** Set the merge policy.
1898 : *
1899 : * This is the same as the C function OGR_FldDomain_SetMergePolicy().
1900 : */
1901 1196 : void SetMergePolicy(OGRFieldDomainMergePolicy policy)
1902 : {
1903 1196 : m_eMergePolicy = policy;
1904 1196 : }
1905 : };
1906 :
1907 : /** Definition of a coded / enumerated field domain.
1908 : *
1909 : * A code field domain is a domain for which only a limited set of codes,
1910 : * associated with their expanded value, are allowed.
1911 : * The type of the code should be the one of the field domain.
1912 : */
1913 : class CPL_DLL OGRCodedFieldDomain final : public OGRFieldDomain
1914 : {
1915 : private:
1916 : std::vector<OGRCodedValue> m_asValues{};
1917 :
1918 : OGRCodedFieldDomain(const OGRCodedFieldDomain &) = delete;
1919 : OGRCodedFieldDomain &operator=(const OGRCodedFieldDomain &) = delete;
1920 :
1921 : public:
1922 : /** Constructor.
1923 : *
1924 : * This is the same as the C function OGR_CodedFldDomain_Create()
1925 : * (except that the C function copies the enumeration, whereas the C++
1926 : * method moves it)
1927 : *
1928 : * @param osName Domain name.
1929 : * @param osDescription Domain description.
1930 : * @param eFieldType Field type. Generally numeric. Potentially
1931 : * OFTDateTime
1932 : * @param eFieldSubType Field subtype.
1933 : * @param asValues Enumeration as (code, value) pairs.
1934 : * Each code should appear only once, but it is the
1935 : * responsibility of the user to check it.
1936 : */
1937 : OGRCodedFieldDomain(const std::string &osName,
1938 : const std::string &osDescription,
1939 : OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
1940 : std::vector<OGRCodedValue> &&asValues);
1941 :
1942 : ~OGRCodedFieldDomain() override;
1943 :
1944 : OGRCodedFieldDomain *Clone() const override;
1945 :
1946 : /** Get the enumeration as (code, value) pairs.
1947 : * The end of the enumeration is signaled by code == NULL.
1948 : *
1949 : * This is the same as the C function OGR_CodedFldDomain_GetEnumeration().
1950 : */
1951 173 : const OGRCodedValue *GetEnumeration() const
1952 : {
1953 173 : return m_asValues.data();
1954 : }
1955 : };
1956 :
1957 : /** Definition of a numeric field domain with a range of validity for values.
1958 : */
1959 : class CPL_DLL OGRRangeFieldDomain final : public OGRFieldDomain
1960 : {
1961 : private:
1962 : OGRField m_sMin;
1963 : OGRField m_sMax;
1964 : bool m_bMinIsInclusive;
1965 : bool m_bMaxIsInclusive;
1966 :
1967 : OGRRangeFieldDomain(const OGRRangeFieldDomain &) = delete;
1968 : OGRRangeFieldDomain &operator=(const OGRRangeFieldDomain &) = delete;
1969 :
1970 : public:
1971 : /** Constructor.
1972 : *
1973 : * This is the same as the C function OGR_RangeFldDomain_Create().
1974 : *
1975 : * @param osName Domain name.
1976 : * @param osDescription Domain description.
1977 : * @param eFieldType Field type.
1978 : * One among OFTInteger, OFTInteger64, OFTReal or
1979 : * OFTDateTime
1980 : * @param eFieldSubType Field subtype.
1981 : * @param sMin Minimum value.
1982 : * Which member in the OGRField enum must be read
1983 : * depends on the field type.
1984 : * If no minimum is set (might not be supported by
1985 : * all backends), then initialize the value with
1986 : * OGR_RawField_SetUnset().
1987 : * @param bMinIsInclusive Whether the minimum value is included in the
1988 : * range.
1989 : * @param sMax Minimum value.
1990 : * Which member in the OGRField enum must be read
1991 : * depends on the field type.
1992 : * If no maximum is set (might not be supported by
1993 : * all backends), then initialize the value with
1994 : * OGR_RawField_SetUnset().
1995 : * @param bMaxIsInclusive Whether the minimum value is included in the
1996 : * range.
1997 : */
1998 : OGRRangeFieldDomain(const std::string &osName,
1999 : const std::string &osDescription,
2000 : OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
2001 : const OGRField &sMin, bool bMinIsInclusive,
2002 : const OGRField &sMax, bool bMaxIsInclusive);
2003 :
2004 : OGRRangeFieldDomain *Clone() const override;
2005 :
2006 : /** Get the minimum value.
2007 : *
2008 : * Which member in the returned OGRField enum must be read depends on the
2009 : * field type.
2010 : *
2011 : * If no minimum value is set, the OGR_RawField_IsUnset() will return true
2012 : * when called on the result.
2013 : *
2014 : * This is the same as the C function OGR_RangeFldDomain_GetMin().
2015 : *
2016 : * @param bIsInclusiveOut set to true if the minimum is included in the
2017 : * range.
2018 : */
2019 52 : const OGRField &GetMin(bool &bIsInclusiveOut) const
2020 : {
2021 52 : bIsInclusiveOut = m_bMinIsInclusive;
2022 52 : return m_sMin;
2023 : }
2024 :
2025 : /** Get the maximum value.
2026 : *
2027 : * Which member in the returned OGRField enum must be read depends on the
2028 : * field type.
2029 : *
2030 : * If no maximum value is set, the OGR_RawField_IsUnset() will return true
2031 : * when called on the result.
2032 : *
2033 : * This is the same as the C function OGR_RangeFldDomain_GetMax().
2034 : *
2035 : * @param bIsInclusiveOut set to true if the maximum is included in the
2036 : * range.
2037 : */
2038 52 : const OGRField &GetMax(bool &bIsInclusiveOut) const
2039 : {
2040 52 : bIsInclusiveOut = m_bMaxIsInclusive;
2041 52 : return m_sMax;
2042 : }
2043 : };
2044 :
2045 : /** Definition of a field domain for field content validated by a glob.
2046 : *
2047 : * Globs are matching expression like "*[a-z][0-1]?"
2048 : */
2049 : class CPL_DLL OGRGlobFieldDomain final : public OGRFieldDomain
2050 : {
2051 : private:
2052 : std::string m_osGlob;
2053 :
2054 : OGRGlobFieldDomain(const OGRGlobFieldDomain &) = delete;
2055 : OGRGlobFieldDomain &operator=(const OGRGlobFieldDomain &) = delete;
2056 :
2057 : public:
2058 : /** Constructor.
2059 : *
2060 : * This is the same as the C function OGR_GlobFldDomain_Create().
2061 : *
2062 : * @param osName Domain name.
2063 : * @param osDescription Domain description.
2064 : * @param eFieldType Field type.
2065 : * @param eFieldSubType Field subtype.
2066 : * @param osBlob Blob expression
2067 : */
2068 : OGRGlobFieldDomain(const std::string &osName,
2069 : const std::string &osDescription,
2070 : OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
2071 : const std::string &osBlob);
2072 :
2073 : OGRGlobFieldDomain *Clone() const override;
2074 :
2075 : /** Get the glob expression.
2076 : *
2077 : * This is the same as the C function OGR_GlobFldDomain_GetGlob().
2078 : */
2079 13 : const std::string &GetGlob() const
2080 : {
2081 13 : return m_osGlob;
2082 : }
2083 : };
2084 :
2085 : /************************************************************************/
2086 : /* OGRFeatureQuery */
2087 : /************************************************************************/
2088 :
2089 : //! @cond Doxygen_Suppress
2090 : class OGRLayer;
2091 : class swq_expr_node;
2092 : class swq_custom_func_registrar;
2093 : struct swq_evaluation_context;
2094 :
2095 : class CPL_DLL OGRFeatureQuery
2096 : {
2097 : private:
2098 : const OGRFeatureDefn *poTargetDefn;
2099 : void *pSWQExpr;
2100 : swq_evaluation_context *m_psContext = nullptr;
2101 :
2102 : char **FieldCollector(void *, char **);
2103 :
2104 : static GIntBig *EvaluateAgainstIndices(const swq_expr_node *, OGRLayer *,
2105 : GIntBig &nFIDCount);
2106 :
2107 : static int CanUseIndex(const swq_expr_node *, OGRLayer *);
2108 :
2109 : OGRErr Compile(const OGRLayer *, const OGRFeatureDefn *, const char *,
2110 : int bCheck,
2111 : swq_custom_func_registrar *poCustomFuncRegistrar);
2112 :
2113 : CPL_DISALLOW_COPY_ASSIGN(OGRFeatureQuery)
2114 :
2115 : public:
2116 : OGRFeatureQuery();
2117 : ~OGRFeatureQuery();
2118 :
2119 : OGRErr Compile(const OGRLayer *, const char *, int bCheck = TRUE,
2120 : swq_custom_func_registrar *poCustomFuncRegistrar = nullptr);
2121 : OGRErr Compile(const OGRFeatureDefn *, const char *, int bCheck = TRUE,
2122 : swq_custom_func_registrar *poCustomFuncRegistrar = nullptr);
2123 : int Evaluate(const OGRFeature *);
2124 :
2125 : GIntBig *EvaluateAgainstIndices(OGRLayer *, OGRErr *);
2126 :
2127 : int CanUseIndex(OGRLayer *);
2128 :
2129 : char **GetUsedFields();
2130 :
2131 3445 : void *GetSWQExpr()
2132 : {
2133 3445 : return pSWQExpr;
2134 : }
2135 : };
2136 :
2137 : //! @endcond
2138 :
2139 : #endif /* ndef OGR_FEATURE_H_INCLUDED */
|