Coverage Report

Created: 2025-06-22 06:59

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