LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/vfk - vfkfeature.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 118 53 44.9 %
Date: 2010-01-09 Functions: 9 8 88.9 %

       1                 : /******************************************************************************
       2                 :  * $Id: vfkfeature.cpp 18487 2010-01-09 02:38:38Z mloskot $
       3                 :  *
       4                 :  * Project:  VFK Reader - Feature definition
       5                 :  * Purpose:  Implements VFKFeature class.
       6                 :  * Author:   Martin Landa, landa.martin gmail.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2009-2010, Martin Landa <landa.martin gmail.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person
      12                 :  * obtaining a copy of this software and associated documentation
      13                 :  * files (the "Software"), to deal in the Software without
      14                 :  * restriction, including without limitation the rights to use, copy,
      15                 :  * modify, merge, publish, distribute, sublicense, and/or sell copies
      16                 :  * of the Software, and to permit persons to whom the Software is
      17                 :  * furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be
      20                 :  * included in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      23                 :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      24                 :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      25                 :  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
      26                 :  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
      27                 :  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
      28                 :  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      29                 :  * SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #include "vfkreader.h"
      33                 : #include "vfkreaderp.h"
      34                 : 
      35                 : #include "cpl_conv.h"
      36                 : #include "cpl_error.h"
      37                 : 
      38                 : /*!
      39                 :   \brief VFKFeature constructor
      40                 : 
      41                 :   \param poDataBlock pointer to VFKDataBlock instance
      42                 : */
      43              53 : VFKFeature::VFKFeature(VFKDataBlock *poDataBlock)
      44                 : {
      45                 :     CPLAssert(NULL != poDataBlock);
      46              53 :     m_poDataBlock   = poDataBlock;
      47                 : 
      48              53 :     m_nFID           = -1;
      49              53 :     m_papszProperty = (VFKProperty **) CPLMalloc(sizeof(VFKProperty *) * poDataBlock->GetPropertyCount());
      50                 : 
      51             705 :     for (int i = 0; i < poDataBlock->GetPropertyCount(); i++)
      52             652 :         m_papszProperty[i] = NULL;
      53                 : 
      54              53 :     m_nGeometryType = poDataBlock->GetGeometryType();
      55              53 :     m_bGeometry     = FALSE;
      56              53 :     m_paGeom        = NULL;
      57              53 : }
      58                 : 
      59                 : /*!
      60                 :   \brief VFKFeature destructor
      61                 : */
      62              53 : VFKFeature::~VFKFeature()
      63                 : {
      64             705 :     for (int i = 0; i < m_poDataBlock->GetPropertyCount(); i++) {
      65             652 :   if (m_papszProperty[i])
      66             652 :       delete m_papszProperty[i];
      67                 :     }
      68                 : 
      69              53 :     CPLFree(m_papszProperty);
      70                 : 
      71              53 :     if (m_paGeom)
      72              40 :   delete m_paGeom;
      73                 :     
      74              53 :     m_poDataBlock = NULL;
      75              53 : }
      76                 : 
      77                 : /*!
      78                 :   \brief Set feature property
      79                 : 
      80                 :   \param iIndex property index
      81                 :   \param pszValue property value
      82                 : */
      83             652 : void VFKFeature::SetProperty(int iIndex, const char *pszValue)
      84                 : {
      85             652 :     if (iIndex < 0 || iIndex >= m_poDataBlock->GetPropertyCount()) {
      86                 :         CPLAssert(FALSE);
      87               0 :         return;
      88                 :     }
      89                 : 
      90             652 :     if (strlen(pszValue) < 1)
      91             180 :   m_papszProperty[iIndex] = new VFKProperty();
      92                 :     else {
      93                 :   OGRFieldType fType;
      94             472 :   fType = m_poDataBlock->GetProperty(iIndex)->GetType();
      95             472 :   switch (fType) {
      96                 :   case OFTInteger:
      97             378 :       m_papszProperty[iIndex] = new VFKProperty(atoi(pszValue));
      98             378 :       break;
      99                 :   case OFTReal:
     100              26 :       m_papszProperty[iIndex] = new VFKProperty(atof(pszValue));
     101              26 :       break;
     102                 :   default:
     103              68 :       m_papszProperty[iIndex] = new VFKProperty(pszValue);
     104                 :       break;
     105                 :   }
     106                 :     }
     107                 : }
     108                 : 
     109                 : /*!
     110                 :   \brief Get property value by index
     111                 : 
     112                 :   \param iIndex property index
     113                 : 
     114                 :   \return property value
     115                 :   \return NULL on error
     116                 : */
     117             657 : const VFKProperty *VFKFeature::GetProperty(int iIndex) const
     118                 : {
     119             657 :     if (iIndex < 0 || iIndex >= m_poDataBlock->GetPropertyCount())
     120               0 :         return NULL;
     121                 : 
     122             657 :     return m_papszProperty[iIndex];
     123                 : }
     124                 : 
     125                 : /*!
     126                 :   \brief Get property value by name
     127                 : 
     128                 :   \param pszName property name
     129                 : 
     130                 :   \return property value
     131                 :   \return NULL on error
     132                 : */
     133              26 : const VFKProperty *VFKFeature::GetProperty(const char *pszName) const
     134                 : {
     135              26 :     return GetProperty(m_poDataBlock->GetPropertyIndex(pszName));
     136                 : }
     137                 : 
     138                 : /*!
     139                 :   \brief Set feature id
     140                 : 
     141                 :   FID: 0 for next, -1 for same
     142                 :   
     143                 :   \param FID feature id
     144                 : */
     145              53 : void VFKFeature::SetFID(long nFID)
     146                 : {
     147              53 :     if (m_nFID > 0)
     148                 :     {
     149               0 :         m_nFID = nFID;
     150                 :     }
     151                 :     
     152              53 :     if (m_nFID < 1)
     153                 :     {
     154              53 :         long nMaxFID = m_poDataBlock->GetMaxFID();
     155              53 :         if (nFID == 0) /* next */
     156                 :         {
     157              40 :             m_nFID = nMaxFID + 1;
     158                 :         }
     159                 :         else /* same */
     160                 :         {
     161              13 :             m_nFID = nMaxFID;
     162                 :         }
     163                 :     }
     164              53 : }
     165                 : 
     166                 : /*!
     167                 :   \brief Set feature geometry
     168                 : 
     169                 :   \param poGeom pointer to OGRGeometry
     170                 : */
     171              66 : void VFKFeature::SetGeometry(OGRGeometry *poGeom)
     172                 : {
     173              66 :     m_bGeometry = TRUE;
     174              66 :     if (!poGeom)
     175              26 :         return;
     176                 : 
     177              40 :     m_paGeom = (OGRGeometry *) poGeom->clone(); /* make copy */
     178                 :     
     179              40 :     if (m_nGeometryType == wkbNone && m_paGeom->IsEmpty())
     180                 :     {
     181                 :         CPLError(CE_Warning, CPLE_AppDefined, 
     182               0 :                  "Empty geometry FID %ld.\n", m_nFID);
     183                 :     }
     184                 : 
     185              40 :     if (m_nGeometryType == wkbLineString && ((OGRLineString *) m_paGeom)->getNumPoints() < 2)
     186                 :     {
     187                 :         CPLError(CE_Warning, CPLE_AppDefined, 
     188                 :                  "Invalid LineString FID %ld (%d points).\n",
     189                 :                  m_nFID,
     190               0 :                  ((OGRLineString *) m_paGeom)->getNumPoints());
     191                 :     }
     192                 : }
     193                 : 
     194                 : /*!
     195                 :   \brief Load geometry
     196                 : 
     197                 :   \return TRUE on success
     198                 :   \return FALSE on failure
     199                 : */
     200               0 : bool VFKFeature::LoadGeometry()
     201                 : {
     202                 :     const char *pszName;
     203                 : 
     204               0 :     if (m_bGeometry) /* geometry already loaded */
     205               0 :         return TRUE;
     206                 : 
     207               0 :     pszName = m_poDataBlock->GetName();
     208                 :     
     209               0 :     if (EQUAL (pszName, "SOBR") || EQUAL (pszName, "OBBP")
     210                 :         || EQUAL (pszName, "SPOL") || EQUAL (pszName, "OB")
     211                 :         || EQUAL (pszName, "OP") || EQUAL (pszName, "OBPEJ"))
     212                 :     {
     213                 :         /* -> wkbPoint */
     214                 :         double x, y;
     215                 :         int i_idxX, i_idxY;
     216                 :         
     217               0 :         i_idxY = m_poDataBlock->GetPropertyIndex("SOURADNICE_Y");
     218               0 :         i_idxX = m_poDataBlock->GetPropertyIndex("SOURADNICE_X");
     219               0 :         if (i_idxY < 0 || i_idxX < 0)
     220               0 :             return FALSE;
     221                 :         
     222               0 :         x = -1.0 * GetProperty(i_idxY)->GetValueD();
     223               0 :         y = -1.0 * GetProperty(i_idxX)->GetValueD();
     224               0 :         OGRPoint pt(x, y);
     225               0 :         SetGeometry(&pt);
     226                 :         
     227               0 :         return TRUE;
     228                 :     }
     229                 :     
     230               0 :     if (EQUAL (pszName, "SBP"))
     231                 :     {
     232                 :         /* -> wkbLineString */
     233                 :         int id, idxId, idxBp_Id, idxPCB, ipcb;
     234                 :         
     235                 :         VFKDataBlock *poDataBlockPoints;
     236                 :         VFKFeature   *poPoint, *poLine;
     237                 :         
     238               0 :         OGRLineString OGRLine;
     239                 :         
     240               0 :         poDataBlockPoints = m_poDataBlock->GetReader()->GetDataBlock("SOBR");
     241               0 :         if (!poDataBlockPoints)
     242               0 :             return FALSE;
     243                 :         
     244               0 :         idxId    = poDataBlockPoints->GetPropertyIndex("ID");
     245               0 :         idxBp_Id = m_poDataBlock->GetPropertyIndex("BP_ID");
     246               0 :         idxPCB   = m_poDataBlock->GetPropertyIndex("PORADOVE_CISLO_BODU");
     247               0 :         if (idxId < 0 || idxBp_Id < 0 || idxPCB < 0)
     248               0 :             return -1;
     249                 :         
     250               0 :         poLine = this;
     251               0 :         while (TRUE)
     252                 :         {
     253               0 :             id   = poLine->GetProperty(idxBp_Id)->GetValueI();
     254               0 :             ipcb = poLine->GetProperty(idxPCB)->GetValueI();
     255               0 :             if (OGRLine.getNumPoints() > 0 && ipcb == 1)
     256                 :             {
     257               0 :                 m_poDataBlock->GetPreviousFeature(); /* push back */
     258               0 :                 break;
     259                 :             }
     260                 :             
     261               0 :             poPoint = poDataBlockPoints->GetFeature(idxId, id);
     262               0 :             if (!poPoint)
     263                 :             {
     264               0 :                 continue;
     265                 :             }
     266               0 :             OGRPoint *pt = (OGRPoint *) poPoint->GetGeometry();
     267               0 :             OGRLine.addPoint(pt);
     268                 :             
     269               0 :             poLine = m_poDataBlock->GetNextFeature();
     270               0 :             if (!poLine)
     271               0 :                 break;
     272                 :         };
     273                 : 
     274               0 :         OGRLine.setCoordinateDimension(2); /* force 2D */
     275               0 :         SetGeometry(&OGRLine);
     276                 :         
     277                 :         /* reset reading */
     278               0 :         poDataBlockPoints->ResetReading();
     279                 :         
     280               0 :         return TRUE;
     281                 :     }
     282                 : 
     283               0 :     if (EQUAL (pszName, "HP"))
     284                 :     {
     285                 :         /* -> wkbLineString */
     286                 :         int           id, idxId, idxHp_Id;
     287                 :         VFKDataBlock *poDataBlockLines;
     288                 :         VFKFeature   *poLine;
     289                 :         
     290               0 :         poDataBlockLines = m_poDataBlock->GetReader()->GetDataBlock("SBP");
     291               0 :         if (!poDataBlockLines)
     292               0 :             return FALSE;
     293                 :         
     294               0 :         idxId    = m_poDataBlock->GetPropertyIndex("ID");
     295               0 :         idxHp_Id = poDataBlockLines->GetPropertyIndex("HP_ID");
     296               0 :         if (idxId < 0 || idxHp_Id < 0)
     297               0 :             return FALSE;
     298                 :         
     299               0 :         id = GetProperty(idxId)->GetValueI();
     300               0 :         poLine = poDataBlockLines->GetFeature(idxHp_Id, id);
     301               0 :         if (!poLine || !poLine->GetGeometry())
     302               0 :             return FALSE;
     303                 :         
     304               0 :         SetGeometry(poLine->GetGeometry());
     305               0 :         poDataBlockLines->ResetReading();
     306                 :         
     307               0 :         return TRUE;
     308                 :     }
     309                 :     
     310               0 :     return FALSE;
     311                 : }
     312                 : 
     313                 : /*!
     314                 :   \brief Get feature geometry
     315                 : 
     316                 :   \return pointer to OGRGeometry
     317                 :   \return NULL on error
     318                 : */
     319             107 : OGRGeometry *VFKFeature::GetGeometry()
     320                 : {
     321             107 :     if (m_nGeometryType != wkbNone && !m_bGeometry)
     322               0 :         LoadGeometry();
     323                 : 
     324             107 :     return m_paGeom;
     325                 : }

Generated by: LCOV version 1.7