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