LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/jsonfg - ogrjsonfgstreamedlayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 70 80 87.5 %
Date: 2024-11-21 22:18:42 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          96 : OGRJSONFGStreamedLayer::OGRJSONFGStreamedLayer(GDALDataset *poDS,
      20             :                                                const char *pszName,
      21             :                                                OGRSpatialReference *poSRS,
      22          96 :                                                OGRwkbGeometryType eGType)
      23          96 :     : m_poDS(poDS), poFeatureDefn_(new OGRFeatureDefn(pszName))
      24             : {
      25             : 
      26          96 :     poFeatureDefn_->Reference();
      27             : 
      28          96 :     SetDescription(poFeatureDefn_->GetName());
      29          96 :     poFeatureDefn_->SetGeomType(eGType);
      30             : 
      31          96 :     if (eGType != wkbNone && poSRS != nullptr)
      32             :     {
      33          95 :         OGRSpatialReference *poSRSClone = poSRS->Clone();
      34          95 :         poFeatureDefn_->GetGeomFieldDefn(0)->SetSpatialRef(poSRSClone);
      35          95 :         poSRSClone->Release();
      36             :     }
      37             : 
      38          96 :     poFeatureDefn_->Seal(/* bSealFields = */ true);
      39          96 : }
      40             : 
      41             : /************************************************************************/
      42             : /*           OGRJSONFGStreamedLayer::~OGRJSONFGStreamedLayer()          */
      43             : /************************************************************************/
      44             : 
      45         192 : OGRJSONFGStreamedLayer::~OGRJSONFGStreamedLayer()
      46             : {
      47          96 :     poFeatureDefn_->Release();
      48         192 : }
      49             : 
      50             : /************************************************************************/
      51             : /*                            SetFile()                                 */
      52             : /************************************************************************/
      53             : 
      54          96 : void OGRJSONFGStreamedLayer::SetFile(VSIVirtualHandleUniquePtr &&poFile)
      55             : {
      56          96 :     poFile_ = std::move(poFile);
      57          96 :     poFile_->Seek(0, SEEK_SET);
      58          96 : }
      59             : 
      60             : /************************************************************************/
      61             : /*                        SetStreamingParser()                          */
      62             : /************************************************************************/
      63             : 
      64          96 : void OGRJSONFGStreamedLayer::SetStreamingParser(
      65             :     std::unique_ptr<OGRJSONFGStreamingParser> &&poStreamingParser)
      66             : {
      67          96 :     poStreamingParser_ = std::move(poStreamingParser);
      68          96 :     poStreamingParser_->SetRequestedLayer(GetName());
      69          96 : }
      70             : 
      71             : /************************************************************************/
      72             : /*                           ResetReading()                             */
      73             : /************************************************************************/
      74             : 
      75         103 : void OGRJSONFGStreamedLayer::ResetReading()
      76             : {
      77         103 :     CPLAssert(poFile_);
      78         103 :     CPLAssert(poStreamingParser_);
      79         103 :     poStreamingParser_ = poStreamingParser_->Clone();
      80         103 :     poFile_->Seek(0, SEEK_SET);
      81         103 :     oSetUsedFIDs_.clear();
      82         103 : }
      83             : 
      84             : /************************************************************************/
      85             : /*                             EnsureUniqueFID()                                 */
      86             : /************************************************************************/
      87             : 
      88         388 : OGRFeature *OGRJSONFGStreamedLayer::EnsureUniqueFID(OGRFeature *poFeat)
      89             : {
      90         388 :     GIntBig nFID = poFeat->GetFID();
      91         388 :     if (nFID == OGRNullFID)
      92             :     {
      93         358 :         nFID = static_cast<GIntBig>(oSetUsedFIDs_.size());
      94         358 :         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         388 :     oSetUsedFIDs_.insert(nFID);
     118         388 :     poFeat->SetFID(nFID);
     119         388 :     return poFeat;
     120             : }
     121             : 
     122             : /************************************************************************/
     123             : /*                        GetNextRawFeature()                           */
     124             : /************************************************************************/
     125             : 
     126         419 : OGRFeature *OGRJSONFGStreamedLayer::GetNextRawFeature()
     127             : {
     128         419 :     CPLAssert(poFile_);
     129         419 :     CPLAssert(poStreamingParser_);
     130             : 
     131         838 :     auto poFeatAndLayer = poStreamingParser_->GetNextFeature();
     132         419 :     if (poFeatAndLayer.first)
     133             :     {
     134         295 :         return EnsureUniqueFID(poFeatAndLayer.first.release());
     135             :     }
     136             : 
     137         248 :     std::vector<GByte> abyBuffer;
     138         124 :     abyBuffer.resize(4096 * 10);
     139             :     while (true)
     140             :     {
     141         124 :         size_t nRead = poFile_->Read(abyBuffer.data(), 1, abyBuffer.size());
     142         124 :         const bool bFinished = nRead < abyBuffer.size();
     143         248 :         if (!poStreamingParser_->Parse(
     144         124 :                 reinterpret_cast<const char *>(abyBuffer.data()), nRead,
     145         372 :                 bFinished) ||
     146         124 :             poStreamingParser_->ExceptionOccurred())
     147             :         {
     148           0 :             break;
     149             :         }
     150             : 
     151         124 :         poFeatAndLayer = poStreamingParser_->GetNextFeature();
     152         124 :         if (poFeatAndLayer.first)
     153             :         {
     154          93 :             return EnsureUniqueFID(poFeatAndLayer.first.release());
     155             :         }
     156          31 :         if (bFinished)
     157          31 :             break;
     158           0 :     }
     159             : 
     160          31 :     return nullptr;
     161             : }
     162             : 
     163             : /************************************************************************/
     164             : /*                           TestCapability()                           */
     165             : /************************************************************************/
     166             : 
     167          36 : int OGRJSONFGStreamedLayer::TestCapability(const char *pszCap)
     168             : 
     169             : {
     170          36 :     if (EQUAL(pszCap, OLCFastFeatureCount))
     171           0 :         return !m_poFilterGeom && !m_poAttrQuery && nFeatureCount_ >= 0;
     172             : 
     173          36 :     else if (EQUAL(pszCap, OLCStringsAsUTF8))
     174          13 :         return TRUE;
     175             : 
     176          23 :     else if (EQUAL(pszCap, OLCZGeometries))
     177           3 :         return TRUE;
     178             : 
     179          20 :     return FALSE;
     180             : }
     181             : 
     182             : /************************************************************************/
     183             : /*                           GetFeatureCount()                          */
     184             : /************************************************************************/
     185             : 
     186          19 : GIntBig OGRJSONFGStreamedLayer::GetFeatureCount(int bForce)
     187             : {
     188          19 :     if (!m_poFilterGeom && !m_poAttrQuery && nFeatureCount_ >= 0)
     189          13 :         return nFeatureCount_;
     190           6 :     return OGRLayer::GetFeatureCount(bForce);
     191             : }

Generated by: LCOV version 1.14