LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/ogdi - ogrogdilayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 209 244 85.7 %
Date: 2024-04-30 17:17:22 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OGDI Bridge
       4             :  * Purpose:  Implements OGROGDILayer class.
       5             :  * Author:   Daniel Morissette, danmo@videotron.ca
       6             :  *           (Based on some code contributed by Frank Warmerdam :)
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2000, Daniel Morissette
      10             :  * Copyright (c) 2008-2013, 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             : 
      32             : #include "ogrogdi.h"
      33             : #include "cpl_conv.h"
      34             : #include "cpl_string.h"
      35             : 
      36             : /************************************************************************/
      37             : /*                           OGROGDILayer()                            */
      38             : /************************************************************************/
      39             : 
      40          19 : OGROGDILayer::OGROGDILayer(OGROGDIDataSource *poODS, const char *pszName,
      41          19 :                            ecs_Family eFamily)
      42          19 :     : m_poODS(poODS), m_nClientID(poODS->GetClientID()),
      43          38 :       m_pszOGDILayerName(CPLStrdup(pszName)), m_eFamily(eFamily),
      44             :       m_poFeatureDefn(nullptr),
      45             :       // Keep a reference on the SpatialRef (owned by the dataset).
      46          19 :       m_poSpatialRef(m_poODS->DSGetSpatialRef()),
      47          19 :       m_sFilterBounds(*(m_poODS->GetGlobalBounds())), m_iNextShapeId(0),
      48          19 :       m_nTotalShapeCount(-1), m_nFilteredOutShapes(0)
      49             : {
      50             : 
      51             :     // Select layer and feature family.
      52          19 :     OGROGDILayer::ResetReading();
      53             : 
      54          19 :     BuildFeatureDefn();
      55          19 : }
      56             : 
      57             : /************************************************************************/
      58             : /*                           ~OGROGDILayer()                           */
      59             : /************************************************************************/
      60             : 
      61          38 : OGROGDILayer::~OGROGDILayer()
      62             : 
      63             : {
      64          19 :     if (m_nFeaturesRead > 0 && m_poFeatureDefn != nullptr)
      65             :     {
      66          16 :         CPLDebug("OGDI", "%d features read on layer '%s'.",
      67           8 :                  (int)m_nFeaturesRead, m_poFeatureDefn->GetName());
      68             :     }
      69             : 
      70          19 :     if (m_poFeatureDefn)
      71          19 :         m_poFeatureDefn->Release();
      72             : 
      73          19 :     CPLFree(m_pszOGDILayerName);
      74             : 
      75             :     // Note: we do not delete m_poSpatialRef since it is owned by the dataset
      76          38 : }
      77             : 
      78             : /************************************************************************/
      79             : /*                          SetSpatialFilter()                          */
      80             : /************************************************************************/
      81             : 
      82         156 : void OGROGDILayer::SetSpatialFilter(OGRGeometry *poGeomIn)
      83             : 
      84             : {
      85         156 :     if (!InstallFilter(poGeomIn))
      86          84 :         return;
      87             : 
      88          72 :     ResetReading();
      89             : 
      90          72 :     m_nTotalShapeCount = -1;
      91             : }
      92             : 
      93             : /************************************************************************/
      94             : /*                         SetAttributeFilter()                         */
      95             : /************************************************************************/
      96             : 
      97         186 : OGRErr OGROGDILayer::SetAttributeFilter(const char *pszQuery)
      98             : {
      99         186 :     OGRErr eErr = OGRLayer::SetAttributeFilter(pszQuery);
     100             : 
     101         186 :     ResetReading();
     102             : 
     103         186 :     m_nTotalShapeCount = -1;
     104             : 
     105         186 :     return eErr;
     106             : }
     107             : 
     108             : /************************************************************************/
     109             : /*                            ResetReading()                            */
     110             : /************************************************************************/
     111             : 
     112         787 : void OGROGDILayer::ResetReading()
     113             : 
     114             : {
     115             :     ecs_LayerSelection sSelectionLayer;
     116             : 
     117         787 :     sSelectionLayer.Select = m_pszOGDILayerName;
     118         787 :     sSelectionLayer.F = m_eFamily;
     119             : 
     120         787 :     ecs_Result *psResult = cln_SelectLayer(m_nClientID, &sSelectionLayer);
     121         787 :     if (ECSERROR(psResult))
     122             :     {
     123           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     124             :                  "Access to layer '%s' Failed: %s\n", m_pszOGDILayerName,
     125           0 :                  psResult->message ? psResult->message : "(no message string)");
     126           0 :         return;
     127             :     }
     128             : 
     129             :     /* Reset spatial filter */
     130         787 :     if (m_poFilterGeom != nullptr)
     131             :     {
     132         198 :         OGREnvelope oEnv;
     133             : 
     134         198 :         m_poFilterGeom->getEnvelope(&oEnv);
     135             : 
     136         198 :         m_sFilterBounds.north = oEnv.MaxY;
     137         198 :         m_sFilterBounds.south = oEnv.MinY;
     138         198 :         m_sFilterBounds.west = oEnv.MinX;
     139         198 :         m_sFilterBounds.east = oEnv.MaxX;
     140             : 
     141         198 :         psResult = cln_SelectRegion(m_nClientID, &m_sFilterBounds);
     142         198 :         if (ECSERROR(psResult))
     143             :         {
     144           0 :             CPLError(CE_Failure, CPLE_AppDefined, "SelectRegion failed: %s",
     145           0 :                      psResult->message ? psResult->message
     146             :                                        : "(no message string)");
     147           0 :             return;
     148             :         }
     149             :     }
     150             :     else
     151             :     {
     152             :         /* Reset to global bounds */
     153         589 :         psResult = cln_SelectRegion(m_nClientID, m_poODS->GetGlobalBounds());
     154         589 :         if (ECSERROR(psResult))
     155             :         {
     156           0 :             CPLError(CE_Failure, CPLE_AppDefined, "SelectRegion failed: %s",
     157           0 :                      psResult->message ? psResult->message
     158             :                                        : "(no message string)");
     159           0 :             return;
     160             :         }
     161             :     }
     162             : 
     163         787 :     m_iNextShapeId = 0;
     164         787 :     m_nFilteredOutShapes = 0;
     165             : }
     166             : 
     167             : /************************************************************************/
     168             : /*                           GetNextFeature()                           */
     169             : /************************************************************************/
     170             : 
     171        1354 : OGRFeature *OGROGDILayer::GetNextFeature()
     172             : 
     173             : {
     174             : 
     175             :     /* Reset reading if we are not the current layer */
     176             :     /* WARNING : this does not allow interleaved reading of layers */
     177        1354 :     if (m_poODS->GetCurrentLayer() != this)
     178             :     {
     179           8 :         m_poODS->SetCurrentLayer(this);
     180           8 :         ResetReading();
     181             :     }
     182             : 
     183             :     while (true)
     184             :     {
     185        1630 :         OGRFeature *poFeature = GetNextRawFeature();
     186        1630 :         if (poFeature == nullptr)
     187         176 :             return nullptr;
     188             : 
     189             :         /* --------------------------------------------------------------------
     190             :          */
     191             :         /*      Do we need to apply an attribute test? */
     192             :         /* --------------------------------------------------------------------
     193             :          */
     194        2632 :         if ((m_poAttrQuery != nullptr && !m_poAttrQuery->Evaluate(poFeature)) ||
     195        1178 :             (m_poFilterGeom != nullptr &&
     196         270 :              !FilterGeometry(poFeature->GetGeometryRef())))
     197             :         {
     198         276 :             m_nFilteredOutShapes++;
     199         276 :             delete poFeature;
     200             :         }
     201             :         else
     202        1178 :             return poFeature;
     203         276 :     }
     204             : }
     205             : 
     206             : /************************************************************************/
     207             : /*                           GetNextFeature()                           */
     208             : /************************************************************************/
     209             : 
     210        1648 : OGRFeature *OGROGDILayer::GetNextRawFeature()
     211             : {
     212             :     /* -------------------------------------------------------------------- */
     213             :     /*      Retrieve object from OGDI server and create new feature         */
     214             :     /* -------------------------------------------------------------------- */
     215        1648 :     ecs_Result *psResult = cln_GetNextObject(m_nClientID);
     216        1648 :     if (!ECSSUCCESS(psResult))
     217             :     {
     218         176 :         if (ECSERROR(psResult) &&
     219         176 :             (psResult->message == nullptr ||
     220         176 :              strstr(psResult->message, "End of selection") == nullptr))
     221             :         {
     222           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     223             :                      "Access to next object of layer '%s' failed: %s\n",
     224             :                      m_pszOGDILayerName,
     225           0 :                      psResult->message ? psResult->message
     226             :                                        : "(no error string)");
     227             :         }
     228             :         // We probably reached EOF... keep track of shape count.
     229         176 :         m_nTotalShapeCount = m_iNextShapeId - m_nFilteredOutShapes;
     230         176 :         return nullptr;
     231             :     }
     232             : 
     233        1472 :     OGRFeature *poFeature = new OGRFeature(m_poFeatureDefn);
     234             : 
     235        1472 :     poFeature->SetFID(m_iNextShapeId++);
     236        1472 :     m_nFeaturesRead++;
     237             : 
     238             :     /* -------------------------------------------------------------------- */
     239             :     /*      Process geometry                                                */
     240             :     /* -------------------------------------------------------------------- */
     241        1472 :     if (m_eFamily == Point)
     242             :     {
     243        1033 :         ecs_Point *psPoint = &(ECSGEOM(psResult).point);
     244        1033 :         OGRPoint *poOGRPoint = new OGRPoint(psPoint->c.x, psPoint->c.y);
     245             : 
     246        1033 :         poOGRPoint->assignSpatialReference(m_poSpatialRef);
     247        1033 :         poFeature->SetGeometryDirectly(poOGRPoint);
     248             :     }
     249         439 :     else if (m_eFamily == Line)
     250             :     {
     251          62 :         ecs_Line *psLine = &(ECSGEOM(psResult).line);
     252          62 :         OGRLineString *poOGRLine = new OGRLineString();
     253             : 
     254          62 :         poOGRLine->setNumPoints(psLine->c.c_len);
     255             : 
     256         634 :         for (int i = 0; i < (int)psLine->c.c_len; i++)
     257             :         {
     258         572 :             poOGRLine->setPoint(i, psLine->c.c_val[i].x, psLine->c.c_val[i].y);
     259             :         }
     260             : 
     261          62 :         poOGRLine->assignSpatialReference(m_poSpatialRef);
     262          62 :         poFeature->SetGeometryDirectly(poOGRLine);
     263             :     }
     264         377 :     else if (m_eFamily == Area)
     265             :     {
     266         228 :         ecs_Area *psArea = &(ECSGEOM(psResult).area);
     267         228 :         OGRPolygon *poOGRPolygon = new OGRPolygon();
     268             : 
     269         456 :         for (int iRing = 0; iRing < (int)psArea->ring.ring_len; iRing++)
     270             :         {
     271         228 :             ecs_FeatureRing *psRing = &(psArea->ring.ring_val[iRing]);
     272         228 :             OGRLinearRing *poOGRRing = new OGRLinearRing();
     273             : 
     274         228 :             poOGRRing->setNumPoints(psRing->c.c_len);
     275             : 
     276       54559 :             for (int i = 0; i < (int)psRing->c.c_len; i++)
     277             :             {
     278       54331 :                 poOGRRing->setPoint(i, psRing->c.c_val[i].x,
     279       54331 :                                     psRing->c.c_val[i].y);
     280             :             }
     281         228 :             poOGRPolygon->addRingDirectly(poOGRRing);
     282             :         }
     283             : 
     284             :         // __TODO__
     285             :         // When OGR supports polygon centroids then we should carry them here
     286             : 
     287         228 :         poOGRPolygon->assignSpatialReference(m_poSpatialRef);
     288         228 :         poFeature->SetGeometryDirectly(poOGRPolygon);
     289             :     }
     290         149 :     else if (m_eFamily == Text)
     291             :     {
     292             :         // __TODO__
     293             :         // For now text is treated as a point and string is lost
     294             :         //
     295         149 :         ecs_Text *psText = &(ECSGEOM(psResult).text);
     296         149 :         OGRPoint *poOGRPoint = new OGRPoint(psText->c.x, psText->c.y);
     297             : 
     298         149 :         poOGRPoint->assignSpatialReference(m_poSpatialRef);
     299         149 :         poFeature->SetGeometryDirectly(poOGRPoint);
     300             :     }
     301             :     else
     302             :     {
     303           0 :         CPLAssert(false);
     304             :     }
     305             : 
     306             :     /* -------------------------------------------------------------------- */
     307             :     /*      Set attributes                                                  */
     308             :     /* -------------------------------------------------------------------- */
     309        1472 :     char *pszAttrList = ECSOBJECTATTR(psResult);
     310             : 
     311       11587 :     for (int iField = 0; iField < m_poFeatureDefn->GetFieldCount(); iField++)
     312             :     {
     313       10115 :         char *pszFieldStart = nullptr;
     314       10115 :         int nNameLen = 0;
     315             : 
     316             :         /* parse out the next attribute value */
     317       10115 :         if (!ecs_FindElement(pszAttrList, &pszFieldStart, &pszAttrList,
     318             :                              &nNameLen, nullptr))
     319             :         {
     320           0 :             nNameLen = 0;
     321           0 :             pszFieldStart = pszAttrList;
     322             :         }
     323             : 
     324             :         /* Skip any trailing white space (for string constants). */
     325             : 
     326       10115 :         if (nNameLen > 0 && pszFieldStart[nNameLen - 1] == ' ')
     327        2881 :             nNameLen--;
     328             : 
     329             :         /* skip leading white space */
     330       14128 :         while (pszFieldStart[0] == ' ' && nNameLen > 0)
     331             :         {
     332        4013 :             pszFieldStart++;
     333        4013 :             nNameLen--;
     334             :         }
     335             : 
     336             :         /* zero terminate the single field value, but save the          */
     337             :         /* character we overwrote, so we can restore it when done.      */
     338             : 
     339       10115 :         char chSavedChar = pszFieldStart[nNameLen];
     340       10115 :         pszFieldStart[nNameLen] = '\0';
     341             : 
     342             :         /* OGR takes care of all field type conversions for us! */
     343             : 
     344       10115 :         poFeature->SetField(iField, pszFieldStart);
     345             : 
     346       10115 :         pszFieldStart[nNameLen] = chSavedChar;
     347             :     }
     348             : 
     349             :     /* -------------------------------------------------------------------- */
     350             :     /*      Apply the text associated with text features if appropriate.    */
     351             :     /* -------------------------------------------------------------------- */
     352        1472 :     if (m_eFamily == Text)
     353             :     {
     354         149 :         poFeature->SetField("text", ECSGEOM(psResult).text.desc);
     355             :     }
     356             : 
     357        1472 :     return poFeature;
     358             : }
     359             : 
     360             : /************************************************************************/
     361             : /*                             GetFeature()                             */
     362             : /************************************************************************/
     363             : 
     364          36 : OGRFeature *OGROGDILayer::GetFeature(GIntBig nFeatureId)
     365             : 
     366             : {
     367             : 
     368          36 :     if (m_nTotalShapeCount != -1 && nFeatureId > m_nTotalShapeCount)
     369          12 :         return nullptr;
     370             : 
     371             :     /* Unset spatial filter */
     372             :     OGRGeometry *poOldFilterGeom =
     373          24 :         (m_poFilterGeom != nullptr) ? m_poFilterGeom->clone() : nullptr;
     374          24 :     if (poOldFilterGeom != nullptr)
     375           6 :         SetSpatialFilter(nullptr);
     376             : 
     377             :     /* Reset reading if we are not the current layer */
     378             :     /* WARNING : this does not allow interleaved reading of layers */
     379          24 :     if (m_poODS->GetCurrentLayer() != this)
     380             :     {
     381           0 :         m_poODS->SetCurrentLayer(this);
     382           0 :         ResetReading();
     383             :     }
     384          24 :     else if (nFeatureId < m_iNextShapeId)
     385          16 :         ResetReading();
     386             : 
     387          88 :     while (m_iNextShapeId != nFeatureId)
     388             :     {
     389          70 :         ecs_Result *psResult = cln_GetNextObject(m_nClientID);
     390          70 :         if (ECSSUCCESS(psResult))
     391          64 :             m_iNextShapeId++;
     392             :         else
     393             :         {
     394             :             // We probably reached EOF... keep track of shape count.
     395           6 :             m_nTotalShapeCount = m_iNextShapeId;
     396           6 :             if (poOldFilterGeom != nullptr)
     397             :             {
     398           0 :                 SetSpatialFilter(poOldFilterGeom);
     399           0 :                 delete poOldFilterGeom;
     400             :             }
     401           6 :             return nullptr;
     402             :         }
     403             :     }
     404             : 
     405             :     // OK, we're ready to read the requested feature...
     406          18 :     OGRFeature *poFeature = GetNextRawFeature();
     407          18 :     if (poOldFilterGeom != nullptr)
     408             :     {
     409           6 :         SetSpatialFilter(poOldFilterGeom);
     410           6 :         delete poOldFilterGeom;
     411             :     }
     412          18 :     return poFeature;
     413             : }
     414             : 
     415             : /************************************************************************/
     416             : /*                          GetFeatureCount()                           */
     417             : /*                                                                      */
     418             : /*      If a spatial filter is in effect, we turn control over to       */
     419             : /*      the generic counter.  Otherwise we return the total count.      */
     420             : /*      Eventually we should consider implementing a more efficient     */
     421             : /*      way of counting features matching a spatial query.              */
     422             : /************************************************************************/
     423             : 
     424          88 : GIntBig OGROGDILayer::GetFeatureCount(int bForce)
     425             : 
     426             : {
     427          88 :     if (m_nTotalShapeCount == -1)
     428             :     {
     429          44 :         m_nTotalShapeCount =
     430          44 :             static_cast<int>(OGRLayer::GetFeatureCount(bForce));
     431             :     }
     432             : 
     433          88 :     return m_nTotalShapeCount;
     434             : }
     435             : 
     436             : /************************************************************************/
     437             : /*                           TestCapability()                           */
     438             : /************************************************************************/
     439             : 
     440         210 : int OGROGDILayer::TestCapability(const char *pszCap)
     441             : 
     442             : {
     443             : /* -------------------------------------------------------------------- */
     444             : /*      Hummm... what are the proper capabilities...                    */
     445             : /*      Does OGDI have any idea of capabilities???                      */
     446             : /*      For now just return FALSE for everything.                       */
     447             : /* -------------------------------------------------------------------- */
     448             : #ifdef __TODO__
     449             :     if (EQUAL(pszCap, OLCFastFeatureCount))
     450             :         return m_poFilterGeom == NULL && m_poAttrQuery == NULL;
     451             : 
     452             :     else if (EQUAL(pszCap, OLCFastSpatialFilter))
     453             :         return FALSE;
     454             : 
     455             :     else
     456             :         return FALSE;
     457             : #endif
     458             : 
     459         210 :     if (EQUAL(pszCap, OLCRandomRead))
     460           0 :         return TRUE;
     461             : 
     462             :     else
     463         210 :         return FALSE;
     464             : }
     465             : 
     466             : /************************************************************************/
     467             : /*                          BuildFeatureDefn()                          */
     468             : /*                                                                      */
     469             : /*      (private) Initializes the schema in m_poFeatureDefn             */
     470             : /************************************************************************/
     471             : 
     472          19 : void OGROGDILayer::BuildFeatureDefn()
     473             : {
     474          19 :     const char *pszGeomName = nullptr;
     475          19 :     OGRwkbGeometryType eLayerGeomType = wkbUnknown;
     476             : 
     477             :     /* -------------------------------------------------------------------- */
     478             :     /*      Feature Defn name will be "<OGDILyrName>_<FeatureFamily>"       */
     479             :     /* -------------------------------------------------------------------- */
     480             : 
     481          19 :     switch (m_eFamily)
     482             :     {
     483           3 :         case Point:
     484           3 :             pszGeomName = "point";
     485           3 :             eLayerGeomType = wkbPoint;
     486           3 :             break;
     487           3 :         case Line:
     488           3 :             pszGeomName = "line";
     489           3 :             eLayerGeomType = wkbLineString;
     490           3 :             break;
     491           7 :         case Area:
     492           7 :             pszGeomName = "area";
     493           7 :             eLayerGeomType = wkbPolygon;
     494           7 :             break;
     495           6 :         case Text:
     496           6 :             pszGeomName = "text";
     497           6 :             eLayerGeomType = wkbPoint;
     498           6 :             break;
     499           0 :         default:
     500           0 :             pszGeomName = "unknown";
     501           0 :             eLayerGeomType = wkbUnknown;
     502           0 :             break;
     503             :     }
     504             : 
     505          19 :     char *pszFeatureDefnName = nullptr;
     506          19 :     if (m_poODS->LaunderLayerNames())
     507             :     {
     508          12 :         pszFeatureDefnName = CPLStrdup(m_pszOGDILayerName);
     509          12 :         char *pszAt = strchr(pszFeatureDefnName, '@');
     510          12 :         if (pszAt)
     511          12 :             *pszAt = '_';
     512          12 :         char *pszLeftParenthesis = strchr(pszFeatureDefnName, '(');
     513          12 :         if (pszLeftParenthesis)
     514          12 :             *pszLeftParenthesis = '\0';
     515             :     }
     516             :     else
     517             :         pszFeatureDefnName =
     518           7 :             CPLStrdup(CPLSPrintf("%s_%s", m_pszOGDILayerName, pszGeomName));
     519             : 
     520          19 :     m_poFeatureDefn = new OGRFeatureDefn(pszFeatureDefnName);
     521          19 :     SetDescription(m_poFeatureDefn->GetName());
     522          19 :     CPLFree(pszFeatureDefnName);
     523          19 :     pszFeatureDefnName = nullptr;
     524             : 
     525          19 :     m_poFeatureDefn->SetGeomType(eLayerGeomType);
     526          19 :     m_poFeatureDefn->Reference();
     527          19 :     m_poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(m_poSpatialRef);
     528             : 
     529             :     /* -------------------------------------------------------------------- */
     530             :     /*      Fetch schema from OGDI server and map to OGR types              */
     531             :     /* -------------------------------------------------------------------- */
     532          19 :     ecs_Result *psResult = cln_GetAttributesFormat(m_nClientID);
     533          19 :     if (ECSERROR(psResult))
     534             :     {
     535           0 :         CPLError(CE_Failure, CPLE_AppDefined, "ECSERROR: %s\n",
     536           0 :                  psResult->message ? psResult->message : "(no message string)");
     537           0 :         return;
     538             :     }
     539             : 
     540          19 :     ecs_ObjAttributeFormat *oaf = &(ECSRESULT(psResult).oaf);
     541          19 :     const int numFields = oaf->oa.oa_len;
     542         131 :     for (int i = 0; i < numFields; i++)
     543             :     {
     544         224 :         OGRFieldDefn oField("", OFTInteger);
     545             : 
     546         112 :         oField.SetName(oaf->oa.oa_val[i].name);
     547         112 :         oField.SetPrecision(0);
     548             : 
     549         112 :         switch (oaf->oa.oa_val[i].type)
     550             :         {
     551          77 :             case Decimal:
     552             :             case Smallint:
     553             :             case Integer:
     554          77 :                 oField.SetType(OFTInteger);
     555             :                 // TODO: Fix spelling - lenght -> length
     556          77 :                 if (oaf->oa.oa_val[i].lenght > 0)
     557          77 :                     oField.SetWidth(oaf->oa.oa_val[i].lenght);
     558             :                 else
     559           0 :                     oField.SetWidth(11);
     560          77 :                 break;
     561             : 
     562           0 :             case Numeric:
     563             :             case Real:
     564             :             case Float:
     565             :             case Double:
     566           0 :                 oField.SetType(OFTReal);
     567           0 :                 if (oaf->oa.oa_val[i].lenght > 0)
     568             :                 {
     569           0 :                     oField.SetWidth(oaf->oa.oa_val[i].lenght);
     570           0 :                     oField.SetPrecision(oaf->oa.oa_val[i].precision);
     571             :                 }
     572             :                 else
     573             :                 {
     574           0 :                     oField.SetWidth(18);
     575           0 :                     oField.SetPrecision(7);
     576             :                 }
     577           0 :                 break;
     578             : 
     579          35 :             case Char:
     580             :             case Varchar:
     581             :             case Longvarchar:
     582             :             default:
     583          35 :                 oField.SetType(OFTString);
     584          35 :                 if (oaf->oa.oa_val[i].lenght > 0)
     585          19 :                     oField.SetWidth(oaf->oa.oa_val[i].lenght);
     586             :                 else
     587          16 :                     oField.SetWidth(64);
     588          35 :                 break;
     589             :         }
     590             : 
     591         112 :         m_poFeatureDefn->AddFieldDefn(&oField);
     592             :     }
     593             : 
     594             :     /* -------------------------------------------------------------------- */
     595             :     /*      Add a text attribute for text objects.                          */
     596             :     /* -------------------------------------------------------------------- */
     597          19 :     if (m_eFamily == Text)
     598             :     {
     599          12 :         OGRFieldDefn oField("text", OFTString);
     600             : 
     601           6 :         m_poFeatureDefn->AddFieldDefn(&oField);
     602             :     }
     603             : }

Generated by: LCOV version 1.14