LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/geojson - ogrgeojsonlayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 218 249 87.6 %
Date: 2024-11-21 22:18:42 Functions: 24 29 82.8 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implementation of OGRGeoJSONLayer class (OGR GeoJSON Driver).
       5             :  * Author:   Mateusz Loskot, mateusz@loskot.net
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2007, Mateusz Loskot
       9             :  * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include <algorithm>
      15             : 
      16             : #if !DEBUG_JSON
      17             : #ifdef __clang__
      18             : #pragma clang diagnostic push
      19             : #pragma clang diagnostic ignored "-Wunknown-pragmas"
      20             : #pragma clang diagnostic ignored "-Wdocumentation"
      21             : #pragma clang diagnostic ignored "-Wold-style-cast"
      22             : #endif
      23             : #endif  // !DEBUG_VERBOSE
      24             : 
      25             : #include <json.h>
      26             : 
      27             : #if !DEBUG_JSON
      28             : #ifdef __clang
      29             : #pragma clang diagnostic pop
      30             : #endif
      31             : #endif  // !DEBUG_VERBOSE
      32             : 
      33             : #include "ogr_geojson.h"
      34             : #include "ogrgeojsonreader.h"
      35             : 
      36             : /************************************************************************/
      37             : /*                       STATIC MEMBERS DEFINITION                      */
      38             : /************************************************************************/
      39             : 
      40             : const char *const OGRGeoJSONLayer::DefaultName = "OGRGeoJSON";
      41             : const OGRwkbGeometryType OGRGeoJSONLayer::DefaultGeometryType = wkbUnknown;
      42             : 
      43             : /************************************************************************/
      44             : /*                           OGRGeoJSONLayer                            */
      45             : /************************************************************************/
      46             : 
      47         465 : OGRGeoJSONLayer::OGRGeoJSONLayer(const char *pszName,
      48             :                                  OGRSpatialReference *poSRSIn,
      49             :                                  OGRwkbGeometryType eGType,
      50             :                                  OGRGeoJSONDataSource *poDS,
      51         465 :                                  OGRGeoJSONReader *poReader)
      52             :     : OGRMemLayer(pszName, poSRSIn, eGType), poDS_(poDS), poReader_(poReader),
      53             :       bHasAppendedFeatures_(false), bOriginalIdModified_(false),
      54         465 :       nTotalFeatureCount_(0)
      55             : {
      56         465 :     SetAdvertizeUTF8(true);
      57         465 :     SetUpdatable(poDS->IsUpdatable());
      58         465 : }
      59             : 
      60             : /************************************************************************/
      61             : /*                          ~OGRGeoJSONLayer                            */
      62             : /************************************************************************/
      63             : 
      64         930 : OGRGeoJSONLayer::~OGRGeoJSONLayer()
      65             : {
      66         465 :     TerminateAppendSession();
      67         465 :     delete poReader_;
      68         930 : }
      69             : 
      70             : /************************************************************************/
      71             : /*                      TerminateAppendSession()                        */
      72             : /************************************************************************/
      73             : 
      74        1006 : void OGRGeoJSONLayer::TerminateAppendSession()
      75             : {
      76        1006 :     if (bHasAppendedFeatures_)
      77             :     {
      78             : #if defined(__GNUC__)
      79             : #pragma GCC diagnostic push
      80             : #pragma GCC diagnostic ignored "-Wnull-dereference"
      81             : #endif
      82           6 :         VSILFILE *fp = poReader_->GetFP();
      83             : #if defined(__GNUC__)
      84             : #pragma GCC diagnostic pop
      85             : #endif
      86           6 :         VSIFPrintfL(fp, "\n]\n}\n");
      87           6 :         VSIFFlushL(fp);
      88           6 :         bHasAppendedFeatures_ = false;
      89             :     }
      90        1006 : }
      91             : 
      92             : /************************************************************************/
      93             : /*                           GetFIDColumn                               */
      94             : /************************************************************************/
      95             : 
      96        1524 : const char *OGRGeoJSONLayer::GetFIDColumn()
      97             : {
      98        1524 :     return sFIDColumn_.c_str();
      99             : }
     100             : 
     101             : /************************************************************************/
     102             : /*                           SetFIDColumn                               */
     103             : /************************************************************************/
     104             : 
     105          46 : void OGRGeoJSONLayer::SetFIDColumn(const char *pszFIDColumn)
     106             : {
     107          46 :     sFIDColumn_ = pszFIDColumn;
     108          46 : }
     109             : 
     110             : /************************************************************************/
     111             : /*                            ResetReading()                            */
     112             : /************************************************************************/
     113             : 
     114        1306 : void OGRGeoJSONLayer::ResetReading()
     115             : {
     116        1306 :     nFeatureReadSinceReset_ = 0;
     117        1306 :     if (poReader_)
     118             :     {
     119         524 :         TerminateAppendSession();
     120         524 :         poReader_->ResetReading();
     121             :     }
     122             :     else
     123         782 :         OGRMemLayer::ResetReading();
     124        1306 : }
     125             : 
     126             : /************************************************************************/
     127             : /*                           GetNextFeature()                           */
     128             : /************************************************************************/
     129             : 
     130        1825 : OGRFeature *OGRGeoJSONLayer::GetNextFeature()
     131             : {
     132        1825 :     if (poReader_)
     133             :     {
     134        1117 :         if (bHasAppendedFeatures_)
     135             :         {
     136           1 :             ResetReading();
     137             :         }
     138             :         while (true)
     139             :         {
     140        1219 :             OGRFeature *poFeature = poReader_->GetNextFeature(this);
     141        1219 :             if (poFeature == nullptr)
     142         173 :                 return nullptr;
     143        2201 :             if ((m_poFilterGeom == nullptr ||
     144         109 :                  FilterGeometry(
     145        2092 :                      poFeature->GetGeomFieldRef(m_iGeomFieldFilter))) &&
     146        1018 :                 (m_poAttrQuery == nullptr ||
     147         151 :                  m_poAttrQuery->Evaluate(poFeature)))
     148             :             {
     149         944 :                 nFeatureReadSinceReset_++;
     150         944 :                 return poFeature;
     151             :             }
     152         102 :             delete poFeature;
     153         102 :         }
     154             :     }
     155             :     else
     156             :     {
     157         708 :         auto ret = OGRMemLayer::GetNextFeature();
     158         708 :         if (ret)
     159             :         {
     160         453 :             nFeatureReadSinceReset_++;
     161             :         }
     162         708 :         return ret;
     163             :     }
     164             : }
     165             : 
     166             : /************************************************************************/
     167             : /*                          GetFeatureCount()                           */
     168             : /************************************************************************/
     169             : 
     170         674 : GIntBig OGRGeoJSONLayer::GetFeatureCount(int bForce)
     171             : {
     172         674 :     if (poReader_)
     173             :     {
     174         364 :         if (m_poFilterGeom == nullptr && m_poAttrQuery == nullptr &&
     175         356 :             nTotalFeatureCount_ >= 0)
     176             :         {
     177         356 :             return nTotalFeatureCount_;
     178             :         }
     179           8 :         return OGRLayer::GetFeatureCount(bForce);
     180             :     }
     181             :     else
     182             :     {
     183         310 :         return OGRMemLayer::GetFeatureCount(bForce);
     184             :     }
     185             : }
     186             : 
     187             : /************************************************************************/
     188             : /*                            GetFeature()                              */
     189             : /************************************************************************/
     190             : 
     191         367 : OGRFeature *OGRGeoJSONLayer::GetFeature(GIntBig nFID)
     192             : {
     193         367 :     if (poReader_)
     194             :     {
     195          27 :         if (!IsUpdatable())
     196             :         {
     197          22 :             return poReader_->GetFeature(this, nFID);
     198             :         }
     199           5 :         return OGRLayer::GetFeature(nFID);
     200             :     }
     201             :     else
     202             :     {
     203         340 :         return OGRMemLayer::GetFeature(nFID);
     204             :     }
     205             : }
     206             : 
     207             : /************************************************************************/
     208             : /*                             IngestAll()                              */
     209             : /************************************************************************/
     210             : 
     211          16 : bool OGRGeoJSONLayer::IngestAll()
     212             : {
     213          16 :     if (poReader_)
     214             :     {
     215          14 :         TerminateAppendSession();
     216             : 
     217          14 :         OGRGeoJSONReader *poReader = poReader_;
     218          14 :         poReader_ = nullptr;
     219             : 
     220          14 :         nTotalFeatureCount_ = -1;
     221          14 :         bool bRet = poReader->IngestAll(this);
     222          14 :         delete poReader;
     223          14 :         return bRet;
     224             :     }
     225             :     else
     226             :     {
     227           2 :         return true;
     228             :     }
     229             : }
     230             : 
     231             : /************************************************************************/
     232             : /*                     SetOrUpdateFeaturePreparation()                  */
     233             : /************************************************************************/
     234             : 
     235         334 : bool OGRGeoJSONLayer::SetOrUpdateFeaturePreparation()
     236             : {
     237         334 :     if (!IsUpdatable())
     238           1 :         return false;
     239         333 :     if (poReader_)
     240             :     {
     241          10 :         auto nNextIndex = nFeatureReadSinceReset_;
     242          10 :         if (!IngestAll())
     243           0 :             return false;
     244          10 :         SetNextByIndex(nNextIndex);
     245             :     }
     246         333 :     return true;
     247             : }
     248             : 
     249             : /************************************************************************/
     250             : /*                           ISetFeature()                              */
     251             : /************************************************************************/
     252             : 
     253         328 : OGRErr OGRGeoJSONLayer::ISetFeature(OGRFeature *poFeature)
     254             : {
     255         328 :     if (!SetOrUpdateFeaturePreparation())
     256           1 :         return OGRERR_FAILURE;
     257         327 :     return OGRMemLayer::ISetFeature(poFeature);
     258             : }
     259             : 
     260             : /************************************************************************/
     261             : /*                         IUpdateFeature()                             */
     262             : /************************************************************************/
     263             : 
     264           6 : OGRErr OGRGeoJSONLayer::IUpdateFeature(OGRFeature *poFeature,
     265             :                                        int nUpdatedFieldsCount,
     266             :                                        const int *panUpdatedFieldsIdx,
     267             :                                        int nUpdatedGeomFieldsCount,
     268             :                                        const int *panUpdatedGeomFieldsIdx,
     269             :                                        bool bUpdateStyleString)
     270             : {
     271           6 :     if (!SetOrUpdateFeaturePreparation())
     272           0 :         return OGRERR_FAILURE;
     273           6 :     return OGRMemLayer::IUpdateFeature(
     274             :         poFeature, nUpdatedFieldsCount, panUpdatedFieldsIdx,
     275           6 :         nUpdatedGeomFieldsCount, panUpdatedGeomFieldsIdx, bUpdateStyleString);
     276             : }
     277             : 
     278             : /************************************************************************/
     279             : /*                         ICreateFeature()                             */
     280             : /************************************************************************/
     281             : 
     282         291 : OGRErr OGRGeoJSONLayer::ICreateFeature(OGRFeature *poFeature)
     283             : {
     284         291 :     if (!IsUpdatable())
     285           0 :         return OGRERR_FAILURE;
     286         291 :     if (poReader_)
     287             :     {
     288         290 :         bool bTryEasyAppend = true;
     289             :         while (true)
     290             :         {
     291             :             // We can trivially append to end of existing file, provided the
     292             :             // following conditions are met:
     293             :             // * the "features" array member is the last one of the main
     294             :             //   object (poReader_->CanEasilyAppend())
     295             :             // * there is no "bbox" at feature collection level (could possibly
     296             :             //   be supported)
     297             :             // * the features have no explicit FID field, so it is trivial to
     298             :             //   derive the FID of newly created features without collision
     299             :             // * we know the total number of existing features
     300         290 :             if (bTryEasyAppend && poReader_->CanEasilyAppend() &&
     301         289 :                 !poReader_->FCHasBBOX() && sFIDColumn_.empty() &&
     302         869 :                 GetLayerDefn()->GetFieldIndex("id") < 0 &&
     303         288 :                 nTotalFeatureCount_ >= 0)
     304             :             {
     305         288 :                 VSILFILE *fp = poReader_->GetFP();
     306         288 :                 if (!bHasAppendedFeatures_)
     307             :                 {
     308             :                     // Locate "} ] }" (or "[ ] }") pattern at end of file
     309           7 :                     VSIFSeekL(fp, 0, SEEK_END);
     310           7 :                     vsi_l_offset nOffset = VSIFTellL(fp);
     311           7 :                     nOffset -= 10;
     312           7 :                     VSIFSeekL(fp, nOffset, SEEK_SET);
     313             :                     char szBuffer[11];
     314           7 :                     VSIFReadL(szBuffer, 10, 1, fp);
     315           7 :                     szBuffer[10] = 0;
     316           7 :                     int i = 9;
     317             :                     // Locate final }
     318          11 :                     while (isspace(static_cast<unsigned char>(szBuffer[i])) &&
     319             :                            i > 0)
     320           4 :                         i--;
     321           7 :                     if (szBuffer[i] != '}')
     322             :                     {
     323           0 :                         bTryEasyAppend = false;
     324           0 :                         continue;
     325             :                     }
     326           7 :                     if (i > 0)
     327           7 :                         i--;
     328             :                     // Locate ']' ending features array
     329          12 :                     while (isspace(static_cast<unsigned char>(szBuffer[i])) &&
     330             :                            i > 0)
     331           5 :                         i--;
     332           7 :                     if (szBuffer[i] != ']')
     333             :                     {
     334           0 :                         bTryEasyAppend = false;
     335           0 :                         continue;
     336             :                     }
     337           7 :                     if (i > 0)
     338           7 :                         i--;
     339          13 :                     while (isspace(static_cast<unsigned char>(szBuffer[i])) &&
     340             :                            i > 0)
     341           6 :                         i--;
     342             :                     // Locate '}' ending last feature, or '[' starting features
     343             :                     // array
     344           7 :                     if (szBuffer[i] != '}' && szBuffer[i] != '[')
     345             :                     {
     346           1 :                         bTryEasyAppend = false;
     347           1 :                         continue;
     348             :                     }
     349           6 :                     bool bExistingFeature = szBuffer[i] == '}';
     350           6 :                     nOffset += i + 1;
     351           6 :                     VSIFSeekL(fp, nOffset, SEEK_SET);
     352           6 :                     if (bExistingFeature)
     353             :                     {
     354           5 :                         VSIFPrintfL(fp, ",");
     355             :                     }
     356           6 :                     VSIFPrintfL(fp, "\n");
     357           6 :                     bHasAppendedFeatures_ = true;
     358             :                 }
     359             :                 else
     360             :                 {
     361         281 :                     VSIFPrintfL(fp, ",\n");
     362             :                 }
     363             :                 json_object *poObj =
     364         287 :                     OGRGeoJSONWriteFeature(poFeature, oWriteOptions_);
     365         287 :                 VSIFPrintfL(fp, "%s", json_object_to_json_string(poObj));
     366         287 :                 json_object_put(poObj);
     367             : 
     368         287 :                 if (poFeature->GetFID() == OGRNullFID)
     369             :                 {
     370         287 :                     poFeature->SetFID(nTotalFeatureCount_);
     371             :                 }
     372         287 :                 nTotalFeatureCount_++;
     373             : 
     374         287 :                 return OGRERR_NONE;
     375             :             }
     376           3 :             else if (IngestAll())
     377             :             {
     378           3 :                 break;
     379             :             }
     380             :             else
     381             :             {
     382           0 :                 return OGRERR_FAILURE;
     383             :             }
     384           1 :         }
     385             :     }
     386           4 :     return OGRMemLayer::ICreateFeature(poFeature);
     387             : }
     388             : 
     389             : /************************************************************************/
     390             : /*                          DeleteFeature()                             */
     391             : /************************************************************************/
     392             : 
     393           5 : OGRErr OGRGeoJSONLayer::DeleteFeature(GIntBig nFID)
     394             : {
     395           5 :     if (!IsUpdatable() || !IngestAll())
     396           2 :         return OGRERR_FAILURE;
     397           3 :     return OGRMemLayer::DeleteFeature(nFID);
     398             : }
     399             : 
     400             : /************************************************************************/
     401             : /*                           CreateField()                              */
     402             : /************************************************************************/
     403             : 
     404           0 : OGRErr OGRGeoJSONLayer::CreateField(const OGRFieldDefn *poField, int bApproxOK)
     405             : {
     406           0 :     if (!IsUpdatable() || !IngestAll())
     407           0 :         return OGRERR_FAILURE;
     408           0 :     return OGRMemLayer::CreateField(poField, bApproxOK);
     409             : }
     410             : 
     411             : /************************************************************************/
     412             : /*                          DeleteField()                               */
     413             : /************************************************************************/
     414             : 
     415           0 : OGRErr OGRGeoJSONLayer::DeleteField(int iField)
     416             : {
     417           0 :     if (!IsUpdatable() || !IngestAll())
     418           0 :         return OGRERR_FAILURE;
     419           0 :     return OGRMemLayer::DeleteField(iField);
     420             : }
     421             : 
     422             : /************************************************************************/
     423             : /*                          ReorderFields()                             */
     424             : /************************************************************************/
     425             : 
     426           0 : OGRErr OGRGeoJSONLayer::ReorderFields(int *panMap)
     427             : {
     428           0 :     if (!IsUpdatable() || !IngestAll())
     429           0 :         return OGRERR_FAILURE;
     430           0 :     return OGRMemLayer::ReorderFields(panMap);
     431             : }
     432             : 
     433             : /************************************************************************/
     434             : /*                         AlterFieldDefn()                             */
     435             : /************************************************************************/
     436             : 
     437           0 : OGRErr OGRGeoJSONLayer::AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
     438             :                                        int nFlagsIn)
     439             : {
     440           0 :     if (!IsUpdatable() || !IngestAll())
     441           0 :         return OGRERR_FAILURE;
     442           0 :     return OGRMemLayer::AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
     443             : }
     444             : 
     445             : /************************************************************************/
     446             : /*                         CreateGeomField()                            */
     447             : /************************************************************************/
     448             : 
     449           0 : OGRErr OGRGeoJSONLayer::CreateGeomField(const OGRGeomFieldDefn *poGeomField,
     450             :                                         int bApproxOK)
     451             : {
     452           0 :     if (!IsUpdatable() || !IngestAll())
     453           0 :         return OGRERR_FAILURE;
     454           0 :     return OGRMemLayer::CreateGeomField(poGeomField, bApproxOK);
     455             : }
     456             : 
     457           5 : OGRErr OGRGeoJSONLayer::GetExtent(OGREnvelope *psExtent, int bForce)
     458             : {
     459           5 :     return GetExtent(0, psExtent, bForce);
     460             : }
     461             : 
     462          48 : OGRErr OGRGeoJSONLayer::GetExtent(int iGeomField, OGREnvelope *psExtent,
     463             :                                   int bForce)
     464             : {
     465          48 :     if (iGeomField != 0)
     466             :     {
     467           4 :         return OGRERR_FAILURE;
     468             :     }
     469             : 
     470          61 :     if (poReader_ && poReader_->ExtentRead() &&
     471          17 :         TestCapability(OLCFastGetExtent))
     472             :     {
     473          15 :         *psExtent = poReader_->GetExtent3D();
     474          15 :         return OGRERR_NONE;
     475             :     }
     476             :     else
     477             :     {
     478          29 :         return OGRMemLayer::GetExtentInternal(iGeomField, psExtent, bForce);
     479             :     }
     480             : }
     481             : 
     482          11 : OGRErr OGRGeoJSONLayer::GetExtent3D(int iGeomField, OGREnvelope3D *psExtent3D,
     483             :                                     int bForce)
     484             : {
     485             : 
     486          11 :     if (iGeomField != 0)
     487             :     {
     488           0 :         return OGRERR_FAILURE;
     489             :     }
     490             : 
     491          22 :     if (poReader_ && poReader_->ExtentRead() &&
     492          11 :         TestCapability(OLCFastGetExtent3D))
     493             :     {
     494           9 :         *psExtent3D = poReader_->GetExtent3D();
     495           9 :         return OGRERR_NONE;
     496             :     }
     497             :     else
     498             :     {
     499           2 :         return OGRMemLayer::GetExtent3D(iGeomField, psExtent3D, bForce);
     500             :     }
     501             : }
     502             : 
     503             : /************************************************************************/
     504             : /*                           TestCapability()                           */
     505             : /************************************************************************/
     506             : 
     507         561 : int OGRGeoJSONLayer::TestCapability(const char *pszCap)
     508             : 
     509             : {
     510         561 :     if (EQUAL(pszCap, OLCCurveGeometries))
     511         188 :         return FALSE;
     512         373 :     else if (EQUAL(pszCap, OLCZGeometries))
     513           6 :         return TRUE;
     514         367 :     else if (EQUAL(pszCap, OLCStringsAsUTF8))
     515          24 :         return TRUE;
     516         343 :     else if (EQUAL(pszCap, OLCFastGetExtent) ||
     517         320 :              EQUAL(pszCap, OLCFastGetExtent3D))
     518          38 :         return m_poFilterGeom == nullptr && m_poAttrQuery == nullptr;
     519         305 :     return OGRMemLayer::TestCapability(pszCap);
     520             : }
     521             : 
     522             : /************************************************************************/
     523             : /*                           SyncToDisk()                               */
     524             : /************************************************************************/
     525             : 
     526           3 : OGRErr OGRGeoJSONLayer::SyncToDisk()
     527             : {
     528           3 :     TerminateAppendSession();
     529             : 
     530           3 :     poDS_->FlushCache(false);
     531           3 :     return OGRERR_NONE;
     532             : }
     533             : 
     534             : /************************************************************************/
     535             : /*                           AddFeature                                 */
     536             : /************************************************************************/
     537             : 
     538         312 : void OGRGeoJSONLayer::AddFeature(OGRFeature *poFeature)
     539             : {
     540         312 :     GIntBig nFID = poFeature->GetFID();
     541             : 
     542             :     // Detect potential FID duplicates and make sure they are eventually
     543             :     // unique.
     544         312 :     if (-1 == nFID)
     545             :     {
     546         253 :         nFID = GetFeatureCount(FALSE);
     547         253 :         OGRFeature *poTryFeature = nullptr;
     548         253 :         while ((poTryFeature = GetFeature(nFID)) != nullptr)
     549             :         {
     550           0 :             nFID++;
     551           0 :             delete poTryFeature;
     552             :         }
     553             :     }
     554             :     else
     555             :     {
     556          59 :         OGRFeature *poTryFeature = nullptr;
     557          59 :         if ((poTryFeature = GetFeature(nFID)) != nullptr)
     558             :         {
     559           3 :             if (!bOriginalIdModified_)
     560             :             {
     561           2 :                 CPLError(
     562             :                     CE_Warning, CPLE_AppDefined,
     563             :                     "Several features with id = " CPL_FRMT_GIB " have been "
     564             :                     "found. Altering it to be unique. This warning will not "
     565             :                     "be emitted anymore for this layer",
     566             :                     nFID);
     567           2 :                 bOriginalIdModified_ = true;
     568             :             }
     569           3 :             delete poTryFeature;
     570           3 :             nFID = GetFeatureCount(FALSE);
     571           5 :             while ((poTryFeature = GetFeature(nFID)) != nullptr)
     572             :             {
     573           2 :                 nFID++;
     574           2 :                 delete poTryFeature;
     575             :             }
     576             :         }
     577             :     }
     578         312 :     poFeature->SetFID(nFID);
     579             : 
     580         312 :     if (!CPL_INT64_FITS_ON_INT32(nFID))
     581           2 :         SetMetadataItem(OLMD_FID64, "YES");
     582             : 
     583         312 :     const bool bIsUpdatable = IsUpdatable();
     584         312 :     SetUpdatable(true);  // Temporary toggle on updatable flag.
     585         312 :     CPL_IGNORE_RET_VAL(OGRMemLayer::SetFeature(poFeature));
     586         312 :     SetUpdatable(bIsUpdatable);
     587         312 :     SetUpdated(false);
     588         312 : }
     589             : 
     590             : /************************************************************************/
     591             : /*                           DetectGeometryType                         */
     592             : /************************************************************************/
     593             : 
     594         195 : void OGRGeoJSONLayer::DetectGeometryType()
     595             : {
     596         195 :     if (GetLayerDefn()->GetGeomType() != wkbUnknown)
     597          59 :         return;
     598             : 
     599         136 :     ResetReading();
     600         136 :     bool bFirstGeometry = true;
     601         136 :     OGRwkbGeometryType eLayerGeomType = wkbUnknown;
     602         273 :     for (const auto &poFeature : *this)
     603             :     {
     604         137 :         const OGRGeometry *poGeometry = poFeature->GetGeometryRef();
     605         137 :         if (nullptr != poGeometry)
     606             :         {
     607          80 :             OGRwkbGeometryType eGeomType = poGeometry->getGeometryType();
     608          80 :             if (!OGRGeoJSONUpdateLayerGeomType(bFirstGeometry, eGeomType,
     609             :                                                eLayerGeomType))
     610             :             {
     611           4 :                 break;
     612             :             }
     613             :         }
     614             :     }
     615             : 
     616             :     {
     617         136 :         auto poFDefn = GetLayerDefn();
     618         272 :         auto oTemporaryUnsealer(poFDefn->GetTemporaryUnsealer());
     619         136 :         poFDefn->SetGeomType(eLayerGeomType);
     620             :     }
     621             : 
     622         136 :     ResetReading();
     623             : }
     624             : 
     625             : /************************************************************************/
     626             : /*                             GetDataset()                             */
     627             : /************************************************************************/
     628             : 
     629           1 : GDALDataset *OGRGeoJSONLayer::GetDataset()
     630             : {
     631           1 :     return poDS_;
     632             : }

Generated by: LCOV version 1.14