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