LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/geoconcept - ogrgeoconceptdatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 148 233 63.5 %
Date: 2024-04-28 23:18:46 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Name:     ogrgeoconceptdatasource.h
       4             :  * Project:  OpenGIS Simple Features Reference Implementation
       5             :  * Purpose:  Implements OGRGeoconceptDataSource class.
       6             :  * Language: C++
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2007, Geoconcept and IGN
      10             :  * Copyright (c) 2008, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * Permission is hereby granted, free of charge, to any person obtaining a
      13             :  * copy of this software and associated documentation files (the "Software"),
      14             :  * to deal in the Software without restriction, including without limitation
      15             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16             :  * and/or sell copies of the Software, and to permit persons to whom the
      17             :  * Software is furnished to do so, subject to the following conditions:
      18             :  *
      19             :  * The above copyright notice and this permission notice shall be included
      20             :  * in all copies or substantial portions of the Software.
      21             :  *
      22             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28             :  * DEALINGS IN THE SOFTWARE.
      29             :  ****************************************************************************/
      30             : 
      31             : #include "cpl_conv.h"
      32             : #include "cpl_string.h"
      33             : #include "ogrgeoconceptdatasource.h"
      34             : #include "ogrgeoconceptlayer.h"
      35             : 
      36             : /************************************************************************/
      37             : /*                         OGRGeoconceptDataSource()                    */
      38             : /************************************************************************/
      39             : 
      40          31 : OGRGeoconceptDataSource::OGRGeoconceptDataSource()
      41             :     : _papoLayers(nullptr), _nLayers(0), _pszGCT(nullptr), _pszName(nullptr),
      42             :       _pszDirectory(nullptr), _pszExt(nullptr), _papszOptions(nullptr),
      43          31 :       _bSingleNewFile(false), _bUpdate(false), _hGXT(nullptr)
      44             : {
      45          31 : }
      46             : 
      47             : /************************************************************************/
      48             : /*                        ~OGRGeoconceptDataSource()                    */
      49             : /************************************************************************/
      50             : 
      51          62 : OGRGeoconceptDataSource::~OGRGeoconceptDataSource()
      52             : 
      53             : {
      54          40 :     for (int i = 0; i < _nLayers; i++)
      55             :     {
      56           9 :         delete _papoLayers[i];
      57             :     }
      58          31 :     CPLFree(_papoLayers);
      59          31 :     CPLFree(_pszGCT);
      60          31 :     CPLFree(_pszName);
      61          31 :     CPLFree(_pszDirectory);
      62          31 :     CPLFree(_pszExt);
      63          31 :     CSLDestroy(_papszOptions);
      64             : 
      65          31 :     if (_hGXT)
      66             :     {
      67          25 :         Close_GCIO(&_hGXT);
      68             :     }
      69          62 : }
      70             : 
      71             : /************************************************************************/
      72             : /*                                Open()                                */
      73             : /*                                                                      */
      74             : /*      Open an existing file.                                          */
      75             : /************************************************************************/
      76             : 
      77          13 : int OGRGeoconceptDataSource::Open(const char *pszName, bool bTestOpen,
      78             :                                   bool bUpdate)
      79             : 
      80             : {
      81             :     /* -------------------------------------------------------------------- */
      82             :     /*      Is the given path a directory or a regular file?                */
      83             :     /* -------------------------------------------------------------------- */
      84             :     VSIStatBufL sStat;
      85             : 
      86          22 :     if (VSIStatL(pszName, &sStat) != 0 ||
      87           9 :         (!VSI_ISDIR(sStat.st_mode) && !VSI_ISREG(sStat.st_mode)))
      88             :     {
      89           4 :         if (!bTestOpen)
      90             :         {
      91           0 :             CPLError(CE_Failure, CPLE_AppDefined,
      92             :                      "%s is neither a file or directory, "
      93             :                      "Geoconcept access failed.",
      94             :                      pszName);
      95             :         }
      96             : 
      97           4 :         return FALSE;
      98             :     }
      99             : 
     100           9 :     if (VSI_ISDIR(sStat.st_mode))
     101             :     {
     102           0 :         CPLDebug("GEOCONCEPT",
     103             :                  "%s is a directory, Geoconcept access is not yet supported.",
     104             :                  pszName);
     105             : 
     106           0 :         return FALSE;
     107             :     }
     108             : 
     109           9 :     if (VSI_ISREG(sStat.st_mode))
     110             :     {
     111           9 :         _bSingleNewFile = false;
     112           9 :         _bUpdate = bUpdate;
     113           9 :         _pszName = CPLStrdup(pszName);
     114           9 :         if (!LoadFile(_bUpdate ? "a+t" : "rt"))
     115             :         {
     116           1 :             CPLDebug("GEOCONCEPT",
     117             :                      "Failed to open Geoconcept %s."
     118             :                      " It may be corrupt.",
     119             :                      pszName);
     120             : 
     121           1 :             return FALSE;
     122             :         }
     123             : 
     124           8 :         return TRUE;
     125             :     }
     126             : 
     127           0 :     return _nLayers > 0;
     128             : }
     129             : 
     130             : /************************************************************************/
     131             : /*                              LoadFile()                              */
     132             : /************************************************************************/
     133             : 
     134          26 : int OGRGeoconceptDataSource::LoadFile(const char *pszMode)
     135             : 
     136             : {
     137          26 :     if (_pszExt == nullptr)
     138             :     {
     139           9 :         const char *pszExtension = CPLGetExtension(_pszName);
     140           9 :         _pszExt = CPLStrdup(pszExtension);
     141             :     }
     142          26 :     CPLStrlwr(_pszExt);
     143             : 
     144          26 :     if (!_pszDirectory)
     145           9 :         _pszDirectory = CPLStrdup(CPLGetPath(_pszName));
     146             : 
     147          26 :     if ((_hGXT = Open_GCIO(_pszName, _pszExt, pszMode, _pszGCT)) == nullptr)
     148             :     {
     149           1 :         return FALSE;
     150             :     }
     151             : 
     152             :     /* Collect layers : */
     153          25 :     GCExportFileMetadata *Meta = GetGCMeta_GCIO(_hGXT);
     154          25 :     if (Meta)
     155             :     {
     156           8 :         const int nC = CountMetaTypes_GCIO(Meta);
     157             : 
     158           8 :         if (nC > 0)
     159             :         {
     160          16 :             for (int iC = 0; iC < nC; iC++)
     161             :             {
     162           8 :                 GCType *aClass = GetMetaType_GCIO(Meta, iC);
     163           8 :                 if (aClass)
     164             :                 {
     165           8 :                     const int nS = CountTypeSubtypes_GCIO(aClass);
     166           8 :                     if (nS)
     167             :                     {
     168          16 :                         for (int iS = 0; iS < nS; iS++)
     169             :                         {
     170             :                             GCSubType *aSubclass =
     171           8 :                                 GetTypeSubtype_GCIO(aClass, iS);
     172           8 :                             if (aSubclass)
     173             :                             {
     174             :                                 OGRGeoconceptLayer *poFile =
     175           8 :                                     new OGRGeoconceptLayer;
     176           8 :                                 if (poFile->Open(aSubclass) != OGRERR_NONE)
     177             :                                 {
     178           0 :                                     delete poFile;
     179           0 :                                     return FALSE;
     180             :                                 }
     181             : 
     182             :                                 /* Add layer to data source layers list */
     183           8 :                                 _papoLayers =
     184             :                                     static_cast<OGRGeoconceptLayer **>(
     185          16 :                                         CPLRealloc(
     186           8 :                                             _papoLayers,
     187             :                                             sizeof(OGRGeoconceptLayer *) *
     188           8 :                                                 (_nLayers + 1)));
     189           8 :                                 _papoLayers[_nLayers++] = poFile;
     190             : 
     191           8 :                                 CPLDebug("GEOCONCEPT", "nLayers=%d - last=[%s]",
     192             :                                          _nLayers,
     193           8 :                                          poFile->GetLayerDefn()->GetName());
     194             :                             }
     195             :                         }
     196             :                     }
     197             :                 }
     198             :             }
     199             :         }
     200             :     }
     201             : 
     202          25 :     return TRUE;
     203             : }
     204             : 
     205             : /************************************************************************/
     206             : /*                               Create()                               */
     207             : /*                                                                      */
     208             : /*      Create a new dataset.                                           */
     209             : /*                                                                      */
     210             : /* Options (-dsco) :                                                    */
     211             : /*   EXTENSION : gxt|txt                                                */
     212             : /*   CONFIG : path to GCT file                                          */
     213             : /************************************************************************/
     214             : 
     215          18 : int OGRGeoconceptDataSource::Create(const char *pszName, char **papszOptions)
     216             : 
     217             : {
     218          18 :     CPLFree(_pszName);
     219          18 :     _papszOptions = CSLDuplicate(papszOptions);
     220             : 
     221          18 :     const char *pszConf = CSLFetchNameValue(papszOptions, "CONFIG");
     222          18 :     if (pszConf != nullptr)
     223             :     {
     224           0 :         _pszGCT = CPLStrdup(pszConf);
     225             :     }
     226             : 
     227          18 :     _pszExt = (char *)CSLFetchNameValue(papszOptions, "EXTENSION");
     228          18 :     const char *pszExtension = CSLFetchNameValue(papszOptions, "EXTENSION");
     229          18 :     if (pszExtension == nullptr)
     230             :     {
     231          18 :         _pszExt = CPLStrdup(CPLGetExtension(pszName));
     232             :     }
     233             :     else
     234             :     {
     235           0 :         _pszExt = CPLStrdup(pszExtension);
     236             :     }
     237             : 
     238          18 :     if (strlen(_pszExt) == 0)
     239             :     {
     240          17 :         if (VSIMkdir(pszName, 0755) != 0)
     241             :         {
     242           1 :             CPLError(CE_Failure, CPLE_AppDefined,
     243             :                      "Directory %s already exists"
     244             :                      " as geoconcept datastore or"
     245             :                      " is made up of a non existing list of directories.",
     246             :                      pszName);
     247             : 
     248           1 :             return FALSE;
     249             :         }
     250          16 :         _pszDirectory = CPLStrdup(pszName);
     251          16 :         CPLFree(_pszExt);
     252          16 :         _pszExt = CPLStrdup("gxt");
     253          16 :         char *pszbName = CPLStrdup(CPLGetBasename(pszName));
     254          16 :         if (strlen(pszbName) == 0)
     255             :         { /* pszName ends with '/' */
     256           0 :             CPLFree(pszbName);
     257           0 :             char *pszNameDup = CPLStrdup(pszName);
     258           0 :             pszNameDup[strlen(pszName) - 2] = '\0';
     259           0 :             pszbName = CPLStrdup(CPLGetBasename(pszNameDup));
     260           0 :             CPLFree(pszNameDup);
     261             :         }
     262          16 :         _pszName = CPLStrdup(
     263          16 :             (char *)CPLFormFilename(_pszDirectory, pszbName, nullptr));
     264          16 :         CPLFree(pszbName);
     265             :     }
     266             :     else
     267             :     {
     268           1 :         _pszDirectory = CPLStrdup(CPLGetPath(pszName));
     269           1 :         _pszName = CPLStrdup(pszName);
     270             :     }
     271             : 
     272             :     /* -------------------------------------------------------------------- */
     273             :     /*      Create a new single file.                                       */
     274             :     /*      OGRGeoconceptDriver::ICreateLayer() will do the job.             */
     275             :     /* -------------------------------------------------------------------- */
     276          17 :     _bSingleNewFile = true;
     277             : 
     278          17 :     if (!LoadFile("wt"))
     279             :     {
     280           0 :         CPLDebug("GEOCONCEPT", "Failed to create Geoconcept %s.", pszName);
     281             : 
     282           0 :         return FALSE;
     283             :     }
     284             : 
     285          17 :     return TRUE;
     286             : }
     287             : 
     288             : /************************************************************************/
     289             : /*                           ICreateLayer()                             */
     290             : /*                                                                      */
     291             : /* Options (-lco) :                                                     */
     292             : /*   FEATURETYPE : TYPE.SUBTYPE                                         */
     293             : /************************************************************************/
     294             : 
     295             : OGRLayer *
     296          17 : OGRGeoconceptDataSource::ICreateLayer(const char *pszLayerName,
     297             :                                       const OGRGeomFieldDefn *poGeomFieldDefn,
     298             :                                       CSLConstList papszOptions)
     299             : 
     300             : {
     301          17 :     if (_hGXT == nullptr)
     302             :     {
     303           0 :         CPLError(CE_Failure, CPLE_NotSupported,
     304             :                  "Internal Error : null datasource handler.");
     305           0 :         return nullptr;
     306             :     }
     307             : 
     308             :     const auto poSRS =
     309          17 :         poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
     310          17 :     if (poSRS == nullptr && !_bUpdate)
     311             :     {
     312          16 :         CPLError(CE_Failure, CPLE_NotSupported,
     313             :                  "SRS is mandatory of creating a Geoconcept Layer.");
     314          16 :         return nullptr;
     315             :     }
     316             : 
     317             :     /*
     318             :      * pszLayerName Class.Subclass if -nln option used, otherwise file name
     319             :      */
     320           1 :     const char *pszFeatureType = nullptr;
     321             :     char pszln[512];
     322             : 
     323           1 :     if (!(pszFeatureType = CSLFetchNameValue(papszOptions, "FEATURETYPE")))
     324             :     {
     325           1 :         if (!pszLayerName || !strchr(pszLayerName, '.'))
     326             :         {
     327           1 :             snprintf(pszln, 511, "%s.%s",
     328             :                      pszLayerName ? pszLayerName : "ANONCLASS",
     329             :                      pszLayerName ? pszLayerName : "ANONSUBCLASS");
     330           1 :             pszln[511] = '\0';
     331           1 :             pszFeatureType = pszln;
     332             :         }
     333             :         else
     334           0 :             pszFeatureType = pszLayerName;
     335             :     }
     336             : 
     337           1 :     char **ft = CSLTokenizeString2(pszFeatureType, ".", 0);
     338           1 :     if (!ft || CSLCount(ft) != 2)
     339             :     {
     340           0 :         CSLDestroy(ft);
     341           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     342             :                  "Feature type name '%s' is incorrect."
     343             :                  "Correct syntax is : Class.Subclass.",
     344             :                  pszFeatureType);
     345           0 :         return nullptr;
     346             :     }
     347             : 
     348             :     /* -------------------------------------------------------------------- */
     349             :     /*      Figure out what type of layer we need.                          */
     350             :     /* -------------------------------------------------------------------- */
     351             :     GCTypeKind gcioFeaType;
     352           1 :     GCDim gcioDim = v2D_GCIO;
     353             : 
     354           1 :     const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
     355           1 :     if (eType == wkbUnknown)
     356           0 :         gcioFeaType = vUnknownItemType_GCIO;
     357           1 :     else if (eType == wkbPoint)
     358           1 :         gcioFeaType = vPoint_GCIO;
     359           0 :     else if (eType == wkbLineString)
     360           0 :         gcioFeaType = vLine_GCIO;
     361           0 :     else if (eType == wkbPolygon)
     362           0 :         gcioFeaType = vPoly_GCIO;
     363           0 :     else if (eType == wkbMultiPoint)
     364           0 :         gcioFeaType = vPoint_GCIO;
     365           0 :     else if (eType == wkbMultiLineString)
     366           0 :         gcioFeaType = vLine_GCIO;
     367           0 :     else if (eType == wkbMultiPolygon)
     368           0 :         gcioFeaType = vPoly_GCIO;
     369           0 :     else if (eType == wkbPoint25D)
     370             :     {
     371           0 :         gcioFeaType = vPoint_GCIO;
     372           0 :         gcioDim = v3DM_GCIO;
     373             :     }
     374           0 :     else if (eType == wkbLineString25D)
     375             :     {
     376           0 :         gcioFeaType = vLine_GCIO;
     377           0 :         gcioDim = v3DM_GCIO;
     378             :     }
     379           0 :     else if (eType == wkbPolygon25D)
     380             :     {
     381           0 :         gcioFeaType = vPoly_GCIO;
     382           0 :         gcioDim = v3DM_GCIO;
     383             :     }
     384           0 :     else if (eType == wkbMultiPoint25D)
     385             :     {
     386           0 :         gcioFeaType = vPoint_GCIO;
     387           0 :         gcioDim = v3DM_GCIO;
     388             :     }
     389           0 :     else if (eType == wkbMultiLineString25D)
     390             :     {
     391           0 :         gcioFeaType = vLine_GCIO;
     392           0 :         gcioDim = v3DM_GCIO;
     393             :     }
     394           0 :     else if (eType == wkbMultiPolygon25D)
     395             :     {
     396           0 :         gcioFeaType = vPoly_GCIO;
     397           0 :         gcioDim = v3DM_GCIO;
     398             :     }
     399             :     else
     400             :     {
     401           0 :         CSLDestroy(ft);
     402           0 :         CPLError(CE_Failure, CPLE_NotSupported,
     403             :                  "Geometry type of '%s' not supported in Geoconcept files.",
     404             :                  OGRGeometryTypeToName(eType));
     405           0 :         return nullptr;
     406             :     }
     407             : 
     408             :     /*
     409             :      * As long as we use the CONFIG, creating a layer implies the
     410             :      * layer name to exist in the CONFIG as "Class.Subclass".
     411             :      * Removing the CONFIG, implies on-the-fly-creation of layers...
     412             :      */
     413           1 :     OGRGeoconceptLayer *poFile = nullptr;
     414             : 
     415           1 :     if (_nLayers > 0)
     416           0 :         for (int iLayer = 0; iLayer < _nLayers; iLayer++)
     417             :         {
     418           0 :             poFile = reinterpret_cast<OGRGeoconceptLayer *>(GetLayer(iLayer));
     419           0 :             if (poFile != nullptr &&
     420           0 :                 EQUAL(poFile->GetLayerDefn()->GetName(), pszFeatureType))
     421             :             {
     422           0 :                 break;
     423             :             }
     424           0 :             poFile = nullptr;
     425             :         }
     426           1 :     if (!poFile)
     427             :     {
     428           1 :         GCSubType *aSubclass = nullptr;
     429           1 :         GCExportFileMetadata *m = GetGCMeta_GCIO(_hGXT);
     430             : 
     431           1 :         if (!m)
     432             :         {
     433           1 :             if (!(m = CreateHeader_GCIO()))
     434             :             {
     435           0 :                 CSLDestroy(ft);
     436           0 :                 return nullptr;
     437             :             }
     438           1 :             SetMetaExtent_GCIO(
     439             :                 m, CreateExtent_GCIO(HUGE_VAL, HUGE_VAL, -HUGE_VAL, -HUGE_VAL));
     440           1 :             SetGCMeta_GCIO(_hGXT, m);
     441             :         }
     442           1 :         if (FindFeature_GCIO(_hGXT, pszFeatureType))
     443             :         {
     444           0 :             CSLDestroy(ft);
     445           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Layer '%s' already exists.",
     446             :                      pszFeatureType);
     447           0 :             return nullptr;
     448             :         }
     449           1 :         if (!AddType_GCIO(_hGXT, ft[0], -1L))
     450             :         {
     451           0 :             CSLDestroy(ft);
     452           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Failed to add layer '%s'.",
     453             :                      pszFeatureType);
     454           0 :             return nullptr;
     455             :         }
     456           1 :         if (!(aSubclass = AddSubType_GCIO(_hGXT, ft[0], ft[1], -1L, gcioFeaType,
     457             :                                           gcioDim)))
     458             :         {
     459           0 :             CSLDestroy(ft);
     460           0 :             CPLError(CE_Failure, CPLE_AppDefined, "Failed to add layer '%s'.",
     461             :                      pszFeatureType);
     462           0 :             return nullptr;
     463             :         }
     464             :         /* complete feature type with private fields : */
     465           1 :         AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kIdentifier_GCIO, -100,
     466             :                              vIntFld_GCIO, nullptr, nullptr);
     467           1 :         AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kClass_GCIO, -101,
     468             :                              vMemoFld_GCIO, nullptr, nullptr);
     469           1 :         AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kSubclass_GCIO, -102,
     470             :                              vMemoFld_GCIO, nullptr, nullptr);
     471           1 :         AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kName_GCIO, -103,
     472             :                              vMemoFld_GCIO, nullptr, nullptr);
     473           1 :         AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kNbFields_GCIO, -104,
     474             :                              vIntFld_GCIO, nullptr, nullptr);
     475           1 :         AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kX_GCIO, -105,
     476             :                              vRealFld_GCIO, nullptr, nullptr);
     477           1 :         AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kY_GCIO, -106,
     478             :                              vRealFld_GCIO, nullptr, nullptr);
     479             :         /* user's fields will be added with Layer->CreateField() method ... */
     480           1 :         switch (gcioFeaType)
     481             :         {
     482           1 :             case vPoint_GCIO:
     483           1 :                 break;
     484           0 :             case vLine_GCIO:
     485           0 :                 AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kXP_GCIO, -107,
     486             :                                      vRealFld_GCIO, nullptr, nullptr);
     487           0 :                 AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kYP_GCIO, -108,
     488             :                                      vRealFld_GCIO, nullptr, nullptr);
     489           0 :                 AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kGraphics_GCIO,
     490             :                                      -109, vUnknownItemType_GCIO, nullptr,
     491             :                                      nullptr);
     492           0 :                 break;
     493           0 :             default:
     494           0 :                 AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kGraphics_GCIO,
     495             :                                      -109, vUnknownItemType_GCIO, nullptr,
     496             :                                      nullptr);
     497           0 :                 break;
     498             :         }
     499           1 :         SetSubTypeGCHandle_GCIO(aSubclass, _hGXT);
     500             : 
     501             :         /* Add layer to data source layers list */
     502           1 :         poFile = new OGRGeoconceptLayer;
     503           1 :         if (poFile->Open(aSubclass) != OGRERR_NONE)
     504             :         {
     505           0 :             CSLDestroy(ft);
     506           0 :             delete poFile;
     507           0 :             return nullptr;
     508             :         }
     509             : 
     510           2 :         _papoLayers = static_cast<OGRGeoconceptLayer **>(CPLRealloc(
     511           1 :             _papoLayers, sizeof(OGRGeoconceptLayer *) * (_nLayers + 1)));
     512           1 :         _papoLayers[_nLayers++] = poFile;
     513             : 
     514           1 :         CPLDebug("GEOCONCEPT", "nLayers=%d - last=[%s]", _nLayers,
     515           1 :                  poFile->GetLayerDefn()->GetName());
     516             :     }
     517           1 :     CSLDestroy(ft);
     518             : 
     519             :     /* -------------------------------------------------------------------- */
     520             :     /*      Assign the coordinate system (if provided)                      */
     521             :     /* -------------------------------------------------------------------- */
     522           1 :     if (poSRS != nullptr)
     523             :     {
     524           1 :         auto poSRSClone = poSRS->Clone();
     525           1 :         poFile->SetSpatialRef(poSRSClone);
     526           1 :         poSRSClone->Release();
     527             :     }
     528             : 
     529           1 :     return poFile;
     530             : }
     531             : 
     532             : /************************************************************************/
     533             : /*                           TestCapability()                           */
     534             : /************************************************************************/
     535             : 
     536          16 : int OGRGeoconceptDataSource::TestCapability(const char *pszCap)
     537             : 
     538             : {
     539          16 :     if (EQUAL(pszCap, ODsCCreateLayer))
     540          16 :         return TRUE;
     541           0 :     else if (EQUAL(pszCap, ODsCZGeometries))
     542           0 :         return TRUE;
     543             : 
     544           0 :     return FALSE;
     545             : }
     546             : 
     547             : /************************************************************************/
     548             : /*                              GetLayer()                              */
     549             : /************************************************************************/
     550             : 
     551           8 : OGRLayer *OGRGeoconceptDataSource::GetLayer(int iLayer)
     552             : 
     553             : {
     554           8 :     if (iLayer < 0 || iLayer >= GetLayerCount())
     555           0 :         return nullptr;
     556             : 
     557           8 :     OGRLayer *poFile = _papoLayers[iLayer];
     558           8 :     return poFile;
     559             : }

Generated by: LCOV version 1.14