LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/kml - kmlnode.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 352 298 84.7 %
Date: 2011-12-18 Functions: 37 30 81.1 %

       1                 : /******************************************************************************
       2                 :  * $Id: kmlnode.cpp 23589 2011-12-17 14:21:01Z 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             279 : std::string Nodetype2String(Nodetype const& type)
      40                 : {
      41             279 :     if(type == Empty)
      42               0 :         return "Empty";
      43             279 :     else if(type == Rest)
      44               0 :         return "Rest";
      45             279 :     else if(type == Mixed)
      46               2 :         return "Mixed";
      47             277 :     else if(type == Point)
      48              71 :         return "Point";
      49             206 :     else if(type == LineString)
      50              77 :         return "LineString";
      51             129 :     else if(type == Polygon)
      52             129 :         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           89296 : bool isNumberDigit(const char cIn)
      66                 : {
      67                 :     return ( cIn == '-' || cIn == '+' || 
      68                 :             (cIn >= '0' && cIn <= '9') ||
      69           89296 :              cIn == '.' || cIn == 'e' || cIn == 'E' );
      70                 : }
      71                 : 
      72            2294 : Coordinate* ParseCoordinate(std::string const& text)
      73                 : {
      74            2294 :     std::string::size_type pos = 0;
      75            2294 :     Coordinate *psTmp = new Coordinate();
      76                 : 
      77                 :     // X coordinate
      78           41823 :     while(isNumberDigit(text[pos++]));
      79            2294 :     psTmp->dfLongitude = CPLAtof(text.substr(0, (pos - 1)).c_str());
      80                 : 
      81                 :     // Y coordinate
      82            2294 :     if(text[pos - 1] != ',')
      83                 :     {
      84               0 :         delete psTmp;
      85               0 :         return NULL;
      86                 :     }
      87            2294 :     std::string tmp(text.substr(pos, text.length() - pos));
      88            2294 :     pos = 0;
      89           39633 :     while(isNumberDigit(tmp[pos++]));
      90            2294 :     psTmp->dfLatitude = CPLAtof(tmp.substr(0, (pos - 1)).c_str());
      91                 :     
      92                 :     // Z coordinate
      93            2294 :     if(tmp[pos - 1] != ',')
      94                 :     {
      95              81 :         psTmp->bHasZ = FALSE;
      96              81 :         psTmp->dfAltitude = 0;
      97              81 :         return psTmp;
      98                 :     }
      99            2213 :     tmp = tmp.substr(pos, tmp.length() - pos);
     100            2213 :     pos = 0;
     101            7840 :     while(isNumberDigit(tmp[pos++]));
     102            2213 :     psTmp->bHasZ = TRUE;
     103            2213 :     psTmp->dfAltitude = CPLAtof(tmp.substr(0, (pos - 1)).c_str());
     104                 : 
     105            2213 :     return psTmp;
     106                 : }
     107                 : 
     108                 : /************************************************************************/
     109                 : /*                         KMLNode methods                              */
     110                 : /************************************************************************/
     111                 : 
     112            1678 : KMLNode::KMLNode()
     113                 : {
     114            1678 :     poParent_ = NULL;
     115            1678 :     pvpoChildren_ = new std::vector<KMLNode*>;
     116            3356 :     pvsContent_ = new std::vector<std::string>;
     117            3356 :     pvoAttributes_ = new std::vector<Attribute*>;
     118            1678 :     eType_ = Unknown;
     119            1678 :     nLayerNumber_ = -1;
     120            1678 :     b25D_ = FALSE;
     121            1678 :     nNumFeatures_ = -1;
     122            1678 : }
     123                 : 
     124            1678 : KMLNode::~KMLNode()
     125                 : {
     126            1678 :     CPLAssert( NULL != pvpoChildren_ );
     127            1678 :     CPLAssert( NULL != pvoAttributes_ );
     128                 : 
     129            1678 :     kml_nodes_t::iterator itChild;
     130            2343 :     for( itChild = pvpoChildren_->begin();
     131                 :          itChild != pvpoChildren_->end(); ++itChild)
     132                 :     {
     133             665 :         delete (*itChild);
     134                 :     }
     135            1678 :     delete pvpoChildren_;
     136                 : 
     137            1678 :     kml_attributes_t::iterator itAttr;
     138            2081 :     for( itAttr = pvoAttributes_->begin();
     139                 :          itAttr != pvoAttributes_->end(); ++itAttr)
     140                 :     {
     141             403 :         delete (*itAttr);
     142                 :     }
     143            1678 :     delete pvoAttributes_;
     144                 : 
     145            1678 :     delete pvsContent_;
     146            1678 : }
     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             655 : int KMLNode::classify(KML* poKML, int nRecLevel)
     204                 : {
     205             655 :     Nodetype curr = Unknown;
     206             655 :     Nodetype all = Empty;
     207                 : 
     208                 :     /* Arbitrary value, but certainly large enough for reasonable usages ! */
     209             655 :     if( nRecLevel == 32 )
     210                 :     {
     211                 :         CPLError( CE_Failure, CPLE_AppDefined,
     212                 :                     "Too many recursiong level (%d) while parsing KML geometry.",
     213               0 :                     nRecLevel );
     214               0 :         return NULL;
     215                 :     }
     216                 : 
     217                 :     //CPLDebug("KML", "%s<%s>", genSpaces(), sName_.c_str());
     218                 :     //nDepth ++;
     219                 :     
     220             655 :     if(sName_.compare("Point") == 0)
     221              27 :         eType_ = Point;
     222             628 :     else if(sName_.compare("LineString") == 0)
     223              27 :         eType_ = LineString;
     224             601 :     else if(sName_.compare("Polygon") == 0)
     225              40 :         eType_ = Polygon;
     226             561 :     else if(poKML->isRest(sName_))
     227              99 :         eType_ = Empty;
     228             462 :     else if(sName_.compare("coordinates") == 0)
     229                 :     {
     230                 :         unsigned int nCountP;
     231             733 :         for(nCountP = 0; nCountP < pvsContent_->size(); nCountP++)
     232                 :         {
     233             634 :             const char* pszCoord = (*pvsContent_)[nCountP].c_str();
     234             634 :             int nComma = 0;
     235            1184 :             while(TRUE)
     236                 :             {
     237            1818 :                 pszCoord = strchr(pszCoord, ',');
     238            1818 :                 if (pszCoord)
     239                 :                 {
     240            1184 :                     nComma ++;
     241            1184 :                     pszCoord ++;
     242                 :                 }
     243                 :                 else
     244                 :                     break;
     245                 :             }
     246             634 :             if (nComma == 2)
     247             550 :                 b25D_ = TRUE;
     248                 :         }
     249                 :     }
     250                 : 
     251             655 :     const kml_nodes_t::size_type size = pvpoChildren_->size();
     252            1303 :     for(kml_nodes_t::size_type z = 0; z < size; z++)
     253                 :     {
     254                 :         //CPLDebug("KML", "%s[%d] %s", genSpaces(), z, (*pvpoChildren_)[z]->sName_.c_str());
     255                 : 
     256                 :         // Classify pvpoChildren_
     257             648 :         if (!(*pvpoChildren_)[z]->classify(poKML, nRecLevel + 1))
     258               0 :             return FALSE;
     259                 : 
     260             648 :         curr = (*pvpoChildren_)[z]->eType_;
     261             648 :         b25D_ |= (*pvpoChildren_)[z]->b25D_;
     262                 : 
     263                 :         // Compare and return if it is mixed
     264             676 :         if(curr != all && all != Empty && curr != Empty)
     265                 :         {
     266              28 :             if (sName_.compare("MultiGeometry") == 0)
     267               2 :                 eType_ = MultiGeometry;
     268                 :             else
     269              26 :                 eType_ = Mixed;
     270                 :         }
     271             620 :         else if(curr != Empty)
     272                 :         {
     273             199 :             all = curr;
     274                 :         }
     275                 :     }
     276                 : 
     277             655 :     if(eType_ == Unknown)
     278                 :     {
     279             454 :         if (sName_.compare("MultiGeometry") == 0)
     280                 :         {
     281               9 :             if (all == Point)
     282               3 :                 eType_ = MultiPoint;
     283               6 :             else if (all == LineString)
     284               2 :                 eType_ = MultiLineString;
     285               4 :             else if (all == Polygon)
     286               2 :                 eType_ = MultiPolygon;
     287                 :             else
     288               2 :                 eType_ = MultiGeometry;
     289                 :         }
     290                 :         else
     291             445 :             eType_ = all;
     292                 :     }
     293                 : 
     294                 :     //nDepth --;
     295                 :     //CPLDebug("KML", "%s</%s> --> eType=%s", genSpaces(), sName_.c_str(), Nodetype2String(eType_).c_str());
     296                 : 
     297             655 :     return TRUE;
     298                 : }
     299                 : 
     300             619 : void KMLNode::eliminateEmpty(KML* poKML)
     301                 : {
     302            1244 :     for(kml_nodes_t::size_type z = 0; z < pvpoChildren_->size(); z++)
     303                 :     {
     304            1415 :         if((*pvpoChildren_)[z]->eType_ == Empty
     305             398 :            && (poKML->isContainer((*pvpoChildren_)[z]->sName_)
     306             392 :                || poKML->isFeatureContainer((*pvpoChildren_)[z]->sName_)))
     307                 :         {
     308              13 :             delete (*pvpoChildren_)[z];
     309              13 :             pvpoChildren_->erase(pvpoChildren_->begin() + z);
     310              13 :             z--;
     311                 :         }
     312                 :         else
     313                 :         {
     314             612 :             (*pvpoChildren_)[z]->eliminateEmpty(poKML);
     315                 :         }
     316                 :     }
     317             619 : }
     318                 : 
     319               0 : void KMLNode::setType(Nodetype oNotet)
     320                 : {
     321               0 :     eType_ = oNotet;
     322               0 : }
     323                 : 
     324              79 : Nodetype KMLNode::getType() const
     325                 : {
     326              79 :     return eType_;
     327                 : }
     328                 : 
     329            1678 : void KMLNode::setName(std::string const& sIn)
     330                 : {
     331            1678 :     sName_ = sIn;
     332            1678 : }
     333                 : 
     334            5519 : const std::string& KMLNode::getName() const
     335                 : {
     336            5519 :     return sName_;
     337                 : }
     338                 : 
     339            1678 : void KMLNode::setLevel(std::size_t nLev)
     340                 : {
     341            1678 :     nLevel_ = nLev;
     342            1678 : }
     343                 : 
     344               0 : std::size_t KMLNode::getLevel() const
     345                 : {
     346               0 :     return nLevel_;
     347                 : }
     348                 : 
     349             403 : void KMLNode::addAttribute(Attribute *poAttr)
     350                 : {
     351             403 :     pvoAttributes_->push_back(poAttr);
     352             403 : }
     353                 : 
     354            1671 : void KMLNode::setParent(KMLNode* poPar)
     355                 : {
     356            1671 :     poParent_ = poPar;
     357            1671 : }
     358                 : 
     359            3349 : KMLNode* KMLNode::getParent() const
     360                 : {
     361            3349 :     return poParent_;
     362                 : }
     363                 : 
     364             678 : void KMLNode::addChildren(KMLNode *poChil)
     365                 : {
     366             678 :     pvpoChildren_->push_back(poChil);
     367             678 : }
     368                 : 
     369             218 : std::size_t KMLNode::countChildren()
     370                 : {
     371             218 :     return pvpoChildren_->size();
     372                 : }
     373                 : 
     374             358 : KMLNode* KMLNode::getChild(std::size_t index) const
     375                 : {
     376             358 :     return (*pvpoChildren_)[index];
     377                 : }
     378                 : 
     379            2652 : void KMLNode::addContent(std::string const& text)
     380                 : {
     381            2652 :     pvsContent_->push_back(text);
     382            2652 : }
     383                 : 
     384            5290 : void KMLNode::appendContent(std::string const& text)
     385                 : {
     386            5290 :     std::string& tmp = (*pvsContent_)[pvsContent_->size() - 1];
     387            5290 :     tmp += text;
     388            5290 : }
     389                 : 
     390            1485 : std::string KMLNode::getContent(std::size_t index) const
     391                 : {
     392            1485 :     return (*pvsContent_)[index];
     393                 : }
     394                 : 
     395             627 : void KMLNode::deleteContent(std::size_t index)
     396                 : {
     397             627 :     if( index < pvsContent_->size() )
     398                 :     {
     399             627 :         pvsContent_->erase(pvsContent_->begin() + index);
     400                 :     }
     401             627 : }
     402                 : 
     403            8552 : std::size_t KMLNode::numContent()
     404                 : {
     405            8552 :     return pvsContent_->size();
     406                 : }
     407                 : 
     408              23 : void KMLNode::setLayerNumber(int nNum)
     409                 : {
     410              23 :     nLayerNumber_ = nNum;
     411              23 : }
     412                 : 
     413               0 : int KMLNode::getLayerNumber() const
     414                 : {
     415               0 :     return nLayerNumber_;
     416                 : }
     417                 : 
     418             290 : std::string KMLNode::getNameElement() const
     419                 : {
     420             290 :     kml_nodes_t::size_type subsize = 0;
     421             290 :     kml_nodes_t::size_type size = pvpoChildren_->size();
     422                 : 
     423             321 :     for( kml_nodes_t::size_type i = 0; i < size; ++i )
     424                 :     {
     425             290 :         if( (*pvpoChildren_)[i]->sName_.compare("name") == 0 )
     426                 :         {
     427             259 :             subsize = (*pvpoChildren_)[i]->pvsContent_->size();
     428             259 :             if( subsize > 0 )
     429                 :             {
     430             259 :                 return (*(*pvpoChildren_)[i]->pvsContent_)[0];
     431                 :             }
     432               0 :             break;
     433                 :         }
     434                 :     }
     435              31 :     return "";
     436                 : }
     437                 : 
     438             267 : std::string KMLNode::getDescriptionElement() const
     439                 : {
     440             267 :     kml_nodes_t::size_type subsize = 0;
     441             267 :     kml_nodes_t::size_type size = pvpoChildren_->size();
     442             659 :     for( kml_nodes_t::size_type i = 0; i < size; ++i )
     443                 :     {
     444             505 :         if( (*pvpoChildren_)[i]->sName_.compare("description") == 0 )
     445                 :         {
     446             113 :             subsize = (*pvpoChildren_)[i]->pvsContent_->size();
     447             113 :             if ( subsize > 0 )
     448                 :             {
     449             113 :                 return (*(*pvpoChildren_)[i]->pvsContent_)[0];
     450                 :             }
     451               0 :             break;
     452                 :         }
     453                 :     }
     454             154 :     return "";
     455                 : }
     456                 : 
     457             357 : std::size_t KMLNode::getNumFeatures()
     458                 : {
     459             357 :     if (nNumFeatures_ < 0)
     460                 :     {
     461              16 :         std::size_t nNum = 0;
     462              16 :         kml_nodes_t::size_type size = pvpoChildren_->size();
     463                 :         
     464             111 :         for( kml_nodes_t::size_type i = 0; i < size; ++i )
     465                 :         {
     466              95 :             if( (*pvpoChildren_)[i]->sName_ == "Placemark" )
     467              69 :                 nNum++;
     468                 :         }
     469              16 :         nNumFeatures_ = (int)nNum;
     470                 :     }
     471             357 :     return nNumFeatures_;
     472                 : }
     473                 : 
     474             282 : OGRGeometry* KMLNode::getGeometry(Nodetype eType)
     475                 : {
     476                 :     unsigned int nCount, nCount2, nCountP;
     477             282 :     OGRGeometry* poGeom = NULL;
     478             282 :     KMLNode* poCoor = NULL;
     479             282 :     Coordinate* psCoord = NULL;
     480                 : 
     481             282 :     if (sName_.compare("Point") == 0)
     482                 :     {
     483                 :         // Search coordinate Element
     484              94 :         for(nCount = 0; nCount < pvpoChildren_->size(); nCount++)
     485                 :         {
     486              92 :             if((*pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0)
     487                 :             {
     488              68 :                 poCoor = (*pvpoChildren_)[nCount];
     489              68 :                 for(nCountP = 0; nCountP < poCoor->pvsContent_->size(); nCountP++)
     490                 :                 {
     491              67 :                     psCoord = ParseCoordinate((*poCoor->pvsContent_)[nCountP]);
     492              67 :                     if(psCoord != NULL)
     493                 :                     {
     494              67 :                         if (psCoord->bHasZ)
     495                 :                             poGeom = new OGRPoint(psCoord->dfLongitude,
     496                 :                                                   psCoord->dfLatitude,
     497              59 :                                                   psCoord->dfAltitude);
     498                 :                         else
     499                 :                             poGeom = new OGRPoint(psCoord->dfLongitude,
     500               8 :                                                   psCoord->dfLatitude);
     501              67 :                         delete psCoord;
     502              67 :                         return poGeom;
     503                 :                     }
     504                 :                 }
     505                 :             }
     506                 :         }
     507               2 :         poGeom = new OGRPoint();
     508                 :     }
     509             213 :     else if (sName_.compare("LineString") == 0)
     510                 :     {
     511                 :         // Search coordinate Element
     512              79 :         poGeom = new OGRLineString();
     513             199 :         for(nCount = 0; nCount < pvpoChildren_->size(); nCount++)
     514                 :         {
     515             120 :             if((*pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0)
     516                 :             {
     517              78 :                 poCoor = (*pvpoChildren_)[nCount];
     518             610 :                 for(nCountP = 0; nCountP < poCoor->pvsContent_->size(); nCountP++)
     519                 :                 {
     520             532 :                     psCoord = ParseCoordinate((*poCoor->pvsContent_)[nCountP]);
     521             532 :                     if(psCoord != NULL)
     522                 :                     {
     523             532 :                         if (psCoord->bHasZ)
     524                 :                             ((OGRLineString*)poGeom)->addPoint(psCoord->dfLongitude,
     525                 :                                                                psCoord->dfLatitude,
     526             518 :                                                                psCoord->dfAltitude);
     527                 :                         else
     528                 :                             ((OGRLineString*)poGeom)->addPoint(psCoord->dfLongitude,
     529              14 :                                                                psCoord->dfLatitude);
     530             532 :                         delete psCoord;
     531                 :                     }
     532                 :                 }
     533                 :             }
     534                 :         }
     535                 :     }
     536             134 :     else if (sName_.compare("Polygon") == 0)
     537                 :     {
     538                 :         //*********************************
     539                 :         // Search outerBoundaryIs Element
     540                 :         //*********************************
     541             123 :         poGeom = new OGRPolygon();
     542             376 :         for(nCount = 0; nCount < pvpoChildren_->size(); nCount++)
     543                 :         {
     544             253 :             if((*pvpoChildren_)[nCount]->sName_.compare("outerBoundaryIs") == 0 &&
     545                 :                (*pvpoChildren_)[nCount]->pvpoChildren_->size() > 0)
     546                 :             {
     547             121 :                 poCoor = (*(*pvpoChildren_)[nCount]->pvpoChildren_)[0];
     548                 :             }
     549                 :         }
     550                 :         // No outer boundary found
     551             123 :         if(poCoor == NULL)
     552                 :         {
     553               2 :             return poGeom;
     554                 :         }
     555                 :         // Search coordinate Element
     556             121 :         OGRLinearRing* poLinearRing = NULL;
     557             241 :         for(nCount = 0; nCount < poCoor->pvpoChildren_->size(); nCount++)
     558                 :         {
     559             120 :             if((*poCoor->pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0)
     560                 :             {
     561            1714 :                 for(nCountP = 0; nCountP < (*poCoor->pvpoChildren_)[nCount]->pvsContent_->size(); nCountP++)
     562                 :                 {
     563            1594 :                     psCoord = ParseCoordinate((*(*poCoor->pvpoChildren_)[nCount]->pvsContent_)[nCountP]);
     564            1594 :                     if(psCoord != NULL)
     565                 :                     {
     566            1594 :                         if (poLinearRing == NULL)
     567                 :                         {
     568             119 :                             poLinearRing = new OGRLinearRing();
     569                 :                         }
     570            1594 :                         if (psCoord->bHasZ)
     571                 :                             poLinearRing->addPoint(psCoord->dfLongitude,
     572                 :                                                    psCoord->dfLatitude,
     573            1552 :                                                    psCoord->dfAltitude);
     574                 :                         else
     575                 :                             poLinearRing->addPoint(psCoord->dfLongitude,
     576              42 :                                                    psCoord->dfLatitude);
     577            1594 :                         delete psCoord;
     578                 :                     }
     579                 :                 }
     580                 :             }
     581                 :         }
     582                 :         // No outer boundary coordinates found
     583             121 :         if(poLinearRing == NULL)
     584                 :         {
     585               2 :             return poGeom;
     586                 :         }
     587                 : 
     588             119 :         ((OGRPolygon*)poGeom)->addRingDirectly(poLinearRing);
     589             119 :         poLinearRing = NULL;
     590                 : 
     591                 :         //*********************************
     592                 :         // Search innerBoundaryIs Elements
     593                 :         //*********************************
     594                 : 
     595             369 :         for(nCount2 = 0; nCount2 < pvpoChildren_->size(); nCount2++)
     596                 :         {
     597             250 :             if((*pvpoChildren_)[nCount2]->sName_.compare("innerBoundaryIs") == 0)
     598                 :             {
     599              21 :                 if (poLinearRing)
     600               0 :                     ((OGRPolygon*)poGeom)->addRingDirectly(poLinearRing);
     601              21 :                 poLinearRing = NULL;
     602                 : 
     603              21 :                 if ((*pvpoChildren_)[nCount2]->pvpoChildren_->size() == 0)
     604               1 :                     continue;
     605                 : 
     606              20 :                 poLinearRing = new OGRLinearRing();
     607                 : 
     608              20 :                 poCoor = (*(*pvpoChildren_)[nCount2]->pvpoChildren_)[0];
     609                 :                 // Search coordinate Element
     610              39 :                 for(nCount = 0; nCount < poCoor->pvpoChildren_->size(); nCount++)
     611                 :                 {
     612              19 :                     if((*poCoor->pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0)
     613                 :                     {
     614             120 :                         for(nCountP = 0; nCountP < (*poCoor->pvpoChildren_)[nCount]->pvsContent_->size(); nCountP++)
     615                 :                         {
     616             101 :                             psCoord = ParseCoordinate((*(*poCoor->pvpoChildren_)[nCount]->pvsContent_)[nCountP]);
     617             101 :                             if(psCoord != NULL)
     618                 :                             {
     619             101 :                                 if (psCoord->bHasZ)
     620                 :                                     poLinearRing->addPoint(psCoord->dfLongitude,
     621                 :                                                         psCoord->dfLatitude,
     622              84 :                                                         psCoord->dfAltitude);
     623                 :                                 else
     624                 :                                     poLinearRing->addPoint(psCoord->dfLongitude,
     625              17 :                                                         psCoord->dfLatitude);
     626             101 :                                 delete psCoord;
     627                 :                             }
     628                 :                         }
     629                 :                     }
     630                 :                 }
     631                 :             }
     632                 :         }
     633                 : 
     634             119 :         if (poLinearRing)
     635              20 :             ((OGRPolygon*)poGeom)->addRingDirectly(poLinearRing);
     636                 :     }
     637              11 :     else if (sName_.compare("MultiGeometry") == 0)
     638                 :     {
     639              11 :         if (eType == MultiPoint)
     640               3 :             poGeom = new OGRMultiPoint();
     641               8 :         else if (eType == MultiLineString)
     642               2 :             poGeom = new OGRMultiLineString();
     643               6 :         else if (eType == MultiPolygon)
     644               2 :             poGeom = new OGRMultiPolygon();
     645                 :         else
     646               4 :             poGeom = new OGRGeometryCollection();
     647              26 :         for(nCount = 0; nCount < pvpoChildren_->size(); nCount++)
     648                 :         {
     649              15 :             OGRGeometry* poSubGeom = (*pvpoChildren_)[nCount]->getGeometry();
     650              15 :             if (poSubGeom)
     651              15 :                 ((OGRGeometryCollection*)poGeom)->addGeometryDirectly(poSubGeom);
     652                 :         }
     653                 :     }
     654                 : 
     655             211 :     return poGeom;
     656                 : }
     657                 : 
     658             330 : Feature* KMLNode::getFeature(std::size_t nNum, int& nLastAsked, int &nLastCount)
     659                 : {
     660             330 :     unsigned int nCount, nCountP = 0;
     661             330 :     KMLNode* poFeat = NULL;
     662             330 :     KMLNode* poTemp = NULL;
     663                 : 
     664             330 :     if(nNum >= this->getNumFeatures())
     665              63 :         return NULL;
     666                 : 
     667             267 :     if (nLastAsked + 1 != (int)nNum)
     668                 :     {
     669               0 :         nCount = 0;
     670               0 :         nCountP = 0;
     671                 :     }
     672                 :     else
     673                 :     {
     674             267 :         nCount = nLastCount + 1;
     675             267 :         nCountP = nLastAsked + 1;
     676                 :     }
     677                 : 
     678             451 :     for(; nCount < pvpoChildren_->size(); nCount++)
     679                 :     {
     680             451 :         if((*pvpoChildren_)[nCount]->sName_.compare("Placemark") == 0)
     681                 :         {
     682             267 :             if(nCountP == nNum)
     683                 :             {
     684             267 :                 poFeat = (*pvpoChildren_)[nCount];
     685             267 :                 break;
     686                 :             }
     687               0 :             nCountP++;
     688                 :         }
     689                 :     }
     690                 : 
     691             267 :     nLastAsked = nNum;
     692             267 :     nLastCount = nCount;
     693                 : 
     694             267 :     if(poFeat == NULL)
     695               0 :         return NULL;
     696                 :         
     697                 :     // Create a feature structure
     698             267 :     Feature *psReturn = new Feature;
     699                 :     // Build up the name
     700             534 :     psReturn->sName = poFeat->getNameElement();
     701                 :     // Build up the description
     702             534 :     psReturn->sDescription = poFeat->getDescriptionElement();
     703                 :     // the type
     704             267 :     psReturn->eType = poFeat->eType_;
     705                 : 
     706             267 :     std::string sElementName;
     707             728 :     if(poFeat->eType_ == Point ||
     708                 :        poFeat->eType_ == LineString ||
     709                 :        poFeat->eType_ == Polygon)
     710             256 :         sElementName = Nodetype2String(poFeat->eType_);
     711              22 :     else if (poFeat->eType_ == MultiGeometry || 
     712                 :              poFeat->eType_ == MultiPoint || 
     713                 :              poFeat->eType_ == MultiLineString || 
     714                 :              poFeat->eType_ == MultiPolygon)
     715              11 :         sElementName = "MultiGeometry";
     716                 :     else
     717                 :     {
     718               0 :         delete psReturn;
     719               0 :         return NULL;
     720                 :     }
     721                 : 
     722             618 :     for(nCount = 0; nCount < poFeat->pvpoChildren_->size(); nCount++)
     723                 :     {
     724             618 :         if((*poFeat->pvpoChildren_)[nCount]->sName_.compare(sElementName) == 0)
     725                 :         {
     726             267 :             poTemp = (*poFeat->pvpoChildren_)[nCount];
     727             267 :             psReturn->poGeom = poTemp->getGeometry(poFeat->eType_);
     728             267 :             if(psReturn->poGeom)
     729             267 :                 return psReturn;
     730                 :             else
     731                 :             {
     732               0 :                 delete psReturn;
     733               0 :                 return NULL;
     734                 :             }
     735                 :         }
     736                 :     }
     737                 : 
     738               0 :     delete psReturn;
     739               0 :     return NULL;
     740            1947 : }

Generated by: LCOV version 1.7