LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/vfk - vfkfeature.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 201 109 54.2 %
Date: 2012-04-28 Functions: 21 11 52.4 %

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

Generated by: LCOV version 1.7