Coverage Report

Created: 2025-11-16 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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