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