DYT/Tool/OpenSceneGraph-3.6.5/include/ogr_feature.h
2024-12-25 07:49:36 +08:00

1982 lines
57 KiB
C++

/******************************************************************************
* $Id$
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: Class for representing a whole feature, and layer schemas.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
* Copyright (c) 1999, Les Technologies SoftMap Inc.
* Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/
#ifndef OGR_FEATURE_H_INCLUDED
#define OGR_FEATURE_H_INCLUDED
#include "cpl_atomic_ops.h"
#include "ogr_featurestyle.h"
#include "ogr_geometry.h"
#include "ogr_geomcoordinateprecision.h"
#include <cstddef>
#include <exception>
#include <memory>
#include <string>
#include <vector>
/**
* \file ogr_feature.h
*
* Simple feature classes.
*/
#ifndef DEFINE_OGRFeatureH
/*! @cond Doxygen_Suppress */
#define DEFINE_OGRFeatureH
/*! @endcond */
#ifdef DEBUG
typedef struct OGRFieldDefnHS *OGRFieldDefnH;
typedef struct OGRFeatureDefnHS *OGRFeatureDefnH;
typedef struct OGRFeatureHS *OGRFeatureH;
typedef struct OGRStyleTableHS *OGRStyleTableH;
#else
/** Opaque type for a field definition (OGRFieldDefn) */
typedef void *OGRFieldDefnH;
/** Opaque type for a feature definition (OGRFeatureDefn) */
typedef void *OGRFeatureDefnH;
/** Opaque type for a feature (OGRFeature) */
typedef void *OGRFeatureH;
/** Opaque type for a style table (OGRStyleTable) */
typedef void *OGRStyleTableH;
#endif
/** Opaque type for a geometry field definition (OGRGeomFieldDefn) */
typedef struct OGRGeomFieldDefnHS *OGRGeomFieldDefnH;
/** Opaque type for a field domain definition (OGRFieldDomain) */
typedef struct OGRFieldDomainHS *OGRFieldDomainH;
#endif /* DEFINE_OGRFeatureH */
class OGRStyleTable;
/************************************************************************/
/* OGRFieldDefn */
/************************************************************************/
/**
* Definition of an attribute of an OGRFeatureDefn. A field is described by :
* <ul>
* <li>a name. See SetName() / GetNameRef()</li>
* <li>an alternative name (optional): alternative descriptive name for the
* field (sometimes referred to as an "alias"). See SetAlternativeName() /
* GetAlternativeNameRef()</li> <li>a type: OFTString, OFTInteger, OFTReal, ...
* See SetType() / GetType()</li> <li>a subtype (optional): OFSTBoolean, ... See
* SetSubType() / GetSubType()</li> <li>a width (optional): maximal number of
* characters. See SetWidth() / GetWidth()</li> <li>a precision (optional):
* number of digits after decimal point. See SetPrecision() /
* GetPrecision()</li> <li>a NOT NULL constraint (optional). See SetNullable() /
* IsNullable()</li> <li>a UNIQUE constraint (optional). See SetUnique() /
* IsUnique()</li> <li>a default value (optional). See SetDefault() /
* GetDefault()</li> <li>a boolean to indicate whether it should be ignored when
* retrieving features. See SetIgnored() / IsIgnored()</li> <li>a field domain
* name (optional). See SetDomainName() / Get DomainName()</li>
* </ul>
*
* Note that once a OGRFieldDefn has been added to a layer definition with
* OGRLayer::AddFieldDefn(), its setter methods should not be called on the
* object returned with OGRLayer::GetLayerDefn()->GetFieldDefn(). Instead,
* OGRLayer::AlterFieldDefn() should be called on a new instance of
* OGRFieldDefn, for drivers that support AlterFieldDefn().
*/
class CPL_DLL OGRFieldDefn
{
private:
char *pszName;
char *pszAlternativeName;
OGRFieldType eType;
OGRJustification eJustify;
int nWidth; // Zero is variable.
int nPrecision;
char *pszDefault;
int bIgnore;
OGRFieldSubType eSubType;
int bNullable;
int bUnique;
std::string m_osDomainName{}; // field domain name. Might be empty
std::string m_osComment{}; // field comment. Might be empty
int m_nTZFlag = OGR_TZFLAG_UNKNOWN;
bool m_bSealed = false;
public:
OGRFieldDefn(const char *, OGRFieldType);
explicit OGRFieldDefn(const OGRFieldDefn *);
~OGRFieldDefn();
void SetName(const char *);
const char *GetNameRef() const
{
return pszName;
}
void SetAlternativeName(const char *);
const char *GetAlternativeNameRef() const
{
return pszAlternativeName;
}
OGRFieldType GetType() const
{
return eType;
}
void SetType(OGRFieldType eTypeIn);
static const char *GetFieldTypeName(OGRFieldType);
OGRFieldSubType GetSubType() const
{
return eSubType;
}
void SetSubType(OGRFieldSubType eSubTypeIn);
static const char *GetFieldSubTypeName(OGRFieldSubType);
OGRJustification GetJustify() const
{
return eJustify;
}
void SetJustify(OGRJustification eJustifyIn)
{
eJustify = eJustifyIn;
}
int GetWidth() const
{
return nWidth;
}
void SetWidth(int nWidthIn);
int GetPrecision() const
{
return nPrecision;
}
void SetPrecision(int nPrecisionIn);
int GetTZFlag() const
{
return m_nTZFlag;
}
void SetTZFlag(int nTZFlag);
void Set(const char *, OGRFieldType, int = 0, int = 0,
OGRJustification = OJUndefined);
void SetDefault(const char *);
const char *GetDefault() const;
int IsDefaultDriverSpecific() const;
int IsIgnored() const
{
return bIgnore;
}
void SetIgnored(int bIgnoreIn)
{
bIgnore = bIgnoreIn;
}
int IsNullable() const
{
return bNullable;
}
void SetNullable(int bNullableIn);
int IsUnique() const
{
return bUnique;
}
void SetUnique(int bUniqueIn);
const std::string &GetDomainName() const
{
return m_osDomainName;
}
void SetDomainName(const std::string &osDomainName);
const std::string &GetComment() const
{
return m_osComment;
}
void SetComment(const std::string &osComment);
int IsSame(const OGRFieldDefn *) const;
/** Convert a OGRFieldDefn* to a OGRFieldDefnH.
* @since GDAL 2.3
*/
static inline OGRFieldDefnH ToHandle(OGRFieldDefn *poFieldDefn)
{
return reinterpret_cast<OGRFieldDefnH>(poFieldDefn);
}
/** Convert a OGRFieldDefnH to a OGRFieldDefn*.
* @since GDAL 2.3
*/
static inline OGRFieldDefn *FromHandle(OGRFieldDefnH hFieldDefn)
{
return reinterpret_cast<OGRFieldDefn *>(hFieldDefn);
}
void Seal();
void Unseal();
/*! @cond Doxygen_Suppress */
struct CPL_DLL TemporaryUnsealer
{
private:
OGRFieldDefn *m_poFieldDefn = nullptr;
CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
public:
explicit TemporaryUnsealer(OGRFieldDefn *poFieldDefn)
: m_poFieldDefn(poFieldDefn)
{
m_poFieldDefn->Unseal();
}
TemporaryUnsealer(TemporaryUnsealer &&) = default;
TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
~TemporaryUnsealer()
{
m_poFieldDefn->Seal();
}
OGRFieldDefn *operator->()
{
return m_poFieldDefn;
}
};
/*! @endcond */
TemporaryUnsealer GetTemporaryUnsealer();
private:
CPL_DISALLOW_COPY_ASSIGN(OGRFieldDefn)
};
#ifdef GDAL_COMPILATION
/** Return an object that temporary unseals the OGRFieldDefn.
*
* The returned object calls Unseal() initially, and when it is destroyed
* it calls Seal().
*
* This method should only be called by driver implementations.
*
* Usage: whileUnsealing(poFieldDefn)->some_method();
*
* @since GDAL 3.9
*/
inline OGRFieldDefn::TemporaryUnsealer whileUnsealing(OGRFieldDefn *object)
{
return object->GetTemporaryUnsealer();
}
#endif
/************************************************************************/
/* OGRGeomFieldDefn */
/************************************************************************/
/**
* Definition of a geometry field of an OGRFeatureDefn. A geometry field is
* described by :
* <ul>
* <li>a name. See SetName() / GetNameRef()</li>
* <li>a type: wkbPoint, wkbLineString, ... See SetType() / GetType()</li>
* <li>a spatial reference system (optional). See SetSpatialRef() /
* GetSpatialRef()</li> <li>a NOT NULL constraint (optional). See SetNullable()
* / IsNullable()</li> <li>a boolean to indicate whether it should be ignored
* when retrieving features. See SetIgnored() / IsIgnored()</li>
* </ul>
*
* Note that once a OGRGeomFieldDefn has been added to a layer definition with
* OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
* object returned with OGRLayer::GetLayerDefn()->GetGeomFieldDefn(). Instead,
* OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
* OGRFieldDefn, for drivers that support AlterFieldDefn().
*
* @since OGR 1.11
*/
class CPL_DLL OGRGeomFieldDefn
{
protected:
//! @cond Doxygen_Suppress
char *pszName = nullptr;
OGRwkbGeometryType eGeomType =
wkbUnknown; /* all values possible except wkbNone */
mutable const OGRSpatialReference *poSRS = nullptr;
int bIgnore = false;
mutable int bNullable = true;
bool m_bSealed = false;
OGRGeomCoordinatePrecision m_oCoordPrecision{};
void Initialize(const char *, OGRwkbGeometryType);
//! @endcond
public:
OGRGeomFieldDefn(const char *pszNameIn, OGRwkbGeometryType eGeomTypeIn);
explicit OGRGeomFieldDefn(const OGRGeomFieldDefn *);
virtual ~OGRGeomFieldDefn();
void SetName(const char *);
const char *GetNameRef() const
{
return pszName;
}
OGRwkbGeometryType GetType() const
{
return eGeomType;
}
void SetType(OGRwkbGeometryType eTypeIn);
virtual const OGRSpatialReference *GetSpatialRef() const;
void SetSpatialRef(const OGRSpatialReference *poSRSIn);
int IsIgnored() const
{
return bIgnore;
}
void SetIgnored(int bIgnoreIn)
{
bIgnore = bIgnoreIn;
}
int IsNullable() const
{
return bNullable;
}
void SetNullable(int bNullableIn);
const OGRGeomCoordinatePrecision &GetCoordinatePrecision() const
{
return m_oCoordPrecision;
}
void SetCoordinatePrecision(const OGRGeomCoordinatePrecision &prec);
int IsSame(const OGRGeomFieldDefn *) const;
/** Convert a OGRGeomFieldDefn* to a OGRGeomFieldDefnH.
* @since GDAL 2.3
*/
static inline OGRGeomFieldDefnH ToHandle(OGRGeomFieldDefn *poGeomFieldDefn)
{
return reinterpret_cast<OGRGeomFieldDefnH>(poGeomFieldDefn);
}
/** Convert a OGRGeomFieldDefnH to a OGRGeomFieldDefn*.
* @since GDAL 2.3
*/
static inline OGRGeomFieldDefn *FromHandle(OGRGeomFieldDefnH hGeomFieldDefn)
{
return reinterpret_cast<OGRGeomFieldDefn *>(hGeomFieldDefn);
}
void Seal();
void Unseal();
/*! @cond Doxygen_Suppress */
struct CPL_DLL TemporaryUnsealer
{
private:
OGRGeomFieldDefn *m_poFieldDefn = nullptr;
CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
public:
explicit TemporaryUnsealer(OGRGeomFieldDefn *poFieldDefn)
: m_poFieldDefn(poFieldDefn)
{
m_poFieldDefn->Unseal();
}
TemporaryUnsealer(TemporaryUnsealer &&) = default;
TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
~TemporaryUnsealer()
{
m_poFieldDefn->Seal();
}
OGRGeomFieldDefn *operator->()
{
return m_poFieldDefn;
}
};
/*! @endcond */
TemporaryUnsealer GetTemporaryUnsealer();
private:
CPL_DISALLOW_COPY_ASSIGN(OGRGeomFieldDefn)
};
#ifdef GDAL_COMPILATION
/** Return an object that temporary unseals the OGRGeomFieldDefn.
*
* The returned object calls Unseal() initially, and when it is destroyed
* it calls Seal().
*
* This method should only be called by driver implementations.
*
* Usage: whileUnsealing(poGeomFieldDefn)->some_method();
*
* @since GDAL 3.9
*/
inline OGRGeomFieldDefn::TemporaryUnsealer
whileUnsealing(OGRGeomFieldDefn *object)
{
return object->GetTemporaryUnsealer();
}
#endif
/************************************************************************/
/* OGRFeatureDefn */
/************************************************************************/
/**
* Definition of a feature class or feature layer.
*
* This object contains schema information for a set of OGRFeatures. In
* table based systems, an OGRFeatureDefn is essentially a layer. In more
* object oriented approaches (such as SF CORBA) this can represent a class
* of features but doesn't necessarily relate to all of a layer, or just one
* layer.
*
* This object also can contain some other information such as a name and
* potentially other metadata.
*
* It is essentially a collection of field descriptions (OGRFieldDefn class).
* Starting with GDAL 1.11, in addition to attribute fields, it can also
* contain multiple geometry fields (OGRGeomFieldDefn class).
*
* It is reasonable for different translators to derive classes from
* OGRFeatureDefn with additional translator specific information.
*
* Note that adding, modifying, removing, reordering a OGRFieldDefn (or a
* OGRGeomFieldDefn) from/to a OGRFeatureDefn that belongs to a OGRLayer should
* not be done through the OGRFeatureDefn::AddFieldDefn(),
* OGRFeatureDefn::DeleteFieldDefn() or OGRFeatureDefn::ReorderFieldDefns()
* methods, but rather through OGRLayer::CreateField(),
* OGRLayer::AlterFieldDefn() or OGRLayer::ReorderFields(), for drivers that
* support those operations.
*/
class CPL_DLL OGRFeatureDefn
{
protected:
//! @cond Doxygen_Suppress
volatile int nRefCount = 0;
mutable std::vector<std::unique_ptr<OGRFieldDefn>> apoFieldDefn{};
mutable std::vector<std::unique_ptr<OGRGeomFieldDefn>> apoGeomFieldDefn{};
char *pszFeatureClassName = nullptr;
bool bIgnoreStyle = false;
friend class TemporaryUnsealer;
bool m_bSealed = false;
int m_nTemporaryUnsealCount = 0;
//! @endcond
public:
explicit OGRFeatureDefn(const char *pszName = nullptr);
virtual ~OGRFeatureDefn();
void SetName(const char *pszName);
virtual const char *GetName() const;
virtual int GetFieldCount() const;
virtual OGRFieldDefn *GetFieldDefn(int i);
virtual const OGRFieldDefn *GetFieldDefn(int i) const;
virtual int GetFieldIndex(const char *) const;
int GetFieldIndexCaseSensitive(const char *) const;
//! @cond Doxygen_Suppress
/** Helper class to iterate over non-geometry fields.
*
* Note: fields should not be added or removed while iterating over them.
*/
struct CPL_DLL Fields
{
private:
OGRFeatureDefn *m_poFDefn;
public:
inline explicit Fields(OGRFeatureDefn *poFDefn) : m_poFDefn(poFDefn)
{
}
struct CPL_DLL ConstIterator
{
private:
OGRFeatureDefn *m_poFDefn;
int m_nIdx;
public:
inline ConstIterator(OGRFeatureDefn *poFDefn, int nIdx)
: m_poFDefn(poFDefn), m_nIdx(nIdx)
{
}
inline const OGRFieldDefn *operator*() const
{
return m_poFDefn->GetFieldDefn(m_nIdx);
}
inline ConstIterator &operator++()
{
m_nIdx++;
return *this;
}
inline bool operator!=(const ConstIterator &it) const
{
return m_nIdx != it.m_nIdx;
}
};
inline ConstIterator begin()
{
return ConstIterator(m_poFDefn, 0);
}
inline ConstIterator end()
{
return ConstIterator(m_poFDefn, m_poFDefn->GetFieldCount());
}
inline size_t size() const
{
return static_cast<std::size_t>(m_poFDefn->GetFieldCount());
}
inline OGRFieldDefn *operator[](size_t i)
{
return m_poFDefn->GetFieldDefn(static_cast<int>(i));
}
inline const OGRFieldDefn *operator[](size_t i) const
{
return m_poFDefn->GetFieldDefn(static_cast<int>(i));
}
};
//! @endcond
/** Return an object that can be used to iterate over non-geometry fields.
\verbatim
for( const auto* poFieldDefn: poFeatureDefn->GetFields() )
{
// do something
}
\endverbatim
@since GDAL 3.7
*/
inline Fields GetFields()
{
return Fields(this);
}
//! @cond Doxygen_Suppress
// That method should only be called if there's a guarantee that
// GetFieldCount() has been called before
int GetFieldCountUnsafe() const
{
return static_cast<int>(apoFieldDefn.size());
}
// Those methods don't check i is n range.
OGRFieldDefn *GetFieldDefnUnsafe(int i)
{
if (apoFieldDefn.empty())
GetFieldDefn(i);
return apoFieldDefn[static_cast<std::size_t>(i)].get();
}
const OGRFieldDefn *GetFieldDefnUnsafe(int i) const
{
if (apoFieldDefn.empty())
GetFieldDefn(i);
return apoFieldDefn[static_cast<std::size_t>(i)].get();
}
//! @endcond
virtual void AddFieldDefn(const OGRFieldDefn *);
virtual OGRErr DeleteFieldDefn(int iField);
virtual OGRErr ReorderFieldDefns(const int *panMap);
virtual int GetGeomFieldCount() const;
virtual OGRGeomFieldDefn *GetGeomFieldDefn(int i);
virtual const OGRGeomFieldDefn *GetGeomFieldDefn(int i) const;
virtual int GetGeomFieldIndex(const char *) const;
//! @cond Doxygen_Suppress
/** Helper class to iterate over geometry fields.
*
* Note: fields should not be added or removed while iterating over them.
*/
struct CPL_DLL GeomFields
{
private:
OGRFeatureDefn *m_poFDefn;
public:
inline explicit GeomFields(OGRFeatureDefn *poFDefn) : m_poFDefn(poFDefn)
{
}
struct CPL_DLL ConstIterator
{
private:
OGRFeatureDefn *m_poFDefn;
int m_nIdx;
public:
inline ConstIterator(OGRFeatureDefn *poFDefn, int nIdx)
: m_poFDefn(poFDefn), m_nIdx(nIdx)
{
}
inline const OGRGeomFieldDefn *operator*() const
{
return m_poFDefn->GetGeomFieldDefn(m_nIdx);
}
inline ConstIterator &operator++()
{
m_nIdx++;
return *this;
}
inline bool operator!=(const ConstIterator &it) const
{
return m_nIdx != it.m_nIdx;
}
};
inline ConstIterator begin()
{
return ConstIterator(m_poFDefn, 0);
}
inline ConstIterator end()
{
return ConstIterator(m_poFDefn, m_poFDefn->GetGeomFieldCount());
}
inline size_t size() const
{
return static_cast<std::size_t>(m_poFDefn->GetGeomFieldCount());
}
inline OGRGeomFieldDefn *operator[](size_t i)
{
return m_poFDefn->GetGeomFieldDefn(static_cast<int>(i));
}
inline const OGRGeomFieldDefn *operator[](size_t i) const
{
return m_poFDefn->GetGeomFieldDefn(static_cast<int>(i));
}
};
//! @endcond
/** Return an object that can be used to iterate over geometry fields.
\verbatim
for( const auto* poGeomFieldDefn: poFeatureDefn->GetGeomFields() )
{
// do something
}
\endverbatim
@since GDAL 3.7
*/
inline GeomFields GetGeomFields()
{
return GeomFields(this);
}
virtual void AddGeomFieldDefn(const OGRGeomFieldDefn *);
virtual void AddGeomFieldDefn(std::unique_ptr<OGRGeomFieldDefn> &&);
virtual OGRErr DeleteGeomFieldDefn(int iGeomField);
virtual OGRwkbGeometryType GetGeomType() const;
virtual void SetGeomType(OGRwkbGeometryType);
virtual OGRFeatureDefn *Clone() const;
int Reference()
{
return CPLAtomicInc(&nRefCount);
}
int Dereference()
{
return CPLAtomicDec(&nRefCount);
}
int GetReferenceCount() const
{
return nRefCount;
}
void Release();
virtual int IsGeometryIgnored() const;
virtual void SetGeometryIgnored(int bIgnore);
virtual bool IsStyleIgnored() const
{
return bIgnoreStyle;
}
virtual void SetStyleIgnored(bool bIgnore)
{
bIgnoreStyle = bIgnore;
}
virtual int IsSame(const OGRFeatureDefn *poOtherFeatureDefn) const;
//! @cond Doxygen_Suppress
void ReserveSpaceForFields(int nFieldCountIn);
//! @endcond
std::vector<int> ComputeMapForSetFrom(const OGRFeatureDefn *poSrcFDefn,
bool bForgiving = true) const;
static OGRFeatureDefn *CreateFeatureDefn(const char *pszName = nullptr);
static void DestroyFeatureDefn(OGRFeatureDefn *);
/** Convert a OGRFeatureDefn* to a OGRFeatureDefnH.
* @since GDAL 2.3
*/
static inline OGRFeatureDefnH ToHandle(OGRFeatureDefn *poFeatureDefn)
{
return reinterpret_cast<OGRFeatureDefnH>(poFeatureDefn);
}
/** Convert a OGRFeatureDefnH to a OGRFeatureDefn*.
* @since GDAL 2.3
*/
static inline OGRFeatureDefn *FromHandle(OGRFeatureDefnH hFeatureDefn)
{
return reinterpret_cast<OGRFeatureDefn *>(hFeatureDefn);
}
void Seal(bool bSealFields);
void Unseal(bool bUnsealFields);
/*! @cond Doxygen_Suppress */
struct CPL_DLL TemporaryUnsealer
{
private:
OGRFeatureDefn *m_poFeatureDefn = nullptr;
bool m_bSealFields = false;
CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
public:
explicit TemporaryUnsealer(OGRFeatureDefn *poFeatureDefn,
bool bSealFields);
TemporaryUnsealer(TemporaryUnsealer &&) = default;
TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
~TemporaryUnsealer();
OGRFeatureDefn *operator->()
{
return m_poFeatureDefn;
}
};
/*! @endcond */
TemporaryUnsealer GetTemporaryUnsealer(bool bSealFields = true);
private:
CPL_DISALLOW_COPY_ASSIGN(OGRFeatureDefn)
};
#ifdef GDAL_COMPILATION
/** Return an object that temporary unseals the OGRFeatureDefn
*
* The returned object calls Unseal() initially, and when it is destroyed
* it calls Seal().
* This method should be called on a OGRFeatureDefn that has been sealed
* previously.
* GetTemporaryUnsealer() calls may be nested, in which case only the first
* one has an effect (similarly to a recursive mutex locked in a nested way
* from the same thread).
*
* This method should only be called by driver implementations.
*
* Usage: whileUnsealing(poFeatureDefn)->some_method();
*
* @param bSealFields Whether fields and geometry fields should be unsealed and
* resealed.
* This is generally desirabled, but in case of deferred
* resolution of them, this parameter should be set to false.
* @since GDAL 3.9
*/
inline OGRFeatureDefn::TemporaryUnsealer whileUnsealing(OGRFeatureDefn *object,
bool bSealFields = true)
{
return object->GetTemporaryUnsealer(bSealFields);
}
#endif
/************************************************************************/
/* OGRFeature */
/************************************************************************/
/**
* A simple feature, including geometry and attributes.
*/
class CPL_DLL OGRFeature
{
private:
GIntBig nFID;
OGRFeatureDefn *poDefn;
OGRGeometry **papoGeometries;
OGRField *pauFields;
char *m_pszNativeData;
char *m_pszNativeMediaType;
bool SetFieldInternal(int i, const OGRField *puValue);
protected:
//! @cond Doxygen_Suppress
mutable char *m_pszStyleString;
mutable OGRStyleTable *m_poStyleTable;
mutable char *m_pszTmpFieldValue;
//! @endcond
bool CopySelfTo(OGRFeature *poNew) const;
public:
explicit OGRFeature(OGRFeatureDefn *);
virtual ~OGRFeature();
/** Field value. */
class CPL_DLL FieldValue
{
friend class OGRFeature;
struct Private;
std::unique_ptr<Private> m_poPrivate;
FieldValue(OGRFeature *poFeature, int iFieldIndex);
FieldValue(const OGRFeature *poFeature, int iFieldIndex);
FieldValue(const FieldValue &oOther) = delete;
FieldValue &Assign(const FieldValue &oOther);
public:
//! @cond Doxygen_Suppress
~FieldValue();
FieldValue &operator=(FieldValue &&oOther);
//! @endcond
/** Set a field value from another one. */
FieldValue &operator=(const FieldValue &oOther);
/** Set an integer value to the field. */
FieldValue &operator=(int nVal);
/** Set an integer value to the field. */
FieldValue &operator=(GIntBig nVal);
/** Set a real value to the field. */
FieldValue &operator=(double dfVal);
/** Set a string value to the field. */
FieldValue &operator=(const char *pszVal);
/** Set a string value to the field. */
FieldValue &operator=(const std::string &osVal);
/** Set an array of integer to the field. */
FieldValue &operator=(const std::vector<int> &oArray);
/** Set an array of big integer to the field. */
FieldValue &operator=(const std::vector<GIntBig> &oArray);
/** Set an array of double to the field. */
FieldValue &operator=(const std::vector<double> &oArray);
/** Set an array of strings to the field. */
FieldValue &operator=(const std::vector<std::string> &oArray);
/** Set an array of strings to the field. */
FieldValue &operator=(CSLConstList papszValues);
/** Set a null value to the field. */
void SetNull();
/** Unset the field. */
void clear();
/** Unset the field. */
void Unset()
{
clear();
}
/** Set date time value/ */
void SetDateTime(int nYear, int nMonth, int nDay, int nHour = 0,
int nMinute = 0, float fSecond = 0.f, int nTZFlag = 0);
/** Return field index. */
int GetIndex() const;
/** Return field definition. */
const OGRFieldDefn *GetDefn() const;
/** Return field name. */
const char *GetName() const
{
return GetDefn()->GetNameRef();
}
/** Return field type. */
OGRFieldType GetType() const
{
return GetDefn()->GetType();
}
/** Return field subtype. */
OGRFieldSubType GetSubType() const
{
return GetDefn()->GetSubType();
}
/** Return whether the field value is unset/empty. */
// cppcheck-suppress functionStatic
bool empty() const
{
return IsUnset();
}
/** Return whether the field value is unset/empty. */
// cppcheck-suppress functionStatic
bool IsUnset() const;
/** Return whether the field value is null. */
// cppcheck-suppress functionStatic
bool IsNull() const;
/** Return the raw field value */
const OGRField *GetRawValue() const;
/** Return the integer value.
* Only use that method if and only if GetType() == OFTInteger.
*/
// cppcheck-suppress functionStatic
int GetInteger() const
{
return GetRawValue()->Integer;
}
/** Return the 64-bit integer value.
* Only use that method if and only if GetType() == OFTInteger64.
*/
// cppcheck-suppress functionStatic
GIntBig GetInteger64() const
{
return GetRawValue()->Integer64;
}
/** Return the double value.
* Only use that method if and only if GetType() == OFTReal.
*/
// cppcheck-suppress functionStatic
double GetDouble() const
{
return GetRawValue()->Real;
}
/** Return the string value.
* Only use that method if and only if GetType() == OFTString.
*/
// cppcheck-suppress functionStatic
const char *GetString() const
{
return GetRawValue()->String;
}
/** Return the date/time/datetime value. */
bool GetDateTime(int *pnYear, int *pnMonth, int *pnDay, int *pnHour,
int *pnMinute, float *pfSecond, int *pnTZFlag) const;
/** Return the field value as integer, with potential conversion */
operator int() const
{
return GetAsInteger();
}
/** Return the field value as 64-bit integer, with potential conversion
*/
operator GIntBig() const
{
return GetAsInteger64();
}
/** Return the field value as double, with potential conversion */
operator double() const
{
return GetAsDouble();
}
/** Return the field value as string, with potential conversion */
operator const char *() const
{
return GetAsString();
}
/** Return the field value as integer list, with potential conversion */
operator const std::vector<int> &() const
{
return GetAsIntegerList();
}
/** Return the field value as 64-bit integer list, with potential
* conversion */
operator const std::vector<GIntBig> &() const
{
return GetAsInteger64List();
}
/** Return the field value as double list, with potential conversion */
operator const std::vector<double> &() const
{
return GetAsDoubleList();
}
/** Return the field value as string list, with potential conversion */
operator const std::vector<std::string> &() const
{
return GetAsStringList();
}
/** Return the field value as string list, with potential conversion */
operator CSLConstList() const;
/** Return the field value as integer, with potential conversion */
int GetAsInteger() const;
/** Return the field value as 64-bit integer, with potential conversion
*/
GIntBig GetAsInteger64() const;
/** Return the field value as double, with potential conversion */
double GetAsDouble() const;
/** Return the field value as string, with potential conversion */
const char *GetAsString() const;
/** Return the field value as integer list, with potential conversion */
const std::vector<int> &GetAsIntegerList() const;
/** Return the field value as 64-bit integer list, with potential
* conversion */
const std::vector<GIntBig> &GetAsInteger64List() const;
/** Return the field value as double list, with potential conversion */
const std::vector<double> &GetAsDoubleList() const;
/** Return the field value as string list, with potential conversion */
const std::vector<std::string> &GetAsStringList() const;
};
/** Field value iterator class. */
class CPL_DLL ConstFieldIterator
{
friend class OGRFeature;
struct Private;
std::unique_ptr<Private> m_poPrivate;
ConstFieldIterator(const OGRFeature *poSelf, int nPos);
public:
//! @cond Doxygen_Suppress
ConstFieldIterator(
ConstFieldIterator &&oOther) noexcept; // declared but not defined.
// Needed for gcc 5.4 at least
~ConstFieldIterator();
const FieldValue &operator*() const;
ConstFieldIterator &operator++();
bool operator!=(const ConstFieldIterator &it) const;
//! @endcond
};
/** Return begin of field value iterator.
*
* Using this iterator for standard range-based loops is safe, but
* due to implementation limitations, you shouldn't try to access
* (dereference) more than one iterator step at a time, since you will get
* a reference to the same object (FieldValue) at each iteration step.
*
* <pre>
* for( auto&& oField: poFeature )
* {
* std::cout << oField.GetIndex() << "," << oField.GetName()<< ": " <<
* oField.GetAsString() << std::endl;
* }
* </pre>
*
* @since GDAL 2.3
*/
ConstFieldIterator begin() const;
/** Return end of field value iterator. */
ConstFieldIterator end() const;
const FieldValue operator[](int iField) const;
FieldValue operator[](int iField);
/** Exception raised by operator[](const char*) when a field is not found.
*/
class FieldNotFoundException : public std::exception
{
};
const FieldValue operator[](const char *pszFieldName) const;
FieldValue operator[](const char *pszFieldName);
OGRFeatureDefn *GetDefnRef()
{
return poDefn;
}
const OGRFeatureDefn *GetDefnRef() const
{
return poDefn;
}
//! @cond Doxygen_Suppress
void SetFDefnUnsafe(OGRFeatureDefn *poNewFDefn);
//! @endcond
OGRErr SetGeometryDirectly(OGRGeometry *);
OGRErr SetGeometry(const OGRGeometry *);
OGRGeometry *GetGeometryRef();
const OGRGeometry *GetGeometryRef() const;
OGRGeometry *StealGeometry() CPL_WARN_UNUSED_RESULT;
int GetGeomFieldCount() const
{
return poDefn->GetGeomFieldCount();
}
OGRGeomFieldDefn *GetGeomFieldDefnRef(int iField)
{
return poDefn->GetGeomFieldDefn(iField);
}
const OGRGeomFieldDefn *GetGeomFieldDefnRef(int iField) const
{
return poDefn->GetGeomFieldDefn(iField);
}
int GetGeomFieldIndex(const char *pszName) const
{
return poDefn->GetGeomFieldIndex(pszName);
}
OGRGeometry *GetGeomFieldRef(int iField);
const OGRGeometry *GetGeomFieldRef(int iField) const;
OGRGeometry *StealGeometry(int iField);
OGRGeometry *GetGeomFieldRef(const char *pszFName);
const OGRGeometry *GetGeomFieldRef(const char *pszFName) const;
OGRErr SetGeomFieldDirectly(int iField, OGRGeometry *);
OGRErr SetGeomField(int iField, const OGRGeometry *);
void Reset();
OGRFeature *Clone() const CPL_WARN_UNUSED_RESULT;
virtual OGRBoolean Equal(const OGRFeature *poFeature) const;
int GetFieldCount() const
{
return poDefn->GetFieldCount();
}
const OGRFieldDefn *GetFieldDefnRef(int iField) const
{
return poDefn->GetFieldDefn(iField);
}
OGRFieldDefn *GetFieldDefnRef(int iField)
{
return poDefn->GetFieldDefn(iField);
}
int GetFieldIndex(const char *pszName) const
{
return poDefn->GetFieldIndex(pszName);
}
int IsFieldSet(int iField) const;
void UnsetField(int iField);
bool IsFieldNull(int iField) const;
void SetFieldNull(int iField);
bool IsFieldSetAndNotNull(int iField) const;
OGRField *GetRawFieldRef(int i)
{
return pauFields + i;
}
const OGRField *GetRawFieldRef(int i) const
{
return pauFields + i;
}
int GetFieldAsInteger(int i) const;
GIntBig GetFieldAsInteger64(int i) const;
double GetFieldAsDouble(int i) const;
const char *GetFieldAsString(int i) const;
const char *GetFieldAsISO8601DateTime(int i,
CSLConstList papszOptions) const;
const int *GetFieldAsIntegerList(int i, int *pnCount) const;
const GIntBig *GetFieldAsInteger64List(int i, int *pnCount) const;
const double *GetFieldAsDoubleList(int i, int *pnCount) const;
char **GetFieldAsStringList(int i) const;
GByte *GetFieldAsBinary(int i, int *pnCount) const;
int GetFieldAsDateTime(int i, int *pnYear, int *pnMonth, int *pnDay,
int *pnHour, int *pnMinute, int *pnSecond,
int *pnTZFlag) const;
int GetFieldAsDateTime(int i, int *pnYear, int *pnMonth, int *pnDay,
int *pnHour, int *pnMinute, float *pfSecond,
int *pnTZFlag) const;
char *GetFieldAsSerializedJSon(int i) const;
//! @cond Doxygen_Suppress
bool IsFieldSetUnsafe(int i) const
{
return !(pauFields[i].Set.nMarker1 == OGRUnsetMarker &&
pauFields[i].Set.nMarker2 == OGRUnsetMarker &&
pauFields[i].Set.nMarker3 == OGRUnsetMarker);
}
bool IsFieldNullUnsafe(int i) const
{
return (pauFields[i].Set.nMarker1 == OGRNullMarker &&
pauFields[i].Set.nMarker2 == OGRNullMarker &&
pauFields[i].Set.nMarker3 == OGRNullMarker);
}
bool IsFieldSetAndNotNullUnsafe(int i) const
{
return IsFieldSetUnsafe(i) && !IsFieldNullUnsafe(i);
}
// Those methods should only be called on a field that is of the type
// consistent with the value, and that is set.
int GetFieldAsIntegerUnsafe(int i) const
{
return pauFields[i].Integer;
}
GIntBig GetFieldAsInteger64Unsafe(int i) const
{
return pauFields[i].Integer64;
}
double GetFieldAsDoubleUnsafe(int i) const
{
return pauFields[i].Real;
}
const char *GetFieldAsStringUnsafe(int i) const
{
return pauFields[i].String;
}
//! @endcond
int GetFieldAsInteger(const char *pszFName) const
{
return GetFieldAsInteger(GetFieldIndex(pszFName));
}
GIntBig GetFieldAsInteger64(const char *pszFName) const
{
return GetFieldAsInteger64(GetFieldIndex(pszFName));
}
double GetFieldAsDouble(const char *pszFName) const
{
return GetFieldAsDouble(GetFieldIndex(pszFName));
}
const char *GetFieldAsString(const char *pszFName) const
{
return GetFieldAsString(GetFieldIndex(pszFName));
}
const char *GetFieldAsISO8601DateTime(const char *pszFName,
CSLConstList papszOptions) const
{
return GetFieldAsISO8601DateTime(GetFieldIndex(pszFName), papszOptions);
}
const int *GetFieldAsIntegerList(const char *pszFName, int *pnCount) const
{
return GetFieldAsIntegerList(GetFieldIndex(pszFName), pnCount);
}
const GIntBig *GetFieldAsInteger64List(const char *pszFName,
int *pnCount) const
{
return GetFieldAsInteger64List(GetFieldIndex(pszFName), pnCount);
}
const double *GetFieldAsDoubleList(const char *pszFName, int *pnCount) const
{
return GetFieldAsDoubleList(GetFieldIndex(pszFName), pnCount);
}
char **GetFieldAsStringList(const char *pszFName) const
{
return GetFieldAsStringList(GetFieldIndex(pszFName));
}
void SetField(int i, int nValue);
void SetField(int i, GIntBig nValue);
void SetField(int i, double dfValue);
void SetField(int i, const char *pszValue);
void SetField(int i, int nCount, const int *panValues);
void SetField(int i, int nCount, const GIntBig *panValues);
void SetField(int i, int nCount, const double *padfValues);
void SetField(int i, const char *const *papszValues);
void SetField(int i, const OGRField *puValue);
void SetField(int i, int nCount, const void *pabyBinary);
void SetField(int i, int nYear, int nMonth, int nDay, int nHour = 0,
int nMinute = 0, float fSecond = 0.f, int nTZFlag = 0);
//! @cond Doxygen_Suppress
// Those methods should only be called on a field that is of the type
// consistent with the value, and in a unset state.
void SetFieldSameTypeUnsafe(int i, int nValue)
{
pauFields[i].Integer = nValue;
pauFields[i].Set.nMarker2 = 0;
pauFields[i].Set.nMarker3 = 0;
}
void SetFieldSameTypeUnsafe(int i, GIntBig nValue)
{
pauFields[i].Integer64 = nValue;
}
void SetFieldSameTypeUnsafe(int i, double dfValue)
{
pauFields[i].Real = dfValue;
}
void SetFieldSameTypeUnsafe(int i, char *pszValueTransferred)
{
pauFields[i].String = pszValueTransferred;
}
//! @endcond
void SetField(const char *pszFName, int nValue)
{
SetField(GetFieldIndex(pszFName), nValue);
}
void SetField(const char *pszFName, GIntBig nValue)
{
SetField(GetFieldIndex(pszFName), nValue);
}
void SetField(const char *pszFName, double dfValue)
{
SetField(GetFieldIndex(pszFName), dfValue);
}
void SetField(const char *pszFName, const char *pszValue)
{
SetField(GetFieldIndex(pszFName), pszValue);
}
void SetField(const char *pszFName, int nCount, const int *panValues)
{
SetField(GetFieldIndex(pszFName), nCount, panValues);
}
void SetField(const char *pszFName, int nCount, const GIntBig *panValues)
{
SetField(GetFieldIndex(pszFName), nCount, panValues);
}
void SetField(const char *pszFName, int nCount, const double *padfValues)
{
SetField(GetFieldIndex(pszFName), nCount, padfValues);
}
void SetField(const char *pszFName, const char *const *papszValues)
{
SetField(GetFieldIndex(pszFName), papszValues);
}
void SetField(const char *pszFName, const OGRField *puValue)
{
SetField(GetFieldIndex(pszFName), puValue);
}
void SetField(const char *pszFName, int nYear, int nMonth, int nDay,
int nHour = 0, int nMinute = 0, float fSecond = 0.f,
int nTZFlag = 0)
{
SetField(GetFieldIndex(pszFName), nYear, nMonth, nDay, nHour, nMinute,
fSecond, nTZFlag);
}
GIntBig GetFID() const
{
return nFID;
}
virtual OGRErr SetFID(GIntBig nFIDIn);
void DumpReadable(FILE *, CSLConstList papszOptions = nullptr) const;
std::string DumpReadableAsString(CSLConstList papszOptions = nullptr) const;
OGRErr SetFrom(const OGRFeature *, int bForgiving = TRUE);
OGRErr SetFrom(const OGRFeature *, const int *panMap, int bForgiving = TRUE,
bool bUseISO8601ForDateTimeAsString = false);
OGRErr SetFieldsFrom(const OGRFeature *, const int *panMap,
int bForgiving = TRUE,
bool bUseISO8601ForDateTimeAsString = false);
//! @cond Doxygen_Suppress
OGRErr RemapFields(OGRFeatureDefn *poNewDefn, const int *panRemapSource);
void AppendField();
OGRErr RemapGeomFields(OGRFeatureDefn *poNewDefn,
const int *panRemapSource);
//! @endcond
int Validate(int nValidateFlags, int bEmitError) const;
void FillUnsetWithDefault(int bNotNullableOnly, char **papszOptions);
bool SerializeToBinary(std::vector<GByte> &abyBuffer) const;
bool DeserializeFromBinary(const GByte *pabyBuffer, size_t nSize);
virtual const char *GetStyleString() const;
virtual void SetStyleString(const char *);
virtual void SetStyleStringDirectly(char *);
/** Return style table.
* @return style table.
*/
virtual OGRStyleTable *GetStyleTable() const
{
return m_poStyleTable;
} /* f.i.x.m.e: add a const qualifier for return type */
virtual void SetStyleTable(OGRStyleTable *poStyleTable);
virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable);
const char *GetNativeData() const
{
return m_pszNativeData;
}
const char *GetNativeMediaType() const
{
return m_pszNativeMediaType;
}
void SetNativeData(const char *pszNativeData);
void SetNativeMediaType(const char *pszNativeMediaType);
static OGRFeature *CreateFeature(OGRFeatureDefn *);
static void DestroyFeature(OGRFeature *);
/** Convert a OGRFeature* to a OGRFeatureH.
* @since GDAL 2.3
*/
static inline OGRFeatureH ToHandle(OGRFeature *poFeature)
{
return reinterpret_cast<OGRFeatureH>(poFeature);
}
/** Convert a OGRFeatureH to a OGRFeature*.
* @since GDAL 2.3
*/
static inline OGRFeature *FromHandle(OGRFeatureH hFeature)
{
return reinterpret_cast<OGRFeature *>(hFeature);
}
private:
CPL_DISALLOW_COPY_ASSIGN(OGRFeature)
};
//! @cond Doxygen_Suppress
struct CPL_DLL OGRFeatureUniquePtrDeleter
{
void operator()(OGRFeature *) const;
};
//! @endcond
/** Unique pointer type for OGRFeature.
* @since GDAL 2.3
*/
typedef std::unique_ptr<OGRFeature, OGRFeatureUniquePtrDeleter>
OGRFeatureUniquePtr;
//! @cond Doxygen_Suppress
/** @see OGRFeature::begin() const */
inline OGRFeature::ConstFieldIterator begin(const OGRFeature *poFeature)
{
return poFeature->begin();
}
/** @see OGRFeature::end() const */
inline OGRFeature::ConstFieldIterator end(const OGRFeature *poFeature)
{
return poFeature->end();
}
/** @see OGRFeature::begin() const */
inline OGRFeature::ConstFieldIterator
begin(const OGRFeatureUniquePtr &poFeature)
{
return poFeature->begin();
}
/** @see OGRFeature::end() const */
inline OGRFeature::ConstFieldIterator end(const OGRFeatureUniquePtr &poFeature)
{
return poFeature->end();
}
//! @endcond
/************************************************************************/
/* OGRFieldDomain */
/************************************************************************/
/* clang-format off */
/**
* Definition of a field domain.
*
* A field domain is a set of constraints that apply to one or several fields.
*
* This is a concept found in
* <a href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/geodatabases/an-overview-of-attribute-domains.htm">File
* Geodatabase</a> or GeoPackage (using the <a href="http://www.geopackage.org/spec/#extension_schema">schema extension</a>)
* for example.
*
* A field domain can be:
* <ul>
* <li>OGRCodedFieldDomain: an enumerated list of (code, value) tuples.</li>
* <li>OGRRangeFieldDomain: a range constraint (min, max).</li>
* <li>OGRGlobFieldDomain: a glob expression.</li>
* </ul>
*
* @since GDAL 3.3
*/
/* clang-format on */
class CPL_DLL OGRFieldDomain
{
protected:
/*! @cond Doxygen_Suppress */
std::string m_osName;
std::string m_osDescription;
OGRFieldDomainType m_eDomainType;
OGRFieldType m_eFieldType;
OGRFieldSubType m_eFieldSubType;
OGRFieldDomainSplitPolicy m_eSplitPolicy = OFDSP_DEFAULT_VALUE;
OGRFieldDomainMergePolicy m_eMergePolicy = OFDMP_DEFAULT_VALUE;
OGRFieldDomain(const std::string &osName, const std::string &osDescription,
OGRFieldDomainType eDomainType, OGRFieldType eFieldType,
OGRFieldSubType eFieldSubType);
/*! @endcond */
public:
/** Destructor.
*
* This is the same as the C function OGR_FldDomain_Destroy().
*/
virtual ~OGRFieldDomain() = 0;
/** Clone.
*
* Return a cloned object, or nullptr in case of error.
*/
virtual OGRFieldDomain *Clone() const = 0;
/** Get the name of the field domain.
*
* This is the same as the C function OGR_FldDomain_GetName().
*/
const std::string &GetName() const
{
return m_osName;
}
/** Get the description of the field domain.
* Empty string if there is none.
*
* This is the same as the C function OGR_FldDomain_GetDescription().
*/
const std::string &GetDescription() const
{
return m_osDescription;
}
/** Get the type of the field domain.
*
* This is the same as the C function OGR_FldDomain_GetDomainType().
*/
OGRFieldDomainType GetDomainType() const
{
return m_eDomainType;
}
/** Get the field type.
*
* This is the same as the C function OGR_FldDomain_GetFieldType().
*/
OGRFieldType GetFieldType() const
{
return m_eFieldType;
}
/** Get the field subtype.
*
* This is the same as the C function OGR_FldDomain_GetFieldSubType().
*/
OGRFieldSubType GetFieldSubType() const
{
return m_eFieldSubType;
}
/** Convert a OGRFieldDomain* to a OGRFieldDomainH. */
static inline OGRFieldDomainH ToHandle(OGRFieldDomain *poFieldDomain)
{
return reinterpret_cast<OGRFieldDomainH>(poFieldDomain);
}
/** Convert a OGRFieldDomainH to a OGRFieldDomain*. */
static inline OGRFieldDomain *FromHandle(OGRFieldDomainH hFieldDomain)
{
return reinterpret_cast<OGRFieldDomain *>(hFieldDomain);
}
/** Get the split policy.
*
* This is the same as the C function OGR_FldDomain_GetSplitPolicy().
*/
OGRFieldDomainSplitPolicy GetSplitPolicy() const
{
return m_eSplitPolicy;
}
/** Set the split policy.
*
* This is the same as the C function OGR_FldDomain_SetSplitPolicy().
*/
void SetSplitPolicy(OGRFieldDomainSplitPolicy policy)
{
m_eSplitPolicy = policy;
}
/** Get the merge policy.
*
* This is the same as the C function OGR_FldDomain_GetMergePolicy().
*/
OGRFieldDomainMergePolicy GetMergePolicy() const
{
return m_eMergePolicy;
}
/** Set the merge policy.
*
* This is the same as the C function OGR_FldDomain_SetMergePolicy().
*/
void SetMergePolicy(OGRFieldDomainMergePolicy policy)
{
m_eMergePolicy = policy;
}
};
/** Definition of a coded / enumerated field domain.
*
* A code field domain is a domain for which only a limited set of codes,
* associated with their expanded value, are allowed.
* The type of the code should be the one of the field domain.
*/
class CPL_DLL OGRCodedFieldDomain final : public OGRFieldDomain
{
private:
std::vector<OGRCodedValue> m_asValues{};
OGRCodedFieldDomain(const OGRCodedFieldDomain &) = delete;
OGRCodedFieldDomain &operator=(const OGRCodedFieldDomain &) = delete;
public:
/** Constructor.
*
* This is the same as the C function OGR_CodedFldDomain_Create()
* (except that the C function copies the enumeration, whereas the C++
* method moves it)
*
* @param osName Domain name.
* @param osDescription Domain description.
* @param eFieldType Field type. Generally numeric. Potentially
* OFTDateTime
* @param eFieldSubType Field subtype.
* @param asValues Enumeration as (code, value) pairs.
* Each code should appear only once, but it is the
* responsibility of the user to check it.
*/
OGRCodedFieldDomain(const std::string &osName,
const std::string &osDescription,
OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
std::vector<OGRCodedValue> &&asValues);
~OGRCodedFieldDomain() override;
OGRCodedFieldDomain *Clone() const override;
/** Get the enumeration as (code, value) pairs.
* The end of the enumeration is signaled by code == NULL.
*
* This is the same as the C function OGR_CodedFldDomain_GetEnumeration().
*/
const OGRCodedValue *GetEnumeration() const
{
return m_asValues.data();
}
};
/** Definition of a numeric field domain with a range of validity for values.
*/
class CPL_DLL OGRRangeFieldDomain final : public OGRFieldDomain
{
private:
OGRField m_sMin;
OGRField m_sMax;
bool m_bMinIsInclusive;
bool m_bMaxIsInclusive;
OGRRangeFieldDomain(const OGRRangeFieldDomain &) = delete;
OGRRangeFieldDomain &operator=(const OGRRangeFieldDomain &) = delete;
public:
/** Constructor.
*
* This is the same as the C function OGR_RangeFldDomain_Create().
*
* @param osName Domain name.
* @param osDescription Domain description.
* @param eFieldType Field type.
* One among OFTInteger, OFTInteger64, OFTReal or
* OFTDateTime
* @param eFieldSubType Field subtype.
* @param sMin Minimum value.
* Which member in the OGRField enum must be read
* depends on the field type.
* If no minimum is set (might not be supported by
* all backends), then initialize the value with
* OGR_RawField_SetUnset().
* @param bMinIsInclusive Whether the minimum value is included in the
* range.
* @param sMax Minimum value.
* Which member in the OGRField enum must be read
* depends on the field type.
* If no maximum is set (might not be supported by
* all backends), then initialize the value with
* OGR_RawField_SetUnset().
* @param bMaxIsInclusive Whether the minimum value is included in the
* range.
*/
OGRRangeFieldDomain(const std::string &osName,
const std::string &osDescription,
OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
const OGRField &sMin, bool bMinIsInclusive,
const OGRField &sMax, bool bMaxIsInclusive);
OGRRangeFieldDomain *Clone() const override
{
auto poDomain = new OGRRangeFieldDomain(
m_osName, m_osDescription, m_eFieldType, m_eFieldSubType, m_sMin,
m_bMinIsInclusive, m_sMax, m_bMaxIsInclusive);
poDomain->SetMergePolicy(m_eMergePolicy);
poDomain->SetSplitPolicy(m_eSplitPolicy);
return poDomain;
}
/** Get the minimum value.
*
* Which member in the returned OGRField enum must be read depends on the
* field type.
*
* If no minimum value is set, the OGR_RawField_IsUnset() will return true
* when called on the result.
*
* This is the same as the C function OGR_RangeFldDomain_GetMin().
*
* @param bIsInclusiveOut set to true if the minimum is included in the
* range.
*/
const OGRField &GetMin(bool &bIsInclusiveOut) const
{
bIsInclusiveOut = m_bMinIsInclusive;
return m_sMin;
}
/** Get the maximum value.
*
* Which member in the returned OGRField enum must be read depends on the
* field type.
*
* If no maximum value is set, the OGR_RawField_IsUnset() will return true
* when called on the result.
*
* This is the same as the C function OGR_RangeFldDomain_GetMax().
*
* @param bIsInclusiveOut set to true if the maximum is included in the
* range.
*/
const OGRField &GetMax(bool &bIsInclusiveOut) const
{
bIsInclusiveOut = m_bMaxIsInclusive;
return m_sMax;
}
};
/** Definition of a field domain for field content validated by a glob.
*
* Globs are matching expression like "*[a-z][0-1]?"
*/
class CPL_DLL OGRGlobFieldDomain final : public OGRFieldDomain
{
private:
std::string m_osGlob;
OGRGlobFieldDomain(const OGRGlobFieldDomain &) = delete;
OGRGlobFieldDomain &operator=(const OGRGlobFieldDomain &) = delete;
public:
/** Constructor.
*
* This is the same as the C function OGR_GlobFldDomain_Create().
*
* @param osName Domain name.
* @param osDescription Domain description.
* @param eFieldType Field type.
* @param eFieldSubType Field subtype.
* @param osBlob Blob expression
*/
OGRGlobFieldDomain(const std::string &osName,
const std::string &osDescription,
OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
const std::string &osBlob);
OGRGlobFieldDomain *Clone() const override
{
auto poDomain = new OGRGlobFieldDomain(
m_osName, m_osDescription, m_eFieldType, m_eFieldSubType, m_osGlob);
poDomain->SetMergePolicy(m_eMergePolicy);
poDomain->SetSplitPolicy(m_eSplitPolicy);
return poDomain;
}
/** Get the glob expression.
*
* This is the same as the C function OGR_GlobFldDomain_GetGlob().
*/
const std::string &GetGlob() const
{
return m_osGlob;
}
};
/************************************************************************/
/* OGRFeatureQuery */
/************************************************************************/
//! @cond Doxygen_Suppress
class OGRLayer;
class swq_expr_node;
class swq_custom_func_registrar;
struct swq_evaluation_context;
class CPL_DLL OGRFeatureQuery
{
private:
OGRFeatureDefn *poTargetDefn;
void *pSWQExpr;
swq_evaluation_context *m_psContext = nullptr;
char **FieldCollector(void *, char **);
static GIntBig *EvaluateAgainstIndices(const swq_expr_node *, OGRLayer *,
GIntBig &nFIDCount);
static int CanUseIndex(const swq_expr_node *, OGRLayer *);
OGRErr Compile(OGRLayer *, OGRFeatureDefn *, const char *, int bCheck,
swq_custom_func_registrar *poCustomFuncRegistrar);
CPL_DISALLOW_COPY_ASSIGN(OGRFeatureQuery)
public:
OGRFeatureQuery();
~OGRFeatureQuery();
OGRErr Compile(OGRLayer *, const char *, int bCheck = TRUE,
swq_custom_func_registrar *poCustomFuncRegistrar = nullptr);
OGRErr Compile(OGRFeatureDefn *, const char *, int bCheck = TRUE,
swq_custom_func_registrar *poCustomFuncRegistrar = nullptr);
int Evaluate(OGRFeature *);
GIntBig *EvaluateAgainstIndices(OGRLayer *, OGRErr *);
int CanUseIndex(OGRLayer *);
char **GetUsedFields();
void *GetSWQExpr()
{
return pSWQExpr;
}
};
//! @endcond
#endif /* ndef OGR_FEATURE_H_INCLUDED */