/****************************************************************************** * $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 * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #ifndef OGR_FEATURE_H_INCLUDED #define OGR_FEATURE_H_INCLUDED #include "cpl_atomic_ops.h" #include "ogr_featurestyle.h" #include "ogr_geometry.h" #include #include #include #include #include /** * \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 : *
    *
  • a name. See SetName() / GetNameRef()
  • *
  • an alternative name (optional): alternative descriptive name for the * field (sometimes referred to as an "alias"). See SetAlternativeName() / * GetAlternativeNameRef()
  • a type: OFTString, OFTInteger, OFTReal, ... * See SetType() / GetType()
  • a subtype (optional): OFSTBoolean, ... See * SetSubType() / GetSubType()
  • a width (optional): maximal number of * characters. See SetWidth() / GetWidth()
  • a precision (optional): * number of digits after decimal point. See SetPrecision() / * GetPrecision()
  • a NOT NULL constraint (optional). See SetNullable() / * IsNullable()
  • a UNIQUE constraint (optional). See SetUnique() / * IsUnique()
  • a default value (optional). See SetDefault() / * GetDefault()
  • a boolean to indicate whether it should be ignored when * retrieving features. See SetIgnored() / IsIgnored()
  • a field domain * name (optional). See SetDomainName() / Get DomainName()
  • *
*/ 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 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) { nWidth = MAX(0, nWidthIn); } int GetPrecision() const { return nPrecision; } void SetPrecision(int nPrecisionIn) { nPrecision = nPrecisionIn; } 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) { bNullable = bNullableIn; } int IsUnique() const { return bUnique; } void SetUnique(int bUniqueIn) { bUnique = bUniqueIn; } const std::string &GetDomainName() const { return m_osDomainName; } void SetDomainName(const std::string &osDomainName) { m_osDomainName = osDomainName; } int IsSame(const OGRFieldDefn *) const; /** Convert a OGRFieldDefn* to a OGRFieldDefnH. * @since GDAL 2.3 */ static inline OGRFieldDefnH ToHandle(OGRFieldDefn *poFieldDefn) { return reinterpret_cast(poFieldDefn); } /** Convert a OGRFieldDefnH to a OGRFieldDefn*. * @since GDAL 2.3 */ static inline OGRFieldDefn *FromHandle(OGRFieldDefnH hFieldDefn) { return reinterpret_cast(hFieldDefn); } private: CPL_DISALLOW_COPY_ASSIGN(OGRFieldDefn) }; /************************************************************************/ /* OGRGeomFieldDefn */ /************************************************************************/ /** * Definition of a geometry field of an OGRFeatureDefn. A geometry field is * described by : *
    *
  • a name. See SetName() / GetNameRef()
  • *
  • a type: wkbPoint, wkbLineString, ... See SetType() / GetType()
  • *
  • a spatial reference system (optional). See SetSpatialRef() / * GetSpatialRef()
  • a NOT NULL constraint (optional). See SetNullable() * / IsNullable()
  • a boolean to indicate whether it should be ignored * when retrieving features. See SetIgnored() / IsIgnored()
  • *
* * @since OGR 1.11 */ class CPL_DLL OGRGeomFieldDefn { protected: //! @cond Doxygen_Suppress char *pszName = nullptr; OGRwkbGeometryType eGeomType = wkbUnknown; /* all values possible except wkbNone */ mutable OGRSpatialReference *poSRS = nullptr; int bIgnore = false; mutable int bNullable = true; 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 OGRSpatialReference *GetSpatialRef() const; void SetSpatialRef(OGRSpatialReference *poSRSIn); int IsIgnored() const { return bIgnore; } void SetIgnored(int bIgnoreIn) { bIgnore = bIgnoreIn; } int IsNullable() const { return bNullable; } void SetNullable(int bNullableIn) { bNullable = bNullableIn; } int IsSame(const OGRGeomFieldDefn *) const; /** Convert a OGRGeomFieldDefn* to a OGRGeomFieldDefnH. * @since GDAL 2.3 */ static inline OGRGeomFieldDefnH ToHandle(OGRGeomFieldDefn *poGeomFieldDefn) { return reinterpret_cast(poGeomFieldDefn); } /** Convert a OGRGeomFieldDefnH to a OGRGeomFieldDefn*. * @since GDAL 2.3 */ static inline OGRGeomFieldDefn *FromHandle(OGRGeomFieldDefnH hGeomFieldDefn) { return reinterpret_cast(hGeomFieldDefn); } private: CPL_DISALLOW_COPY_ASSIGN(OGRGeomFieldDefn) }; /************************************************************************/ /* 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. */ class CPL_DLL OGRFeatureDefn { protected: //! @cond Doxygen_Suppress volatile int nRefCount = 0; mutable std::vector> apoFieldDefn{}; mutable std::vector> apoGeomFieldDefn{}; char *pszFeatureClassName = nullptr; bool bIgnoreStyle = false; //! @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 // That method should only be called if there's a guarantee that // GetFieldCount() has been called before int GetFieldCountUnsafe() const { return static_cast(apoFieldDefn.size()); } // Those methods don't check i is n range. OGRFieldDefn *GetFieldDefnUnsafe(int i) { if (apoFieldDefn.empty()) GetFieldDefn(i); return apoFieldDefn[static_cast(i)].get(); } const OGRFieldDefn *GetFieldDefnUnsafe(int i) const { if (apoFieldDefn.empty()) GetFieldDefn(i); return apoFieldDefn[static_cast(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; virtual void AddGeomFieldDefn(const OGRGeomFieldDefn *); virtual void AddGeomFieldDefn(std::unique_ptr &&); 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 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(poFeatureDefn); } /** Convert a OGRFeatureDefnH to a OGRFeatureDefn*. * @since GDAL 2.3 */ static inline OGRFeatureDefn *FromHandle(OGRFeatureDefnH hFeatureDefn) { return reinterpret_cast(hFeatureDefn); } private: CPL_DISALLOW_COPY_ASSIGN(OGRFeatureDefn) }; /************************************************************************/ /* 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 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 &oArray); /** Set an array of big integer to the field. */ FieldValue &operator=(const std::vector &oArray); /** Set an array of double to the field. */ FieldValue &operator=(const std::vector &oArray); /** Set an array of strings to the field. */ FieldValue &operator=(const std::vector &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 &() const { return GetAsIntegerList(); } /** Return the field value as 64-bit integer list, with potential * conversion */ operator const std::vector &() const { return GetAsInteger64List(); } /** Return the field value as double list, with potential conversion */ operator const std::vector &() const { return GetAsDoubleList(); } /** Return the field value as string list, with potential conversion */ operator const std::vector &() 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 &GetAsIntegerList() const; /** Return the field value as 64-bit integer list, with potential * conversion */ const std::vector &GetAsInteger64List() const; /** Return the field value as double list, with potential conversion */ const std::vector &GetAsDoubleList() const; /** Return the field value as string list, with potential conversion */ const std::vector &GetAsStringList() const; }; /** Field value iterator class. */ class CPL_DLL ConstFieldIterator { friend class OGRFeature; struct Private; std::unique_ptr 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. * *
     * for( auto&& oField: poFeature )
     * {
     *      std::cout << oField.GetIndex() << "," << oField.GetName()<< ": " <<
     * oField.GetAsString() << std::endl;
     * }
     * 
* * @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 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 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 *, char **papszOptions = nullptr) const; OGRErr SetFrom(const OGRFeature *, int = TRUE); OGRErr SetFrom(const OGRFeature *, const int *, int = TRUE); OGRErr SetFieldsFrom(const OGRFeature *, const int *, int = TRUE); //! @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); 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(poFeature); } /** Convert a OGRFeatureH to a OGRFeature*. * @since GDAL 2.3 */ static inline OGRFeature *FromHandle(OGRFeatureH hFeature) { return reinterpret_cast(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 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 * File * Geodatabase or GeoPackage (using the schema extension) * for example. * * A field domain can be: *
    *
  • OGRCodedFieldDomain: an enumerated list of (code, value) tuples.
  • *
  • OGRRangeFieldDomain: a range constraint (min, max).
  • *
  • OGRGlobFieldDomain: a glob expression.
  • *
* * @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(poFieldDomain); } /** Convert a OGRFieldDomainH to a OGRFieldDomain*. */ static inline OGRFieldDomain *FromHandle(OGRFieldDomainH hFieldDomain) { return reinterpret_cast(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 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 &&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; class CPL_DLL OGRFeatureQuery { private: OGRFeatureDefn *poTargetDefn; void *pSWQExpr; char **FieldCollector(void *, char **); GIntBig *EvaluateAgainstIndices(swq_expr_node *, OGRLayer *, GIntBig &nFIDCount); int CanUseIndex(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 */