LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/vfk - vfkdatablock.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 420 153 36.4 %
Date: 2013-03-30 Functions: 32 16 50.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: vfkdatablock.cpp 25721 2013-03-09 16:21:46Z martinl $
       3                 :  *
       4                 :  * Project:  VFK Reader - Data block definition
       5                 :  * Purpose:  Implements VFKDataBlock class.
       6                 :  * Author:   Martin Landa, landa.martin gmail.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2009-2013, 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 <ctime>
      33                 : 
      34                 : #include "vfkreader.h"
      35                 : #include "vfkreaderp.h"
      36                 : 
      37                 : #include "cpl_conv.h"
      38                 : #include "cpl_error.h"
      39                 : 
      40                 : /*!
      41                 :   \brief VFK Data Block constructor
      42                 : 
      43                 :   \param pszName data block name
      44                 : */
      45             122 : IVFKDataBlock::IVFKDataBlock(const char *pszName, const IVFKReader *poReader)
      46                 : {
      47             122 :     m_pszName        = CPLStrdup(pszName);
      48                 :     
      49             122 :     m_nPropertyCount = 0;
      50             122 :     m_papoProperty   = NULL;
      51                 : 
      52             122 :     m_nFeatureCount  = -1; /* load data on first request */
      53             122 :     m_papoFeature    = NULL;
      54                 : 
      55             122 :     m_iNextFeature   = -1;
      56                 : 
      57             122 :     m_nGeometryType     = wkbUnknown;
      58             122 :     m_bGeometry         = FALSE;   /* geometry is not loaded by default */
      59             122 :     m_bGeometryPerBlock = TRUE;    /* load geometry per block/feature */
      60                 : 
      61             122 :     m_poReader       = (IVFKReader *) poReader;
      62             122 : }
      63                 : 
      64                 : /*!
      65                 :   \brief VFKDataBlock destructor
      66                 : */
      67             122 : IVFKDataBlock::~IVFKDataBlock()
      68                 : {
      69             122 :     CPLFree(m_pszName);
      70                 : 
      71            1272 :     for (int i = 0; i < m_nPropertyCount; i++) {
      72            1150 :         if (m_papoProperty[i])
      73            1150 :             delete m_papoProperty[i];
      74                 :     }
      75             122 :     CPLFree(m_papoProperty);
      76                 : 
      77             202 :     for (int i = 0; i < m_nFeatureCount; i++) {
      78              80 :         if (m_papoFeature[i])
      79              80 :             delete m_papoFeature[i];
      80                 :     }
      81             122 :     CPLFree(m_papoFeature);
      82             122 : }
      83                 : 
      84                 : /*!
      85                 :   \brief Get property definition
      86                 : 
      87                 :   \param iIndex property index
      88                 : 
      89                 :   \return pointer to VFKPropertyDefn definition or NULL on failure
      90                 : */
      91            3467 : VFKPropertyDefn *IVFKDataBlock::GetProperty(int iIndex) const
      92                 : {
      93            3467 :     if(iIndex < 0 || iIndex >= m_nPropertyCount)
      94               0 :         return NULL;
      95                 : 
      96            3467 :     return m_papoProperty[iIndex];
      97                 : }
      98                 : 
      99                 : /*!
     100                 :   \brief Set properties
     101                 : 
     102                 :   \param poLine pointer to line
     103                 : */
     104             122 : void IVFKDataBlock::SetProperties(const char *poLine)
     105                 : {
     106                 :     const char *poChar, *poProp;
     107                 :     char *pszName, *pszType;
     108                 :     int   nLength;
     109                 :     
     110             122 :     pszName = pszType = NULL;
     111                 :     
     112                 :     /* skip data block name */
     113             122 :     for (poChar = poLine; *poChar != '0' && *poChar != ';'; poChar++)
     114                 :         ;
     115             122 :     if (*poChar == '\0')
     116               0 :         return;
     117                 : 
     118             122 :     poChar++;
     119                 : 
     120                 :     /* read property name/type */
     121             122 :     poProp  = poChar;
     122             122 :     nLength = 0;
     123           14456 :     while(*poChar != '\0') {
     124           14212 :         if (*poChar == ' ') {
     125            1150 :             pszName = (char *) CPLRealloc(pszName, nLength + 1);
     126            1150 :             strncpy(pszName, poProp, nLength);
     127            1150 :             pszName[nLength] = '\0';
     128                 :             
     129            1150 :             poProp = ++poChar;
     130            1150 :             nLength = 0;
     131                 :         }
     132           13062 :         else if (*poChar == ';') {
     133            1028 :             pszType = (char *) CPLRealloc(pszType, nLength + 1);
     134            1028 :             strncpy(pszType, poProp, nLength);
     135            1028 :             pszType[nLength] = '\0';
     136                 :             
     137                 :             /* add property */
     138            1028 :             if (pszName && *pszName != '\0' &&
     139                 :                 pszType && *pszType != '\0')
     140            1028 :                 AddProperty(pszName, pszType);
     141                 :             
     142            1028 :             poProp = ++poChar;
     143            1028 :             nLength = 0;
     144                 :         }
     145           14212 :         poChar++;
     146           14212 :         nLength++;
     147                 :     }
     148                 : 
     149             122 :     pszType = (char *) CPLRealloc(pszType, nLength + 1);
     150             122 :     strncpy(pszType, poProp, nLength);
     151             122 :     pszType[nLength] = '\0';
     152                 :     
     153                 :     /* add property */
     154             122 :     if (pszName && *pszName != '\0' &&
     155                 :         pszType && *pszType != '\0')
     156             122 :         AddProperty(pszName, pszType);
     157                 :     
     158             122 :     CPLFree(pszName);
     159             122 :     CPLFree(pszType);
     160                 : }
     161                 : 
     162                 : /*!
     163                 :   \brief Add data block property
     164                 : 
     165                 :   \param pszName property name
     166                 :   \param pszType property type
     167                 : 
     168                 :   \return number of properties
     169                 : */
     170            1150 : int IVFKDataBlock::AddProperty(const char *pszName, const char *pszType)
     171                 : {
     172                 :     VFKPropertyDefn *poNewProperty = new VFKPropertyDefn(pszName, pszType,
     173            1150 :                                                          m_poReader->IsLatin2());
     174                 : 
     175            1150 :     m_nPropertyCount++;
     176                 :     
     177                 :     m_papoProperty = (VFKPropertyDefn **)
     178            1150 :         CPLRealloc(m_papoProperty, sizeof (VFKPropertyDefn *) * m_nPropertyCount);
     179            1150 :     m_papoProperty[m_nPropertyCount-1] = poNewProperty;
     180                 : 
     181            1150 :     return m_nPropertyCount;
     182                 : }
     183                 : 
     184              29 : int IVFKDataBlock::GetFeatureCount()
     185                 : {
     186              29 :     if (m_nFeatureCount < 0) {
     187               2 :         m_poReader->ReadDataRecords(this); /* read VFK data records */
     188               2 :         if (m_bGeometryPerBlock && !m_bGeometry) {
     189               2 :             LoadGeometry(); /* get real number of features */
     190                 :         }
     191                 :     }
     192                 : 
     193              29 :     return m_nFeatureCount;
     194                 : }
     195                 : 
     196                 : /*!
     197                 :   \brief Set number of features per data block
     198                 : 
     199                 :   \param nNewCount number of features
     200                 :   \param bIncrement increment current value
     201                 : */
     202              12 : void IVFKDataBlock::SetFeatureCount(int nNewCount, bool bIncrement)
     203                 : {
     204              12 :     if (bIncrement) {
     205               0 :         m_nFeatureCount += nNewCount;
     206                 :     }
     207                 :     else {
     208              12 :         m_nFeatureCount = nNewCount;
     209                 :     }
     210              12 : }
     211                 : 
     212                 : /*!
     213                 :   \brief Reset reading
     214                 : 
     215                 :   \param iIdx force index
     216                 : */
     217               3 : void IVFKDataBlock::ResetReading(int iIdx)
     218                 : {
     219               3 :     if (iIdx > -1) {
     220               0 :         m_iNextFeature = iIdx;
     221                 :     }
     222                 :     else {
     223               3 :         m_iNextFeature = 0;
     224                 :     }
     225               3 : }
     226                 : 
     227                 : /*!
     228                 :   \brief Get next feature
     229                 : 
     230                 :   \return pointer to VFKFeature instance or NULL on error
     231                 : */
     232              15 : IVFKFeature *IVFKDataBlock::GetNextFeature()
     233                 : {
     234              15 :     if (m_nFeatureCount < 0) {
     235               0 :         m_poReader->ReadDataRecords(this);
     236                 :     }
     237                 :     
     238              15 :     if (m_bGeometryPerBlock && !m_bGeometry) {
     239               0 :         LoadGeometry();
     240                 :     }
     241                 :     
     242              15 :     if (m_iNextFeature < 0)
     243               0 :         ResetReading();
     244                 : 
     245              15 :     if (m_iNextFeature < 0 || m_iNextFeature >= m_nFeatureCount)
     246               1 :         return NULL;
     247                 :     
     248              14 :     return m_papoFeature[m_iNextFeature++];
     249                 : }
     250                 : 
     251                 : /*!
     252                 :   \brief Get previous feature
     253                 : 
     254                 :   \return pointer to VFKFeature instance or NULL on error
     255                 : */
     256               0 : IVFKFeature *IVFKDataBlock::GetPreviousFeature()
     257                 : {
     258               0 :     if (m_nFeatureCount < 0) {
     259               0 :         m_poReader->ReadDataRecords(this);
     260                 :     }
     261                 :     
     262               0 :     if (m_bGeometryPerBlock && !m_bGeometry) {
     263               0 :        LoadGeometry();
     264                 :     }
     265                 : 
     266               0 :     if (m_iNextFeature < 0)
     267               0 :         ResetReading();
     268                 :     
     269               0 :     if (m_iNextFeature < 0 || m_iNextFeature >= m_nFeatureCount)
     270               0 :         return NULL;
     271                 :     
     272               0 :     return m_papoFeature[m_iNextFeature--];
     273                 : }
     274                 : 
     275                 : /*!
     276                 :   \brief Get first feature
     277                 : 
     278                 :   \return pointer to VFKFeature instance or NULL on error
     279                 : */
     280               0 : IVFKFeature *IVFKDataBlock::GetFirstFeature()
     281                 : {
     282               0 :     if (m_nFeatureCount < 0) {
     283               0 :         m_poReader->ReadDataRecords(this);
     284                 :     }
     285                 :         
     286               0 :     if (m_bGeometryPerBlock && !m_bGeometry) {
     287               0 :         LoadGeometry();
     288                 :     }
     289                 :     
     290               0 :     if (m_nFeatureCount < 1)
     291               0 :         return NULL;
     292                 :     
     293               0 :     return m_papoFeature[0];
     294                 : }
     295                 : 
     296                 : /*!
     297                 :   \brief Get last feature
     298                 : 
     299                 :   \return pointer to VFKFeature instance or NULL on error
     300                 : */
     301               0 : IVFKFeature *IVFKDataBlock::GetLastFeature()
     302                 : {
     303               0 :     if (m_nFeatureCount < 0) {
     304               0 :         m_poReader->ReadDataRecords(this);
     305                 :     }
     306                 :     
     307               0 :     if (m_bGeometryPerBlock && !m_bGeometry) {
     308               0 :         LoadGeometry();
     309                 :     }
     310                 :     
     311               0 :     if (m_nFeatureCount < 1)
     312               0 :         return NULL;
     313                 :     
     314               0 :     return m_papoFeature[m_nFeatureCount-1];
     315                 : }
     316                 : 
     317                 : /*!
     318                 :   \brief Get property index by name
     319                 : 
     320                 :   \param pszName property name
     321                 : 
     322                 :   \return property index or -1 on error (property name not found)
     323                 : */
     324               0 : int IVFKDataBlock::GetPropertyIndex(const char *pszName) const
     325                 : {
     326               0 :     for (int i = 0; i < m_nPropertyCount; i++)
     327               0 :         if (EQUAL(pszName,m_papoProperty[i]->GetName()))
     328               0 :             return i;
     329                 :     
     330               0 :     return -1;
     331                 : }
     332                 : 
     333                 : /*!
     334                 :   \brief Set geometry type (point, linestring, polygon)
     335                 : 
     336                 :   \return geometry type
     337                 : */
     338             122 : OGRwkbGeometryType IVFKDataBlock::SetGeometryType()
     339                 : {
     340             122 :     m_nGeometryType = wkbNone; /* pure attribute records */
     341                 :     
     342             134 :     if (EQUAL (m_pszName, "SOBR") ||
     343                 :         EQUAL (m_pszName, "OBBP") ||
     344                 :         EQUAL (m_pszName, "SPOL") ||
     345                 :         EQUAL (m_pszName, "OB") ||
     346                 :         EQUAL (m_pszName, "OP") ||
     347                 :         EQUAL (m_pszName, "OBPEJ"))
     348              12 :         m_nGeometryType = wkbPoint;
     349                 :     
     350             116 :     else if (EQUAL (m_pszName, "SBP") ||
     351                 :              EQUAL (m_pszName, "HP") ||
     352                 :              EQUAL (m_pszName, "DPM"))
     353               6 :         m_nGeometryType = wkbLineString;
     354                 :     
     355             104 :     else if (EQUAL (m_pszName, "PAR") ||
     356                 :              EQUAL (m_pszName, "BUD"))
     357               4 :         m_nGeometryType = wkbPolygon;
     358                 :     
     359             122 :     return m_nGeometryType;
     360                 : }
     361                 : 
     362                 : /*!
     363                 :   \brief Get geometry type
     364                 : 
     365                 :   \return geometry type
     366                 : */
     367             369 : OGRwkbGeometryType IVFKDataBlock::GetGeometryType() const
     368                 : {
     369             369 :     return m_nGeometryType;
     370                 : }
     371                 : 
     372                 : /*!
     373                 :   \brief Get feature by index
     374                 : 
     375                 :   \param iIndex feature index
     376                 : 
     377                 :   \return pointer to feature definition or NULL on failure
     378                 : */
     379             107 : IVFKFeature *IVFKDataBlock::GetFeatureByIndex(int iIndex) const
     380                 : {
     381             107 :     if(iIndex < 0 || iIndex >= m_nFeatureCount)
     382               0 :         return NULL;
     383                 : 
     384             107 :     return m_papoFeature[iIndex];
     385                 : }
     386                 : 
     387                 : /*!
     388                 :   \brief Get feature by FID
     389                 : 
     390                 :   Modifies next feature id.
     391                 :   
     392                 :   \param nFID feature id
     393                 : 
     394                 :   \return pointer to feature definition or NULL on failure (not found)
     395                 : */
     396               1 : IVFKFeature *IVFKDataBlock::GetFeature(long nFID)
     397                 : {
     398               1 :     if (m_nFeatureCount < 0) {
     399               0 :         m_poReader->ReadDataRecords(this);
     400                 :     }
     401                 :     
     402               1 :     if (nFID < 1 || nFID > m_nFeatureCount)
     403               0 :         return NULL;
     404                 : 
     405               1 :     if (m_bGeometryPerBlock && !m_bGeometry) {
     406               0 :         LoadGeometry();
     407                 :     }
     408                 :     
     409               1 :     return GetFeatureByIndex(int (nFID) - 1); /* zero-based index */
     410                 : }
     411                 : 
     412                 : /*!
     413                 :   \brief Load geometry
     414                 : 
     415                 :   Print warning when some invalid features are detected.
     416                 : 
     417                 :   \return number of invalid features or -1 on failure
     418                 : */
     419              10 : int IVFKDataBlock::LoadGeometry()
     420                 : {
     421                 :     int           nInvalid;
     422                 :     clock_t       start, end;
     423                 :     
     424              10 :     if (m_bGeometry)
     425               2 :         return 0;
     426                 : 
     427               8 :     nInvalid    = 0;
     428               8 :     m_bGeometry = TRUE;
     429               8 :     start       = clock();
     430                 : 
     431               8 :     if (m_nFeatureCount < 0) {
     432               6 :         m_poReader->ReadDataRecords(this);
     433                 :     }
     434                 : 
     435              10 :     if (EQUAL (m_pszName, "SOBR") ||
     436                 :         EQUAL (m_pszName, "SPOL") ||
     437                 :         EQUAL (m_pszName, "OP") ||
     438                 :         EQUAL (m_pszName, "OBPEJ") ||
     439                 :         EQUAL (m_pszName, "OB") ||
     440                 :         EQUAL (m_pszName, "OBBP")) {
     441                 :         /* -> wkbPoint */
     442               2 :         nInvalid = LoadGeometryPoint();
     443                 :     }
     444               6 :     else if (EQUAL (m_pszName, "SBP")) {
     445                 :         /* -> wkbLineString */
     446               2 :         nInvalid = LoadGeometryLineStringSBP();
     447                 :     }
     448               6 :     else if (EQUAL (m_pszName, "HP") ||
     449                 :              EQUAL (m_pszName, "DPM")) {
     450                 :         /* -> wkbLineString */
     451               2 :         nInvalid = LoadGeometryLineStringHP();
     452                 :     }
     453               2 :     else if (EQUAL (m_pszName, "PAR") ||
     454                 :              EQUAL (m_pszName, "BUD")) {
     455                 :         /* -> wkbPolygon */
     456               2 :         nInvalid = LoadGeometryPolygon();
     457                 :     }
     458                 :     
     459               8 :     end = clock();
     460                 :     
     461               8 :     if (nInvalid > 0) {
     462                 :         CPLError(CE_Warning, CPLE_AppDefined, 
     463               0 :                  "%s: %d invalid features found", m_pszName, nInvalid);
     464                 :     }
     465                 :     CPLDebug("OGR_VFK", "VFKDataBlock::LoadGeometry(): name=%s time=%ld sec",
     466               8 :              m_pszName, (long)((end - start) / CLOCKS_PER_SEC));
     467                 : 
     468               8 :     return nInvalid;
     469                 : }
     470                 : 
     471                 : /*!
     472                 :   \brief Add linestring to a ring (private)
     473                 : 
     474                 :   \param[in,out] papoRing list of rings
     475                 :   \param poLine pointer to linestring to be added to a ring 
     476                 :   \param bNewRing  create new ring
     477                 :   \param bBackword allow backward direction
     478                 : 
     479                 :   \return TRUE on success or FALSE on failure
     480                 : */
     481              51 : bool IVFKDataBlock::AppendLineToRing(PointListArray *papoRing, const OGRLineString *poLine,
     482                 :                                      bool bNewRing, bool bBackward)
     483                 : {
     484                 :     OGRPoint *poFirst, *poLast;
     485                 :     OGRPoint *poFirstNew, *poLastNew;
     486                 : 
     487              51 :     OGRPoint  pt;
     488              51 :     PointList poList;
     489                 : 
     490                 :     /* OGRLineString -> PointList */
     491             153 :     for (int i = 0; i < poLine->getNumPoints(); i++) {
     492             102 :         poLine->getPoint(i, &pt);
     493             102 :         poList.push_back(pt);
     494                 :     }
     495                 : 
     496                 :     /* create new ring */
     497              51 :     if (bNewRing) {
     498               1 :         papoRing->push_back(new PointList(poList));
     499               1 :         return TRUE;
     500                 :     }
     501                 :     
     502              50 :     poFirstNew = &(poList.front());
     503              50 :     poLastNew  = &(poList.back());
     504              88 :     for (PointListArray::const_iterator i = papoRing->begin(), e = papoRing->end();
     505                 :          i != e; ++i) {
     506              50 :         PointList *ring = (*i);
     507              50 :         poFirst = &(ring->front());
     508              50 :         poLast  = &(ring->back());
     509              50 :         if (!poFirst || !poLast || poLine->getNumPoints() < 2)
     510               0 :             return FALSE;
     511                 : 
     512              50 :         if (poFirstNew->Equals(poLast)) {
     513                 :             /* forward, skip first point */
     514               9 :             ring->insert(ring->end(), poList.begin()+1, poList.end());
     515               9 :             return TRUE;
     516                 :         }
     517                 :         
     518              41 :         if (bBackward && poFirstNew->Equals(poFirst)) {
     519                 :             /* backward, skip last point */
     520               0 :             ring->insert(ring->begin(), poList.rbegin(), poList.rend()-1);
     521               0 :             return TRUE;
     522                 :         }
     523                 :         
     524              41 :         if (poLastNew->Equals(poLast)) {
     525                 :             /* backward, skip first point */
     526               3 :             ring->insert(ring->end(), poList.rbegin()+1, poList.rend());
     527               3 :             return TRUE;
     528                 :         }
     529                 :         
     530              38 :         if (bBackward && poLastNew->Equals(poFirst)) {
     531                 :             /* forward, skip last point */
     532               0 :             ring->insert(ring->begin(), poList.begin(), poList.end()-1);
     533               0 :             return TRUE;
     534                 :         }
     535                 :     }
     536                 : 
     537              38 :     return FALSE;
     538                 : }
     539                 : 
     540                 : /*!
     541                 :   \brief Set next feature
     542                 : 
     543                 :   \param poFeature pointer to current feature
     544                 : 
     545                 :   \return index of current feature or -1 on failure
     546                 : */
     547               0 : int IVFKDataBlock::SetNextFeature(const IVFKFeature *poFeature)
     548                 : {
     549               0 :     for (int i = 0; i < m_nFeatureCount; i++) {
     550               0 :         if (m_papoFeature[i] == poFeature) {
     551               0 :             m_iNextFeature = i + 1;
     552               0 :             return i;
     553                 :         }
     554                 :     }
     555                 : 
     556               0 :     return -1;
     557                 : }
     558                 : 
     559                 : /*!
     560                 :   \brief Add feature
     561                 : 
     562                 :   \param poNewFeature pointer to VFKFeature instance
     563                 : */
     564              80 : void IVFKDataBlock::AddFeature(IVFKFeature *poNewFeature)
     565                 : {
     566              80 :     m_nFeatureCount++;
     567                 :     
     568                 :     m_papoFeature = (IVFKFeature **)
     569              80 :         CPLRealloc(m_papoFeature, sizeof (IVFKFeature *) * m_nFeatureCount);
     570              80 :     m_papoFeature[m_nFeatureCount-1] = poNewFeature;
     571              80 : }
     572                 : 
     573                 : /*!
     574                 :   \brief Get first found feature based on it's properties
     575                 :   
     576                 :   Note: modifies next feature.
     577                 :   
     578                 :   \param idx property index
     579                 :   \param value property value
     580                 :   \param poList list of features (NULL to loop all features)
     581                 : 
     582                 :   \return pointer to feature definition or NULL on failure (not found)
     583                 : */
     584               0 : VFKFeature *VFKDataBlock::GetFeature(int idx, GUIntBig value, VFKFeatureList *poList)
     585                 : {
     586                 :     GUIntBig    iPropertyValue;
     587                 :     VFKFeature *poVfkFeature;
     588                 : 
     589               0 :     if (poList) {
     590               0 :         for (VFKFeatureList::iterator i = poList->begin(), e = poList->end();
     591                 :              i != e; ++i) {
     592               0 :             poVfkFeature = *i;
     593               0 :             iPropertyValue = strtoul(poVfkFeature->GetProperty(idx)->GetValueS(), NULL, 0);
     594               0 :             if (iPropertyValue == value) {
     595               0 :                 poList->erase(i); /* ??? */
     596               0 :                 return poVfkFeature;
     597                 :             }
     598                 :         }
     599                 :     }
     600                 :     else {
     601               0 :         for (int i = 0; i < m_nFeatureCount; i++) {
     602               0 :             poVfkFeature = (VFKFeature *) GetFeatureByIndex(i);
     603               0 :             iPropertyValue = strtoul(poVfkFeature->GetProperty(idx)->GetValueS(), NULL, 0);
     604               0 :             if (iPropertyValue == value) {
     605               0 :                 m_iNextFeature = i + 1;
     606               0 :                 return poVfkFeature;
     607                 :             }
     608                 :         }
     609                 :     }
     610                 :     
     611               0 :     return NULL;
     612                 : }
     613                 : 
     614                 : /*!
     615                 :   \brief Get features based on properties
     616                 :   
     617                 :   \param idx property index
     618                 :   \param value property value
     619                 :   
     620                 :   \return list of features
     621                 : */
     622               0 : VFKFeatureList VFKDataBlock::GetFeatures(int idx, GUIntBig value)
     623                 : {
     624                 :     GUIntBig    iPropertyValue;
     625                 :     VFKFeature *poVfkFeature;
     626               0 :     std::vector<VFKFeature *> poResult;
     627                 : 
     628               0 :     for (int i = 0; i < m_nFeatureCount; i++) {
     629               0 :         poVfkFeature = (VFKFeature *) GetFeatureByIndex(i);
     630               0 :         iPropertyValue = strtoul(poVfkFeature->GetProperty(idx)->GetValueS(), NULL, 0);
     631               0 :         if (iPropertyValue == value) {
     632               0 :             poResult.push_back(poVfkFeature);
     633                 :         }
     634                 :     }
     635                 :     
     636               0 :     return poResult;
     637                 : }
     638                 : 
     639                 : /*!
     640                 :   \brief Get features based on properties
     641                 :   
     642                 :   \param idx1 property index
     643                 :   \param idx2 property index
     644                 :   \param value property value
     645                 :   
     646                 :   \return list of features
     647                 : */
     648               0 : VFKFeatureList VFKDataBlock::GetFeatures(int idx1, int idx2, GUIntBig value)
     649                 : {
     650                 :     GUIntBig    iPropertyValue1, iPropertyValue2;
     651                 :     VFKFeature *poVfkFeature;
     652               0 :     std::vector<VFKFeature *> poResult;
     653                 :     
     654               0 :     for (int i = 0; i < m_nFeatureCount; i++) {
     655               0 :         poVfkFeature = (VFKFeature *) GetFeatureByIndex(i);
     656               0 :         iPropertyValue1 = strtoul(poVfkFeature->GetProperty(idx1)->GetValueS(), NULL, 0);
     657               0 :         if (idx2 < 0) {
     658               0 :             if (iPropertyValue1 == value) {
     659               0 :                 poResult.push_back(poVfkFeature);
     660                 :             }
     661                 :         }
     662                 :         else {
     663               0 :             iPropertyValue2 = strtoul(poVfkFeature->GetProperty(idx2)->GetValueS(), NULL, 0);
     664               0 :             if (iPropertyValue1 == value || iPropertyValue2 == value) {
     665               0 :                 poResult.push_back(poVfkFeature);
     666                 :             }
     667                 :         }
     668                 :     }
     669                 :     
     670               0 :     return poResult;
     671                 : }
     672                 : 
     673                 : /*!
     674                 :   \brief Get feature count based on property value
     675                 : 
     676                 :   \param pszName property name
     677                 :   \param pszValue property value
     678                 : 
     679                 :   \return number of features or -1 on error
     680                 : */
     681               0 : int VFKDataBlock::GetFeatureCount(const char *pszName, const char *pszValue)
     682                 : {
     683                 :     int nfeatures, propIdx;
     684                 :     VFKFeature *poVFKFeature;
     685                 : 
     686               0 :     propIdx = GetPropertyIndex(pszName);
     687               0 :     if (propIdx < 0)
     688               0 :         return -1;
     689                 :     
     690               0 :     nfeatures = 0;
     691               0 :     for (int i = 0; i < ((IVFKDataBlock *) this)->GetFeatureCount(); i++) {
     692               0 :         poVFKFeature = (VFKFeature *) ((IVFKDataBlock *) this)->GetFeature(i);
     693               0 :         if (!poVFKFeature)
     694               0 :             return -1;
     695               0 :         if (EQUAL (poVFKFeature->GetProperty(propIdx)->GetValueS(), pszValue))
     696               0 :             nfeatures++;
     697                 :     }
     698                 : 
     699               0 :     return nfeatures;
     700                 : }
     701                 : 
     702                 : /*!
     703                 :   \brief Load geometry (point layers)
     704                 : 
     705                 :   \return number of invalid features
     706                 : */
     707               0 : int VFKDataBlock::LoadGeometryPoint()
     708                 : {
     709                 :     /* -> wkbPoint */
     710                 :     long   nInvalid;
     711                 :     double x, y;
     712                 :     int    i_idxX, i_idxY;
     713                 :     
     714                 :     VFKFeature *poFeature;
     715                 :     
     716               0 :     nInvalid = 0;
     717               0 :     i_idxY = GetPropertyIndex("SOURADNICE_Y");
     718               0 :     i_idxX = GetPropertyIndex("SOURADNICE_X");
     719               0 :     if (i_idxY < 0 || i_idxX < 0) {
     720                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     721               0 :                  "Corrupted data (%s).\n", m_pszName);
     722               0 :         return nInvalid;
     723                 :     }
     724                 :     
     725               0 :     for (int j = 0; j < ((IVFKDataBlock *) this)->GetFeatureCount(); j++) {
     726               0 :         poFeature = (VFKFeature *) GetFeatureByIndex(j);
     727               0 :         x = -1.0 * poFeature->GetProperty(i_idxY)->GetValueD();
     728               0 :         y = -1.0 * poFeature->GetProperty(i_idxX)->GetValueD();
     729               0 :         OGRPoint pt(x, y);
     730               0 :         if (!poFeature->SetGeometry(&pt))
     731               0 :             nInvalid++;
     732                 :     }
     733                 :     
     734               0 :     return nInvalid;
     735                 : }
     736                 : 
     737                 : /*!
     738                 :   \brief Load geometry (linestring SBP layer)
     739                 : 
     740                 :   \return number of invalid features
     741                 : */
     742               0 : int VFKDataBlock::LoadGeometryLineStringSBP()
     743                 : {
     744                 :     int      idxId, idxBp_Id, idxPCB;
     745                 :     GUIntBig id, ipcb;
     746                 :     int      nInvalid;
     747                 :     
     748                 :     VFKDataBlock *poDataBlockPoints;
     749                 :     VFKFeature   *poFeature, *poPoint, *poLine;
     750                 :     
     751               0 :     OGRLineString oOGRLine;
     752                 :     
     753               0 :     nInvalid  = 0;
     754               0 :     poLine    = NULL;
     755                 :     
     756               0 :     poDataBlockPoints = (VFKDataBlock *) m_poReader->GetDataBlock("SOBR");
     757               0 :     if (NULL == poDataBlockPoints) {
     758                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     759               0 :                  "Data block %s not found.\n", m_pszName);
     760               0 :         return nInvalid;
     761                 :     }
     762                 :     
     763               0 :     poDataBlockPoints->LoadGeometry();
     764               0 :     idxId    = poDataBlockPoints->GetPropertyIndex("ID");
     765               0 :     idxBp_Id = GetPropertyIndex("BP_ID");
     766               0 :     idxPCB   = GetPropertyIndex("PORADOVE_CISLO_BODU");
     767               0 :     if (idxId < 0 || idxBp_Id < 0 || idxPCB < 0) {
     768                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     769               0 :                  "Corrupted data (%s).\n", m_pszName);
     770               0 :         return nInvalid;
     771                 :     }
     772                 :     
     773               0 :     for (int j = 0; j < ((IVFKDataBlock *) this)->GetFeatureCount(); j++) {
     774               0 :         poFeature = (VFKFeature *) GetFeatureByIndex(j);
     775               0 :         CPLAssert(NULL != poFeature);
     776                 :         
     777               0 :         poFeature->SetGeometry(NULL);
     778               0 :         id   = strtoul(poFeature->GetProperty(idxBp_Id)->GetValueS(), NULL, 0);
     779               0 :         ipcb = strtoul(poFeature->GetProperty(idxPCB)->GetValueS(), NULL, 0);
     780               0 :         if (ipcb == 1) {
     781               0 :             if (!oOGRLine.IsEmpty()) {
     782               0 :                 oOGRLine.setCoordinateDimension(2); /* force 2D */
     783               0 :                 if (!poLine->SetGeometry(&oOGRLine))
     784               0 :                     nInvalid++;
     785               0 :                 oOGRLine.empty(); /* restore line */
     786                 :             }
     787               0 :             poLine = poFeature;
     788                 :         }
     789                 :         else {
     790               0 :             poFeature->SetGeometryType(wkbUnknown);
     791                 :         }
     792               0 :         poPoint = poDataBlockPoints->GetFeature(idxId, id);
     793               0 :         if (!poPoint)
     794               0 :             continue;
     795               0 :         OGRPoint *pt = (OGRPoint *) poPoint->GetGeometry();
     796               0 :         oOGRLine.addPoint(pt);
     797                 :     }
     798                 :     /* add last line */
     799               0 :     oOGRLine.setCoordinateDimension(2); /* force 2D */
     800               0 :     if (poLine) {
     801               0 :         if (!poLine->SetGeometry(&oOGRLine))
     802               0 :             nInvalid++;
     803                 :     }
     804               0 :     poDataBlockPoints->ResetReading();
     805                 : 
     806               0 :     return nInvalid;
     807                 : }
     808                 : 
     809                 : /*!
     810                 :   \brief Load geometry (linestring HP/DPM layer)
     811                 : 
     812                 :   \return number of invalid features
     813                 : */
     814               0 : int VFKDataBlock::LoadGeometryLineStringHP()
     815                 : {
     816                 :     long          nInvalid;
     817                 :     int           idxId, idxMy_Id, idxPCB;
     818                 :     GUIntBig      id;
     819                 :     
     820                 :     VFKDataBlock  *poDataBlockLines;
     821                 :     VFKFeature    *poFeature, *poLine;
     822               0 :     VFKFeatureList poLineList;
     823                 :     
     824               0 :     nInvalid = 0;
     825                 :     
     826               0 :     poDataBlockLines = (VFKDataBlock *) m_poReader->GetDataBlock("SBP");
     827               0 :     if (NULL == poDataBlockLines) {
     828                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     829               0 :                  "Data block %s not found.\n", m_pszName);
     830               0 :         return nInvalid;
     831                 :     }
     832                 :     
     833               0 :     poDataBlockLines->LoadGeometry();
     834               0 :     idxId    = GetPropertyIndex("ID");
     835               0 :     if (EQUAL (m_pszName, "HP"))
     836               0 :         idxMy_Id = poDataBlockLines->GetPropertyIndex("HP_ID");
     837                 :     else
     838               0 :         idxMy_Id = poDataBlockLines->GetPropertyIndex("DPM_ID");
     839               0 :     idxPCB   = poDataBlockLines->GetPropertyIndex("PORADOVE_CISLO_BODU");
     840               0 :     if (idxId < 0 || idxMy_Id < 0 || idxPCB < 0) {
     841                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     842               0 :                  "Corrupted data (%s).\n", m_pszName);
     843               0 :         return nInvalid;
     844                 :     }
     845                 :     
     846               0 :     poLineList = poDataBlockLines->GetFeatures(idxPCB, 1); /* reduce to first segment */
     847               0 :     for (int i = 0; i < ((IVFKDataBlock *) this)->GetFeatureCount(); i++) {
     848               0 :         poFeature = (VFKFeature *) GetFeatureByIndex(i);
     849               0 :         CPLAssert(NULL != poFeature);
     850               0 :         id = strtoul(poFeature->GetProperty(idxId)->GetValueS(), NULL, 0);
     851               0 :         poLine = poDataBlockLines->GetFeature(idxMy_Id, id, &poLineList);
     852               0 :         if (!poLine || !poLine->GetGeometry())
     853               0 :             continue;
     854               0 :         if (!poFeature->SetGeometry(poLine->GetGeometry()))
     855               0 :             nInvalid++;
     856                 :     }
     857               0 :     poDataBlockLines->ResetReading();
     858                 : 
     859               0 :     return nInvalid;
     860                 : }
     861                 : 
     862                 : /*!
     863                 :   \brief Load geometry (polygon BUD/PAR layers)
     864                 : 
     865                 :   \return number of invalid features
     866                 : */
     867               0 : int VFKDataBlock::LoadGeometryPolygon()
     868                 : {
     869                 :     long nInvalid;
     870                 :     bool bIsPar, bNewRing, bFound;
     871                 :         
     872                 :     GUIntBig id, idOb;
     873                 :     int  nCount, nCountMax;
     874                 :     int idxId, idxPar1, idxPar2, idxBud, idxOb, idxIdOb;
     875                 :     
     876                 :     VFKFeature   *poFeature;
     877                 :     VFKDataBlock *poDataBlockLines1, *poDataBlockLines2;
     878                 :     
     879               0 :     VFKFeatureList   poLineList;
     880               0 :     PointListArray   poRingList; /* first is to be considered as exterior */
     881                 :     
     882               0 :     OGRLinearRing ogrRing;
     883               0 :     OGRPolygon    ogrPolygon;
     884                 :     
     885               0 :     idxPar1 = idxPar2 = idxBud = idxOb = idxIdOb = 0;
     886               0 :     nInvalid = 0;
     887               0 :     if (EQUAL (m_pszName, "PAR")) {
     888               0 :         poDataBlockLines1 = (VFKDataBlock *) m_poReader->GetDataBlock("HP");
     889               0 :         poDataBlockLines2 = poDataBlockLines1;
     890               0 :         bIsPar = TRUE;
     891                 :     }
     892                 :     else {
     893               0 :         poDataBlockLines1 = (VFKDataBlock *) m_poReader->GetDataBlock("OB");
     894               0 :         poDataBlockLines2 = (VFKDataBlock *) m_poReader->GetDataBlock("SBP");
     895               0 :         bIsPar = FALSE;
     896                 :     }
     897               0 :     if (NULL == poDataBlockLines1 || NULL == poDataBlockLines2) {
     898                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     899               0 :                  "Data block %s not found.\n", m_pszName);
     900               0 :         return nInvalid;
     901                 :     }
     902                 :     
     903               0 :     poDataBlockLines1->LoadGeometry();
     904               0 :     poDataBlockLines2->LoadGeometry();
     905               0 :     idxId = GetPropertyIndex("ID");
     906               0 :     if (idxId < 0) {
     907                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     908               0 :                  "Corrupted data (%s).\n", m_pszName);
     909               0 :         return nInvalid;
     910                 :     }
     911                 :     
     912               0 :     if (bIsPar) {
     913               0 :         idxPar1 = poDataBlockLines1->GetPropertyIndex("PAR_ID_1");
     914               0 :         idxPar2 = poDataBlockLines1->GetPropertyIndex("PAR_ID_2");
     915               0 :         if (idxPar1 < 0 || idxPar2 < 0) {
     916                 :             CPLError(CE_Failure, CPLE_NotSupported, 
     917               0 :                      "Corrupted data (%s).\n", m_pszName);
     918               0 :             return nInvalid;
     919                 :         }
     920                 :     }
     921                 :     else { /* BUD */
     922               0 :         idxIdOb  = poDataBlockLines1->GetPropertyIndex("ID");
     923               0 :         idxBud = poDataBlockLines1->GetPropertyIndex("BUD_ID");
     924               0 :         idxOb  = poDataBlockLines2->GetPropertyIndex("OB_ID");
     925               0 :         if (idxIdOb < 0 || idxBud < 0 || idxOb < 0) {
     926                 :             CPLError(CE_Failure, CPLE_NotSupported, 
     927               0 :                      "Corrupted data (%s).\n", m_pszName);
     928               0 :             return nInvalid;
     929                 :         }
     930                 :     }
     931                 :     
     932               0 :     for (int i = 0; i < ((IVFKDataBlock *) this)->GetFeatureCount(); i++) {
     933               0 :         poFeature = (VFKFeature *) GetFeatureByIndex(i);
     934               0 :         CPLAssert(NULL != poFeature);
     935               0 :         id = strtoul(poFeature->GetProperty(idxId)->GetValueS(), NULL, 0);
     936               0 :         if (bIsPar) {
     937               0 :             poLineList = poDataBlockLines1->GetFeatures(idxPar1, idxPar2, id);
     938                 :         }
     939                 :         else {
     940                 :             VFKFeature *poLineOb, *poLineSbp;
     941               0 :             std::vector<VFKFeature *> poLineListOb;
     942               0 :             poLineListOb = poDataBlockLines1->GetFeatures(idxBud, id);
     943               0 :             for (std::vector<VFKFeature *>::const_iterator iOb = poLineListOb.begin(), eOb = poLineListOb.end();
     944                 :                  iOb != eOb; ++iOb) {
     945               0 :                 poLineOb = (*iOb);
     946               0 :                 idOb = strtoul(poLineOb->GetProperty(idxIdOb)->GetValueS(), NULL, 0);
     947               0 :                 poLineSbp = poDataBlockLines2->GetFeature(idxOb, idOb);
     948               0 :                 if (poLineSbp)
     949               0 :                     poLineList.push_back(poLineSbp);
     950               0 :             }
     951                 :         }
     952               0 :         if (poLineList.size() < 1)
     953               0 :             continue;
     954                 :         
     955                 :         /* clear */
     956               0 :         ogrPolygon.empty();
     957               0 :         poRingList.clear();
     958                 :         
     959                 :         /* collect rings (points) */
     960               0 :         bFound = FALSE;
     961               0 :         nCount = 0;
     962               0 :         nCountMax = poLineList.size() * 2;
     963               0 :         while (poLineList.size() > 0 && nCount < nCountMax) {
     964               0 :             bNewRing = !bFound ? TRUE : FALSE;
     965               0 :             bFound = FALSE;
     966               0 :             for (VFKFeatureList::iterator iHp = poLineList.begin(), eHp = poLineList.end();
     967                 :                  iHp != eHp; ++iHp) {
     968               0 :                 const OGRLineString *pLine = (OGRLineString *) (*iHp)->GetGeometry();
     969               0 :                 if (pLine && AppendLineToRing(&poRingList, pLine, bNewRing)) {
     970               0 :                     bFound = TRUE;
     971               0 :                     poLineList.erase(iHp);
     972               0 :                     break;
     973                 :                 }
     974                 :             }
     975               0 :             nCount++;
     976                 :         }
     977                 :         /* create rings */
     978               0 :         for (PointListArray::const_iterator iRing = poRingList.begin(), eRing = poRingList.end();
     979                 :              iRing != eRing; ++iRing) {
     980               0 :             PointList *poList = *iRing;
     981               0 :             ogrRing.empty();
     982               0 :             for (PointList::iterator iPoint = poList->begin(), ePoint = poList->end();
     983                 :                  iPoint != ePoint; ++iPoint) {
     984               0 :                 ogrRing.addPoint(&(*iPoint));
     985                 :             }
     986               0 :             ogrPolygon.addRing(&ogrRing);
     987                 :         }
     988                 :         /* set polygon */
     989               0 :         ogrPolygon.setCoordinateDimension(2); /* force 2D */
     990               0 :         if (!poFeature->SetGeometry(&ogrPolygon))
     991               0 :             nInvalid++;
     992                 :     }
     993                 :     
     994                 :     /* free ring list */
     995               0 :     for (PointListArray::iterator iRing = poRingList.begin(),
     996               0 :              eRing = poRingList.end(); iRing != eRing; ++iRing) {
     997               0 :         delete (*iRing);
     998               0 :         *iRing = NULL;
     999                 :     }
    1000               0 :     poDataBlockLines1->ResetReading();
    1001               0 :     poDataBlockLines2->ResetReading();
    1002                 : 
    1003               0 :     return nInvalid;
    1004                 : }

Generated by: LCOV version 1.7