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

Generated by: LCOV version 1.14