LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/kml - kmlnode.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 348
Code covered: 85.3 % Executed lines: 297

       1                 : /******************************************************************************
       2                 :  * $Id: kmlnode.cpp 19643 2010-05-08 21:56:18Z rouault $
       3                 :  *
       4                 :  * Project:  KML Driver
       5                 :  * Purpose:  Class for building up the node structure of the kml file.
       6                 :  * Author:   Jens Oberender, j.obi@troja.net
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2007, Jens Oberender
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : #include "kmlnode.h"
      30                 : #include "cpl_conv.h"
      31                 : // std
      32                 : #include <string>
      33                 : #include <vector>
      34                 : 
      35                 : /************************************************************************/
      36                 : /*                           Help functions                             */
      37                 : /************************************************************************/
      38                 : 
      39              51 : std::string Nodetype2String(Nodetype const& type)
      40                 : {
      41              51 :     if(type == Empty)
      42               0 :         return "Empty";
      43              51 :     else if(type == Rest)
      44               0 :         return "Rest";
      45              51 :     else if(type == Mixed)
      46               2 :         return "Mixed";
      47              49 :     else if(type == Point)
      48              17 :         return "Point";
      49              32 :     else if(type == LineString)
      50              11 :         return "LineString";
      51              21 :     else if(type == Polygon)
      52              21 :         return "Polygon";
      53               0 :     else if(type == MultiGeometry)
      54               0 :         return "MultiGeometry";
      55               0 :     else if(type == MultiPoint)
      56               0 :         return "MultiPoint";
      57               0 :     else if(type == MultiLineString)
      58               0 :         return "MultiLineString";
      59               0 :     else if(type == MultiPolygon)
      60               0 :         return "MultiPolygon";
      61                 :     else
      62               0 :         return "Unknown";
      63                 : }
      64                 : 
      65            8985 : bool isNumberDigit(const char cIn)
      66                 : {
      67                 :     return ( cIn == '-' || cIn == '+' || 
      68                 :             (cIn >= '0' && cIn <= '9') ||
      69            8985 :              cIn == '.' || cIn == 'e' || cIn == 'E' );
      70                 : }
      71                 : 
      72             301 : Coordinate* ParseCoordinate(std::string const& text)
      73                 : {
      74             301 :     std::string::size_type pos = 0;
      75             301 :     Coordinate *psTmp = new Coordinate();
      76                 : 
      77                 :     // X coordinate
      78            4251 :     while(isNumberDigit(text[pos++]));
      79             301 :     psTmp->dfLongitude = CPLAtof(text.substr(0, (pos - 1)).c_str());
      80                 : 
      81                 :     // Y coordinate
      82             301 :     if(text[pos - 1] != ',')
      83                 :     {
      84               0 :         delete psTmp;
      85               0 :         return NULL;
      86                 :     }
      87             301 :     std::string tmp(text.substr(pos, text.length() - pos));
      88             301 :     pos = 0;
      89            4044 :     while(isNumberDigit(tmp[pos++]));
      90             301 :     psTmp->dfLatitude = CPLAtof(tmp.substr(0, (pos - 1)).c_str());
      91                 :     
      92                 :     // Z coordinate
      93             301 :     if(tmp[pos - 1] != ',')
      94                 :     {
      95              81 :         psTmp->bHasZ = FALSE;
      96              81 :         psTmp->dfAltitude = 0;
      97             382 :         return psTmp;
      98                 :     }
      99             220 :     tmp = tmp.substr(pos, tmp.length() - pos);
     100             220 :     pos = 0;
     101             690 :     while(isNumberDigit(tmp[pos++]));
     102             220 :     psTmp->bHasZ = TRUE;
     103             220 :     psTmp->dfAltitude = CPLAtof(tmp.substr(0, (pos - 1)).c_str());
     104                 : 
     105             220 :     return psTmp;
     106                 : }
     107                 : 
     108                 : /************************************************************************/
     109                 : /*                         KMLNode methods                              */
     110                 : /************************************************************************/
     111                 : 
     112             674 : KMLNode::KMLNode()
     113                 : {
     114             674 :     poParent_ = NULL;
     115             674 :     pvpoChildren_ = new std::vector<KMLNode*>;
     116            1348 :     pvsContent_ = new std::vector<std::string>;
     117            1348 :     pvoAttributes_ = new std::vector<Attribute*>;
     118             674 :     eType_ = Unknown;
     119             674 :     nLayerNumber_ = -1;
     120             674 :     b25D_ = FALSE;
     121             674 :     nNumFeatures_ = -1;
     122             674 : }
     123                 : 
     124             674 : KMLNode::~KMLNode()
     125                 : {
     126             674 :     CPLAssert( NULL != pvpoChildren_ );
     127             674 :     CPLAssert( NULL != pvoAttributes_ );
     128                 : 
     129             674 :     kml_nodes_t::iterator itChild;
     130            1006 :     for( itChild = pvpoChildren_->begin();
     131                 :          itChild != pvpoChildren_->end(); ++itChild)
     132                 :     {
     133             332 :         delete (*itChild);
     134                 :     }
     135             674 :     delete pvpoChildren_;
     136                 : 
     137             674 :     kml_attributes_t::iterator itAttr;
     138             820 :     for( itAttr = pvoAttributes_->begin();
     139                 :          itAttr != pvoAttributes_->end(); ++itAttr)
     140                 :     {
     141             146 :         delete (*itAttr);
     142                 :     }
     143             674 :     delete pvoAttributes_;
     144                 : 
     145             674 :     delete pvsContent_;
     146             674 : }
     147                 : 
     148               0 : void KMLNode::print(unsigned int what)
     149                 : {
     150               0 :     std::string indent;
     151               0 :     for(std::size_t l = 0; l < nLevel_; l++)
     152               0 :         indent += " ";
     153                 : 
     154               0 :     if(nLevel_ > 0)
     155                 :     {
     156               0 :         if(nLayerNumber_ > -1)
     157                 :         {
     158                 :             CPLDebug("KML", "%s%s (nLevel: %d Type: %s poParent: %s pvpoChildren_: %d pvsContent_: %d pvoAttributes_: %d) <--- Layer #%d", 
     159                 :                         indent.c_str(), sName_.c_str(), (int) nLevel_, Nodetype2String(eType_).c_str(), poParent_->sName_.c_str(), 
     160               0 :                         (int) pvpoChildren_->size(), (int) pvsContent_->size(), (int) pvoAttributes_->size(), nLayerNumber_);
     161                 :         }
     162                 :         else
     163                 :         {
     164                 :             CPLDebug("KML", "%s%s (nLevel: %d Type: %s poParent: %s pvpoChildren_: %d pvsContent_: %d pvoAttributes_: %d)", 
     165                 :                         indent.c_str(), sName_.c_str(), (int) nLevel_, Nodetype2String(eType_).c_str(), poParent_->sName_.c_str(), 
     166               0 :                         (int) pvpoChildren_->size(), (int) pvsContent_->size(), (int) pvoAttributes_->size());
     167                 :         }
     168                 :     }
     169                 :     else
     170                 :     {
     171                 :         CPLDebug("KML", "%s%s (nLevel: %d Type: %s pvpoChildren_: %d pvsContent_: %d pvoAttributes_: %d)", 
     172                 :                  indent.c_str(), sName_.c_str(), (int) nLevel_, Nodetype2String(eType_).c_str(), (int) pvpoChildren_->size(), 
     173               0 :                  (int) pvsContent_->size(), (int) pvoAttributes_->size());
     174                 :     }
     175                 : 
     176               0 :     if(what == 1 || what == 3)
     177                 :     {
     178               0 :         for(kml_content_t::size_type z = 0; z < pvsContent_->size(); z++)
     179               0 :             CPLDebug("KML", "%s|->pvsContent_: '%s'", indent.c_str(), (*pvsContent_)[z].c_str());
     180                 :     }
     181                 : 
     182               0 :     if(what == 2 || what == 3)
     183                 :     {
     184               0 :         for(kml_attributes_t::size_type z = 0; z < pvoAttributes_->size(); z++)
     185               0 :             CPLDebug("KML", "%s|->pvoAttributes_: %s = '%s'", indent.c_str(), (*pvoAttributes_)[z]->sName.c_str(), (*pvoAttributes_)[z]->sValue.c_str());
     186                 :     }
     187                 : 
     188               0 :     for(kml_nodes_t::size_type z = 0; z < pvpoChildren_->size(); z++)
     189               0 :         (*pvpoChildren_)[z]->print(what);
     190               0 : }
     191                 : 
     192                 : //static int nDepth = 0;
     193                 : //static char* genSpaces()
     194                 : //{
     195                 : //    static char spaces[128];
     196                 : //    int i;
     197                 : //    for(i=0;i<nDepth;i++)
     198                 : //        spaces[i] = ' ';
     199                 : //    spaces[i] = '\0';
     200                 : //    return spaces;
     201                 : //}
     202                 : 
     203             333 : void KMLNode::classify(KML* poKML)
     204                 : {
     205             333 :     Nodetype curr = Unknown;
     206             333 :     Nodetype all = Empty;
     207                 :     
     208                 :     //CPLDebug("KML", "%s<%s>", genSpaces(), sName_.c_str());
     209                 :     //nDepth ++;
     210                 :     
     211             333 :     if(sName_.compare("Point") == 0)
     212              18 :         eType_ = Point;
     213             315 :     else if(sName_.compare("LineString") == 0)
     214              15 :         eType_ = LineString;
     215             300 :     else if(sName_.compare("Polygon") == 0)
     216              22 :         eType_ = Polygon;
     217             278 :     else if(poKML->isRest(sName_))
     218              59 :         eType_ = Empty;
     219             219 :     else if(sName_.compare("coordinates") == 0)
     220                 :     {
     221                 :         unsigned int nCountP;
     222             327 :         for(nCountP = 0; nCountP < pvsContent_->size(); nCountP++)
     223                 :         {
     224             269 :             const char* pszCoord = (*pvsContent_)[nCountP].c_str();
     225             269 :             int nComma = 0;
     226             454 :             while(TRUE)
     227                 :             {
     228             723 :                 pszCoord = strchr(pszCoord, ',');
     229             723 :                 if (pszCoord)
     230                 :                 {
     231             454 :                     nComma ++;
     232             454 :                     pszCoord ++;
     233                 :                 }
     234                 :                 else
     235             269 :                     break;
     236                 :             }
     237             269 :             if (nComma == 2)
     238             185 :                 b25D_ = TRUE;
     239                 :         }
     240                 :     }
     241                 : 
     242             333 :     const kml_nodes_t::size_type size = pvpoChildren_->size();
     243             662 :     for(kml_nodes_t::size_type z = 0; z < size; z++)
     244                 :     {
     245                 :         //CPLDebug("KML", "%s[%d] %s", genSpaces(), z, (*pvpoChildren_)[z]->sName_.c_str());
     246                 : 
     247                 :         // Classify pvpoChildren_
     248             329 :         (*pvpoChildren_)[z]->classify(poKML);
     249                 : 
     250             329 :         curr = (*pvpoChildren_)[z]->eType_;
     251             329 :         b25D_ |= (*pvpoChildren_)[z]->b25D_;
     252                 : 
     253                 :         // Compare and return if it is mixed
     254             353 :         if(curr != all && all != Empty && curr != Empty)
     255                 :         {
     256              24 :             if (sName_.compare("MultiGeometry") == 0)
     257               2 :                 eType_ = MultiGeometry;
     258                 :             else
     259              22 :                 eType_ = Mixed;
     260                 :         }
     261             305 :         else if(curr != Empty)
     262                 :         {
     263             107 :             all = curr;
     264                 :         }
     265                 :     }
     266                 : 
     267             333 :     if(eType_ == Unknown)
     268                 :     {
     269             213 :         if (sName_.compare("MultiGeometry") == 0)
     270                 :         {
     271               9 :             if (all == Point)
     272               3 :                 eType_ = MultiPoint;
     273               6 :             else if (all == LineString)
     274               2 :                 eType_ = MultiLineString;
     275               4 :             else if (all == Polygon)
     276               2 :                 eType_ = MultiPolygon;
     277                 :             else
     278               2 :                 eType_ = MultiGeometry;
     279                 :         }
     280                 :         else
     281             204 :             eType_ = all;
     282                 :     }
     283                 : 
     284                 :     //nDepth --;
     285                 :     //CPLDebug("KML", "%s</%s> --> eType=%s", genSpaces(), sName_.c_str(), Nodetype2String(eType_).c_str());
     286             333 : }
     287                 : 
     288             315 : void KMLNode::eliminateEmpty(KML* poKML)
     289                 : {
     290             633 :     for(kml_nodes_t::size_type z = 0; z < pvpoChildren_->size(); z++)
     291                 :     {
     292             318 :         if((*pvpoChildren_)[z]->eType_ == Empty
     293                 :            && (poKML->isContainer((*pvpoChildren_)[z]->sName_)
     294                 :                || poKML->isFeatureContainer((*pvpoChildren_)[z]->sName_)))
     295                 :         {
     296               7 :             delete (*pvpoChildren_)[z];
     297               7 :             pvpoChildren_->erase(pvpoChildren_->begin() + z);
     298               7 :             z--;
     299                 :         }
     300                 :         else
     301                 :         {
     302             311 :             (*pvpoChildren_)[z]->eliminateEmpty(poKML);
     303                 :         }
     304                 :     }
     305             315 : }
     306                 : 
     307               0 : void KMLNode::setType(Nodetype oNotet)
     308                 : {
     309               0 :     eType_ = oNotet;
     310               0 : }
     311                 : 
     312              39 : Nodetype KMLNode::getType() const
     313                 : {
     314              39 :     return eType_;
     315                 : }
     316                 : 
     317             674 : void KMLNode::setName(std::string const& sIn)
     318                 : {
     319             674 :     sName_ = sIn;
     320             674 : }
     321                 : 
     322            2254 : const std::string& KMLNode::getName() const
     323                 : {
     324            2254 :     return sName_;
     325                 : }
     326                 : 
     327             674 : void KMLNode::setLevel(std::size_t nLev)
     328                 : {
     329             674 :     nLevel_ = nLev;
     330             674 : }
     331                 : 
     332               0 : std::size_t KMLNode::getLevel() const
     333                 : {
     334               0 :     return nLevel_;
     335                 : }
     336                 : 
     337             146 : void KMLNode::addAttribute(Attribute *poAttr)
     338                 : {
     339             146 :     pvoAttributes_->push_back(poAttr);
     340             146 : }
     341                 : 
     342             670 : void KMLNode::setParent(KMLNode* poPar)
     343                 : {
     344             670 :     poParent_ = poPar;
     345             670 : }
     346                 : 
     347            1344 : KMLNode* KMLNode::getParent() const
     348                 : {
     349            1344 :     return poParent_;
     350                 : }
     351                 : 
     352             339 : void KMLNode::addChildren(KMLNode *poChil)
     353                 : {
     354             339 :     pvpoChildren_->push_back(poChil);
     355             339 : }
     356                 : 
     357             104 : std::size_t KMLNode::countChildren()
     358                 : {
     359             104 :     return pvpoChildren_->size();
     360                 : }
     361                 : 
     362             172 : KMLNode* KMLNode::getChild(std::size_t index) const
     363                 : {
     364             172 :     return (*pvpoChildren_)[index];
     365                 : }
     366                 : 
     367            1026 : void KMLNode::addContent(std::string const& text)
     368                 : {
     369            1026 :     pvsContent_->push_back(text);
     370            1026 : }
     371                 : 
     372            1896 : void KMLNode::appendContent(std::string const& text)
     373                 : {
     374            1896 :     std::string& tmp = (*pvsContent_)[pvsContent_->size() - 1];
     375            1896 :     tmp += text;
     376            1896 : }
     377                 : 
     378             549 : std::string KMLNode::getContent(std::size_t index) const
     379                 : {
     380             549 :     return (*pvsContent_)[index];
     381                 : }
     382                 : 
     383             261 : void KMLNode::deleteContent(std::size_t index)
     384                 : {
     385             261 :     if( index < pvsContent_->size() )
     386                 :     {
     387             261 :         pvsContent_->erase(pvsContent_->begin() + index);
     388                 :     }
     389             261 : }
     390                 : 
     391            3177 : std::size_t KMLNode::numContent()
     392                 : {
     393            3177 :     return pvsContent_->size();
     394                 : }
     395                 : 
     396              10 : void KMLNode::setLayerNumber(int nNum)
     397                 : {
     398              10 :     nLayerNumber_ = nNum;
     399              10 : }
     400                 : 
     401               0 : int KMLNode::getLayerNumber() const
     402                 : {
     403               0 :     return nLayerNumber_;
     404                 : }
     405                 : 
     406              62 : std::string KMLNode::getNameElement() const
     407                 : {
     408              62 :     kml_nodes_t::size_type subsize = 0;
     409              62 :     kml_nodes_t::size_type size = pvpoChildren_->size();
     410                 : 
     411              92 :     for( kml_nodes_t::size_type i = 0; i < size; ++i )
     412                 :     {
     413              62 :         if( (*pvpoChildren_)[i]->sName_.compare("name") == 0 )
     414                 :         {
     415              32 :             subsize = (*pvpoChildren_)[i]->pvsContent_->size();
     416              32 :             if( subsize > 0 )
     417                 :             {
     418              32 :                 return (*(*pvpoChildren_)[i]->pvsContent_)[0];
     419                 :             }
     420               0 :             break;
     421                 :         }
     422                 :     }
     423              30 :     return "";
     424                 : }
     425                 : 
     426              52 : std::string KMLNode::getDescriptionElement() const
     427                 : {
     428              52 :     kml_nodes_t::size_type subsize = 0;
     429              52 :     kml_nodes_t::size_type size = pvpoChildren_->size();
     430             113 :     for( kml_nodes_t::size_type i = 0; i < size; ++i )
     431                 :     {
     432              75 :         if( (*pvpoChildren_)[i]->sName_.compare("description") == 0 )
     433                 :         {
     434              14 :             subsize = (*pvpoChildren_)[i]->pvsContent_->size();
     435              14 :             if ( subsize > 0 )
     436                 :             {
     437              14 :                 return (*(*pvpoChildren_)[i]->pvsContent_)[0];
     438                 :             }
     439               0 :             break;
     440                 :         }
     441                 :     }
     442              38 :     return "";
     443                 : }
     444                 : 
     445              56 : std::size_t KMLNode::getNumFeatures()
     446                 : {
     447              56 :     if (nNumFeatures_ < 0)
     448                 :     {
     449               7 :         std::size_t nNum = 0;
     450               7 :         kml_nodes_t::size_type size = pvpoChildren_->size();
     451                 :         
     452              62 :         for( kml_nodes_t::size_type i = 0; i < size; ++i )
     453                 :         {
     454              55 :             if( (*pvpoChildren_)[i]->sName_ == "Placemark" )
     455              45 :                 nNum++;
     456                 :         }
     457               7 :         nNumFeatures_ = (int)nNum;
     458                 :     }
     459              56 :     return nNumFeatures_;
     460                 : }
     461                 : 
     462              67 : OGRGeometry* KMLNode::getGeometry(Nodetype eType)
     463                 : {
     464                 :     unsigned int nCount, nCount2, nCountP;
     465              67 :     OGRGeometry* poGeom = NULL;
     466              67 :     KMLNode* poCoor = NULL;
     467              67 :     Coordinate* psCoord = NULL;
     468                 : 
     469              67 :     if (sName_.compare("Point") == 0)
     470                 :     {
     471                 :         // Search coordinate Element
     472              25 :         for(nCount = 0; nCount < pvpoChildren_->size(); nCount++)
     473                 :         {
     474              23 :             if((*pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0)
     475                 :             {
     476              19 :                 poCoor = (*pvpoChildren_)[nCount];
     477              19 :                 for(nCountP = 0; nCountP < poCoor->pvsContent_->size(); nCountP++)
     478                 :                 {
     479              18 :                     psCoord = ParseCoordinate((*poCoor->pvsContent_)[nCountP]);
     480              18 :                     if(psCoord != NULL)
     481                 :                     {
     482              18 :                         if (psCoord->bHasZ)
     483                 :                             poGeom = new OGRPoint(psCoord->dfLongitude,
     484                 :                                                   psCoord->dfLatitude,
     485              10 :                                                   psCoord->dfAltitude);
     486                 :                         else
     487                 :                             poGeom = new OGRPoint(psCoord->dfLongitude,
     488               8 :                                                   psCoord->dfLatitude);
     489              18 :                         delete psCoord;
     490              18 :                         return poGeom;
     491                 :                     }
     492                 :                 }
     493                 :             }
     494                 :         }
     495               2 :         poGeom = new OGRPoint();
     496                 :     }
     497              47 :     else if (sName_.compare("LineString") == 0)
     498                 :     {
     499                 :         // Search coordinate Element
     500              15 :         poGeom = new OGRLineString();
     501              31 :         for(nCount = 0; nCount < pvpoChildren_->size(); nCount++)
     502                 :         {
     503              16 :             if((*pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0)
     504                 :             {
     505              14 :                 poCoor = (*pvpoChildren_)[nCount];
     506              58 :                 for(nCountP = 0; nCountP < poCoor->pvsContent_->size(); nCountP++)
     507                 :                 {
     508              44 :                     psCoord = ParseCoordinate((*poCoor->pvsContent_)[nCountP]);
     509              44 :                     if(psCoord != NULL)
     510                 :                     {
     511              44 :                         if (psCoord->bHasZ)
     512                 :                             ((OGRLineString*)poGeom)->addPoint(psCoord->dfLongitude,
     513                 :                                                                psCoord->dfLatitude,
     514              30 :                                                                psCoord->dfAltitude);
     515                 :                         else
     516                 :                             ((OGRLineString*)poGeom)->addPoint(psCoord->dfLongitude,
     517              14 :                                                                psCoord->dfLatitude);
     518              44 :                         delete psCoord;
     519                 :                     }
     520                 :                 }
     521                 :             }
     522                 :         }
     523                 :     }
     524              32 :     else if (sName_.compare("Polygon") == 0)
     525                 :     {
     526                 :         //*********************************
     527                 :         // Search outerBoundaryIs Element
     528                 :         //*********************************
     529              21 :         poGeom = new OGRPolygon();
     530              56 :         for(nCount = 0; nCount < pvpoChildren_->size(); nCount++)
     531                 :         {
     532              35 :             if((*pvpoChildren_)[nCount]->sName_.compare("outerBoundaryIs") == 0 &&
     533                 :                (*pvpoChildren_)[nCount]->pvpoChildren_->size() > 0)
     534                 :             {
     535              19 :                 poCoor = (*(*pvpoChildren_)[nCount]->pvpoChildren_)[0];
     536                 :             }
     537                 :         }
     538                 :         // No outer boundary found
     539              21 :         if(poCoor == NULL)
     540                 :         {
     541               2 :             return poGeom;
     542                 :         }
     543                 :         // Search coordinate Element
     544              19 :         OGRLinearRing* poLinearRing = NULL;
     545              37 :         for(nCount = 0; nCount < poCoor->pvpoChildren_->size(); nCount++)
     546                 :         {
     547              18 :             if((*poCoor->pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0)
     548                 :             {
     549             240 :                 for(nCountP = 0; nCountP < (*poCoor->pvpoChildren_)[nCount]->pvsContent_->size(); nCountP++)
     550                 :                 {
     551             222 :                     psCoord = ParseCoordinate((*(*poCoor->pvpoChildren_)[nCount]->pvsContent_)[nCountP]);
     552             222 :                     if(psCoord != NULL)
     553                 :                     {
     554             222 :                         if (poLinearRing == NULL)
     555                 :                         {
     556              17 :                             poLinearRing = new OGRLinearRing();
     557                 :                         }
     558             222 :                         if (psCoord->bHasZ)
     559                 :                             poLinearRing->addPoint(psCoord->dfLongitude,
     560                 :                                                    psCoord->dfLatitude,
     561             180 :                                                    psCoord->dfAltitude);
     562                 :                         else
     563                 :                             poLinearRing->addPoint(psCoord->dfLongitude,
     564              42 :                                                    psCoord->dfLatitude);
     565             222 :                         delete psCoord;
     566                 :                     }
     567                 :                 }
     568                 :             }
     569                 :         }
     570                 :         // No outer boundary coordinates found
     571              19 :         if(poLinearRing == NULL)
     572                 :         {
     573               2 :             return poGeom;
     574                 :         }
     575                 : 
     576              17 :         ((OGRPolygon*)poGeom)->addRingDirectly(poLinearRing);
     577              17 :         poLinearRing = NULL;
     578                 : 
     579                 :         //*********************************
     580                 :         // Search innerBoundaryIs Elements
     581                 :         //*********************************
     582                 : 
     583              49 :         for(nCount2 = 0; nCount2 < pvpoChildren_->size(); nCount2++)
     584                 :         {
     585              32 :             if((*pvpoChildren_)[nCount2]->sName_.compare("innerBoundaryIs") == 0)
     586                 :             {
     587               7 :                 if (poLinearRing)
     588               0 :                     ((OGRPolygon*)poGeom)->addRingDirectly(poLinearRing);
     589               7 :                 poLinearRing = NULL;
     590                 : 
     591               7 :                 if ((*pvpoChildren_)[nCount2]->pvpoChildren_->size() == 0)
     592               1 :                     continue;
     593                 : 
     594               6 :                 poLinearRing = new OGRLinearRing();
     595                 : 
     596               6 :                 poCoor = (*(*pvpoChildren_)[nCount2]->pvpoChildren_)[0];
     597                 :                 // Search coordinate Element
     598              11 :                 for(nCount = 0; nCount < poCoor->pvpoChildren_->size(); nCount++)
     599                 :                 {
     600               5 :                     if((*poCoor->pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0)
     601                 :                     {
     602              22 :                         for(nCountP = 0; nCountP < (*poCoor->pvpoChildren_)[nCount]->pvsContent_->size(); nCountP++)
     603                 :                         {
     604              17 :                             psCoord = ParseCoordinate((*(*poCoor->pvpoChildren_)[nCount]->pvsContent_)[nCountP]);
     605              17 :                             if(psCoord != NULL)
     606                 :                             {
     607              17 :                                 if (psCoord->bHasZ)
     608                 :                                     poLinearRing->addPoint(psCoord->dfLongitude,
     609                 :                                                         psCoord->dfLatitude,
     610               0 :                                                         psCoord->dfAltitude);
     611                 :                                 else
     612                 :                                     poLinearRing->addPoint(psCoord->dfLongitude,
     613              17 :                                                         psCoord->dfLatitude);
     614              17 :                                 delete psCoord;
     615                 :                             }
     616                 :                         }
     617                 :                     }
     618                 :                 }
     619                 :             }
     620                 :         }
     621                 : 
     622              17 :         if (poLinearRing)
     623               6 :             ((OGRPolygon*)poGeom)->addRingDirectly(poLinearRing);
     624                 :     }
     625              11 :     else if (sName_.compare("MultiGeometry") == 0)
     626                 :     {
     627              11 :         if (eType == MultiPoint)
     628               3 :             poGeom = new OGRMultiPoint();
     629               8 :         else if (eType == MultiLineString)
     630               2 :             poGeom = new OGRMultiLineString();
     631               6 :         else if (eType == MultiPolygon)
     632               2 :             poGeom = new OGRMultiPolygon();
     633                 :         else
     634               4 :             poGeom = new OGRGeometryCollection();
     635              26 :         for(nCount = 0; nCount < pvpoChildren_->size(); nCount++)
     636                 :         {
     637              15 :             OGRGeometry* poSubGeom = (*pvpoChildren_)[nCount]->getGeometry();
     638              15 :             if (poSubGeom)
     639              15 :                 ((OGRGeometryCollection*)poGeom)->addGeometryDirectly(poSubGeom);
     640                 :         }
     641                 :     }
     642                 : 
     643              45 :     return poGeom;
     644                 : }
     645                 : 
     646              55 : Feature* KMLNode::getFeature(std::size_t nNum, int& nLastAsked, int &nLastCount)
     647                 : {
     648              55 :     unsigned int nCount, nCountP = 0;
     649              55 :     KMLNode* poFeat = NULL;
     650              55 :     KMLNode* poTemp = NULL;
     651                 : 
     652              55 :     if(nNum >= this->getNumFeatures())
     653               3 :         return NULL;
     654                 : 
     655              52 :     if (nLastAsked + 1 != nNum)
     656                 :     {
     657               0 :         nCount = 0;
     658               0 :         nCountP = 0;
     659                 :     }
     660                 :     else
     661                 :     {
     662              52 :         nCount = nLastCount + 1;
     663              52 :         nCountP = nLastAsked + 1;
     664                 :     }
     665                 : 
     666              68 :     for(; nCount < pvpoChildren_->size(); nCount++)
     667                 :     {
     668              68 :         if((*pvpoChildren_)[nCount]->sName_.compare("Placemark") == 0)
     669                 :         {
     670              52 :             if(nCountP == nNum)
     671                 :             {
     672              52 :                 poFeat = (*pvpoChildren_)[nCount];
     673              52 :                 break;
     674                 :             }
     675               0 :             nCountP++;
     676                 :         }
     677                 :     }
     678                 : 
     679              52 :     nLastAsked = nNum;
     680              52 :     nLastCount = nCount;
     681                 : 
     682              52 :     if(poFeat == NULL)
     683               0 :         return NULL;
     684                 :         
     685                 :     // Create a feature structure
     686              52 :     Feature *psReturn = new Feature;
     687                 :     // Build up the name
     688             104 :     psReturn->sName = poFeat->getNameElement();
     689                 :     // Build up the description
     690             104 :     psReturn->sDescription = poFeat->getDescriptionElement();
     691                 :     // the type
     692              52 :     psReturn->eType = poFeat->eType_;
     693                 : 
     694              52 :     std::string sElementName;
     695             132 :     if(poFeat->eType_ == Point ||
     696                 :        poFeat->eType_ == LineString ||
     697                 :        poFeat->eType_ == Polygon)
     698              41 :         sElementName = Nodetype2String(poFeat->eType_);
     699              22 :     else if (poFeat->eType_ == MultiGeometry || 
     700                 :              poFeat->eType_ == MultiPoint || 
     701                 :              poFeat->eType_ == MultiLineString || 
     702                 :              poFeat->eType_ == MultiPolygon)
     703              11 :         sElementName = "MultiGeometry";
     704                 :     else
     705                 :     {
     706               0 :         delete psReturn;
     707              52 :         return NULL;
     708                 :     }
     709                 : 
     710              89 :     for(nCount = 0; nCount < poFeat->pvpoChildren_->size(); nCount++)
     711                 :     {
     712              89 :         if((*poFeat->pvpoChildren_)[nCount]->sName_.compare(sElementName) == 0)
     713                 :         {
     714              52 :             poTemp = (*poFeat->pvpoChildren_)[nCount];
     715              52 :             psReturn->poGeom = poTemp->getGeometry(poFeat->eType_);
     716              52 :             if(psReturn->poGeom)
     717              52 :                 return psReturn;
     718                 :             else
     719                 :             {
     720               0 :                 delete psReturn;
     721               0 :                 return NULL;
     722                 :             }
     723                 :         }
     724                 :     }
     725                 : 
     726               0 :     delete psReturn;
     727               0 :     return NULL;
     728             896 : }

Generated by: LTP GCOV extension version 1.5