Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Defines OGRUnionLayer class 5 : * Author: Even Rouault, even dot rouault at spatialys.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2012-2014, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #ifndef OGRUNIONLAYER_H_INCLUDED 14 : #define OGRUNIONLAYER_H_INCLUDED 15 : 16 : #ifndef DOXYGEN_SKIP 17 : 18 : #include "ogrsf_frmts.h" 19 : 20 : #include <algorithm> 21 : #include <utility> 22 : 23 : /************************************************************************/ 24 : /* OGRUnionLayerGeomFieldDefn */ 25 : /************************************************************************/ 26 : 27 : class CPL_DLL OGRUnionLayerGeomFieldDefn final : public OGRGeomFieldDefn 28 : { 29 : public: 30 : int bGeomTypeSet = false; 31 : int bSRSSet = false; 32 : OGREnvelope sStaticEnvelope{}; 33 : 34 : OGRUnionLayerGeomFieldDefn(const char *pszName, OGRwkbGeometryType eType); 35 : explicit OGRUnionLayerGeomFieldDefn(const OGRGeomFieldDefn *poSrc); 36 : explicit OGRUnionLayerGeomFieldDefn( 37 : const OGRUnionLayerGeomFieldDefn *poSrc); 38 : ~OGRUnionLayerGeomFieldDefn(); 39 : }; 40 : 41 : /************************************************************************/ 42 : /* OGRUnionLayer */ 43 : /************************************************************************/ 44 : 45 : typedef enum 46 : { 47 : FIELD_FROM_FIRST_LAYER, 48 : FIELD_UNION_ALL_LAYERS, 49 : FIELD_INTERSECTION_ALL_LAYERS, 50 : FIELD_SPECIFIED, 51 : } FieldUnionStrategy; 52 : 53 : class CPL_DLL OGRUnionLayer final : public OGRLayer 54 : { 55 : private: 56 : CPL_DISALLOW_COPY_ASSIGN(OGRUnionLayer) 57 : 58 : struct Layer 59 : { 60 : std::unique_ptr<OGRLayer> poLayerKeeper{}; 61 : OGRLayer *poLayer = nullptr; 62 : bool bModified = false; 63 : bool bCheckIfAutoWrap = false; 64 : 65 : CPL_DISALLOW_COPY_ASSIGN(Layer) 66 : 67 223 : Layer(OGRLayer *poLayerIn, bool bOwnedIn) 68 223 : : poLayerKeeper(bOwnedIn ? poLayerIn : nullptr), 69 223 : poLayer(bOwnedIn ? poLayerKeeper.get() : poLayerIn) 70 : { 71 223 : } 72 : 73 99 : Layer(Layer &&) = default; 74 : Layer &operator=(Layer &&) = default; 75 : 76 11453 : OGRLayer *operator->() 77 : { 78 11453 : return poLayer; 79 : } 80 : 81 4 : std::pair<OGRLayer *, bool> release() 82 : { 83 4 : const bool bOwnedBackup = poLayerKeeper != nullptr; 84 : OGRLayer *poLayerBackup = 85 4 : poLayerKeeper ? poLayerKeeper.release() : poLayer; 86 4 : poLayerKeeper.reset(); 87 8 : return std::make_pair(poLayerBackup, bOwnedBackup); 88 : } 89 : 90 4 : void reset(std::unique_ptr<OGRLayer> poLayerIn) 91 : { 92 4 : poLayerKeeper = std::move(poLayerIn); 93 4 : poLayer = poLayerKeeper.get(); 94 4 : } 95 : }; 96 : 97 : CPLString osName{}; 98 : 99 : std::vector<Layer> m_apoSrcLayers{}; 100 : 101 : OGRFeatureDefn *poFeatureDefn = nullptr; 102 : int nFields = 0; 103 : OGRFieldDefn **papoFields = nullptr; 104 : int nGeomFields = 0; 105 : OGRUnionLayerGeomFieldDefn **papoGeomFields = nullptr; 106 : FieldUnionStrategy eFieldStrategy = FIELD_UNION_ALL_LAYERS; 107 : CPLString osSourceLayerFieldName{}; 108 : 109 : int bPreserveSrcFID = false; 110 : 111 : GIntBig nFeatureCount = -1; 112 : 113 : int iCurLayer = -1; 114 : char *pszAttributeFilter = nullptr; 115 : int nNextFID = 0; 116 : int *panMap = nullptr; 117 : CPLStringList m_aosIgnoredFields{}; 118 : int bAttrFilterPassThroughValue = -1; 119 : const OGRSpatialReference *poGlobalSRS = nullptr; 120 : 121 : void AutoWarpLayerIfNecessary(int iSubLayer); 122 : OGRFeature *TranslateFromSrcLayer(OGRFeature *poSrcFeature); 123 : void ApplyAttributeFilterToSrcLayer(int iSubLayer); 124 : int GetAttrFilterPassThroughValue(); 125 : void ConfigureActiveLayer(); 126 : void SetSpatialFilterToSourceLayer(OGRLayer *poSrcLayer); 127 : 128 : public: 129 : OGRUnionLayer( 130 : const char *pszName, int nSrcLayers, /* must be >= 1 */ 131 : OGRLayer * 132 : *papoSrcLayers, /* array itself ownership always transferred, layer 133 : ownership depending on bTakeLayerOwnership */ 134 : int bTakeLayerOwnership); 135 : 136 : virtual ~OGRUnionLayer(); 137 : 138 : /* All the following non virtual methods must be called just after the 139 : * constructor */ 140 : /* and before any virtual method */ 141 : void SetFields( 142 : FieldUnionStrategy eFieldStrategy, int nFields, 143 : OGRFieldDefn **papoFields, /* duplicated by the method */ 144 : int nGeomFields, /* maybe -1 to explicitly disable geometry fields */ 145 : OGRUnionLayerGeomFieldDefn * 146 : *papoGeomFields /* duplicated by the method */); 147 : void SetSourceLayerFieldName(const char *pszSourceLayerFieldName); 148 : void SetPreserveSrcFID(int bPreserveSrcFID); 149 : void SetFeatureCount(int nFeatureCount); 150 : 151 328 : virtual const char *GetName() override 152 : { 153 328 : return osName.c_str(); 154 : } 155 : 156 : virtual OGRwkbGeometryType GetGeomType() override; 157 : 158 : virtual void ResetReading() override; 159 : virtual OGRFeature *GetNextFeature() override; 160 : 161 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override; 162 : 163 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override; 164 : 165 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override; 166 : 167 : virtual OGRErr IUpsertFeature(OGRFeature *poFeature) override; 168 : 169 : OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount, 170 : const int *panUpdatedFieldsIdx, 171 : int nUpdatedGeomFieldsCount, 172 : const int *panUpdatedGeomFieldsIdx, 173 : bool bUpdateStyleString) override; 174 : 175 : virtual OGRFeatureDefn *GetLayerDefn() override; 176 : 177 : virtual OGRSpatialReference *GetSpatialRef() override; 178 : 179 : virtual GIntBig GetFeatureCount(int) override; 180 : 181 : virtual OGRErr SetAttributeFilter(const char *) override; 182 : 183 : virtual int TestCapability(const char *) override; 184 : 185 : virtual OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, 186 : bool bForce) override; 187 : 188 : virtual OGRErr ISetSpatialFilter(int iGeomField, 189 : const OGRGeometry *) override; 190 : 191 : virtual OGRErr SetIgnoredFields(CSLConstList papszFields) override; 192 : 193 : virtual OGRErr SyncToDisk() override; 194 : }; 195 : 196 : #endif /* #ifndef DOXYGEN_SKIP */ 197 : 198 : #endif // OGRUNIONLAYER_H_INCLUDED