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