LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/sosi - ogrsosilayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 152 231 65.8 %
Date: 2024-05-15 17:37:59 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  SOSI Translator
       4             :  * Purpose:  Implements OGRSOSILayer.
       5             :  * Author:   Thomas Hirsch, <thomas.hirsch statkart no>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2010, Thomas Hirsch
       9             :  * Copyright (c) 2010-2014, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #include "ogr_sosi.h"
      31             : #include <map>
      32             : #include <memory>
      33             : #include <stdio.h>
      34             : #include <string.h>
      35             : 
      36             : /************************************************************************/
      37             : /*                           OGRSOSILayer()                             */
      38             : /************************************************************************/
      39             : 
      40           6 : OGRSOSILayer::OGRSOSILayer(OGRSOSIDataSource *poPar, OGRFeatureDefn *poFeatDefn,
      41           6 :                            LC_FILADM *poFil, S2I *poHeadDefn)
      42             : {
      43           6 :     poParent = poPar;
      44           6 :     poFileadm = poFil;
      45           6 :     poFeatureDefn = poFeatDefn;
      46           6 :     poHeaderDefn = poHeadDefn;
      47           6 :     nNextFID = 0;
      48           6 :     poNextSerial = nullptr;
      49             : 
      50           6 :     SetDescription(poFeatureDefn->GetName());
      51           6 :     if (poFeatureDefn->GetGeomFieldCount() > 0)
      52           6 :         poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poParent->poSRS);
      53             : 
      54           6 :     OGRSOSILayer::ResetReading();
      55           6 : }
      56             : 
      57             : /************************************************************************/
      58             : /*                           ~OGRSOSILayer()                            */
      59             : /************************************************************************/
      60          12 : OGRSOSILayer::~OGRSOSILayer()
      61             : {
      62           6 :     poFeatureDefn->Release();
      63          12 : }
      64             : 
      65             : /************************************************************************/
      66             : /*                           GetLayerDefn()                             */
      67             : /************************************************************************/
      68           0 : OGRFeatureDefn *OGRSOSILayer::GetLayerDefn()
      69             : {
      70           0 :     return poFeatureDefn;
      71             : }
      72             : 
      73             : #ifdef WRITE_SUPPORT
      74             : /************************************************************************/
      75             : /*                           CreateField()                              */
      76             : /************************************************************************/
      77             : OGRErr OGRSOSILayer::CreateField(OGRFieldDefn *poField,
      78             :                                  CPL_UNUSED int bApproxOK)
      79             : {
      80             :     poFeatureDefn->AddFieldDefn(poField);
      81             :     return OGRERR_NONE; /* We'll just gladly accept any "field" we find */
      82             : }
      83             : 
      84             : /************************************************************************/
      85             : /*                           ICreateFeature()                            */
      86             : /************************************************************************/
      87             : OGRErr OGRSOSILayer::ICreateFeature(OGRFeature *poFeature)
      88             : {
      89             :     // short nNavn;
      90             :     long nSerial;
      91             : 
      92             :     const char *pszSosi = NULL;
      93             :     switch (poFeatureDefn->GetGeomType())
      94             :     {
      95             :         case wkbPoint:
      96             :         {
      97             :             pszSosi = ".PUNKT";
      98             :             break;
      99             :         }
     100             :         case wkbLineString:
     101             :         {
     102             :             pszSosi = ".KURVE";
     103             :             break;
     104             :         }
     105             :         case wkbPolygon:
     106             :         {
     107             :             pszSosi = ".FLATE";
     108             :             break;
     109             :         }
     110             :         default:
     111             :         {
     112             :             CPLError(CE_Warning, CPLE_AppDefined,
     113             :                      "Unknown geometry type in CreateFeature.");
     114             :             return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
     115             :         }
     116             :     }
     117             :     /*nNavn = */ LC_NyGr(poFileadm, (char *)pszSosi, &oNextSerial, &nSerial);
     118             :     /* === WIP - Work in progress === */
     119             :     /* PutGI for all headers */
     120             :     char pszGi[255];
     121             :     for (int i = 0; i < poFeature->GetFieldCount(); i++)
     122             :     {
     123             :         int n = snprintf(pszGi, 255, "%s",
     124             :                          poFeature->GetFieldDefnRef(i)->GetNameRef());
     125             :         if (n < 255)
     126             :         {
     127             :             /*int m = */ snprintf(pszGi + (n - 1), 255 - n, "%s",
     128             :                                   poFeature->GetFieldAsString(i));
     129             :             /* check overflow */
     130             :         }
     131             :         LC_PutGi(i + 2, pszGi); /* should add headers too */
     132             :     }
     133             :     // LC_OppdaterEndret(0);
     134             :     /* PutTK for all coords */
     135             :     /* ... */
     136             :     /* === /WIP - Work in progress === */
     137             :     LC_WsGr(poFileadm); /* Writing the header here! */
     138             :     return OGRERR_NONE;
     139             : }
     140             : #endif
     141             : 
     142             : /************************************************************************/
     143             : /*                           GetNextFeature()                           */
     144             : /************************************************************************/
     145          63 : OGRFeature *OGRSOSILayer::GetNextFeature()
     146             : {
     147             :     short nName, nNumLines;
     148             :     long nNumCoo;
     149             :     unsigned short nInfo;
     150             : 
     151             :     // Used to limit the number of limit the fields to be appended.
     152             :     // Default is that duplicates will appended if no appendFieldsMap parameter
     153             :     // is sent.
     154         126 :     std::map<std::string, std::string> appendFieldsMap;
     155             : 
     156             :     // Get appendFieldsMap and update appendFieldsMap if present;
     157             :     // The input must on this format
     158             : 
     159             :     // -oo appendFieldsMap="BEITEBRUKERID:,&FIELD2test: &FIELD3test:;"
     160             :     // With the example above the field BEITEBRUKERID append character will be
     161             :     // ':', for FIELD2test it will space and for FIELD3test it will be ;
     162             : 
     163             :     // -oo appendFieldsMap="BEITEBRUKERID&FIELD2test&FIELD3test"
     164             :     // With the example above the append character will be ',' for fields in the
     165             :     // list
     166             : 
     167             :     const char *appendFieldsMapInput =
     168          63 :         CSLFetchNameValue(poParent->GetOpenOptions(), "appendFieldsMap");
     169         126 :     CPLStringList aosTokens(CSLTokenizeString2(appendFieldsMapInput, "&", 0));
     170         147 :     for (int i = 0; i < aosTokens.size(); i++)
     171             :     {
     172         168 :         std::string filedsAndDelimStr = aosTokens[i];
     173          84 :         std::size_t found = filedsAndDelimStr.find(":");
     174         168 :         std::string appfieldName = filedsAndDelimStr;
     175          84 :         std::string appfieldDelimiter = ",";
     176          84 :         if (found < filedsAndDelimStr.length())
     177             :         {
     178          42 :             appfieldName = filedsAndDelimStr.substr(0, found);
     179          42 :             appfieldDelimiter = filedsAndDelimStr.substr(found + 1);
     180             :         }
     181         168 :         appendFieldsMap.insert(std::pair<std::string, std::string>(
     182          84 :             appfieldName, appfieldDelimiter));
     183             :     }
     184             : 
     185             :     /* iterate through the SOSI groups*/
     186         129 :     while (LC_NextBgr(poNextSerial, LC_FRAMGR))
     187             :     {
     188             :         nName =
     189         123 :             LC_RxGr(&oNextSerial, LES_OPTIMALT, &nNumLines, &nNumCoo, &nInfo);
     190             : 
     191         123 :         S2S oHeaders;
     192         123 :         S2S::iterator iHeaders;
     193             :         /* extract reference strings from group header */
     194         123 :         CPLString osKey, osValue;
     195        1116 :         for (short i = 1; i <= nNumLines; i++)
     196             :         {
     197         993 :             char *pszLine = LC_GetGi(i);
     198         993 :             if (pszLine[0] == '!')
     199           0 :                 continue; /* If we have a comment line, skip it. */
     200         993 :             if ((pszLine[0] == ':') || (pszLine[0] == '('))
     201             :             { /* if we have a continued REF line... */
     202             :                 osValue.append(
     203           9 :                     CPLString(pszLine)); /* append to previous line. */
     204             :                 oHeaders.insert(
     205           9 :                     std::pair<CPLString, CPLString>(osKey, osValue));
     206           9 :                 continue;
     207             :             }
     208        2874 :             while (pszLine[0] == '.')
     209        1890 :                 pszLine++; /* skipping the dots at the beginning of a SOSI line
     210             :                             */
     211             :             char *pszUTFLine =
     212         984 :                 CPLRecode(pszLine, poParent->pszEncoding,
     213             :                           CPL_ENC_UTF8); /* switch to UTF encoding here */
     214         984 :             char *pszPos = strstr(pszUTFLine, " ");
     215         984 :             if (pszPos != nullptr)
     216             :             {
     217         957 :                 osKey = CPLString(std::string(pszUTFLine, pszPos));
     218             :                 // Check if this oskey is used before in this feature
     219         966 :                 if (oHeaders.count(osKey) > 0 &&
     220         966 :                     appendFieldsMap.count(osKey.c_str()) > 0)
     221             :                 {
     222             :                     // get old osvalue so we can append the next value
     223          12 :                     CPLString newAppendOsValue = oHeaders[osKey];
     224             : 
     225             :                     // append split character
     226           6 :                     newAppendOsValue.append(appendFieldsMap[osKey]);
     227             : 
     228             :                     // append new value
     229           6 :                     newAppendOsValue.append(CPLString(pszPos + 1));
     230             : 
     231             :                     // the new value
     232           6 :                     oHeaders[osKey] = std::move(newAppendOsValue);
     233             :                 }
     234             :                 else
     235             :                 {
     236         951 :                     osValue = CPLString(pszPos + 1);
     237             :                     oHeaders.insert(
     238         951 :                         std::pair<CPLString, CPLString>(osKey, osValue));
     239             :                 }
     240             :             }
     241         984 :             CPLFree(pszUTFLine);
     242             :         }
     243             : 
     244             :         /* get Feature from fyba, according to feature definition */
     245           0 :         std::unique_ptr<OGRGeometry> poGeom;
     246         123 :         OGRwkbGeometryType oGType = wkbUnknown;
     247             : 
     248         123 :         switch (nName)
     249             :         {
     250           0 :             case INGEN_GRUPPE:
     251             :             { /* No group */
     252           0 :                 CPLDebug("[GetNextFeature]", "Could not load further groups - "
     253             :                                              "FYBA reported INGEN_GRUPPE.");
     254           0 :                 break;
     255             :             }
     256           9 :             case L_FLATE:
     257             :             { /* Area */
     258           9 :                 oGType = wkbPolygon;
     259             :                 auto poOuter =
     260           9 :                     std::make_unique<OGRLinearRing>(); /* Initialize a new
     261             :                                                           closed polygon */
     262             :                 long nRefNr;
     263             :                 unsigned char nRefStatus;
     264             :                 long nRefCount;
     265           9 :                 bool correct = true;
     266             :                 LC_GRF_STATUS oGrfStat;
     267             : 
     268             :                 // Iterate through all objects that constitute this area.
     269           9 :                 LC_InitGetRefFlate(&oGrfStat);
     270           9 :                 nRefCount = LC_GetRefFlate(&oGrfStat, GRF_YTRE, &nRefNr,
     271             :                                            &nRefStatus, 1);
     272         162 :                 while (nRefCount > 0)
     273             :                 {
     274         153 :                     if (poParent->papoBuiltGeometries[nRefNr] == nullptr)
     275             :                     {
     276             :                         // This should not happen under normal operation.
     277           0 :                         CPLError(CE_Warning, CPLE_AppDefined,
     278             :                                  "Feature %li referenced by %li, but it was "
     279             :                                  "not initialized. Geometry may be broken.",
     280             :                                  nRefNr, oNextSerial.lNr);
     281           0 :                         correct = false;
     282             :                         // return NULL;
     283           0 :                         break;
     284             :                     }
     285         153 :                     OGRGeometry *geom = poParent->papoBuiltGeometries[nRefNr];
     286         153 :                     if (geom->getGeometryType() == wkbLineString)
     287             :                     {
     288         153 :                         OGRLineString *poCurve = geom->toLineString();
     289         153 :                         if (nRefStatus == LC_MED_DIG)
     290             :                         { /* clockwise */
     291          90 :                             poOuter->addSubLineString(poCurve);
     292             :                         }
     293          63 :                         else if (nRefStatus == LC_MOT_DIG)
     294             :                         { /* counter-clockwise */
     295          63 :                             poOuter->addSubLineString(
     296          63 :                                 poCurve, poCurve->getNumPoints() - 1, 0);
     297             :                         }
     298             :                         else
     299             :                         {
     300           0 :                             CPLError(CE_Failure, CPLE_OpenFailed,
     301             :                                      "Internal error: GRF_*_OY encountered.");
     302           0 :                             return nullptr;
     303             :                         }
     304             :                     }
     305             :                     else
     306             :                     {
     307           0 :                         CPLError(CE_Warning, CPLE_AppDefined,
     308             :                                  "Element %li composed of non-linestrings (REF "
     309             :                                  "%li of type %i). Ignored.",
     310             :                                  oNextSerial.lNr, nRefNr,
     311           0 :                                  geom->getGeometryType());
     312             :                     }
     313         153 :                     nRefCount = LC_GetRefFlate(&oGrfStat, GRF_YTRE, &nRefNr,
     314             :                                                &nRefStatus, 1);
     315             :                 }
     316             : 
     317           9 :                 if (correct)
     318             :                 {
     319           9 :                     auto poLy = std::make_unique<OGRPolygon>();
     320           9 :                     poOuter->closeRings();
     321           9 :                     poLy->addRingDirectly(poOuter.release());
     322             : 
     323           0 :                     std::unique_ptr<OGRLinearRing> poInner;
     324           9 :                     nRefCount = LC_GetRefFlate(&oGrfStat, GRF_INDRE, &nRefNr,
     325             :                                                &nRefStatus, 1);
     326           9 :                     while (nRefCount > 0)
     327             :                     {
     328           0 :                         if (nRefNr == -1)
     329             :                         {
     330           0 :                             if (poInner && poInner->getNumPoints() > 2)
     331             :                             { /* If this is not the first polygon, terminate and
     332             :                                  add the last */
     333           0 :                                 poInner->closeRings();
     334           0 :                                 poLy->addRingDirectly(poInner.release());
     335             :                             }
     336           0 :                             poInner.reset(
     337           0 :                                 new OGRLinearRing()); /* Initialize a new closed
     338             :                                                          polygon */
     339             :                         }
     340             :                         else
     341             :                         {
     342           0 :                             if (poParent->papoBuiltGeometries[nRefNr] ==
     343             :                                 nullptr)
     344             :                             { /* this shouldn't happen under normal operation */
     345           0 :                                 CPLError(CE_Fatal, CPLE_AppDefined,
     346             :                                          "Feature %li referenced by %li, but "
     347             :                                          "it was not initialized.",
     348             :                                          nRefNr, oNextSerial.lNr);
     349           0 :                                 return nullptr;
     350             :                             }
     351           0 :                             OGRGeometry *geom =
     352           0 :                                 poParent->papoBuiltGeometries[nRefNr];
     353           0 :                             if (geom->getGeometryType() == wkbLineString)
     354             :                             {
     355           0 :                                 OGRLineString *poCurve = geom->toLineString();
     356           0 :                                 if (poInner && nRefStatus == LC_MED_DIG)
     357             :                                 { /* clockwise */
     358           0 :                                     poInner->addSubLineString(poCurve);
     359             :                                 }
     360           0 :                                 else if (poInner && nRefStatus == LC_MOT_DIG)
     361             :                                 { /* counter-clockwise */
     362           0 :                                     poInner->addSubLineString(
     363           0 :                                         poCurve, poCurve->getNumPoints() - 1,
     364             :                                         0);
     365             :                                 }
     366             :                                 else
     367             :                                 {
     368           0 :                                     CPLError(CE_Failure, CPLE_OpenFailed,
     369             :                                              "Internal error: GRF_*_OY "
     370             :                                              "encountered.");
     371           0 :                                     return nullptr;
     372             :                                 }
     373             :                             }
     374             :                             else
     375             :                             {
     376           0 :                                 CPLError(
     377             :                                     CE_Warning, CPLE_AppDefined,
     378             :                                     "Element %li composed of non-linestrings "
     379             :                                     "(REF %li of type %i). Ignored.",
     380             :                                     oNextSerial.lNr, nRefNr,
     381           0 :                                     geom->getGeometryType());
     382             :                             }
     383             :                         }
     384           0 :                         nRefCount = LC_GetRefFlate(&oGrfStat, GRF_INDRE,
     385             :                                                    &nRefNr, &nRefStatus, 1);
     386             :                     }
     387           9 :                     poGeom = std::move(poLy);
     388             :                 }
     389           9 :                 break;
     390             :             }
     391         105 :             case L_KURVE: /* curve */
     392             :             case L_LINJE: /* curve, not simplifyable */
     393             :             case L_BUEP:
     394             :             { /* curve, interpolated from circular arc */
     395         105 :                 oGType = wkbLineString;
     396         210 :                 if (poParent->papoBuiltGeometries[oNextSerial.lNr] == nullptr ||
     397         105 :                     poParent->papoBuiltGeometries[oNextSerial.lNr]
     398         105 :                             ->getGeometryType() != wkbLineString)
     399             :                 {
     400             :                     // This should not happen under normal operation.
     401           0 :                     CPLError(CE_Warning, CPLE_AppDefined,
     402             :                              "Curve or line %li may have a broken geometry",
     403             :                              oNextSerial.lNr);
     404             :                     // return NULL;
     405           0 :                     break;
     406             :                 }
     407             :                 const OGRLineString *poCurve =
     408         105 :                     poParent->papoBuiltGeometries[oNextSerial.lNr]
     409         105 :                         ->toLineString();
     410         105 :                 poGeom.reset(poCurve->clone());
     411         105 :                 break;
     412             :             }
     413           0 :             case L_TEKST:
     414             :             { /* text */
     415           0 :                 oGType = wkbMultiPoint;
     416           0 :                 if (poParent->papoBuiltGeometries[oNextSerial.lNr] == nullptr ||
     417           0 :                     poParent->papoBuiltGeometries[oNextSerial.lNr]
     418           0 :                             ->getGeometryType() != wkbMultiPoint)
     419             :                 {
     420             :                     // This should not happen under normal operation.
     421           0 :                     CPLError(CE_Warning, CPLE_AppDefined,
     422             :                              "Text point %li may have a broken geometry",
     423             :                              oNextSerial.lNr);
     424             :                     // return NULL;
     425           0 :                     break;
     426             :                 }
     427             :                 const OGRMultiPoint *poMP =
     428           0 :                     poParent->papoBuiltGeometries[oNextSerial.lNr]
     429           0 :                         ->toMultiPoint();
     430           0 :                 poGeom.reset(poMP->clone());
     431           0 :                 break;
     432             :             }
     433           0 :             case L_SYMBOL:
     434             :             {
     435             :                 // CPLError( CE_Warning, CPLE_OpenFailed, "Geometry of type
     436             :                 // SYMBOL treated as point (PUNKT).");
     437             :                 [[fallthrough]];
     438             :             }
     439             :             case L_PUNKT:
     440             :             { /* point */
     441           0 :                 oGType = wkbPoint;
     442           0 :                 if (poParent->papoBuiltGeometries[oNextSerial.lNr] == nullptr ||
     443           0 :                     poParent->papoBuiltGeometries[oNextSerial.lNr]
     444           0 :                             ->getGeometryType() != wkbPoint)
     445             :                 {
     446             :                     // This should not happen under normal operation.
     447           0 :                     CPLError(CE_Warning, CPLE_AppDefined,
     448             :                              "Point or symbol %li may have a broken geometry",
     449             :                              oNextSerial.lNr);
     450             :                     // return NULL;
     451           0 :                     break;
     452             :                 }
     453             :                 const OGRPoint *poPoint =
     454           0 :                     poParent->papoBuiltGeometries[oNextSerial.lNr]->toPoint();
     455           0 :                 poGeom.reset(poPoint->clone());
     456           0 :                 break;
     457             :             }
     458           9 :             case L_DEF: /* skip user definitions and headers here */
     459             :             case L_HODE:
     460             :             {
     461           9 :                 break;
     462             :             }
     463           0 :             default:
     464             :             { /* complain a bit about anything else that is not implemented */
     465           0 :                 CPLError(CE_Failure, CPLE_OpenFailed,
     466             :                          "Unrecognized geometry of type %i.", nName);
     467           0 :                 break;
     468             :             }
     469             :         }
     470             : 
     471         123 :         if (poGeom == nullptr)
     472           9 :             continue; /* skipping L_HODE and unrecognized groups */
     473         114 :         if (oGType != poFeatureDefn->GetGeomType())
     474             :         {
     475          57 :             continue; /* skipping features that are not the correct geometry */
     476             :         }
     477             : 
     478          57 :         OGRFeature *poFeature = new OGRFeature(poFeatureDefn);
     479             : 
     480             :         /* set all headers found in this group - we export everything, just in
     481             :          * case */
     482         492 :         for (iHeaders = oHeaders.begin(); iHeaders != oHeaders.end();
     483         435 :              ++iHeaders)
     484             :         {
     485         435 :             OGRSOSIDataType *poType = SOSIGetType(iHeaders->first);
     486         435 :             OGRSOSISimpleDataType *poElements = poType->getElements();
     487             : 
     488         435 :             const char *pszLine = iHeaders->second.c_str();
     489         435 :             char **tokens = CSLTokenizeString(iHeaders->second.c_str());
     490             : 
     491         909 :             for (int k = 0; k < poType->getElementCount(); k++)
     492             :             {
     493         531 :                 if (tokens[k] == nullptr)
     494          57 :                     break;
     495             : 
     496         474 :                 if (strcmp(poElements[k].GetName(), "") == 0)
     497          63 :                     continue;
     498         411 :                 const auto oIter = poHeaderDefn->find(poElements[k].GetName());
     499             :                 const int iHNr =
     500         411 :                     oIter == poHeaderDefn->end() ? -1 : oIter->second;
     501         411 :                 if (iHNr == -1)
     502             :                 {
     503           0 :                     CPLError(CE_Warning, CPLE_AppDefined,
     504             :                              "Could not find field definition for %s.",
     505           0 :                              poElements[k].GetName());
     506           0 :                     continue;
     507             :                 }
     508         411 :                 OGRFieldType nType = poElements[k].GetType();
     509         411 :                 switch (nType)
     510             :                 {
     511          96 :                     case OFTInteger:
     512             :                     {
     513          96 :                         poFeature->SetField(iHNr, SOSITypeToInt(tokens[k]));
     514          96 :                         break;
     515             :                     }
     516           0 :                     case OFTDate:
     517             :                     {
     518             :                         int date[3];
     519           0 :                         SOSITypeToDate(tokens[k], date);
     520           0 :                         poFeature->SetField(iHNr, date[0], date[1], date[2]);
     521           0 :                         break;
     522             :                     }
     523         117 :                     case OFTDateTime:
     524             :                     {
     525             :                         int date[6];
     526         117 :                         SOSITypeToDateTime(tokens[k], date);
     527         117 :                         if (date[0] > 0)
     528         117 :                             poFeature->SetField(iHNr, date[0], date[1], date[2],
     529             :                                                 date[3], date[4],
     530         117 :                                                 static_cast<float>(date[5]), 1);
     531         117 :                         break;
     532             :                     }
     533           0 :                     case OFTReal:
     534             :                     {
     535           0 :                         poFeature->SetField(iHNr, SOSITypeToReal(tokens[k]));
     536           0 :                         break;
     537             :                     }
     538         198 :                     default:
     539             :                     {
     540         198 :                         if ((k == 0) &&
     541         198 :                             ((pszLine[0] == '\'') || (pszLine[0] == '\"')))
     542             :                         { /* If the value is quoted, ignore these */
     543          30 :                             int nLen = static_cast<int>(strlen(pszLine));
     544          30 :                             char *pszNline = (char *)CPLMalloc(nLen - 1);
     545          30 :                             strncpy(pszNline, pszLine + 1, nLen - 2);
     546          30 :                             pszNline[nLen - 2] = '\0';
     547          30 :                             poFeature->SetField(iHNr, pszNline);
     548          30 :                             CPLFree(pszNline);
     549             :                         }
     550             :                         else
     551             :                         {
     552         168 :                             poFeature->SetField(iHNr, tokens[k]);
     553             :                         }
     554         198 :                         break;
     555             :                     }
     556             :                 }
     557             :             }
     558             : 
     559         435 :             CSLDestroy(tokens);
     560             :         }
     561             : 
     562          57 :         poGeom->assignSpatialReference(poParent->poSRS);
     563             : 
     564          57 :         poFeature->SetGeometryDirectly(poGeom.release());
     565          57 :         poFeature->SetFID(nNextFID++);
     566             : 
     567             :         /* Loop until we have a feature that matches the definition */
     568         114 :         if ((m_poFilterGeom == nullptr ||
     569         114 :              FilterGeometry(poFeature->GetGeometryRef())) &&
     570          57 :             (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
     571          57 :             return poFeature;
     572           0 :         delete poFeature;
     573             :     }
     574           6 :     return nullptr;
     575             : }
     576             : 
     577             : /************************************************************************/
     578             : /*                           ResetReading()                             */
     579             : /************************************************************************/
     580          18 : void OGRSOSILayer::ResetReading()
     581             : {
     582          18 :     LC_SBSn(&oSnradm, poFileadm, 0,
     583          18 :             poFileadm->lAntGr); /* set FYBA Search limits */
     584          18 :     poNextSerial = &oNextSerial;
     585          18 :     LC_InitNextBgr(poNextSerial);
     586          18 :     nNextFID = 0;
     587          18 : }
     588             : 
     589             : /************************************************************************/
     590             : /*                              TestCapability()                        */
     591             : /************************************************************************/
     592             : 
     593           0 : int OGRSOSILayer::TestCapability(const char *pszCap)
     594             : {
     595             : 
     596           0 :     if (EQUAL(pszCap, OLCStringsAsUTF8))
     597           0 :         return TRUE;
     598             : #if 0
     599             :     if( EQUAL(pszCap,OLCCreateField) )
     600             :         return TRUE;
     601             :     else
     602             : #endif
     603           0 :     return FALSE;
     604             : }

Generated by: LCOV version 1.14