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 <mutex> 22 : #include <utility> 23 : 24 : /************************************************************************/ 25 : /* OGRUnionLayerGeomFieldDefn */ 26 : /************************************************************************/ 27 : 28 319 : class CPL_DLL OGRUnionLayerGeomFieldDefn final : public OGRGeomFieldDefn 29 : { 30 : public: 31 : int bGeomTypeSet = false; 32 : int bSRSSet = false; 33 : OGREnvelope sStaticEnvelope{}; 34 : 35 : OGRUnionLayerGeomFieldDefn(const char *pszName, OGRwkbGeometryType eType); 36 : explicit OGRUnionLayerGeomFieldDefn(const OGRGeomFieldDefn &oSrc); 37 : OGRUnionLayerGeomFieldDefn(const OGRUnionLayerGeomFieldDefn &oSrc); 38 : OGRUnionLayerGeomFieldDefn(OGRUnionLayerGeomFieldDefn &&) = default; 39 : ~OGRUnionLayerGeomFieldDefn() override; 40 : 41 : OGRUnionLayerGeomFieldDefn & 42 : operator=(const OGRUnionLayerGeomFieldDefn &) = delete; 43 : OGRUnionLayerGeomFieldDefn & 44 : operator=(OGRUnionLayerGeomFieldDefn &&) = delete; 45 : }; 46 : 47 : /************************************************************************/ 48 : /* OGRUnionLayer */ 49 : /************************************************************************/ 50 : 51 : typedef enum 52 : { 53 : FIELD_FROM_FIRST_LAYER, 54 : FIELD_UNION_ALL_LAYERS, 55 : FIELD_INTERSECTION_ALL_LAYERS, 56 : FIELD_SPECIFIED, 57 : } FieldUnionStrategy; 58 : 59 : class CPL_DLL OGRUnionLayer final : public OGRLayer 60 : { 61 : private: 62 : CPL_DISALLOW_COPY_ASSIGN(OGRUnionLayer) 63 : 64 : struct Layer 65 : { 66 : std::unique_ptr<OGRLayer> poLayerKeeper{}; 67 : OGRLayer *poLayer = nullptr; 68 : bool bModified = false; 69 : bool bCheckIfAutoWrap = false; 70 : 71 : CPL_DISALLOW_COPY_ASSIGN(Layer) 72 : 73 230 : Layer(OGRLayer *poLayerIn, bool bOwnedIn) 74 230 : : poLayerKeeper(bOwnedIn ? poLayerIn : nullptr), 75 230 : poLayer(bOwnedIn ? poLayerKeeper.get() : poLayerIn) 76 : { 77 230 : } 78 : 79 107 : Layer(Layer &&) = default; 80 : Layer &operator=(Layer &&) = default; 81 : 82 8191 : OGRLayer *operator->() 83 : { 84 8191 : return poLayer; 85 : } 86 : 87 733 : const OGRLayer *operator->() const 88 : { 89 733 : return poLayer; 90 : } 91 : 92 4 : std::pair<OGRLayer *, bool> release() 93 : { 94 4 : const bool bOwnedBackup = poLayerKeeper != nullptr; 95 : OGRLayer *poLayerBackup = 96 4 : poLayerKeeper ? poLayerKeeper.release() : poLayer; 97 4 : poLayerKeeper.reset(); 98 8 : return std::make_pair(poLayerBackup, bOwnedBackup); 99 : } 100 : 101 4 : void reset(std::unique_ptr<OGRLayer> poLayerIn) 102 : { 103 4 : poLayerKeeper = std::move(poLayerIn); 104 4 : poLayer = poLayerKeeper.get(); 105 4 : } 106 : }; 107 : 108 : CPLString osName{}; 109 : 110 : std::vector<Layer> m_apoSrcLayers{}; 111 : 112 : mutable OGRFeatureDefn *poFeatureDefn = nullptr; 113 : std::vector<std::unique_ptr<OGRFieldDefn>> apoFields{}; 114 : std::vector<std::unique_ptr<OGRUnionLayerGeomFieldDefn>> apoGeomFields{}; 115 : bool bUseGeomFields = true; 116 : FieldUnionStrategy eFieldStrategy = FIELD_UNION_ALL_LAYERS; 117 : CPLString osSourceLayerFieldName{}; 118 : 119 : int bPreserveSrcFID = false; 120 : 121 : GIntBig nFeatureCount = -1; 122 : 123 : int iCurLayer = -1; 124 : bool m_bHasAlreadyIteratedOverFeatures = false; 125 : char *pszAttributeFilter = nullptr; 126 : int nNextFID = 0; 127 : int *panMap = nullptr; 128 : CPLStringList m_aosIgnoredFields{}; 129 : mutable int bAttrFilterPassThroughValue = -1; 130 : mutable const OGRSpatialReference *poGlobalSRS = nullptr; 131 : 132 : std::mutex m_oMutex{}; 133 : 134 : /* Map from target FID to (source layer, source FID) */ 135 : struct FIDRange 136 : { 137 : GIntBig nDstFIDStart = 0; 138 : GIntBig nFIDCount = 0; 139 : GIntBig nSrcFIDStart = 0; 140 : int nLayerIdx = 0; 141 : }; 142 : 143 : std::vector<FIDRange> m_fidRanges{}; 144 : bool m_fidRangesInvalid = false; 145 : bool m_fidRangesComplete = false; 146 : 147 : void AutoWarpLayerIfNecessary(int iSubLayer); 148 : std::unique_ptr<OGRFeature> TranslateFromSrcLayer(OGRFeature *poSrcFeature, 149 : GIntBig nFID); 150 : void ApplyAttributeFilterToSrcLayer(int iSubLayer); 151 : int GetAttrFilterPassThroughValue() const; 152 : void ConfigureActiveLayer(); 153 : void SetSpatialFilterToSourceLayer(OGRLayer *poSrcLayer); 154 : 155 : public: 156 : OGRUnionLayer( 157 : const char *pszName, int nSrcLayers, /* must be >= 1 */ 158 : OGRLayer * 159 : *papoSrcLayers, /* array itself ownership always transferred, layer 160 : ownership depending on bTakeLayerOwnership */ 161 : int bTakeLayerOwnership); 162 : 163 : ~OGRUnionLayer() override; 164 : 165 : /* All the following non virtual methods must be called just after the 166 : * constructor */ 167 : /* and before any virtual method */ 168 : void SetFields( 169 : FieldUnionStrategy eFieldStrategy, int nFields, 170 : const OGRFieldDefn *paoFields, /* duplicated by the method */ 171 : int nGeomFields, /* maybe -1 to explicitly disable geometry fields */ 172 : const OGRUnionLayerGeomFieldDefn 173 : *paoGeomFields /* duplicated by the method */); 174 : void SetFields(FieldUnionStrategy eFieldStrategy, 175 : const OGRFeatureDefn *poFeatureDefnIn); 176 : 177 : void SetSourceLayerFieldName(const char *pszSourceLayerFieldName); 178 : void SetPreserveSrcFID(int bPreserveSrcFID); 179 : void SetFeatureCount(int nFeatureCount); 180 : 181 329 : const char *GetName() const override 182 : { 183 329 : return osName.c_str(); 184 : } 185 : 186 : OGRwkbGeometryType GetGeomType() const override; 187 : 188 : void ResetReading() override; 189 : OGRFeature *GetNextFeature() override; 190 : 191 : OGRFeature *GetFeature(GIntBig nFeatureId) override; 192 : 193 : OGRErr ICreateFeature(OGRFeature *poFeature) override; 194 : 195 : OGRErr ISetFeature(OGRFeature *poFeature) override; 196 : 197 : OGRErr IUpsertFeature(OGRFeature *poFeature) override; 198 : 199 : OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount, 200 : const int *panUpdatedFieldsIdx, 201 : int nUpdatedGeomFieldsCount, 202 : const int *panUpdatedGeomFieldsIdx, 203 : bool bUpdateStyleString) override; 204 : 205 : const OGRFeatureDefn *GetLayerDefn() const override; 206 : 207 : const OGRSpatialReference *GetSpatialRef() const override; 208 : 209 : GIntBig GetFeatureCount(int) override; 210 : 211 : OGRErr SetAttributeFilter(const char *) override; 212 : 213 : int TestCapability(const char *) const override; 214 : 215 : OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, 216 : bool bForce) override; 217 : 218 : virtual OGRErr ISetSpatialFilter(int iGeomField, 219 : const OGRGeometry *) override; 220 : 221 : OGRErr SetIgnoredFields(CSLConstList papszFields) override; 222 : 223 : OGRErr SyncToDisk() override; 224 : }; 225 : 226 : #endif /* #ifndef DOXYGEN_SKIP */ 227 : 228 : #endif // OGRUNIONLAYER_H_INCLUDED