LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/geoconcept - ogrgeoconceptlayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 173 308 56.2 %
Date: 2024-11-21 22:18:42 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGRGeoconceptLayer class.
       5             :  * Author:   Didier Richard, didier.richard@ign.fr
       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             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #include "cpl_conv.h"
      16             : #include "cpl_string.h"
      17             : #include "ogrgeoconceptlayer.h"
      18             : 
      19             : /************************************************************************/
      20             : /*                         OGRGeoconceptLayer()                         */
      21             : /************************************************************************/
      22             : 
      23           9 : OGRGeoconceptLayer::OGRGeoconceptLayer()
      24           9 :     : _poFeatureDefn(nullptr), _gcFeature(nullptr)
      25             : {
      26           9 : }
      27             : 
      28             : /************************************************************************/
      29             : /*                          ~OGRGeoconceptLayer()                      */
      30             : /************************************************************************/
      31             : 
      32          36 : OGRGeoconceptLayer::~OGRGeoconceptLayer()
      33             : 
      34             : {
      35           9 :     if (_poFeatureDefn)
      36             :     {
      37          18 :         CPLDebug("GEOCONCEPT", "%ld features on layer %s.",
      38           9 :                  GetSubTypeNbFeatures_GCIO(_gcFeature),
      39           9 :                  _poFeatureDefn->GetName());
      40             : 
      41           9 :         _poFeatureDefn->Release();
      42             :     }
      43             : 
      44           9 :     _gcFeature = nullptr; /* deleted when OGCGeoconceptDatasource destroyed */
      45          18 : }
      46             : 
      47             : /************************************************************************/
      48             : /*                              Open()                                  */
      49             : /************************************************************************/
      50             : 
      51           9 : OGRErr OGRGeoconceptLayer::Open(GCSubType *Subclass)
      52             : 
      53             : {
      54           9 :     _gcFeature = Subclass;
      55           9 :     if (GetSubTypeFeatureDefn_GCIO(_gcFeature))
      56             :     {
      57           8 :         _poFeatureDefn = reinterpret_cast<OGRFeatureDefn *>(
      58           8 :             GetSubTypeFeatureDefn_GCIO(_gcFeature));
      59           8 :         SetDescription(_poFeatureDefn->GetName());
      60           8 :         _poFeatureDefn->Reference();
      61             :     }
      62             :     else
      63             :     {
      64             :         char pszln[512];
      65           1 :         snprintf(pszln, 511, "%s.%s", GetSubTypeName_GCIO(_gcFeature),
      66           1 :                  GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)));
      67           1 :         pszln[511] = '\0';
      68             : 
      69           1 :         _poFeatureDefn = new OGRFeatureDefn(pszln);
      70           1 :         SetDescription(_poFeatureDefn->GetName());
      71           1 :         _poFeatureDefn->Reference();
      72           1 :         _poFeatureDefn->SetGeomType(wkbUnknown);
      73             : 
      74           1 :         const int n = CountSubTypeFields_GCIO(_gcFeature);
      75           1 :         if (n > 0)
      76             :         {
      77             :             OGRFieldType oft;
      78           8 :             for (int i = 0; i < n; i++)
      79             :             {
      80           7 :                 GCField *aField = GetSubTypeField_GCIO(_gcFeature, i);
      81           7 :                 if (aField)
      82             :                 {
      83           7 :                     if (IsPrivateField_GCIO(aField))
      84           7 :                         continue;
      85           0 :                     switch (GetFieldKind_GCIO(aField))
      86             :                     {
      87           0 :                         case vIntFld_GCIO:
      88             :                         case vPositionFld_GCIO:
      89           0 :                             oft = OFTInteger;
      90           0 :                             break;
      91           0 :                         case vRealFld_GCIO:
      92             :                         case vLengthFld_GCIO:
      93             :                         case vAreaFld_GCIO:
      94           0 :                             oft = OFTReal;
      95           0 :                             break;
      96           0 :                         case vDateFld_GCIO:
      97           0 :                             oft = OFTDate;
      98           0 :                             break;
      99           0 :                         case vTimeFld_GCIO:
     100           0 :                             oft = OFTTime;
     101           0 :                             break;
     102           0 :                         case vMemoFld_GCIO:
     103             :                         case vChoiceFld_GCIO:
     104             :                         case vInterFld_GCIO:
     105             :                         default:
     106           0 :                             oft = OFTString;
     107           0 :                             break;
     108             :                     }
     109           0 :                     OGRFieldDefn ofd(GetFieldName_GCIO(aField), oft);
     110           0 :                     _poFeatureDefn->AddFieldDefn(&ofd);
     111             :                 }
     112             :             }
     113             :         }
     114           1 :         SetSubTypeFeatureDefn_GCIO(_gcFeature, (OGRFeatureDefnH)_poFeatureDefn);
     115           1 :         _poFeatureDefn->Reference();
     116             :     }
     117             : 
     118           9 :     if (_poFeatureDefn->GetGeomFieldCount() > 0)
     119           9 :         _poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(GetSpatialRef());
     120             : 
     121           9 :     return OGRERR_NONE;
     122             : }
     123             : 
     124             : /************************************************************************/
     125             : /*                            ResetReading()                            */
     126             : /************************************************************************/
     127             : 
     128           6 : void OGRGeoconceptLayer::ResetReading()
     129             : 
     130             : {
     131           6 :     Rewind_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature), _gcFeature);
     132           6 : }
     133             : 
     134             : /************************************************************************/
     135             : /*                           GetNextFeature()                           */
     136             : /************************************************************************/
     137             : 
     138          37 : OGRFeature *OGRGeoconceptLayer::GetNextFeature()
     139             : 
     140             : {
     141          37 :     OGRFeature *poFeature = nullptr;
     142             : 
     143             :     for (;;)
     144             :     {
     145          37 :         if (!(poFeature = (OGRFeature *)ReadNextFeature_GCIO(_gcFeature)))
     146             :         {
     147             :             /*
     148             :              * As several features are embed in the Geoconcept file,
     149             :              * when reaching the end of the feature type, resetting
     150             :              * the reader would allow reading other features :
     151             :              * ogrinfo -ro export.gxt FT1 FT2 ...
     152             :              * will be all features for all features types !
     153             :              */
     154           6 :             Rewind_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature), nullptr);
     155           6 :             break;
     156             :         }
     157          62 :         if ((m_poFilterGeom == nullptr ||
     158          62 :              FilterGeometry(poFeature->GetGeometryRef())) &&
     159          31 :             (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
     160             :         {
     161          31 :             break;
     162             :         }
     163           0 :         delete poFeature;
     164             :     }
     165             : 
     166         130 :     CPLDebug("GEOCONCEPT",
     167             :              "FID : " CPL_FRMT_GIB "\n"
     168             :              "%s  : %s",
     169          31 :              poFeature ? poFeature->GetFID() : -1L,
     170          31 :              poFeature && poFeature->GetFieldCount() > 0
     171          31 :                  ? poFeature->GetFieldDefnRef(0)->GetNameRef()
     172             :                  : "-",
     173          31 :              poFeature && poFeature->GetFieldCount() > 0
     174          31 :                  ? poFeature->GetFieldAsString(0)
     175             :                  : "");
     176             : 
     177          37 :     return poFeature;
     178             : }
     179             : 
     180             : /************************************************************************/
     181             : /*            OGRGeoconceptLayer_GetCompatibleFieldName()               */
     182             : /************************************************************************/
     183             : 
     184          15 : static char *OGRGeoconceptLayer_GetCompatibleFieldName(const char *pszName)
     185             : {
     186          15 :     char *pszCompatibleName = CPLStrdup(pszName);
     187         169 :     for (int i = 0; pszCompatibleName[i] != 0; i++)
     188             :     {
     189         154 :         if (pszCompatibleName[i] == ' ')
     190           0 :             pszCompatibleName[i] = '_';
     191             :     }
     192          15 :     return pszCompatibleName;
     193             : }
     194             : 
     195             : /************************************************************************/
     196             : /*                           ICreateFeature()                            */
     197             : /************************************************************************/
     198             : 
     199           2 : OGRErr OGRGeoconceptLayer::ICreateFeature(OGRFeature *poFeature)
     200             : 
     201             : {
     202           2 :     OGRGeometry *poGeom = poFeature->GetGeometryRef();
     203             : 
     204           2 :     if (poGeom == nullptr)
     205             :     {
     206           0 :         CPLError(
     207             :             CE_Warning, CPLE_NotSupported,
     208             :             "NULL geometry not supported in Geoconcept, feature skipped.\n");
     209           0 :         return OGRERR_NONE;
     210             :     }
     211             : 
     212           2 :     OGRwkbGeometryType eGt = poGeom->getGeometryType();
     213           2 :     switch (wkbFlatten(eGt))
     214             :     {
     215           2 :         case wkbPoint:
     216             :         case wkbMultiPoint:
     217           2 :             if (GetSubTypeKind_GCIO(_gcFeature) == vUnknownItemType_GCIO)
     218             :             {
     219           0 :                 SetSubTypeKind_GCIO(_gcFeature, vPoint_GCIO);
     220             :             }
     221           2 :             else if (GetSubTypeKind_GCIO(_gcFeature) != vPoint_GCIO)
     222             :             {
     223           0 :                 CPLError(CE_Failure, CPLE_NotSupported,
     224             :                          "Can't write non ponctual feature in a ponctual "
     225             :                          "Geoconcept layer %s.\n",
     226           0 :                          _poFeatureDefn->GetName());
     227           0 :                 return OGRERR_FAILURE;
     228             :             }
     229           2 :             break;
     230           0 :         case wkbLineString:
     231             :         case wkbMultiLineString:
     232           0 :             if (GetSubTypeKind_GCIO(_gcFeature) == vUnknownItemType_GCIO)
     233             :             {
     234           0 :                 SetSubTypeKind_GCIO(_gcFeature, vLine_GCIO);
     235             :             }
     236           0 :             else if (GetSubTypeKind_GCIO(_gcFeature) != vLine_GCIO)
     237             :             {
     238           0 :                 CPLError(
     239             :                     CE_Failure, CPLE_NotSupported,
     240             :                     "Can't write non linear feature in a linear Geoconcept "
     241             :                     "layer %s.\n",
     242           0 :                     _poFeatureDefn->GetName());
     243           0 :                 return OGRERR_FAILURE;
     244             :             }
     245           0 :             break;
     246           0 :         case wkbPolygon:
     247             :         case wkbMultiPolygon:
     248           0 :             if (GetSubTypeKind_GCIO(_gcFeature) == vUnknownItemType_GCIO)
     249             :             {
     250           0 :                 SetSubTypeKind_GCIO(_gcFeature, vPoly_GCIO);
     251             :             }
     252           0 :             else if (GetSubTypeKind_GCIO(_gcFeature) != vPoly_GCIO)
     253             :             {
     254           0 :                 CPLError(CE_Failure, CPLE_NotSupported,
     255             :                          "Can't write non polygonal feature in a polygonal "
     256             :                          "Geoconcept layer %s.\n",
     257           0 :                          _poFeatureDefn->GetName());
     258           0 :                 return OGRERR_FAILURE;
     259             :             }
     260           0 :             break;
     261           0 :         default:
     262           0 :             CPLError(CE_Warning, CPLE_AppDefined,
     263             :                      "Geometry type %s not supported in Geoconcept, "
     264             :                      "feature skipped.\n",
     265             :                      OGRGeometryTypeToName(eGt));
     266           0 :             return OGRERR_NONE;
     267             :     }
     268           2 :     if (GetSubTypeDim_GCIO(_gcFeature) == vUnknown3D_GCIO)
     269             :     {
     270           0 :         if (poGeom->getCoordinateDimension() == 3)
     271             :         {
     272           0 :             SetSubTypeDim_GCIO(_gcFeature, v3D_GCIO);
     273             :         }
     274             :         else
     275             :         {
     276           0 :             SetSubTypeDim_GCIO(_gcFeature, v2D_GCIO);
     277             :         }
     278             :     }
     279             : 
     280           2 :     int nbGeom = 0;
     281           2 :     bool isSingle = false;
     282             : 
     283           2 :     switch (wkbFlatten(eGt))
     284             :     {
     285           2 :         case wkbPoint:
     286             :         case wkbLineString:
     287             :         case wkbPolygon:
     288           2 :             nbGeom = 1;
     289           2 :             isSingle = true;
     290           2 :             break;
     291           0 :         case wkbMultiPoint:
     292             :         case wkbMultiLineString:
     293             :         case wkbMultiPolygon:
     294           0 :             nbGeom = poGeom->toGeometryCollection()->getNumGeometries();
     295           0 :             isSingle = false;
     296           0 :             break;
     297           0 :         default:
     298           0 :             nbGeom = 0;
     299           0 :             isSingle = false;
     300           0 :             break;
     301             :     }
     302             : 
     303             :     /* 1st feature, let's write header : */
     304           4 :     if (GetGCMode_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature)) ==
     305           4 :             vWriteAccess_GCIO &&
     306           2 :         GetFeatureCount(TRUE) == 0)
     307           1 :         if (WriteHeader_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature)) == nullptr)
     308             :         {
     309           0 :             return OGRERR_FAILURE;
     310             :         }
     311             : 
     312           2 :     if (nbGeom > 0)
     313             :     {
     314           4 :         for (int iGeom = 0; iGeom < nbGeom; iGeom++)
     315             :         {
     316           4 :             int nextField = StartWritingFeature_GCIO(
     317             :                 _gcFeature,
     318           2 :                 isSingle ? static_cast<int>(poFeature->GetFID()) : OGRNullFID);
     319          10 :             while (nextField != WRITECOMPLETED_GCIO)
     320             :             {
     321           8 :                 if (nextField == WRITEERROR_GCIO)
     322             :                 {
     323           0 :                     return OGRERR_FAILURE;
     324             :                 }
     325           8 :                 if (nextField == GEOMETRYEXPECTED_GCIO)
     326             :                 {
     327             :                     OGRGeometry *poGeomPart =
     328             :                         isSingle
     329           2 :                             ? poGeom
     330           0 :                             : poGeom->toGeometryCollection()->getGeometryRef(
     331           2 :                                   iGeom);
     332           2 :                     nextField = WriteFeatureGeometry_GCIO(
     333             :                         _gcFeature, (OGRGeometryH)poGeomPart);
     334             :                 }
     335             :                 else
     336             :                 {
     337             :                     GCField *theField =
     338           6 :                         GetSubTypeField_GCIO(_gcFeature, nextField);
     339             :                     /* for each field, find out its mapping ... */
     340           6 :                     int nF = poFeature->GetFieldCount();
     341           6 :                     if (nF > 0)
     342             :                     {
     343           6 :                         int iF = 0;
     344          12 :                         for (; iF < nF; iF++)
     345             :                         {
     346             :                             OGRFieldDefn *poField =
     347          12 :                                 poFeature->GetFieldDefnRef(iF);
     348             :                             char *pszName =
     349          12 :                                 OGRGeoconceptLayer_GetCompatibleFieldName(
     350             :                                     poField->GetNameRef());
     351          12 :                             if (EQUAL(pszName, GetFieldName_GCIO(theField)))
     352             :                             {
     353           6 :                                 CPLFree(pszName);
     354           6 :                                 nextField = WriteFeatureFieldAsString_GCIO(
     355             :                                     _gcFeature, nextField,
     356           6 :                                     poFeature->IsFieldSetAndNotNull(iF)
     357           5 :                                         ? poFeature->GetFieldAsString(iF)
     358             :                                         : nullptr);
     359           6 :                                 break;
     360             :                             }
     361           6 :                             CPLFree(pszName);
     362             :                         }
     363           6 :                         if (iF == nF)
     364             :                         {
     365           0 :                             CPLError(CE_Failure, CPLE_AppDefined,
     366             :                                      "Can't find a field attached to %s on "
     367             :                                      "Geoconcept layer %s.\n",
     368             :                                      GetFieldName_GCIO(theField),
     369           0 :                                      _poFeatureDefn->GetName());
     370           0 :                             return OGRERR_FAILURE;
     371             :                         }
     372             :                     }
     373             :                     else
     374             :                     {
     375           0 :                         nextField = WRITECOMPLETED_GCIO;
     376             :                     }
     377             :                 }
     378             :             }
     379           2 :             StopWritingFeature_GCIO(_gcFeature);
     380             :         }
     381             :     }
     382             : 
     383           2 :     return OGRERR_NONE;
     384             : }
     385             : 
     386             : /************************************************************************/
     387             : /*                           GetSpatialRef()                            */
     388             : /************************************************************************/
     389             : 
     390          12 : OGRSpatialReference *OGRGeoconceptLayer::GetSpatialRef()
     391             : 
     392             : {
     393          12 :     GCExportFileH *hGXT = GetSubTypeGCHandle_GCIO(_gcFeature);
     394          12 :     if (!hGXT)
     395           0 :         return nullptr;
     396          12 :     GCExportFileMetadata *Meta = GetGCMeta_GCIO(hGXT);
     397          12 :     if (!Meta)
     398           0 :         return nullptr;
     399          12 :     return (OGRSpatialReference *)GetMetaSRS_GCIO(Meta);
     400             : }
     401             : 
     402             : /************************************************************************/
     403             : /*                          GetFeatureCount()                           */
     404             : /*                                                                      */
     405             : /*      If a spatial filter is in effect, we turn control over to       */
     406             : /*      the generic counter.  Otherwise we return the total count.      */
     407             : /************************************************************************/
     408             : 
     409           7 : GIntBig OGRGeoconceptLayer::GetFeatureCount(int bForce)
     410             : 
     411             : {
     412           7 :     if (m_poFilterGeom != nullptr || m_poAttrQuery != nullptr)
     413           0 :         return OGRLayer::GetFeatureCount(bForce);
     414             : 
     415           7 :     return GetSubTypeNbFeatures_GCIO(_gcFeature);
     416             : }
     417             : 
     418             : /************************************************************************/
     419             : /*                             GetExtent()                              */
     420             : /************************************************************************/
     421             : 
     422           0 : OGRErr OGRGeoconceptLayer::GetExtent(OGREnvelope *psExtent,
     423             :                                      CPL_UNUSED int bForce)
     424             : {
     425           0 :     GCExtent *theExtent = GetSubTypeExtent_GCIO(_gcFeature);
     426           0 :     if (!theExtent)
     427           0 :         return OGRERR_FAILURE;
     428           0 :     psExtent->MinX = GetExtentULAbscissa_GCIO(theExtent);
     429           0 :     psExtent->MinY = GetExtentLROrdinate_GCIO(theExtent);
     430           0 :     psExtent->MaxX = GetExtentLRAbscissa_GCIO(theExtent);
     431           0 :     psExtent->MaxY = GetExtentULOrdinate_GCIO(theExtent);
     432             : 
     433           0 :     return OGRERR_NONE;
     434             : }
     435             : 
     436             : /************************************************************************/
     437             : /*                           TestCapability()                           */
     438             : /************************************************************************/
     439             : 
     440           2 : int OGRGeoconceptLayer::TestCapability(const char *pszCap)
     441             : 
     442             : {
     443           2 :     if (EQUAL(pszCap, OLCRandomRead))
     444           0 :         return FALSE;  // the GetFeature() method does not work for this layer.
     445             :                        // TODO
     446             : 
     447           2 :     else if (EQUAL(pszCap, OLCSequentialWrite))
     448           0 :         return TRUE;  // the CreateFeature() method works for this layer.
     449             : 
     450           2 :     else if (EQUAL(pszCap, OLCRandomWrite))
     451           0 :         return FALSE;  // the SetFeature() method is not operational on this
     452             :                        // layer.
     453             : 
     454           2 :     else if (EQUAL(pszCap, OLCFastSpatialFilter))
     455           0 :         return FALSE;  // this layer does not implement spatial filtering
     456             :                        // efficiently.
     457             : 
     458           2 :     else if (EQUAL(pszCap, OLCFastFeatureCount))
     459           0 :         return FALSE;  // this layer can not return a feature count efficiently.
     460             :                        // FIXME
     461             : 
     462           2 :     else if (EQUAL(pszCap, OLCFastGetExtent))
     463           0 :         return FALSE;  // this layer can not return its data extent efficiently.
     464             :                        // FIXME
     465             : 
     466           2 :     else if (EQUAL(pszCap, OLCFastSetNextByIndex))
     467           0 :         return FALSE;  // this layer can not perform the SetNextByIndex() call
     468             :                        // efficiently.
     469             : 
     470           2 :     else if (EQUAL(pszCap, OLCDeleteFeature))
     471           0 :         return FALSE;
     472             : 
     473           2 :     else if (EQUAL(pszCap, OLCCreateField))
     474           0 :         return TRUE;
     475             : 
     476           2 :     else if (EQUAL(pszCap, OLCZGeometries))
     477           0 :         return TRUE;
     478             : 
     479           2 :     return FALSE;
     480             : }
     481             : 
     482             : /************************************************************************/
     483             : /*                            CreateField()                             */
     484             : /************************************************************************/
     485             : 
     486           3 : OGRErr OGRGeoconceptLayer::CreateField(const OGRFieldDefn *poField,
     487             :                                        CPL_UNUSED int bApproxOK)
     488             : {
     489           3 :     if (GetGCMode_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature)) == vReadAccess_GCIO)
     490             :     {
     491           0 :         CPLError(CE_Failure, CPLE_NotSupported,
     492             :                  "Can't create fields on a read-only Geoconcept layer.\n");
     493           0 :         return OGRERR_FAILURE;
     494             :     }
     495             : 
     496             :     /* -------------------------------------------------------------------- */
     497             :     /*      Add field to layer                                              */
     498             :     /* -------------------------------------------------------------------- */
     499             : 
     500             :     {
     501             :         /* check whether field exists ... */
     502             :         char *pszName =
     503           3 :             OGRGeoconceptLayer_GetCompatibleFieldName(poField->GetNameRef());
     504             : 
     505           3 :         GCField *theField = FindFeatureField_GCIO(_gcFeature, pszName);
     506           3 :         if (!theField)
     507             :         {
     508           3 :             if (GetFeatureCount(TRUE) > 0)
     509             :             {
     510           0 :                 CPLError(CE_Failure, CPLE_NotSupported,
     511             :                          "Can't create field '%s' on existing Geoconcept layer "
     512             :                          "'%s.%s'.\n",
     513           0 :                          pszName, GetSubTypeName_GCIO(_gcFeature),
     514           0 :                          GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)));
     515           0 :                 CPLFree(pszName);
     516           0 :                 return OGRERR_FAILURE;
     517             :             }
     518           3 :             if (GetSubTypeNbFields_GCIO(_gcFeature) == -1)
     519           1 :                 SetSubTypeNbFields_GCIO(_gcFeature, 0L);
     520           3 :             if (!(theField = AddSubTypeField_GCIO(
     521           3 :                       GetSubTypeGCHandle_GCIO(_gcFeature),
     522           3 :                       GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)),
     523           3 :                       GetSubTypeName_GCIO(_gcFeature),
     524           6 :                       FindFeatureFieldIndex_GCIO(_gcFeature, kNbFields_GCIO) +
     525           3 :                           GetSubTypeNbFields_GCIO(_gcFeature) + 1,
     526           3 :                       pszName, GetSubTypeNbFields_GCIO(_gcFeature) - 999L,
     527             :                       vUnknownItemType_GCIO, nullptr, nullptr)))
     528             :             {
     529           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     530             :                          "Field '%s' could not be created for Feature %s.%s.\n",
     531           0 :                          pszName, GetSubTypeName_GCIO(_gcFeature),
     532           0 :                          GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)));
     533           0 :                 CPLFree(pszName);
     534           0 :                 return OGRERR_FAILURE;
     535             :             }
     536           3 :             SetSubTypeNbFields_GCIO(_gcFeature,
     537             :                                     GetSubTypeNbFields_GCIO(_gcFeature) + 1);
     538           3 :             _poFeatureDefn->AddFieldDefn(poField);
     539             :         }
     540             :         else
     541             :         {
     542           0 :             if (_poFeatureDefn->GetFieldIndex(GetFieldName_GCIO(theField)) ==
     543             :                 -1)
     544             :             {
     545           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     546             :                          "Field %s not found for Feature %s.%s.\n",
     547             :                          GetFieldName_GCIO(theField),
     548           0 :                          GetSubTypeName_GCIO(_gcFeature),
     549           0 :                          GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)));
     550           0 :                 CPLFree(pszName);
     551           0 :                 return OGRERR_FAILURE;
     552             :             }
     553             :         }
     554             : 
     555           3 :         CPLFree(pszName);
     556           3 :         pszName = nullptr;
     557             : 
     558             :         /* check/update type ? */
     559           3 :         if (GetFieldKind_GCIO(theField) == vUnknownItemType_GCIO)
     560             :         {
     561           3 :             switch (poField->GetType())
     562             :             {
     563           0 :                 case OFTInteger:
     564           0 :                     SetFieldKind_GCIO(theField, vIntFld_GCIO);
     565           0 :                     break;
     566           0 :                 case OFTReal:
     567           0 :                     SetFieldKind_GCIO(theField, vRealFld_GCIO);
     568           0 :                     break;
     569           0 :                 case OFTDate:
     570           0 :                     SetFieldKind_GCIO(theField, vDateFld_GCIO);
     571           0 :                     break;
     572           0 :                 case OFTTime:
     573             :                 case OFTDateTime:
     574           0 :                     SetFieldKind_GCIO(theField, vTimeFld_GCIO);
     575           0 :                     break;
     576           3 :                 case OFTString:
     577           3 :                     SetFieldKind_GCIO(theField, vMemoFld_GCIO);
     578           3 :                     break;
     579           0 :                 case OFTIntegerList:
     580             :                 case OFTRealList:
     581             :                 case OFTStringList:
     582             :                 case OFTBinary:
     583             :                 default:
     584           0 :                     CPLError(CE_Failure, CPLE_NotSupported,
     585             :                              "Can't create fields of type %s on Geoconcept "
     586             :                              "feature %s.\n",
     587             :                              OGRFieldDefn::GetFieldTypeName(poField->GetType()),
     588           0 :                              _poFeatureDefn->GetName());
     589           0 :                     return OGRERR_FAILURE;
     590             :             }
     591             :         }
     592             :     }
     593             : 
     594           3 :     return OGRERR_NONE;
     595             : }
     596             : 
     597             : /************************************************************************/
     598             : /*                             SyncToDisk()                             */
     599             : /************************************************************************/
     600             : 
     601           0 : OGRErr OGRGeoconceptLayer::SyncToDisk()
     602             : 
     603             : {
     604           0 :     FFlush_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature));
     605           0 :     return OGRERR_NONE;
     606             : }
     607             : 
     608             : /************************************************************************/
     609             : /*                             SetSpatialRef()                          */
     610             : /************************************************************************/
     611             : 
     612           1 : void OGRGeoconceptLayer::SetSpatialRef(OGRSpatialReference *poSpatialRef)
     613             : 
     614             : {
     615           1 :     OGRSpatialReference *poSRS = GetSpatialRef();
     616             :     /*-----------------------------------------------------------------
     617             :      * Keep a copy of the OGRSpatialReference...
     618             :      * Note: we have to take the reference count into account...
     619             :      *----------------------------------------------------------------*/
     620           1 :     if (poSRS && poSRS->Dereference() == 0)
     621           0 :         delete poSRS;
     622             : 
     623           1 :     if (!poSpatialRef)
     624           0 :         return;
     625             : 
     626           1 :     poSRS = poSpatialRef->Clone();
     627           1 :     poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
     628           1 :     GCExportFileH *hGXT = GetSubTypeGCHandle_GCIO(_gcFeature);
     629           1 :     if (!hGXT)
     630             :     {
     631           0 :         delete poSRS;
     632           0 :         return;
     633             :     }
     634           1 :     GCExportFileMetadata *Meta = GetGCMeta_GCIO(hGXT);
     635           1 :     if (!Meta)
     636             :     {
     637           0 :         delete poSRS;
     638           0 :         return;
     639             :     }
     640           1 :     GCSysCoord *os = GetMetaSysCoord_GCIO(Meta);
     641           1 :     GCSysCoord *ns = OGRSpatialReference2SysCoord_GCSRS(
     642           1 :         reinterpret_cast<OGRSpatialReferenceH>(poSRS));
     643             : 
     644           1 :     if (os && ns && GetSysCoordSystemID_GCSRS(os) != -1 &&
     645           0 :         (GetSysCoordSystemID_GCSRS(os) != GetSysCoordSystemID_GCSRS(ns) ||
     646           0 :          GetSysCoordTimeZone_GCSRS(os) != GetSysCoordTimeZone_GCSRS(ns)))
     647             :     {
     648           0 :         CPLError(CE_Warning, CPLE_AppDefined,
     649             :                  "Can't change SRS on Geoconcept layers.\n");
     650           0 :         DestroySysCoord_GCSRS(&ns);
     651           0 :         delete poSRS;
     652           0 :         return;
     653             :     }
     654             : 
     655           1 :     if (os)
     656           0 :         DestroySysCoord_GCSRS(&os);
     657           1 :     SetMetaSysCoord_GCIO(Meta, ns);
     658           1 :     SetMetaSRS_GCIO(Meta, (OGRSpatialReferenceH)poSRS);
     659           1 :     return;
     660             : }

Generated by: LCOV version 1.14