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

Generated by: LCOV version 1.14