LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/kml - kmlnode.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 355 300 84.5 %
Date: 2012-12-26 Functions: 38 31 81.6 %

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

Generated by: LCOV version 1.7