/src/gdal/ogr/ogrsf_frmts/generic/ogrunionlayer.h
Line | Count | Source |
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 &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 | | Layer(OGRLayer *poLayerIn, bool bOwnedIn) |
74 | 0 | : poLayerKeeper(bOwnedIn ? poLayerIn : nullptr), |
75 | 0 | poLayer(bOwnedIn ? poLayerKeeper.get() : poLayerIn) |
76 | 0 | { |
77 | 0 | } |
78 | | |
79 | 0 | Layer(Layer &&) = default; |
80 | | Layer &operator=(Layer &&) = default; |
81 | | |
82 | | OGRLayer *operator->() |
83 | 0 | { |
84 | 0 | return poLayer; |
85 | 0 | } |
86 | | |
87 | | const OGRLayer *operator->() const |
88 | 0 | { |
89 | 0 | return poLayer; |
90 | 0 | } |
91 | | |
92 | | std::pair<OGRLayer *, bool> release() |
93 | 0 | { |
94 | 0 | const bool bOwnedBackup = poLayerKeeper != nullptr; |
95 | 0 | OGRLayer *poLayerBackup = |
96 | 0 | poLayerKeeper ? poLayerKeeper.release() : poLayer; |
97 | 0 | poLayerKeeper.reset(); |
98 | 0 | return std::make_pair(poLayerBackup, bOwnedBackup); |
99 | 0 | } |
100 | | |
101 | | void reset(std::unique_ptr<OGRLayer> poLayerIn) |
102 | 0 | { |
103 | 0 | poLayerKeeper = std::move(poLayerIn); |
104 | 0 | poLayer = poLayerKeeper.get(); |
105 | 0 | } |
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 | | const char *GetName() const override |
182 | 0 | { |
183 | 0 | return osName.c_str(); |
184 | 0 | } |
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 |