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