/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 *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 | | Layer(OGRLayer *poLayerIn, bool bOwnedIn) |
69 | 0 | : poLayerKeeper(bOwnedIn ? poLayerIn : nullptr), |
70 | 0 | poLayer(bOwnedIn ? poLayerKeeper.get() : poLayerIn) |
71 | 0 | { |
72 | 0 | } |
73 | | |
74 | 0 | Layer(Layer &&) = default; |
75 | | Layer &operator=(Layer &&) = default; |
76 | | |
77 | | OGRLayer *operator->() |
78 | 0 | { |
79 | 0 | return poLayer; |
80 | 0 | } |
81 | | |
82 | | const OGRLayer *operator->() const |
83 | 0 | { |
84 | 0 | return poLayer; |
85 | 0 | } |
86 | | |
87 | | std::pair<OGRLayer *, bool> release() |
88 | 0 | { |
89 | 0 | const bool bOwnedBackup = poLayerKeeper != nullptr; |
90 | 0 | OGRLayer *poLayerBackup = |
91 | 0 | poLayerKeeper ? poLayerKeeper.release() : poLayer; |
92 | 0 | poLayerKeeper.reset(); |
93 | 0 | return std::make_pair(poLayerBackup, bOwnedBackup); |
94 | 0 | } |
95 | | |
96 | | void reset(std::unique_ptr<OGRLayer> poLayerIn) |
97 | 0 | { |
98 | 0 | poLayerKeeper = std::move(poLayerIn); |
99 | 0 | poLayer = poLayerKeeper.get(); |
100 | 0 | } |
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 | | bool m_bHasAlreadyIteratedOverFeatures = false; |
121 | | char *pszAttributeFilter = nullptr; |
122 | | int nNextFID = 0; |
123 | | int *panMap = nullptr; |
124 | | CPLStringList m_aosIgnoredFields{}; |
125 | | mutable int bAttrFilterPassThroughValue = -1; |
126 | | mutable const OGRSpatialReference *poGlobalSRS = nullptr; |
127 | | |
128 | | std::mutex m_oMutex{}; |
129 | | |
130 | | /* Map from target FID to (source layer, source FID) */ |
131 | | struct FIDRange |
132 | | { |
133 | | GIntBig nDstFIDStart = 0; |
134 | | GIntBig nFIDCount = 0; |
135 | | GIntBig nSrcFIDStart = 0; |
136 | | int nLayerIdx = 0; |
137 | | }; |
138 | | |
139 | | std::vector<FIDRange> m_fidRanges{}; |
140 | | bool m_fidRangesInvalid = false; |
141 | | bool m_fidRangesComplete = false; |
142 | | |
143 | | void AutoWarpLayerIfNecessary(int iSubLayer); |
144 | | std::unique_ptr<OGRFeature> TranslateFromSrcLayer(OGRFeature *poSrcFeature, |
145 | | GIntBig nFID); |
146 | | void ApplyAttributeFilterToSrcLayer(int iSubLayer); |
147 | | int GetAttrFilterPassThroughValue() const; |
148 | | void ConfigureActiveLayer(); |
149 | | void SetSpatialFilterToSourceLayer(OGRLayer *poSrcLayer); |
150 | | |
151 | | public: |
152 | | OGRUnionLayer( |
153 | | const char *pszName, int nSrcLayers, /* must be >= 1 */ |
154 | | OGRLayer * |
155 | | *papoSrcLayers, /* array itself ownership always transferred, layer |
156 | | ownership depending on bTakeLayerOwnership */ |
157 | | int bTakeLayerOwnership); |
158 | | |
159 | | ~OGRUnionLayer() override; |
160 | | |
161 | | /* All the following non virtual methods must be called just after the |
162 | | * constructor */ |
163 | | /* and before any virtual method */ |
164 | | void SetFields( |
165 | | FieldUnionStrategy eFieldStrategy, int nFields, |
166 | | OGRFieldDefn **papoFields, /* duplicated by the method */ |
167 | | int nGeomFields, /* maybe -1 to explicitly disable geometry fields */ |
168 | | OGRUnionLayerGeomFieldDefn * |
169 | | *papoGeomFields /* duplicated by the method */); |
170 | | void SetSourceLayerFieldName(const char *pszSourceLayerFieldName); |
171 | | void SetPreserveSrcFID(int bPreserveSrcFID); |
172 | | void SetFeatureCount(int nFeatureCount); |
173 | | |
174 | | const char *GetName() const override |
175 | 0 | { |
176 | 0 | return osName.c_str(); |
177 | 0 | } |
178 | | |
179 | | OGRwkbGeometryType GetGeomType() const override; |
180 | | |
181 | | void ResetReading() override; |
182 | | OGRFeature *GetNextFeature() override; |
183 | | |
184 | | OGRFeature *GetFeature(GIntBig nFeatureId) override; |
185 | | |
186 | | OGRErr ICreateFeature(OGRFeature *poFeature) override; |
187 | | |
188 | | OGRErr ISetFeature(OGRFeature *poFeature) override; |
189 | | |
190 | | OGRErr IUpsertFeature(OGRFeature *poFeature) override; |
191 | | |
192 | | OGRErr IUpdateFeature(OGRFeature *poFeature, int nUpdatedFieldsCount, |
193 | | const int *panUpdatedFieldsIdx, |
194 | | int nUpdatedGeomFieldsCount, |
195 | | const int *panUpdatedGeomFieldsIdx, |
196 | | bool bUpdateStyleString) override; |
197 | | |
198 | | const OGRFeatureDefn *GetLayerDefn() const override; |
199 | | |
200 | | const OGRSpatialReference *GetSpatialRef() const override; |
201 | | |
202 | | GIntBig GetFeatureCount(int) override; |
203 | | |
204 | | OGRErr SetAttributeFilter(const char *) override; |
205 | | |
206 | | int TestCapability(const char *) const override; |
207 | | |
208 | | OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, |
209 | | bool bForce) override; |
210 | | |
211 | | virtual OGRErr ISetSpatialFilter(int iGeomField, |
212 | | const OGRGeometry *) override; |
213 | | |
214 | | OGRErr SetIgnoredFields(CSLConstList papszFields) override; |
215 | | |
216 | | OGRErr SyncToDisk() override; |
217 | | }; |
218 | | |
219 | | #endif /* #ifndef DOXYGEN_SKIP */ |
220 | | |
221 | | #endif // OGRUNIONLAYER_H_INCLUDED |