LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/jsonfg - ogr_jsonfg.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 41 49 83.7 %
Date: 2024-05-14 23:54:21 Functions: 25 28 89.3 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implementation of OGC Features and Geometries JSON (JSON-FG)
       5             :  * Author:   Even Rouault <even.rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2023, Even Rouault <even.rouault at spatialys.com>
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #ifndef OGR_JSONFG_H_INCLUDED
      30             : #define OGR_JSONFG_H_INCLUDED
      31             : 
      32             : #include "cpl_vsi_virtual.h"
      33             : 
      34             : #include "gdal_priv.h"
      35             : #include "ogrsf_frmts.h"
      36             : #include "ogrgeojsonutils.h"
      37             : #include "ogrgeojsonwriter.h"
      38             : #include "ogrjsoncollectionstreamingparser.h"
      39             : #include "ogr_mem.h"
      40             : #include "directedacyclicgraph.hpp"
      41             : 
      42             : #include <map>
      43             : #include <set>
      44             : #include <utility>
      45             : 
      46             : /************************************************************************/
      47             : /*                         OGRJSONFGMemLayer                            */
      48             : /************************************************************************/
      49             : 
      50             : /** Layer with all features ingested into memory. */
      51          98 : class OGRJSONFGMemLayer final : public OGRMemLayer
      52             : {
      53             :   public:
      54             :     OGRJSONFGMemLayer(GDALDataset *poDS, const char *pszName,
      55             :                       OGRSpatialReference *poSRS, OGRwkbGeometryType eGType);
      56             :     ~OGRJSONFGMemLayer();
      57             : 
      58           0 :     const char *GetFIDColumn() override
      59             :     {
      60           0 :         return osFIDColumn_.c_str();
      61             :     }
      62             : 
      63             :     int TestCapability(const char *pszCap) override;
      64             : 
      65           0 :     void SetFIDColumn(const char *pszName)
      66             :     {
      67           0 :         osFIDColumn_ = pszName;
      68           0 :     }
      69             : 
      70             :     void AddFeature(std::unique_ptr<OGRFeature> poFeature);
      71             : 
      72          23 :     GDALDataset *GetDataset() override
      73             :     {
      74          23 :         return m_poDS;
      75             :     }
      76             : 
      77             :   private:
      78             :     GDALDataset *m_poDS = nullptr;
      79             :     std::string osFIDColumn_{};
      80             :     bool bOriginalIdModified_ = false;
      81             : 
      82             :     CPL_DISALLOW_COPY_ASSIGN(OGRJSONFGMemLayer)
      83             : };
      84             : 
      85             : /************************************************************************/
      86             : /*                    OGRJSONFGStreamedLayer                            */
      87             : /************************************************************************/
      88             : 
      89             : class OGRJSONFGStreamingParser;
      90             : 
      91             : /** Layer with features being acquired progressively through a streaming
      92             :  parser.
      93             : 
      94             :  Only applies for FeatureCollection read through a file
      95             : */
      96             : class OGRJSONFGStreamedLayer final
      97             :     : public OGRLayer,
      98             :       public OGRGetNextFeatureThroughRaw<OGRJSONFGStreamedLayer>
      99             : {
     100             :   public:
     101             :     OGRJSONFGStreamedLayer(GDALDataset *poDS, const char *pszName,
     102             :                            OGRSpatialReference *poSRS,
     103             :                            OGRwkbGeometryType eGType);
     104             :     ~OGRJSONFGStreamedLayer();
     105             : 
     106             :     // BEGIN specific public API
     107             : 
     108             :     //! Set the FID column name
     109           0 :     void SetFIDColumn(const char *pszName)
     110             :     {
     111           0 :         osFIDColumn_ = pszName;
     112           0 :     }
     113             : 
     114             :     //! Set the total feature count
     115          92 :     void SetFeatureCount(GIntBig nCount)
     116             :     {
     117          92 :         nFeatureCount_ = nCount;
     118          92 :     }
     119             : 
     120             :     /** Set the file handle.
     121             : 
     122             :      Must be called before GetNextFeature() is called
     123             :      */
     124             :     void SetFile(VSIVirtualHandleUniquePtr &&poFile);
     125             : 
     126             :     /** Set the streaming parser
     127             : 
     128             :      Must be called before GetNextFeature() is called
     129             :      */
     130             :     void SetStreamingParser(
     131             :         std::unique_ptr<OGRJSONFGStreamingParser> &&poStreamingParser);
     132             : 
     133             :     // END specific public API
     134             : 
     135         522 :     const char *GetFIDColumn() override
     136             :     {
     137         522 :         return osFIDColumn_.c_str();
     138             :     }
     139             : 
     140        2204 :     OGRFeatureDefn *GetLayerDefn() override
     141             :     {
     142        2204 :         return poFeatureDefn_;
     143             :     }
     144             : 
     145             :     int TestCapability(const char *pszCap) override;
     146             : 
     147             :     GIntBig GetFeatureCount(int bForce) override;
     148             : 
     149             :     void ResetReading() override;
     150             : 
     151         309 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRJSONFGStreamedLayer)
     152             : 
     153          15 :     GDALDataset *GetDataset() override
     154             :     {
     155          15 :         return m_poDS;
     156             :     }
     157             : 
     158             :   private:
     159             :     GDALDataset *m_poDS = nullptr;
     160             :     OGRFeatureDefn *poFeatureDefn_ = nullptr;
     161             :     std::string osFIDColumn_{};
     162             : 
     163             :     /** Total number of features. */
     164             :     GIntBig nFeatureCount_ = -1;
     165             : 
     166             :     VSIVirtualHandleUniquePtr poFile_{};
     167             : 
     168             :     std::unique_ptr<OGRJSONFGStreamingParser> poStreamingParser_{};
     169             : 
     170             :     /** Whether a warning has been emitted about feature IDs having been
     171             :      * modified */
     172             :     bool bOriginalIdModified_ = false;
     173             :     /** Set of feature IDs read/allocated up to that point */
     174             :     std::set<GIntBig> oSetUsedFIDs_{};
     175             : 
     176             :     /** Ensure the FID of the feature is unique */
     177             :     OGRFeature *EnsureUniqueFID(OGRFeature *poFeat);
     178             : 
     179             :     /** Return next feature (without filter) */
     180             :     OGRFeature *GetNextRawFeature();
     181             : 
     182             :     CPL_DISALLOW_COPY_ASSIGN(OGRJSONFGStreamedLayer)
     183             : };
     184             : 
     185             : /************************************************************************/
     186             : /*                         OGRJSONFGWriteLayer                          */
     187             : /************************************************************************/
     188             : 
     189             : class OGRJSONFGDataset;
     190             : 
     191             : class OGRJSONFGWriteLayer final : public OGRLayer
     192             : {
     193             :   public:
     194             :     OGRJSONFGWriteLayer(
     195             :         const char *pszName, const OGRSpatialReference *poSRS,
     196             :         std::unique_ptr<OGRCoordinateTransformation> &&poCTToWGS84,
     197             :         const std::string &osCoordRefSys, OGRwkbGeometryType eGType,
     198             :         CSLConstList papszOptions, OGRJSONFGDataset *poDS);
     199             :     ~OGRJSONFGWriteLayer();
     200             : 
     201             :     //
     202             :     // OGRLayer Interface
     203             :     //
     204         687 :     OGRFeatureDefn *GetLayerDefn() override
     205             :     {
     206         687 :         return poFeatureDefn_;
     207             :     }
     208             : 
     209           1 :     OGRSpatialReference *GetSpatialRef() override
     210             :     {
     211           1 :         return nullptr;
     212             :     }
     213             : 
     214          16 :     void ResetReading() override
     215             :     {
     216          16 :     }
     217             : 
     218          16 :     OGRFeature *GetNextFeature() override
     219             :     {
     220          16 :         return nullptr;
     221             :     }
     222             : 
     223             :     OGRErr ICreateFeature(OGRFeature *poFeature) override;
     224             :     OGRErr CreateField(const OGRFieldDefn *poField, int bApproxOK) override;
     225             :     int TestCapability(const char *pszCap) override;
     226             : 
     227             :     OGRErr SyncToDisk() override;
     228             : 
     229             :     GDALDataset *GetDataset() override;
     230             : 
     231             :   private:
     232             :     OGRJSONFGDataset *poDS_{};
     233             :     OGRFeatureDefn *poFeatureDefn_ = nullptr;
     234             :     std::unique_ptr<OGRCoordinateTransformation> poCTToWGS84_;
     235             :     bool bIsWGS84CRS_ = false;
     236             :     bool m_bMustSwapForPlace = false;
     237             :     int nOutCounter_ = 0;
     238             :     std::string osCoordRefSys_{};
     239             : 
     240             :     OGRGeoJSONWriteOptions oWriteOptions_{};
     241             :     OGRGeoJSONWriteOptions oWriteOptionsPlace_{};
     242             :     bool bWriteFallbackGeometry_ = true;
     243             : 
     244             :     CPL_DISALLOW_COPY_ASSIGN(OGRJSONFGWriteLayer)
     245             : };
     246             : 
     247             : /************************************************************************/
     248             : /*                           OGRJSONFGDataset                           */
     249             : /************************************************************************/
     250             : 
     251             : class OGRJSONFGReader;
     252             : 
     253             : class OGRJSONFGDataset final : public GDALDataset
     254             : {
     255             :   public:
     256         211 :     OGRJSONFGDataset() = default;
     257             :     ~OGRJSONFGDataset();
     258             : 
     259             :     bool Open(GDALOpenInfo *poOpenInfo, GeoJSONSourceType nSrcType);
     260             :     bool Create(const char *pszName, CSLConstList papszOptions);
     261             : 
     262          43 :     int GetLayerCount() override
     263             :     {
     264          43 :         return static_cast<int>(apoLayers_.size());
     265             :     }
     266             : 
     267             :     OGRLayer *GetLayer(int i) override;
     268             : 
     269             :     //! Return the output file handle. Used by OGRJSONFGWriteLayer
     270         230 :     VSILFILE *GetOutputFile() const
     271             :     {
     272         230 :         return fpOut_;
     273             :     }
     274             : 
     275             :     /** Return whether there is a single output layer.
     276             :      * Used by OGRJSONFGWriteLayer
     277             :      */
     278         240 :     bool IsSingleOutputLayer() const
     279             :     {
     280         240 :         return bSingleOutputLayer_;
     281             :     }
     282             : 
     283             :     //! Return whether the output file is seekable
     284           2 :     bool GetFpOutputIsSeekable() const
     285             :     {
     286           2 :         return bFpOutputIsSeekable_;
     287             :     }
     288             : 
     289             :     void BeforeCreateFeature();
     290             : 
     291             :     OGRLayer *ICreateLayer(const char *pszName,
     292             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     293             :                            CSLConstList papszOptions) override;
     294             : 
     295             :     int TestCapability(const char *pszCap) override;
     296             : 
     297             :     OGRErr SyncToDiskInternal();
     298             : 
     299             :   protected:
     300             :     friend class OGRJSONFGReader;
     301             :     OGRJSONFGMemLayer *AddLayer(std::unique_ptr<OGRJSONFGMemLayer> &&poLayer);
     302             :     OGRJSONFGStreamedLayer *
     303             :     AddLayer(std::unique_ptr<OGRJSONFGStreamedLayer> &&poLayer);
     304             : 
     305             :   private:
     306             :     char *pszGeoData_ = nullptr;
     307             :     size_t nGeoDataLen_ = 0;
     308             :     std::vector<std::unique_ptr<OGRLayer>> apoLayers_{};
     309             :     std::unique_ptr<OGRJSONFGReader> poReader_{};
     310             : 
     311             :     // Write side
     312             :     VSILFILE *fpOut_ = nullptr;
     313             :     bool bSingleOutputLayer_ = false;
     314             :     bool bHasEmittedFeatures_ = false;
     315             :     bool bFpOutputIsSeekable_ = false;
     316             : 
     317             :     /** Offset at which the '] }' terminating sequence has already been
     318             :      * written by SyncToDisk(). 0 if it has not been written.
     319             :      */
     320             :     vsi_l_offset m_nPositionBeforeFCClosed = 0;
     321             : 
     322             :     bool ReadFromFile(GDALOpenInfo *poOpenInfo, const char *pszUnprefixed);
     323             :     bool ReadFromService(GDALOpenInfo *poOpenInfo, const char *pszSource);
     324             : 
     325             :     void FinishWriting();
     326             : 
     327             :     bool EmitStartFeaturesIfNeededAndReturnIfFirstFeature();
     328             : 
     329             :     CPL_DISALLOW_COPY_ASSIGN(OGRJSONFGDataset)
     330             : };
     331             : 
     332             : /************************************************************************/
     333             : /*                          OGRJSONFGReader                             */
     334             : /************************************************************************/
     335             : 
     336             : class OGRJSONFGReader
     337             : {
     338             :   public:
     339         141 :     OGRJSONFGReader() = default;
     340             :     ~OGRJSONFGReader();
     341             : 
     342             :     /** Load all features from the passed in JSON text in OGRJSONFGMemLayer(s)
     343             :      *
     344             :      * This method should only be called once, and is exclusive with
     345             :      * AnalyzeWithStreamingParser()
     346             :      */
     347             :     bool Load(OGRJSONFGDataset *poDS, const char *pszText,
     348             :               const std::string &osDefaultLayerName);
     349             : 
     350             :     /** Do a first pass analysis of the content of the passed file to create
     351             :      * OGRJSONFGStreamedLayer's
     352             :      *
     353             :      * It is the responsibility of the caller to call
     354             :      * SetFile() and SetStreamingParser() on the created layers afterwards
     355             :      *
     356             :      * This method should only be called once, and is exclusive with
     357             :      * Load()
     358             :      */
     359             :     bool AnalyzeWithStreamingParser(OGRJSONFGDataset *poDS, VSILFILE *fp,
     360             :                                     const std::string &osDefaultLayerName,
     361             :                                     bool &bCanTryWithNonStreamingParserOut);
     362             : 
     363             :     /** Geometry element we are interested in. */
     364             :     enum class GeometryElement
     365             :     {
     366             :         /** Use "place" when possible, fallback to "geometry" otherwise. */
     367             :         AUTO,
     368             :         /** Only use "place" */
     369             :         PLACE,
     370             :         /** Only use "geometry" */
     371             :         GEOMETRY,
     372             :     };
     373             : 
     374             :     /** Sets the geometry element we are interested in. */
     375           6 :     void SetGeometryElement(GeometryElement elt)
     376             :     {
     377           6 :         eGeometryElement_ = elt;
     378           6 :     }
     379             : 
     380             :     /** Returns a OGRFeature built from the passed in JSON object.
     381             :      *
     382             :      * @param poObj JSON feature
     383             :      * @param pszRequestedLayer name of the layer of interest, or nullptr if
     384             :      * no filtering needed on the layer name. If the feature does not belong
     385             :      * to the requested layer, nullptr is returned.
     386             :      * @param pOutMemLayer Pointer to the OGRJSONFGMemLayer* layer to which
     387             :      * the returned feature belongs to. May be nullptr. Only applies when
     388             :      * the Load() method has been used.
     389             :      * @param pOutStreamedLayer Pointer to the OGRJSONFGStreamedLayer* layer to
     390             :      * which the returned feature belongs to. May be nullptr. Only applies when
     391             :      * the AnalyzeWithStreamingParser() method has been used.
     392             :      */
     393             :     std::unique_ptr<OGRFeature>
     394             :     ReadFeature(json_object *poObj, const char *pszRequestedLayer,
     395             :                 OGRJSONFGMemLayer **pOutMemLayer,
     396             :                 OGRJSONFGStreamedLayer **pOutStreamedLayer);
     397             : 
     398             :   protected:
     399             :     friend class OGRJSONFGStreamingParser;
     400             : 
     401             :     bool GenerateLayerDefnFromFeature(json_object *poObj);
     402             : 
     403             :   private:
     404             :     GeometryElement eGeometryElement_ = GeometryElement::AUTO;
     405             : 
     406             :     OGRJSONFGDataset *poDS_ = nullptr;
     407             :     std::string osDefaultLayerName_{};
     408             :     json_object *poObject_ = nullptr;
     409             : 
     410             :     bool bFlattenNestedAttributes_ = false;
     411             :     char chNestedAttributeSeparator_ = 0;
     412             :     bool bArrayAsString_ = false;
     413             :     bool bDateAsString_ = false;
     414             : 
     415             :     /** Layer building context, specific to one layer. */
     416         153 :     struct LayerDefnBuildContext
     417             :     {
     418             :         //! Maps a field name to its index in apoFieldDefn[]
     419             :         std::map<std::string, int> oMapFieldNameToIdx{};
     420             : 
     421             :         //! Vector of OGRFieldDefn
     422             :         std::vector<std::unique_ptr<OGRFieldDefn>> apoFieldDefn{};
     423             : 
     424             :         //! Directed acyclic graph used to build the order of fields.
     425             :         gdal::DirectedAcyclicGraph<int, std::string> dag{};
     426             : 
     427             :         /** Set of indices of apoFieldDefn[] for which no type information is
     428             :          * known yet. */
     429             :         std::set<int> aoSetUndeterminedTypeFields{};
     430             : 
     431             :         //! Whether at least one feature has a "coordRefSys" member.
     432             :         bool bHasCoordRefSysAtFeatureLevel = false;
     433             : 
     434             :         /** CRS object corresponding to "coordRefsys" member at feature level.
     435             :          * Only set if homogeneous among features.
     436             :          */
     437             :         std::unique_ptr<OGRSpatialReference> poCRSAtFeatureLevel{};
     438             : 
     439             :         /** Serialized JSON value of "coordRefsys" member at feature level.
     440             :          * Only set if homogeneous among features.
     441             :          */
     442             :         std::string osCoordRefSysAtFeatureLevel{};
     443             : 
     444             :         /** Whether to switch X/Y ordinates in geometries appearing in "place"
     445             :          * element. Only applies to CRS at layer level.
     446             :          */
     447             :         bool bSwapPlacesXY = false;
     448             : 
     449             :         //! Whether the layer CRS is WGS 84.
     450             :         bool bLayerCRSIsWGS84 = false;
     451             : 
     452             :         //! Coordinate transformation from WGS 84 to layer CRS (might be null)
     453             :         std::unique_ptr<OGRCoordinateTransformation> poCTWGS84ToLayerCRS{};
     454             : 
     455             :         /** Feature count */
     456             :         GIntBig nFeatureCount = 0;
     457             : 
     458             :         //! Whether the Feature.id should be mapped to a OGR field.
     459             :         bool bFeatureLevelIdAsAttribute = false;
     460             : 
     461             :         //! Whether the Feature.id should be mapped to a OGR FID.
     462             :         bool bFeatureLevelIdAsFID = false;
     463             : 
     464             :         //! Whether 64-bit integers are needed for OGR FID.
     465             :         bool bNeedFID64 = false;
     466             : 
     467             :         //! Whether detection of layer geometry type is still needed.
     468             :         bool bDetectLayerGeomType = true;
     469             : 
     470             :         //! Whether no geometry has been analyzed yet.
     471             :         bool bFirstGeometry = true;
     472             : 
     473             :         //! Layer geometry type.
     474             :         OGRwkbGeometryType eLayerGeomType = wkbUnknown;
     475             : 
     476             :         //! Whether a Feature.time.date element has been found.
     477             :         bool bHasTimeDate = false;
     478             : 
     479             :         //! Whether a Feature.time.timestamp element has been found.
     480             :         bool bHasTimeTimestamp = false;
     481             : 
     482             :         /** Whether a Feature.time.interval[0] element of type timestamp has
     483             :          * been found */
     484             :         bool bHasTimeIntervalStartTimestamp = false;
     485             : 
     486             :         /** Whether a Feature.time.interval[0] element of type date has
     487             :          * been found */
     488             :         bool bHasTimeIntervalStartDate = false;
     489             : 
     490             :         /** Whether a Feature.time.interval[1] element of type timestamp has
     491             :          * been found */
     492             :         bool bHasTimeIntervalEndTimestamp = false;
     493             : 
     494             :         /** Whether a Feature.time.interval[1] element of type date has
     495             :          * been found */
     496             :         bool bHasTimeIntervalEndDate = false;
     497             : 
     498             :         //! Index of OGR field "time" / "jsonfg_time"
     499             :         int nIdxFieldTime = -1;
     500             : 
     501             :         //! Index of OGR field "time_start" / "jsonfg_time_start"
     502             :         int nIdxFieldTimeStart = -1;
     503             : 
     504             :         //! Index of OGR field "time_end" / "jsonfg_time_end"
     505             :         int nIdxFieldTimeEnd = -1;
     506             : 
     507             :         //! Corresponding OGRJSONFGMemLayer (only for Load() ingestion mode)
     508             :         OGRJSONFGMemLayer *poMemLayer = nullptr;
     509             : 
     510             :         /** Corresponding OGRJSONFGStreamedLayer(only for
     511             :          * AnalyzeWithStreamingParser() mode) */
     512             :         OGRJSONFGStreamedLayer *poStreamedLayer = nullptr;
     513             : 
     514         294 :         LayerDefnBuildContext() = default;
     515          12 :         LayerDefnBuildContext(LayerDefnBuildContext &&) = default;
     516             :         LayerDefnBuildContext &operator=(LayerDefnBuildContext &&) = default;
     517             : 
     518             :       private:
     519             :         CPL_DISALLOW_COPY_ASSIGN(LayerDefnBuildContext)
     520             :     };
     521             : 
     522             :     //! Maps a layer name to its build context
     523             :     std::map<std::string, LayerDefnBuildContext> oMapBuildContext_{};
     524             : 
     525             :     //
     526             :     // Copy operations not supported.
     527             :     //
     528             :     CPL_DISALLOW_COPY_ASSIGN(OGRJSONFGReader)
     529             : 
     530             :     const char *GetLayerNameForFeature(json_object *poObj) const;
     531             :     bool GenerateLayerDefns();
     532             :     bool FinalizeGenerateLayerDefns(bool bStreamedLayer);
     533             :     void FinalizeBuildContext(LayerDefnBuildContext &oBuildContext,
     534             :                               const char *pszLayerName, bool bStreamedLayer,
     535             :                               bool bInvalidCRS, bool bSwapPlacesXYTopLevel,
     536             :                               OGRSpatialReference *poSRSTopLevel);
     537             : };
     538             : 
     539             : /************************************************************************/
     540             : /*                      OGRJSONFGStreamingParser                        */
     541             : /************************************************************************/
     542             : 
     543             : /** FeatureCollection streaming parser. */
     544         478 : class OGRJSONFGStreamingParser final : public OGRJSONCollectionStreamingParser
     545             : {
     546             :     OGRJSONFGReader &m_oReader;
     547             :     std::string m_osRequestedLayer{};
     548             : 
     549             :     std::vector<std::pair<std::unique_ptr<OGRFeature>, OGRLayer *>>
     550             :         m_apoFeatures{};
     551             :     size_t m_nCurFeatureIdx = 0;
     552             : 
     553             :     CPL_DISALLOW_COPY_ASSIGN(OGRJSONFGStreamingParser)
     554             : 
     555             :   protected:
     556             :     void GotFeature(json_object *poObj, bool bFirstPass,
     557             :                     const std::string &osJson) override;
     558             :     void TooComplex() override;
     559             : 
     560             :   public:
     561             :     OGRJSONFGStreamingParser(OGRJSONFGReader &oReader, bool bFirstPass);
     562             :     ~OGRJSONFGStreamingParser();
     563             : 
     564          92 :     void SetRequestedLayer(const char *pszRequestedLayer)
     565             :     {
     566          92 :         m_osRequestedLayer = pszRequestedLayer;
     567          92 :     }
     568             : 
     569             :     std::unique_ptr<OGRJSONFGStreamingParser> Clone();
     570             : 
     571             :     std::pair<std::unique_ptr<OGRFeature>, OGRLayer *> GetNextFeature();
     572             : };
     573             : 
     574             : bool OGRJSONFGMustSwapXY(const OGRSpatialReference *poSRS);
     575             : 
     576             : #endif  // OGR_JSONFG_H_INCLUDED

Generated by: LCOV version 1.14