LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/kml - kmlnode.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 343 288 84.0 %
Date: 2010-01-09 Functions: 35 30 85.7 %

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

Generated by: LCOV version 1.7