LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/vfk - vfkfeature.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 209 116 55.5 %
Date: 2012-12-26 Functions: 21 11 52.4 %

       1                 : /******************************************************************************
       2                 :  * $Id: vfkfeature.cpp 25340 2012-12-21 20:30:21Z rouault $
       3                 :  *
       4                 :  * Project:  VFK Reader - Feature definition
       5                 :  * Purpose:  Implements IVFKFeature/VFKFeature class.
       6                 :  * Author:   Martin Landa, landa.martin gmail.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2009-2010, 2012, 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 IVFKFeature constructor
      40                 : 
      41                 :   \param poDataBlock pointer to VFKDataBlock instance
      42                 : */
      43             107 : IVFKFeature::IVFKFeature(IVFKDataBlock *poDataBlock)
      44                 : {
      45             107 :     CPLAssert(NULL != poDataBlock);
      46             107 :     m_poDataBlock   = poDataBlock;
      47                 :     
      48             107 :     m_nFID          = -1;
      49             107 :     m_nGeometryType = poDataBlock->GetGeometryType();
      50             107 :     m_bGeometry     = FALSE;
      51             107 :     m_bValid        = FALSE;
      52             107 :     m_paGeom        = NULL;
      53             107 : }
      54                 : 
      55                 : /*!
      56                 :   \brief IVFKFeature destructor
      57                 : */
      58             107 : IVFKFeature::~IVFKFeature()
      59                 : {
      60             107 :     if (m_paGeom)
      61              40 :         delete m_paGeom;
      62                 :     
      63             107 :     m_poDataBlock = NULL;
      64             107 : }
      65                 : 
      66                 : /*!
      67                 :   \brief Set feature geometry type
      68                 : */
      69              13 : void IVFKFeature::SetGeometryType(OGRwkbGeometryType nGeomType)
      70                 : {
      71              13 :     m_nGeometryType = nGeomType;
      72              13 : }
      73                 : 
      74                 : /*!
      75                 :   \brief Set feature id
      76                 : 
      77                 :   FID: 0 for next, -1 for same
      78                 :   
      79                 :   \param nFID feature id
      80                 : */
      81              53 : void IVFKFeature::SetFID(long nFID)
      82                 : {
      83              53 :     if (m_nFID > 0) {
      84               0 :         m_nFID = nFID;
      85                 :     }
      86                 :     
      87              53 :     if (m_nFID < 1) {
      88                 :         long nMaxFID;
      89                 :         
      90              53 :         nMaxFID = m_poDataBlock->GetMaxFID();
      91              53 :         if (nFID == 0) {
      92                 :             /* next */
      93              40 :             m_nFID = nMaxFID + 1;
      94                 :         }
      95                 :         else {
      96                 :             /* same */
      97              13 :             m_nFID = nMaxFID;
      98                 :         }
      99                 :     }
     100              53 : }
     101                 : 
     102                 : /*!
     103                 :   \brief Set feature geometry
     104                 : 
     105                 :   \param poGeom pointer to OGRGeometry
     106                 : 
     107                 :   \return TRUE on valid feature or otherwise FALSE
     108                 : */
     109              67 : bool IVFKFeature::SetGeometry(OGRGeometry *poGeom)
     110                 : {
     111              67 :     m_bGeometry = TRUE;
     112              67 :     if (!poGeom)
     113              26 :         return m_bValid;
     114                 : 
     115              41 :     delete m_paGeom;
     116              41 :     m_paGeom = (OGRGeometry *) poGeom->clone(); /* make copy */
     117                 : 
     118              41 :     m_bValid = TRUE;    
     119              41 :     if (m_nGeometryType == wkbNone && m_paGeom->IsEmpty()) {
     120                 :         CPLError(CE_Warning, CPLE_AppDefined, 
     121               0 :                  "Empty geometry FID %ld.\n", m_nFID);
     122               0 :         m_bValid = FALSE;
     123                 :     }
     124                 :     
     125              41 :     if (m_nGeometryType == wkbLineString &&
     126                 :         ((OGRLineString *) m_paGeom)->getNumPoints() < 2) {
     127               0 :         m_bValid = FALSE;
     128                 :     }
     129                 :     
     130              41 :     if (m_nGeometryType == wkbPolygon) {
     131                 :         OGRLinearRing *poRing;
     132               1 :         poRing = ((OGRPolygon *) m_paGeom)->getExteriorRing();
     133               1 :         if (!poRing || poRing->getNumPoints() < 3)
     134               0 :             m_bValid = FALSE;
     135                 :     }
     136                 : 
     137              41 :     return m_bValid;
     138                 : }
     139                 : 
     140                 : /*!
     141                 :   \brief Get feature geometry
     142                 : 
     143                 :   \return pointer to OGRGeometry or NULL on error
     144                 : */
     145              85 : OGRGeometry *IVFKFeature::GetGeometry()
     146                 : {
     147              85 :     if (m_nGeometryType != wkbNone && !m_bGeometry)
     148               0 :         LoadGeometry();
     149                 : 
     150              85 :     return m_paGeom;
     151                 : }
     152                 : 
     153                 : 
     154                 : /*!
     155                 :   \brief Load geometry
     156                 : 
     157                 :   \return TRUE on success or FALSE on failure
     158                 : */
     159               0 : bool IVFKFeature::LoadGeometry()
     160                 : {
     161                 :     const char *pszName;
     162               0 :     CPLString osSQL;
     163                 :     
     164               0 :     if (m_bGeometry)
     165               0 :         return TRUE;
     166                 : 
     167               0 :     pszName  = m_poDataBlock->GetName();
     168                 :     
     169               0 :     if (EQUAL (pszName, "SOBR") ||
     170                 :         EQUAL (pszName, "OBBP") ||
     171                 :         EQUAL (pszName, "SPOL") ||
     172                 :         EQUAL (pszName, "OB") ||
     173                 :         EQUAL (pszName, "OP") ||
     174                 :         EQUAL (pszName, "OBPEJ")) {
     175                 :         /* -> wkbPoint */
     176                 :         
     177               0 :         return LoadGeometryPoint();
     178                 :     }
     179               0 :     else if (EQUAL (pszName, "SBP")) {
     180                 :         /* -> wkbLineString */
     181               0 :         return LoadGeometryLineStringSBP();
     182                 :     }
     183               0 :     else if (EQUAL (pszName, "HP") ||
     184                 :              EQUAL (pszName, "DPM")) {
     185                 :         /* -> wkbLineString */
     186               0 :         return LoadGeometryLineStringHP();
     187                 :     }
     188               0 :     else if (EQUAL (pszName, "PAR") ||
     189                 :              EQUAL (pszName, "BUD")) {
     190                 :         /* -> wkbPolygon */
     191               0 :         return LoadGeometryPolygon();
     192                 :     }
     193                 : 
     194               0 :     return FALSE;
     195                 : }
     196                 : 
     197                 : /*!
     198                 :   \brief VFKFeature constructor
     199                 : 
     200                 :   \param poDataBlock pointer to VFKDataBlock instance
     201                 : */
     202              53 : VFKFeature::VFKFeature(IVFKDataBlock *poDataBlock) : IVFKFeature(poDataBlock)
     203                 : {
     204              53 :     m_propertyList.assign(poDataBlock->GetPropertyCount(), VFKProperty());
     205              53 :     CPLAssert(size_t (poDataBlock->GetPropertyCount()) == m_propertyList.size());
     206              53 : }
     207                 : 
     208                 : /*!
     209                 :   \brief Set feature properties
     210                 : 
     211                 :   \param pszLine pointer to line containing feature definition
     212                 : 
     213                 :   \return TRUE on success or FALSE on failure
     214                 : */
     215              53 : bool VFKFeature::SetProperties(const char *pszLine)
     216                 : {
     217                 :     int iIndex, nLength;
     218                 :     const char *poChar, *poProp;
     219                 :     char* pszProp;
     220                 :     bool inString;
     221                 :     
     222              53 :     pszProp = NULL;
     223                 :     
     224                 :     /* set feature properties */
     225              53 :     for (poChar = pszLine; *poChar != '\0' && *poChar != ';'; poChar++)
     226                 :         /* skip data block name */
     227                 :         ;
     228              53 :     if (poChar == '\0')
     229               0 :         return FALSE;
     230                 : 
     231              53 :     poChar++; /* skip ';' */
     232                 :     
     233              53 :     poProp = poChar;
     234              53 :     iIndex = 0;
     235              53 :     nLength = 0;
     236              53 :     inString = FALSE;
     237            3753 :     while(*poChar != '\0') {
     238            3648 :         if (*poChar == '"' && 
     239                 :             (*(poChar-1) == ';' || *(poChar+1) == ';' || *(poChar+1) == '\0')) {
     240             177 :             poChar++; /* skip '"' */
     241             177 :             inString = inString ? FALSE : TRUE;
     242             177 :             if (inString) {
     243             109 :                 poProp = poChar;
     244             109 :                 if (*poChar == '"') { 
     245              41 :                     poChar++;
     246              41 :                     inString = FALSE;
     247                 :                 }
     248                 :             }
     249             177 :             if (*poChar == '\0')
     250               1 :                 break;
     251                 :         }
     252            4246 :         if (*poChar == ';' && !inString) {
     253             599 :             pszProp = (char *) CPLRealloc(pszProp, nLength + 1);
     254             599 :             if (nLength > 0)
     255             445 :                 strncpy(pszProp, poProp, nLength);
     256             599 :             pszProp[nLength] = '\0';
     257             599 :             if (!SetProperty(iIndex, pszProp))
     258               0 :                 return FALSE;
     259             599 :             iIndex++;
     260             599 :             poProp = ++poChar;
     261             599 :             nLength = 0;
     262                 :         }
     263                 :         else {
     264            3048 :             poChar++;
     265            3048 :             nLength++;
     266                 :         }
     267                 :     }
     268                 : 
     269                 :     /* append last property */
     270              53 :     if (inString) {
     271               0 :         nLength--; /* ignore '"' */
     272                 :     }
     273              53 :     pszProp = (char *) CPLRealloc(pszProp, nLength + 1);
     274              53 :     if (nLength > 0)
     275              27 :         strncpy(pszProp, poProp, nLength);
     276              53 :     pszProp[nLength] = '\0';
     277              53 :     if (!SetProperty(iIndex, pszProp))
     278               0 :         return FALSE;
     279                 :     
     280                 :     /* set fid */
     281              53 :     if (EQUAL(m_poDataBlock->GetName(), "SBP")) {
     282                 :         GUIntBig id;
     283                 :         const VFKProperty *poVfkProperty;
     284                 : 
     285              26 :         poVfkProperty = GetProperty("PORADOVE_CISLO_BODU");
     286              26 :         if (poVfkProperty)
     287                 :         {
     288              26 :             id = strtoul(poVfkProperty->GetValueS(), NULL, 0);
     289              26 :             if (id == 1)
     290              13 :                 SetFID(0); /* set next feature */
     291                 :             else
     292              13 :                 SetFID(-1); /* set same feature */
     293                 :         }
     294                 :     }
     295                 :     else {
     296              27 :         SetFID(0); /* set next feature */
     297                 :     }
     298              53 :     m_poDataBlock->SetMaxFID(GetFID()); /* update max value */
     299                 : 
     300              53 :     CPLFree(pszProp);
     301                 : 
     302              53 :     return TRUE;
     303                 : }
     304                 : 
     305                 : /*!
     306                 :   \brief Set feature property
     307                 : 
     308                 :   \param iIndex property index
     309                 :   \param pszValue property value
     310                 : 
     311                 :   \return TRUE on success
     312                 :   \return FALSE on failure
     313                 : */
     314             652 : bool VFKFeature::SetProperty(int iIndex, const char *pszValue)
     315                 : {
     316             652 :     if (iIndex < 0 || iIndex >= m_poDataBlock->GetPropertyCount() || size_t(iIndex) >= m_propertyList.size())
     317               0 :         return FALSE;
     318                 :     
     319             652 :     if (strlen(pszValue) < 1)
     320             180 :         m_propertyList[iIndex] = VFKProperty();
     321                 :     else {
     322                 :         OGRFieldType fType;
     323                 : 
     324                 :         const char *pszEncoding;
     325                 :         char       *pszValueEnc;
     326                 :                 
     327             472 :         fType = m_poDataBlock->GetProperty(iIndex)->GetType();
     328             472 :         switch (fType) {
     329                 :         case OFTInteger:
     330             139 :             m_propertyList[iIndex] = VFKProperty(atoi(pszValue));
     331             139 :             break;
     332                 :         case OFTReal:
     333              26 :             m_propertyList[iIndex] = VFKProperty(CPLAtof(pszValue));
     334              26 :             break;
     335                 :         default:
     336             307 :             pszEncoding = m_poDataBlock->GetProperty(iIndex)->GetEncoding();
     337             307 :             if (pszEncoding) {
     338                 :                 pszValueEnc = CPLRecode(pszValue, pszEncoding,
     339              28 :                                         CPL_ENC_UTF8);
     340              28 :                 m_propertyList[iIndex] = VFKProperty(pszValueEnc);
     341              28 :                 CPLFree(pszValueEnc);
     342                 :             }
     343                 :             else {
     344             279 :                 m_propertyList[iIndex] = VFKProperty(pszValue);
     345                 :             }
     346                 :             break;
     347                 :         }
     348                 :     }
     349             652 :     return TRUE;
     350                 : }
     351                 : 
     352                 : /*!
     353                 :   \brief Get property value by index
     354                 : 
     355                 :   \param iIndex property index
     356                 : 
     357                 :   \return property value
     358                 :   \return NULL on error
     359                 : */
     360             678 : const VFKProperty *VFKFeature::GetProperty(int iIndex) const
     361                 : {
     362             678 :     if (iIndex < 0 || iIndex >= m_poDataBlock->GetPropertyCount() || size_t(iIndex) >= m_propertyList.size())
     363               0 :         return NULL;
     364                 :     
     365             678 :     const VFKProperty* poProperty = &m_propertyList[iIndex];
     366             678 :     return poProperty;
     367                 : }
     368                 : 
     369                 : /*!
     370                 :   \brief Get property value by name
     371                 : 
     372                 :   \param pszName property name
     373                 : 
     374                 :   \return property value
     375                 :   \return NULL on error
     376                 : */
     377              26 : const VFKProperty *VFKFeature::GetProperty(const char *pszName) const
     378                 : {
     379              26 :     return GetProperty(m_poDataBlock->GetPropertyIndex(pszName));
     380                 : }
     381                 : 
     382                 : /*!
     383                 :   \brief Load geometry (point layers)
     384                 : 
     385                 :   \todo Really needed?
     386                 :   
     387                 :   \return TRUE on success
     388                 :   \return FALSE on failure
     389                 : */
     390               0 : bool VFKFeature::LoadGeometryPoint()
     391                 : {
     392                 :     double x, y;
     393                 :     int i_idxX, i_idxY;
     394                 :     
     395               0 :     i_idxY = m_poDataBlock->GetPropertyIndex("SOURADNICE_Y");
     396               0 :     i_idxX = m_poDataBlock->GetPropertyIndex("SOURADNICE_X");
     397               0 :     if (i_idxY < 0 || i_idxX < 0)
     398               0 :         return FALSE;
     399                 :     
     400               0 :     x = -1.0 * GetProperty(i_idxY)->GetValueD();
     401               0 :     y = -1.0 * GetProperty(i_idxX)->GetValueD();
     402               0 :     OGRPoint pt(x, y);
     403               0 :     SetGeometry(&pt);
     404                 :     
     405               0 :     return TRUE;
     406                 : }
     407                 : 
     408                 : /*!
     409                 :   \brief Load geometry (linestring SBP layer)
     410                 : 
     411                 :   \todo Really needed?
     412                 : 
     413                 :   \return TRUE on success or FALSE on failure
     414                 : */
     415               0 : bool VFKFeature::LoadGeometryLineStringSBP()
     416                 : {
     417                 :     int id, idxId, idxBp_Id, idxPCB, ipcb;
     418                 :     
     419                 :     VFKDataBlock *poDataBlockPoints;
     420                 :     VFKFeature   *poPoint, *poLine;
     421                 :     
     422               0 :     OGRLineString OGRLine;
     423                 :     
     424               0 :     poDataBlockPoints = (VFKDataBlock *) m_poDataBlock->GetReader()->GetDataBlock("SOBR");
     425               0 :     if (!poDataBlockPoints)
     426               0 :         return FALSE;
     427                 :     
     428               0 :     idxId    = poDataBlockPoints->GetPropertyIndex("ID");
     429               0 :     idxBp_Id = m_poDataBlock->GetPropertyIndex("BP_ID");
     430               0 :     idxPCB   = m_poDataBlock->GetPropertyIndex("PORADOVE_CISLO_BODU");
     431               0 :     if (idxId < 0 || idxBp_Id < 0 || idxPCB < 0)
     432               0 :         return false;
     433                 :     
     434               0 :     poLine = this;
     435               0 :     while (TRUE)
     436                 :     {
     437               0 :         id   = poLine->GetProperty(idxBp_Id)->GetValueI();
     438               0 :         ipcb = poLine->GetProperty(idxPCB)->GetValueI();
     439               0 :         if (OGRLine.getNumPoints() > 0 && ipcb == 1)
     440                 :         {
     441               0 :             m_poDataBlock->GetPreviousFeature(); /* push back */
     442               0 :             break;
     443                 :         }
     444                 :         
     445               0 :         poPoint = poDataBlockPoints->GetFeature(idxId, id);
     446               0 :         if (!poPoint)
     447                 :         {
     448               0 :             continue;
     449                 :         }
     450               0 :         OGRPoint *pt = (OGRPoint *) poPoint->GetGeometry();
     451               0 :         OGRLine.addPoint(pt);
     452                 :         
     453               0 :         poLine = (VFKFeature *) m_poDataBlock->GetNextFeature();
     454               0 :         if (!poLine)
     455               0 :             break;
     456                 :     };
     457                 :     
     458               0 :     OGRLine.setCoordinateDimension(2); /* force 2D */
     459               0 :     SetGeometry(&OGRLine);
     460                 :     
     461                 :     /* reset reading */
     462               0 :     poDataBlockPoints->ResetReading();
     463                 :     
     464               0 :     return TRUE;
     465                 : }
     466                 : 
     467                 : /*!
     468                 :   \brief Load geometry (linestring HP/DPM layer)
     469                 : 
     470                 :   \todo Really needed?
     471                 : 
     472                 :   \return TRUE on success or FALSE on failure
     473                 : */
     474               0 : bool VFKFeature::LoadGeometryLineStringHP()
     475                 : {
     476                 :     int           id, idxId, idxHp_Id;
     477                 :     VFKDataBlock *poDataBlockLines;
     478                 :     VFKFeature   *poLine;
     479                 :     
     480               0 :     poDataBlockLines = (VFKDataBlock *) m_poDataBlock->GetReader()->GetDataBlock("SBP");
     481               0 :     if (!poDataBlockLines)
     482               0 :         return FALSE;
     483                 :     
     484               0 :     idxId    = m_poDataBlock->GetPropertyIndex("ID");
     485               0 :     idxHp_Id = poDataBlockLines->GetPropertyIndex("HP_ID");
     486               0 :     if (idxId < 0 || idxHp_Id < 0)
     487               0 :         return FALSE;
     488                 :     
     489               0 :     id = GetProperty(idxId)->GetValueI();
     490               0 :     poLine = poDataBlockLines->GetFeature(idxHp_Id, id);
     491               0 :     if (!poLine || !poLine->GetGeometry())
     492               0 :         return FALSE;
     493                 :     
     494               0 :     SetGeometry(poLine->GetGeometry());
     495               0 :     poDataBlockLines->ResetReading();
     496                 :     
     497               0 :     return TRUE;
     498                 : }
     499                 : 
     500                 : /*!
     501                 :   \brief Load geometry (polygon BUD/PAR layers)
     502                 : 
     503                 :   \todo Implement (really needed?)
     504                 : 
     505                 :   \return TRUE on success or FALSE on failure
     506                 : */
     507               0 : bool VFKFeature::LoadGeometryPolygon()
     508                 : {
     509               0 :     return FALSE;
     510                 : }
     511               0 : OGRErr VFKFeature::LoadProperties(OGRFeature *poFeature)
     512                 : {
     513               0 :     for (int iField = 0; iField < m_poDataBlock->GetPropertyCount(); iField++) {
     514               0 :         if (GetProperty(iField)->IsNull())
     515               0 :             continue;
     516               0 :         OGRFieldType fType = poFeature->GetDefnRef()->GetFieldDefn(iField)->GetType();
     517               0 :         if (fType == OFTInteger) 
     518                 :             poFeature->SetField(iField,
     519               0 :                                 GetProperty(iField)->GetValueI());
     520               0 :         else if (fType == OFTReal)
     521                 :             poFeature->SetField(iField,
     522               0 :                                 GetProperty(iField)->GetValueD());
     523                 :         else
     524                 :             poFeature->SetField(iField,
     525               0 :                                 GetProperty(iField)->GetValueS());
     526                 :     }
     527                 : 
     528               0 :     return OGRERR_NONE;
     529                 : }

Generated by: LCOV version 1.7