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