LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/libkml - ogrlibkmlfeaturestyle.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 101 27 26.7 %
Date: 2012-04-28 Functions: 5 4 80.0 %

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Project:  KML Translator
       4                 :  * Purpose:  Implements OGRLIBKMLDriver
       5                 :  * Author:   Brian Case, rush at winkey dot org
       6                 :  *
       7                 :  ******************************************************************************
       8                 :  * Copyright (c) 2010, Brian Case
       9                 :  *
      10                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      11                 :  * copy of this software and associated documentation files (the "Software"),
      12                 :  * to deal in the Software without restriction, including without limitation
      13                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14                 :  * and/or sell copies of the Software, and to permit persons to whom the
      15                 :  * Software is furnished to do so, subject to the following conditions:
      16                 :  *
      17                 :  * The above copyright notice and this permission notice shall be included
      18                 :  * in all copies or substantial portions of the Software.
      19                 :  *
      20                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26                 :  * DEALINGS IN THE SOFTWARE.
      27                 :  *****************************************************************************/
      28                 : 
      29                 : #include <ogrsf_frmts.h>
      30                 : #include <ogr_featurestyle.h>
      31                 : #include <string>
      32                 : #include <iostream>
      33                 : using namespace std;
      34                 : 
      35                 : #include <kml/dom.h>
      36                 : 
      37                 : using kmldom::KmlFactory;;
      38                 : using kmldom::IconStylePtr;
      39                 : using kmldom::PolyStylePtr;
      40                 : using kmldom::LineStylePtr;
      41                 : using kmldom::LabelStylePtr;
      42                 : using kmldom::StylePtr;
      43                 : using kmldom::Style;
      44                 : using kmldom::StyleMapPtr;
      45                 : using kmldom::StyleSelectorPtr;
      46                 : 
      47                 : 
      48                 : #include "ogrlibkmlfeaturestyle.h"
      49                 : #include "ogrlibkmlstyle.h"
      50                 : 
      51                 : /******************************************************************************
      52                 :  function to write out a features style to kml
      53                 : 
      54                 : args:
      55                 :             poOgrLayer      the layer the feature is in
      56                 :             poOgrFeat       the feature
      57                 :             poKmlFactory    the kml dom factory
      58                 :             poKmlPlacemark  the placemark to add it to
      59                 : 
      60                 : returns:
      61                 :             nothing
      62                 : ******************************************************************************/
      63                 : 
      64              54 : void featurestyle2kml (
      65                 :     OGRLIBKMLDataSource * poOgrDS,
      66                 :     OGRLayer * poOgrLayer,
      67                 :     OGRFeature * poOgrFeat,
      68                 :     KmlFactory * poKmlFactory,
      69                 :     PlacemarkPtr poKmlPlacemark )
      70                 : {
      71                 : 
      72                 :     /***** get the style table *****/
      73                 : 
      74                 :     OGRStyleTable *poOgrSTBL;
      75                 : 
      76              54 :     const char *pszStyleString = poOgrFeat->GetStyleString (  );
      77                 : 
      78                 :     /***** does the feature have style? *****/
      79                 : 
      80              54 :     if ( pszStyleString ) {
      81                 : 
      82                 :         /***** does it ref a style table? *****/
      83                 : 
      84               0 :         if ( *pszStyleString == '@' ) {
      85                 : 
      86                 :             /***** is the name in the layer style table *****/
      87                 : 
      88                 :             OGRStyleTable *hSTBLLayer;
      89               0 :             const char *pszTest = NULL;
      90                 : 
      91               0 :             if ( ( hSTBLLayer = poOgrLayer->GetStyleTable (  ) ) )
      92               0 :                 pszTest = hSTBLLayer->Find ( pszStyleString );
      93                 : 
      94               0 :             if ( pszTest ) {
      95               0 :                 string oTmp = "#";
      96                 : 
      97               0 :                 oTmp.append ( pszStyleString + 1 );
      98                 : 
      99               0 :                 poKmlPlacemark->set_styleurl ( oTmp );
     100                 :             }
     101                 : 
     102                 : 
     103                 :             /***** assume its a dataset style, mayby the user will add it later *****/
     104                 : 
     105                 :             else {
     106               0 :                 string oTmp;
     107                 : 
     108               0 :                 if ( poOgrDS->GetStylePath (  ) )
     109               0 :                     oTmp.append ( poOgrDS->GetStylePath (  ) );
     110               0 :                 oTmp.append ( "#" );
     111               0 :                 oTmp.append ( pszStyleString + 1 );
     112                 : 
     113               0 :                 poKmlPlacemark->set_styleurl ( oTmp );
     114                 :             }
     115                 :         }
     116                 : 
     117                 :         /***** no style table ref *****/
     118                 : 
     119                 :         else {
     120               0 :             StylePtr poKmlStyle = poKmlFactory->CreateStyle (  );
     121                 : 
     122                 :             /***** parse the style string *****/
     123                 : 
     124                 :             addstylestring2kml ( pszStyleString, poKmlStyle, poKmlFactory,
     125               0 :                                  poKmlPlacemark, poOgrFeat );
     126                 : 
     127                 :             /***** add the style to the placemark *****/
     128                 : 
     129               0 :             poKmlPlacemark->set_styleselector ( poKmlStyle );
     130                 : 
     131                 :         }
     132                 :     }
     133                 : 
     134                 :     /***** get the style table *****/
     135                 : 
     136              54 :     else if ( ( poOgrSTBL = poOgrFeat->GetStyleTable (  ) ) ) {
     137                 : 
     138                 : 
     139               0 :         StylePtr poKmlStyle = poKmlFactory->CreateStyle (  );
     140                 : 
     141                 :         /***** parse the style table *****/
     142                 : 
     143               0 :         poOgrSTBL->ResetStyleStringReading (  );
     144                 :         const char *pszStyleString;
     145                 : 
     146               0 :         while ( ( pszStyleString = poOgrSTBL->GetNextStyle (  ) ) ) {
     147                 : 
     148               0 :             if ( *pszStyleString == '@' ) {
     149                 : 
     150                 :                 /***** is the name in the layer style table *****/
     151                 : 
     152                 :                 OGRStyleTable *poOgrSTBLLayer;
     153               0 :                 const char *pszTest = NULL;
     154                 : 
     155               0 :                 if ( ( poOgrSTBLLayer = poOgrLayer->GetStyleTable (  ) ) )
     156               0 :                     poOgrSTBLLayer->Find ( pszStyleString );
     157                 : 
     158               0 :                 if ( pszTest ) {
     159               0 :                     string oTmp = "#";
     160                 : 
     161               0 :                     oTmp.append ( pszStyleString + 1 );
     162                 : 
     163               0 :                     poKmlPlacemark->set_styleurl ( oTmp );
     164                 :                 }
     165                 : 
     166                 :                 /***** assume its a dataset style,      *****/
     167                 :                 /***** mayby the user will add it later *****/
     168                 : 
     169                 :                 else {
     170               0 :                     string oTmp;
     171                 : 
     172               0 :                     if ( poOgrDS->GetStylePath (  ) )
     173               0 :                         oTmp.append ( poOgrDS->GetStylePath (  ) );
     174               0 :                     oTmp.append ( "#" );
     175               0 :                     oTmp.append ( pszStyleString + 1 );
     176                 : 
     177               0 :                     poKmlPlacemark->set_styleurl ( oTmp );
     178                 :                 }
     179                 :             }
     180                 : 
     181                 :             else {
     182                 : 
     183                 :                 /***** parse the style string *****/
     184                 : 
     185                 :                 addstylestring2kml ( pszStyleString, poKmlStyle,
     186               0 :                                      poKmlFactory, poKmlPlacemark, poOgrFeat );
     187                 : 
     188                 :                 /***** add the style to the placemark *****/
     189                 : 
     190               0 :                 poKmlPlacemark->set_styleselector ( poKmlStyle );
     191                 : 
     192                 :             }
     193               0 :         }
     194                 :     }
     195              54 : }
     196                 : 
     197                 : 
     198                 : /******************************************************************************
     199                 :  function to read a kml style into ogr's featurestyle
     200                 : ******************************************************************************/
     201                 : 
     202             552 : void kml2featurestyle (
     203                 :     PlacemarkPtr poKmlPlacemark,
     204                 :     OGRLIBKMLDataSource * poOgrDS,
     205                 :     OGRLayer * poOgrLayer,
     206                 :     OGRFeature * poOgrFeat )
     207                 : {
     208                 : 
     209                 :     /***** does the placemark have a style url? *****/
     210                 : 
     211             552 :     if (    poKmlPlacemark->has_styleurl (  ) ) {
     212                 : 
     213             324 :         const string poKmlStyleUrl = poKmlPlacemark->get_styleurl (  );
     214                 : 
     215                 :         /***** is the name in the layer style table *****/
     216                 : 
     217             324 :         char *pszUrl = CPLStrdup ( poKmlStyleUrl.c_str (  ) );
     218                 : 
     219                 :         OGRStyleTable *poOgrSTBLLayer;
     220             324 :         const char *pszTest = NULL;
     221                 : 
     222                 :         /***** is it a layer style ? *****/
     223                 : 
     224             648 :         if ( *pszUrl == '#'
     225             324 :              && ( poOgrSTBLLayer = poOgrLayer->GetStyleTable (  ) ) )
     226                 :         {
     227              28 :              pszTest = poOgrSTBLLayer->Find ( pszUrl + 1 );
     228                 :         }
     229                 : 
     230             324 :         if ( pszTest ) {
     231                 : 
     232                 :             /***** should we resolve the style *****/
     233                 : 
     234              28 :             const char *pszResolve = CPLGetConfigOption ( "LIBKML_RESOLVE_STYLE", "no" );
     235                 : 
     236              28 :             if (EQUAL(pszResolve, "yes")) {
     237                 : 
     238               0 :                 poOgrFeat->SetStyleString ( pszTest );
     239                 :             }
     240                 : 
     241                 :             else {
     242                 : 
     243              28 :                 *pszUrl = '@';
     244                 : 
     245              28 :                 poOgrFeat->SetStyleString( pszUrl );
     246                 : 
     247                 :             }
     248                 : 
     249                 :         }
     250                 : 
     251                 :         /***** is it a dataset style? *****/
     252                 :         
     253                 :         else {
     254                 : 
     255             296 :             int nPathLen = strlen ( poOgrDS->GetStylePath (  ) );
     256                 : 
     257             296 :             if (    nPathLen == 0
     258                 :                  || EQUALN ( pszUrl, poOgrDS->GetStylePath (  ), nPathLen ))
     259                 :             {
     260                 : 
     261                 :                 /***** should we resolve the style *****/
     262                 : 
     263             296 :                 const char *pszResolve = CPLGetConfigOption ( "LIBKML_RESOLVE_STYLE", "no" );
     264                 : 
     265             296 :                 if (    EQUAL(pszResolve, "yes")
     266               0 :                      && ( poOgrSTBLLayer = poOgrDS->GetStyleTable (  ) )
     267                 :                      && ( pszTest = poOgrSTBLLayer->Find ( pszUrl + nPathLen + 1) )
     268                 :                    )
     269                 :                 {
     270                 : 
     271               0 :                     poOgrFeat->SetStyleString ( pszTest );
     272                 :                 }
     273                 : 
     274                 :                 else {
     275                 : 
     276             296 :                     pszUrl[nPathLen] = '@';
     277             296 :                     poOgrFeat->SetStyleString ( pszUrl + nPathLen );
     278                 :                 }
     279                 :        
     280                 :             }
     281                 :             
     282                 :             /**** its someplace else *****/
     283                 : 
     284                 :             else {
     285                 : 
     286               0 :                 const char *pszFetch = CPLGetConfigOption ( "LIBKML_EXTERNAL_STYLE", "no" );
     287                 : 
     288               0 :                 if ( EQUAL(pszFetch, "yes") ) {
     289                 : 
     290                 :                     /***** load up the style table *****/
     291                 : 
     292               0 :                     char *pszUrlTmp = CPLStrdup(pszUrl);
     293                 :                     char *pszPound;
     294               0 :                     if ((pszPound = strchr(pszUrlTmp, '#'))) {
     295                 :                         
     296               0 :                         *pszPound = '\0';
     297                 :                     }
     298                 : 
     299                 :                     /***** try it as a url then a file *****/
     300                 : 
     301               0 :                     VSILFILE *fp = NULL;
     302                 : 
     303               0 :                     if (    (fp = VSIFOpenL( CPLFormFilename( "/vsicurl/",
     304                 :                                                               pszUrlTmp,
     305                 :                                                               NULL),
     306                 :                                              "r" ))
     307                 :                         ||  (fp = VSIFOpenL( pszUrlTmp, "r" )))
     308                 :                     {
     309                 : 
     310                 :                         char szbuf[1025];
     311               0 :                         std::string oStyle = "";
     312                 : 
     313                 :                         /***** loop, read and copy to a string *****/
     314                 : 
     315                 :                         size_t nRead;
     316                 :                     
     317               0 :                         do {
     318                 :                             
     319               0 :                             nRead = VSIFReadL(szbuf, 1, sizeof(szbuf) - 1, fp);
     320                 :                             
     321               0 :                             if (nRead == 0)
     322               0 :                                 break;
     323                 : 
     324                 :                             /***** copy buf to the string *****/
     325                 : 
     326               0 :                             szbuf[nRead] = '\0';
     327               0 :                             oStyle.append( szbuf );
     328                 : 
     329                 :                         } while (!VSIFEofL(fp));
     330                 : 
     331               0 :                         VSIFCloseL(fp);
     332                 : 
     333                 :                         /***** parse the kml into the ds style table *****/
     334                 : 
     335               0 :                         if ( poOgrDS->ParseIntoStyleTable (&oStyle, pszUrlTmp)) {
     336                 : 
     337                 :                             kml2featurestyle (poKmlPlacemark,
     338                 :                                               poOgrDS,
     339                 :                                               poOgrLayer,
     340               0 :                                               poOgrFeat );
     341                 :                         }
     342                 : 
     343                 :                         else {
     344                 : 
     345                 :                             /***** if failed just store the url *****/
     346                 : 
     347               0 :                             poOgrFeat->SetStyleString ( pszUrl );
     348               0 :                         }
     349                 :                     }
     350               0 :                     CPLFree(pszUrlTmp);
     351                 :                 }
     352                 : 
     353                 :                 else {
     354                 : 
     355               0 :                     poOgrFeat->SetStyleString ( pszUrl );
     356                 :                 }
     357                 :             }
     358                 : 
     359                 :         }
     360             324 :         CPLFree ( pszUrl );
     361                 : 
     362                 :     }
     363                 : 
     364                 :     /***** does the placemark have a style selector *****/
     365                 : 
     366             552 :    if ( poKmlPlacemark->has_styleselector (  ) ) {
     367                 : 
     368                 :         StyleSelectorPtr poKmlStyleSelector =
     369               0 :             poKmlPlacemark->get_styleselector (  );
     370                 : 
     371                 :         /***** is the style a style? *****/
     372                 : 
     373               0 :         if ( poKmlStyleSelector->IsA ( kmldom::Type_Style ) ) {
     374               0 :             StylePtr poKmlStyle = AsStyle ( poKmlStyleSelector );
     375                 : 
     376               0 :             OGRStyleMgr *poOgrSM = new OGRStyleMgr;
     377                 : 
     378                 :             /***** if were resolveing style the feature  *****/
     379                 :             /***** might already have styling to add too *****/
     380                 :             
     381               0 :             const char *pszResolve = CPLGetConfigOption ( "LIBKML_RESOLVE_STYLE", "no" );
     382               0 :             if (EQUAL(pszResolve, "yes")) {
     383               0 :                  poOgrSM->InitFromFeature ( poOgrFeat );
     384                 :             }
     385                 :             else {
     386                 : 
     387                 :                 /***** if featyurestyle gets a name tool this needs changed to the above *****/
     388                 :                 
     389               0 :                 poOgrSM->InitStyleString ( NULL );
     390                 :             }
     391                 : 
     392                 :             /***** read the style *****/
     393                 : 
     394               0 :             kml2stylestring ( poKmlStyle, poOgrSM );
     395                 : 
     396                 :             /***** add the style to the feature *****/
     397                 :             
     398               0 :             poOgrFeat->SetStyleString(poOgrSM->GetStyleString(NULL));
     399                 : 
     400               0 :             delete poOgrSM;
     401                 :         }
     402                 : 
     403                 :         /***** is the style a stylemap? *****/
     404                 : 
     405               0 :         else if ( poKmlStyleSelector->IsA ( kmldom::Type_StyleMap ) ) {
     406                 :             /* todo need to figure out what to do with a style map */
     407               0 :         }
     408                 : 
     409                 : 
     410                 :     }
     411            4581 : }

Generated by: LCOV version 1.7