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