LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/vfk - vfkdatablocksqlite.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 209 170 81.3 %
Date: 2012-12-26 Functions: 7 7 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: vfkdatablocksqlite.cpp 25340 2012-12-21 20:30:21Z rouault $
       3                 :  *
       4                 :  * Project:  VFK Reader - Data block definition (SQLite)
       5                 :  * Purpose:  Implements VFKDataBlockSQLite
       6                 :  * Author:   Martin Landa, landa.martin gmail.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 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                 : #ifdef HAVE_SQLITE
      39                 : 
      40                 : /*!
      41                 :   \brief Load geometry (point layers)
      42                 : 
      43                 :   \return number of invalid features
      44                 : */
      45               1 : int VFKDataBlockSQLite::LoadGeometryPoint()
      46                 : {
      47                 :     int   nInvalid;
      48                 :     double x, y;
      49                 : 
      50               1 :     CPLString     osSQL;
      51                 :     sqlite3_stmt *hStmt;
      52                 :     
      53                 :     VFKFeatureSQLite *poFeature;
      54                 :     VFKReaderSQLite  *poReader;
      55                 :         
      56               1 :     nInvalid  = 0;
      57               1 :     poReader  = (VFKReaderSQLite*) m_poReader;
      58                 : 
      59               1 :     osSQL.Printf("SELECT SOURADNICE_Y,SOURADNICE_X FROM '%s'", m_pszName);
      60               1 :     hStmt = poReader->PrepareStatement(osSQL.c_str());
      61                 :     
      62               1 :     ResetReading();
      63              14 :     while(poReader->ExecuteSQL(hStmt) == OGRERR_NONE) {
      64              13 :         poFeature = (VFKFeatureSQLite *) GetNextFeature();
      65              13 :         CPLAssert(NULL != poFeature);
      66                 :         
      67              13 :         x = -1.0 * sqlite3_column_double(hStmt, 0);
      68              13 :         y = -1.0 * sqlite3_column_double(hStmt, 1);
      69              13 :         OGRPoint pt(x, y);
      70              13 :         if (!poFeature->SetGeometry(&pt))
      71               0 :             nInvalid++;
      72                 :     }
      73               1 :     ResetReading();
      74                 : 
      75               1 :     return nInvalid;
      76                 : }
      77                 : 
      78                 : /*!
      79                 :   \brief Load geometry (linestring SBP layer)
      80                 : 
      81                 :   \return number of invalid features
      82                 : */
      83               1 : int VFKDataBlockSQLite::LoadGeometryLineStringSBP()
      84                 : {
      85                 :     int      nInvalid;
      86                 :     int      rowId;
      87                 :     GUIntBig id, ipcb;
      88                 : 
      89               1 :     CPLString     osSQL;
      90                 :     sqlite3_stmt *hStmt;
      91                 :     
      92                 :     VFKReaderSQLite    *poReader;
      93                 :     VFKDataBlockSQLite *poDataBlockPoints;
      94                 :     VFKFeatureSQLite   *poFeature, *poPoint, *poLine;
      95                 :     
      96               1 :     OGRLineString oOGRLine;
      97                 :     
      98               1 :     nInvalid  = 0;
      99               1 :     poReader  = (VFKReaderSQLite*) m_poReader;
     100               1 :     poLine    = NULL;
     101                 :     
     102               1 :     poDataBlockPoints = (VFKDataBlockSQLite *) m_poReader->GetDataBlock("SOBR");
     103               1 :     if (NULL == poDataBlockPoints) {
     104                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     105               0 :                  "Data block %s not found.\n", m_pszName);
     106               0 :         return nInvalid;
     107                 :     }
     108                 :     
     109               1 :     poDataBlockPoints->LoadGeometry();
     110                 :     
     111               3 :     for (int i = 0; i < 2; i++) {
     112               2 :         if (i == 0)
     113                 :             osSQL.Printf("SELECT BP_ID,PORADOVE_CISLO_BODU,_rowid_,ID FROM '%s' WHERE "
     114                 :                          "HP_ID IS NOT NULL OR OB_ID IS NOT NULL OR DPM_ID IS NOT NULL "
     115               1 :                          "ORDER BY HP_ID,OB_ID,DPM_ID,PORADOVE_CISLO_BODU", m_pszName);
     116                 :         else
     117                 :             osSQL.Printf("SELECT BP_ID,PORADOVE_CISLO_BODU,_rowid_,ID FROM '%s' WHERE "
     118                 :                          "OB_ID IS NULL AND HP_ID IS NULL AND DPM_ID IS NULL "
     119               1 :                          "ORDER BY ID,PORADOVE_CISLO_BODU", m_pszName);
     120                 :         
     121               2 :         hStmt = poReader->PrepareStatement(osSQL.c_str());
     122                 :         
     123              30 :         while(poReader->ExecuteSQL(hStmt) == OGRERR_NONE) {
     124              26 :             id    = sqlite3_column_double(hStmt, 0);
     125              26 :             ipcb  = sqlite3_column_double(hStmt, 1);
     126              26 :             rowId = sqlite3_column_int(hStmt, 2) - 1;
     127              26 :             poFeature = (VFKFeatureSQLite *) GetFeatureByIndex(rowId);
     128              26 :             if (!poFeature)
     129               0 :                 continue;
     130              26 :             poFeature->SetGeometry(NULL);
     131                 :             
     132              26 :             if (ipcb == 1) {
     133              13 :                 if (!oOGRLine.IsEmpty()) {
     134              12 :                     oOGRLine.setCoordinateDimension(2); /* force 2D */
     135              12 :                     if (poLine && !poLine->SetGeometry(&oOGRLine))
     136               0 :                         nInvalid++;
     137              12 :                     oOGRLine.empty(); /* restore line */
     138                 :                 }
     139              13 :                 poLine = poFeature;
     140                 :             }
     141                 :             else {
     142              13 :                 poFeature->SetGeometryType(wkbUnknown);
     143                 :             }
     144                 :             
     145              26 :             poPoint = (VFKFeatureSQLite *) poDataBlockPoints->GetFeature("ID", id);
     146              26 :             if (!poPoint)
     147               0 :                 continue;
     148              26 :             OGRPoint *pt = (OGRPoint *) poPoint->GetGeometry();
     149              26 :             if (!pt)
     150               0 :                 continue;
     151              26 :             oOGRLine.addPoint(pt);
     152                 :         }
     153                 :         /* add last line */
     154               2 :         oOGRLine.setCoordinateDimension(2); /* force 2D */
     155               2 :         if (poLine && !poLine->SetGeometry(&oOGRLine))
     156               0 :             nInvalid++;
     157                 :     }
     158                 :     
     159               1 :     return nInvalid;
     160                 : }
     161                 : 
     162                 : /*!
     163                 :   \brief Load geometry (linestring HP/DPM layer)
     164                 : 
     165                 :   \return number of invalid features
     166                 : */
     167               1 : int VFKDataBlockSQLite::LoadGeometryLineStringHP()
     168                 : {
     169                 :     int          nInvalid;
     170                 :     int          rowId;
     171                 :     
     172               1 :     CPLString    osColumn, osSQL;
     173                 :     const char  *vrColumn[2];
     174                 :     GUIntBig     vrValue[2];
     175                 :     
     176                 :     sqlite3_stmt *hStmt;
     177                 :     
     178                 :     VFKReaderSQLite    *poReader;
     179                 :     VFKDataBlockSQLite *poDataBlockLines;
     180                 :     VFKFeatureSQLite   *poFeature, *poLine;
     181                 :     
     182               1 :     nInvalid  = 0;
     183               1 :     poReader  = (VFKReaderSQLite*) m_poReader;
     184                 :     
     185               1 :     poDataBlockLines = (VFKDataBlockSQLite *) m_poReader->GetDataBlock("SBP");
     186               1 :     if (NULL == poDataBlockLines) {
     187                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     188               0 :                  "Data block %s not found.\n", m_pszName);
     189               0 :         return nInvalid;
     190                 :     }
     191                 :     
     192               1 :     poDataBlockLines->LoadGeometry();
     193               1 :     osColumn.Printf("%s_ID", m_pszName);
     194               1 :     vrColumn[0] = osColumn.c_str();
     195               1 :     vrColumn[1] = "PORADOVE_CISLO_BODU";
     196               1 :     vrValue[1]  = 1; /* reduce to first segment */
     197                 :     
     198               1 :     osSQL.Printf("SELECT ID,_rowid_ FROM '%s'", m_pszName);
     199               1 :     hStmt = poReader->PrepareStatement(osSQL.c_str());
     200                 :     
     201              15 :     while(poReader->ExecuteSQL(hStmt) == OGRERR_NONE) {
     202              13 :         vrValue[0] = sqlite3_column_double(hStmt, 0);
     203              13 :         rowId      = sqlite3_column_int(hStmt, 1) - 1;
     204              13 :         poFeature  = (VFKFeatureSQLite *) GetFeatureByIndex(rowId);
     205                 :             
     206              13 :         poLine = poDataBlockLines->GetFeature(vrColumn, vrValue, 2);
     207              13 :         if (!poLine || !poLine->GetGeometry())
     208               0 :             continue;
     209              13 :         if (!poFeature->SetGeometry(poLine->GetGeometry()))
     210               0 :             nInvalid++;
     211                 :     }
     212                 :     
     213               1 :     return nInvalid;
     214                 : }
     215                 : 
     216                 : /*!
     217                 :   \brief Load geometry (polygon BUD/PAR layers)
     218                 : 
     219                 :   \return number of invalid features
     220                 : */
     221               1 : int VFKDataBlockSQLite::LoadGeometryPolygon()
     222                 : {
     223                 :     int  nInvalid;
     224                 :     int  rowId, nCount, nCountMax;
     225                 :     bool bIsPar, bNewRing, bFound;
     226                 :         
     227               1 :     CPLString    osSQL;
     228                 :     const char  *vrColumn[2];
     229                 :     GUIntBig     vrValue[2];
     230                 :     GUIntBig     id, idOb;
     231                 :     
     232                 :     sqlite3_stmt *hStmt;
     233                 :     
     234                 :     VFKReaderSQLite    *poReader;
     235                 :     VFKDataBlockSQLite *poDataBlockLines1, *poDataBlockLines2;
     236                 :     VFKFeatureSQLite   *poFeature;
     237                 : 
     238               1 :     VFKFeatureSQLiteList  poLineList;
     239                 :     /* first is to be considered as exterior */
     240               1 :     PointListArray        poRingList;
     241                 :     
     242               1 :     OGRLinearRing ogrRing;
     243               1 :     OGRPolygon    ogrPolygon;
     244                 :     
     245               1 :     nInvalid  = 0;
     246               1 :     poReader  = (VFKReaderSQLite*) m_poReader;
     247                 :     
     248               1 :     if (EQUAL (m_pszName, "PAR")) {
     249               1 :         poDataBlockLines1 = (VFKDataBlockSQLite *) m_poReader->GetDataBlock("HP");
     250               1 :         poDataBlockLines2 = poDataBlockLines1;
     251               1 :         bIsPar = TRUE;
     252                 :     }
     253                 :     else {
     254               0 :         poDataBlockLines1 = (VFKDataBlockSQLite *) m_poReader->GetDataBlock("OB");
     255               0 :         poDataBlockLines2 = (VFKDataBlockSQLite *) m_poReader->GetDataBlock("SBP");
     256               0 :         bIsPar = FALSE;
     257                 :     }
     258               1 :     if (NULL == poDataBlockLines1 || NULL == poDataBlockLines2) {
     259                 :         CPLError(CE_Failure, CPLE_NotSupported, 
     260               0 :                  "Data block %s not found.\n", m_pszName);
     261               0 :         return nInvalid;
     262                 :     }
     263                 :     
     264               1 :     poDataBlockLines1->LoadGeometry();
     265               1 :     poDataBlockLines2->LoadGeometry();
     266                 :     
     267               1 :     if (bIsPar) {
     268               1 :         vrColumn[0] = "PAR_ID_1";
     269               1 :         vrColumn[1] = "PAR_ID_2";
     270                 :     }
     271                 :     else {
     272               0 :         vrColumn[0] = "OB_ID";
     273               0 :         vrColumn[1] = "PORADOVE_CISLO_BODU";
     274               0 :         vrValue[1]  = 1;
     275                 :     }
     276                 : 
     277               1 :     osSQL.Printf("SELECT ID,_rowid_ FROM '%s'", m_pszName);
     278               1 :     hStmt = poReader->PrepareStatement(osSQL.c_str());
     279                 :     
     280               3 :     while(poReader->ExecuteSQL(hStmt) == OGRERR_NONE) {
     281               1 :         id        = sqlite3_column_double(hStmt, 0);
     282               1 :         rowId     = sqlite3_column_int(hStmt, 1) - 1;
     283               1 :         poFeature = (VFKFeatureSQLite *) GetFeatureByIndex(rowId);
     284               1 :         if (bIsPar) {
     285               1 :             vrValue[0] = vrValue[1] = id;
     286               1 :             poLineList = poDataBlockLines1->GetFeatures(vrColumn, vrValue, 2);
     287                 :         }
     288                 :         else {
     289                 :             VFKFeatureSQLite *poLineSbp;
     290               0 :             std::vector<VFKFeatureSQLite *> poLineListOb;
     291                 :             sqlite3_stmt *hStmtOb;
     292                 :             
     293                 :             osSQL.Printf("SELECT ID FROM '%s' WHERE BUD_ID = %llu",
     294               0 :                          poDataBlockLines1->GetName(), id);
     295               0 :             hStmtOb = poReader->PrepareStatement(osSQL.c_str());
     296                 :             
     297               0 :             while(poReader->ExecuteSQL(hStmtOb) == OGRERR_NONE) {
     298               0 :                 idOb = sqlite3_column_double(hStmtOb, 0); 
     299               0 :                 vrValue[0] = idOb;
     300               0 :                 poLineSbp = poDataBlockLines2->GetFeature(vrColumn, vrValue, 2);
     301               0 :                 if (poLineSbp)
     302               0 :                     poLineList.push_back(poLineSbp);
     303               0 :             }
     304                 :         }
     305               1 :         if (poLineList.size() < 1)
     306               0 :             continue;
     307                 :         
     308                 :         /* clear */
     309               1 :         ogrPolygon.empty();
     310               1 :         poRingList.clear();
     311                 :         
     312                 :         /* collect rings (points) */
     313               1 :         bFound = FALSE;
     314               1 :         nCount = 0;
     315               1 :         nCountMax = poLineList.size() * 2;
     316              15 :         while (poLineList.size() > 0 && nCount < nCountMax) {
     317              13 :             bNewRing = !bFound ? TRUE : FALSE;
     318              13 :             bFound = FALSE;
     319              18 :             for (VFKFeatureSQLiteList::iterator iHp = poLineList.begin(), eHp = poLineList.end();
     320                 :                  iHp != eHp; ++iHp) {
     321              18 :                 const OGRLineString *pLine = (OGRLineString *) (*iHp)->GetGeometry();
     322              18 :                 if (pLine && AppendLineToRing(&poRingList, pLine, bNewRing)) {
     323              13 :                     bFound = TRUE;
     324              13 :                     poLineList.erase(iHp);
     325              13 :                     break;
     326                 :                 }
     327                 :             }
     328              13 :             nCount++;
     329                 :         }
     330                 :         
     331               1 :         if (poLineList.size() > 0) {
     332                 :             CPLError(CE_Warning, CPLE_AppDefined, 
     333                 :                      "Unable to collect rings for feature %llu (%s).\n",
     334               0 :                      id, m_pszName);
     335               0 :             continue;
     336                 :         }
     337                 :         
     338                 :         /* create rings */
     339               2 :         for (PointListArray::const_iterator iRing = poRingList.begin(), eRing = poRingList.end();
     340                 :              iRing != eRing; ++iRing) {
     341               1 :             PointList *poList = *iRing;
     342               1 :             ogrRing.empty();
     343              15 :             for (PointList::iterator iPoint = poList->begin(), ePoint = poList->end();
     344                 :                  iPoint != ePoint; ++iPoint) {
     345              14 :                 ogrRing.addPoint(&(*iPoint));
     346                 :             }
     347               1 :             ogrPolygon.addRing(&ogrRing);
     348                 :         }
     349                 :         
     350                 :         /* set polygon */
     351               1 :         ogrPolygon.setCoordinateDimension(2); /* force 2D */
     352               1 :         if (!poFeature->SetGeometry(&ogrPolygon))
     353               0 :             nInvalid++;
     354                 :     }
     355                 :     
     356                 :     /* free ring list */
     357               2 :     for (PointListArray::iterator iRing = poRingList.begin(), eRing = poRingList.end();
     358                 :          iRing != eRing; ++iRing) {
     359               1 :         delete (*iRing);
     360               1 :         *iRing = NULL;
     361                 :     }
     362                 :     
     363               1 :     return nInvalid;
     364                 : }
     365                 : 
     366                 : /*!
     367                 :   \brief Get first found feature based on it's property
     368                 :   
     369                 :   \param column property name
     370                 :   \param value property value
     371                 :   
     372                 :   \return pointer to feature definition or NULL on failure (not found)
     373                 : */
     374              26 : VFKFeatureSQLite *VFKDataBlockSQLite::GetFeature(const char *column, GUIntBig value)
     375                 : {
     376                 :     int idx;
     377              26 :     CPLString osSQL;
     378                 :     VFKReaderSQLite  *poReader;
     379                 : 
     380                 :     sqlite3_stmt *hStmt;
     381                 :     
     382              26 :     poReader = (VFKReaderSQLite*) m_poReader;
     383                 :     
     384              26 :     osSQL.Printf("SELECT _rowid_ from '%s' WHERE %s = %llu", m_pszName, column, value);
     385              26 :     hStmt = poReader->PrepareStatement(osSQL.c_str());
     386              26 :     if (poReader->ExecuteSQL(hStmt) != OGRERR_NONE)
     387               0 :         return NULL;
     388                 :     
     389              26 :     idx = sqlite3_column_int(hStmt, 0) - 1;
     390              26 :     if (idx < 0 || idx >= m_nFeatureCount) // ? assert
     391               0 :         return NULL;
     392                 :     
     393              26 :     sqlite3_finalize(hStmt);
     394                 : 
     395              26 :     return (VFKFeatureSQLite *) GetFeatureByIndex(idx);
     396                 : }
     397                 : 
     398                 : /*!
     399                 :   \brief Get first found feature based on it's properties (AND)
     400                 :   
     401                 :   \param column array of property names
     402                 :   \param value array of property values
     403                 :   \param num number of array items
     404                 :   
     405                 :   \return pointer to feature definition or NULL on failure (not found)
     406                 : */
     407              13 : VFKFeatureSQLite *VFKDataBlockSQLite::GetFeature(const char **column, GUIntBig *value, int num)
     408                 : {
     409                 :     int idx;
     410              13 :     CPLString osSQL, osItem;
     411                 :     VFKReaderSQLite  *poReader;
     412                 : 
     413                 :     sqlite3_stmt *hStmt;
     414                 :     
     415              13 :     poReader = (VFKReaderSQLite*) m_poReader;
     416                 :     
     417              13 :     osSQL.Printf("SELECT _rowid_ from '%s' WHERE ", m_pszName);
     418              39 :     for (int i = 0; i < num; i++) {
     419              26 :         if (i > 0)
     420              13 :             osItem.Printf(" AND %s = %llu", column[i], value[i]);
     421                 :         else
     422              13 :             osItem.Printf("%s = %llu", column[i], value[i]);
     423              26 :         osSQL += osItem;
     424                 :     }
     425                 :     
     426              13 :     hStmt = poReader->PrepareStatement(osSQL.c_str());
     427              13 :     if (poReader->ExecuteSQL(hStmt) != OGRERR_NONE)
     428               0 :         return NULL;
     429                 :     
     430              13 :     idx = sqlite3_column_int(hStmt, 0) - 1;
     431                 :     
     432              13 :     if (idx < 0 || idx >= m_nFeatureCount) // ? assert
     433               0 :         return NULL;
     434                 : 
     435              13 :     sqlite3_finalize(hStmt);
     436                 :     
     437              13 :     return (VFKFeatureSQLite *) GetFeatureByIndex(idx);
     438                 : }
     439                 : 
     440                 : /*!
     441                 :   \brief Get features based on properties
     442                 :   
     443                 :   \param column array of property names
     444                 :   \param value array of property values
     445                 :   \param num number of array items
     446                 :   
     447                 :   \return list of features
     448                 : */
     449               1 : VFKFeatureSQLiteList VFKDataBlockSQLite::GetFeatures(const char **column, GUIntBig *value, int num)
     450                 : {
     451                 :     int idx;
     452               1 :     CPLString osSQL, osItem;
     453                 : 
     454                 :     VFKReaderSQLite     *poReader;
     455               1 :     VFKFeatureSQLiteList fList;
     456                 :     
     457                 :     sqlite3_stmt *hStmt;
     458                 :     
     459               1 :     poReader = (VFKReaderSQLite*) m_poReader;
     460                 :     
     461               1 :     osSQL.Printf("SELECT _rowid_ from '%s' WHERE ", m_pszName);
     462               3 :     for (int i = 0; i < num; i++) {
     463               2 :         if (i > 0)
     464               1 :             osItem.Printf(" OR %s = %llu", column[i], value[i]);
     465                 :         else
     466               1 :             osItem.Printf("%s = %llu", column[i], value[i]);
     467               2 :         osSQL += osItem;
     468                 :     }
     469                 :     
     470               1 :     hStmt = poReader->PrepareStatement(osSQL.c_str());
     471              15 :     while (poReader->ExecuteSQL(hStmt) == OGRERR_NONE) {
     472              13 :         idx = sqlite3_column_int(hStmt, 0) - 1;
     473              13 :         if (idx < 0 || idx >= m_nFeatureCount)
     474               0 :             continue; // assert?
     475              13 :         fList.push_back((VFKFeatureSQLite *)GetFeatureByIndex(idx));
     476                 :     }
     477                 :     
     478               1 :     return fList;
     479                 : }
     480                 : 
     481                 : #endif // HAVE_SQLITE

Generated by: LCOV version 1.7