LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/generic - ogrunionlayer.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 21 21 100.0 %
Date: 2026-01-21 22:42:07 Functions: 9 9 100.0 %

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

Generated by: LCOV version 1.14