LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/jsonfg - ogrjsonfgstreamedlayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 72 82 87.8 %
Date: 2025-10-22 13:51:22 Functions: 10 10 100.0 %

          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             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "ogr_jsonfg.h"
      14             : 
      15             : /************************************************************************/
      16             : /*             OGRJSONFGStreamedLayer::OGRJSONFGStreamedLayer()         */
      17             : /************************************************************************/
      18             : 
      19         130 : OGRJSONFGStreamedLayer::OGRJSONFGStreamedLayer(GDALDataset *poDS,
      20             :                                                const char *pszName,
      21             :                                                OGRSpatialReference *poSRS,
      22         130 :                                                OGRwkbGeometryType eGType)
      23         130 :     : m_poDS(poDS), poFeatureDefn_(new OGRFeatureDefn(pszName))
      24             : {
      25             : 
      26         130 :     poFeatureDefn_->Reference();
      27             : 
      28         130 :     SetDescription(poFeatureDefn_->GetName());
      29         130 :     poFeatureDefn_->SetGeomType(eGType);
      30             : 
      31         130 :     if (eGType != wkbNone && poSRS != nullptr)
      32             :     {
      33         129 :         OGRSpatialReference *poSRSClone = poSRS->Clone();
      34         129 :         poFeatureDefn_->GetGeomFieldDefn(0)->SetSpatialRef(poSRSClone);
      35         129 :         poSRSClone->Release();
      36             :     }
      37             : 
      38         130 :     poFeatureDefn_->Seal(/* bSealFields = */ true);
      39         130 : }
      40             : 
      41             : /************************************************************************/
      42             : /*           OGRJSONFGStreamedLayer::~OGRJSONFGStreamedLayer()          */
      43             : /************************************************************************/
      44             : 
      45         260 : OGRJSONFGStreamedLayer::~OGRJSONFGStreamedLayer()
      46             : {
      47         130 :     poFeatureDefn_->Release();
      48         260 : }
      49             : 
      50             : /************************************************************************/
      51             : /*                            SetFile()                                 */
      52             : /************************************************************************/
      53             : 
      54         130 : void OGRJSONFGStreamedLayer::SetFile(VSIVirtualHandleUniquePtr &&poFile)
      55             : {
      56         130 :     poFile_ = std::move(poFile);
      57         130 :     poFile_->Seek(0, SEEK_SET);
      58         130 : }
      59             : 
      60             : /************************************************************************/
      61             : /*                        SetStreamingParser()                          */
      62             : /************************************************************************/
      63             : 
      64         130 : void OGRJSONFGStreamedLayer::SetStreamingParser(
      65             :     std::unique_ptr<OGRJSONFGStreamingParser> &&poStreamingParser)
      66             : {
      67         130 :     poStreamingParser_ = std::move(poStreamingParser);
      68         130 :     poStreamingParser_->SetRequestedLayer(GetName());
      69         130 : }
      70             : 
      71             : /************************************************************************/
      72             : /*                           ResetReading()                             */
      73             : /************************************************************************/
      74             : 
      75         107 : void OGRJSONFGStreamedLayer::ResetReading()
      76             : {
      77         107 :     CPLAssert(poFile_);
      78         107 :     CPLAssert(poStreamingParser_);
      79         107 :     poStreamingParser_ = poStreamingParser_->Clone();
      80         107 :     poFile_->Seek(0, SEEK_SET);
      81         107 :     oSetUsedFIDs_.clear();
      82         107 : }
      83             : 
      84             : /************************************************************************/
      85             : /*                             EnsureUniqueFID()                                 */
      86             : /************************************************************************/
      87             : 
      88         431 : OGRFeature *OGRJSONFGStreamedLayer::EnsureUniqueFID(OGRFeature *poFeat)
      89             : {
      90         431 :     GIntBig nFID = poFeat->GetFID();
      91         431 :     if (nFID == OGRNullFID)
      92             :     {
      93         401 :         nFID = static_cast<GIntBig>(oSetUsedFIDs_.size());
      94         401 :         while (oSetUsedFIDs_.find(nFID) != oSetUsedFIDs_.end())
      95             :         {
      96           0 :             ++nFID;
      97             :         }
      98             :     }
      99          30 :     else if (oSetUsedFIDs_.find(nFID) != oSetUsedFIDs_.end())
     100             :     {
     101           0 :         if (!bOriginalIdModified_)
     102             :         {
     103           0 :             CPLError(CE_Warning, CPLE_AppDefined,
     104             :                      "Several features with id = " CPL_FRMT_GIB " have "
     105             :                      "been found. Altering it to be unique. "
     106             :                      "This warning will not be emitted anymore for "
     107             :                      "this layer",
     108             :                      nFID);
     109           0 :             bOriginalIdModified_ = true;
     110             :         }
     111           0 :         nFID = static_cast<GIntBig>(oSetUsedFIDs_.size());
     112           0 :         while (oSetUsedFIDs_.find(nFID) != oSetUsedFIDs_.end())
     113             :         {
     114           0 :             ++nFID;
     115             :         }
     116             :     }
     117         431 :     oSetUsedFIDs_.insert(nFID);
     118         431 :     poFeat->SetFID(nFID);
     119         431 :     return poFeat;
     120             : }
     121             : 
     122             : /************************************************************************/
     123             : /*                        GetNextRawFeature()                           */
     124             : /************************************************************************/
     125             : 
     126         467 : OGRFeature *OGRJSONFGStreamedLayer::GetNextRawFeature()
     127             : {
     128         467 :     CPLAssert(poFile_);
     129         467 :     CPLAssert(poStreamingParser_);
     130             : 
     131         934 :     auto poFeatAndLayer = poStreamingParser_->GetNextFeature();
     132         467 :     if (poFeatAndLayer.first)
     133             :     {
     134         304 :         return EnsureUniqueFID(poFeatAndLayer.first.release());
     135             :     }
     136             : 
     137         326 :     std::vector<GByte> abyBuffer;
     138         163 :     abyBuffer.resize(4096 * 10);
     139             :     while (true)
     140             :     {
     141         163 :         size_t nRead = poFile_->Read(abyBuffer.data(), 1, abyBuffer.size());
     142         163 :         const bool bFinished = nRead < abyBuffer.size();
     143         326 :         if (!poStreamingParser_->Parse(
     144             :                 std::string_view(
     145         163 :                     reinterpret_cast<const char *>(abyBuffer.data()), nRead),
     146         489 :                 bFinished) ||
     147         163 :             poStreamingParser_->ExceptionOccurred())
     148             :         {
     149           0 :             break;
     150             :         }
     151             : 
     152         163 :         poFeatAndLayer = poStreamingParser_->GetNextFeature();
     153         163 :         if (poFeatAndLayer.first)
     154             :         {
     155         127 :             return EnsureUniqueFID(poFeatAndLayer.first.release());
     156             :         }
     157          36 :         if (bFinished)
     158          36 :             break;
     159           0 :     }
     160             : 
     161          36 :     return nullptr;
     162             : }
     163             : 
     164             : /************************************************************************/
     165             : /*                           TestCapability()                           */
     166             : /************************************************************************/
     167             : 
     168          39 : int OGRJSONFGStreamedLayer::TestCapability(const char *pszCap) const
     169             : 
     170             : {
     171          39 :     if (EQUAL(pszCap, OLCFastFeatureCount))
     172           0 :         return !m_poFilterGeom && !m_poAttrQuery && nFeatureCount_ >= 0;
     173             : 
     174          39 :     else if (EQUAL(pszCap, OLCStringsAsUTF8))
     175          13 :         return TRUE;
     176             : 
     177          26 :     else if (EQUAL(pszCap, OLCZGeometries) ||
     178          23 :              EQUAL(pszCap, OLCMeasuredGeometries) ||
     179          19 :              EQUAL(pszCap, OLCCurveGeometries))
     180             :     {
     181          11 :         return TRUE;
     182             :     }
     183             : 
     184          15 :     return FALSE;
     185             : }
     186             : 
     187             : /************************************************************************/
     188             : /*                           GetFeatureCount()                          */
     189             : /************************************************************************/
     190             : 
     191          19 : GIntBig OGRJSONFGStreamedLayer::GetFeatureCount(int bForce)
     192             : {
     193          19 :     if (!m_poFilterGeom && !m_poAttrQuery && nFeatureCount_ >= 0)
     194          13 :         return nFeatureCount_;
     195           6 :     return OGRLayer::GetFeatureCount(bForce);
     196             : }

Generated by: LCOV version 1.14