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

Generated by: LCOV version 1.14