LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/libkml - ogrlibkmllayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 212 162 76.4 %
Date: 2011-12-18 Functions: 17 10 58.8 %

       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 "ogr_libkml.h"
      30                 : //#include "cpl_conv.h"
      31                 : //#include "cpl_string.h"
      32                 : #include "cpl_error.h"
      33                 : 
      34                 : #include <kml/dom.h>
      35                 : 
      36                 : using kmldom::KmlFactory;
      37                 : using kmldom::PlacemarkPtr;
      38                 : using kmldom::Placemark;
      39                 : using kmldom::DocumentPtr;
      40                 : using kmldom::ContainerPtr;
      41                 : using kmldom::FeaturePtr;
      42                 : using kmldom::KmlPtr;
      43                 : using kmldom::Kml;
      44                 : using kmlengine::KmzFile;
      45                 : using kmlengine::KmlFile;
      46                 : using kmlengine::Bbox;
      47                 : using kmldom::ExtendedDataPtr;
      48                 : using kmldom::SchemaDataPtr;
      49                 : using kmldom::DataPtr;
      50                 : 
      51                 : #include "ogrlibkmlfeature.h"
      52                 : #include "ogrlibkmlfield.h"
      53                 : #include "ogrlibkmlstyle.h"
      54                 : 
      55                 : /******************************************************************************
      56                 :  OGRLIBKMLLayer constructor
      57                 : 
      58                 :  Args:          pszLayerName    the name of the layer
      59                 :                 poSpatialRef    the spacial Refrance for the layer
      60                 :                 eGType          the layers geometry type
      61                 :                 poOgrDS         pointer to the datasource the layer is in
      62                 :                 poKmlRoot       pointer to the root kml element of the layer
      63                 :                 pszFileName     the filename of the layer
      64                 :                 bNew            true if its a new layer
      65                 :                 bUpdate         true if the layer is writeable
      66                 :  
      67                 :  Returns:       nothing
      68                 :                 
      69                 : ******************************************************************************/
      70                 : 
      71              46 : OGRLIBKMLLayer::OGRLIBKMLLayer ( const char *pszLayerName,
      72                 :                                  OGRSpatialReference * poSpatialRef,
      73                 :                                  OGRwkbGeometryType eGType,
      74                 :                                  OGRLIBKMLDataSource * poOgrDS,
      75                 :                                  ElementPtr poKmlRoot,
      76                 :                                  ContainerPtr poKmlContainer,
      77                 :                                  const char *pszFileName,
      78                 :                                  int bNew,
      79              46 :                                  int bUpdate )
      80                 : {
      81                 : 
      82              46 :     m_poStyleTable = NULL;
      83              46 :     iFeature = 0;
      84              46 :     nFeatures = 0;
      85              46 :     nFID = 1;
      86                 : 
      87              46 :     this->bUpdate = bUpdate;
      88              46 :     m_pszName = CPLStrdup ( pszLayerName );
      89              46 :     m_pszFileName = CPLStrdup ( pszFileName );
      90              46 :     m_poOgrDS = poOgrDS;
      91                 : 
      92              46 :     m_poOgrSRS = new OGRSpatialReference ( NULL );
      93              46 :     m_poOgrSRS->SetWellKnownGeogCS ( "WGS84" );
      94                 : 
      95              46 :     m_poOgrFeatureDefn = new OGRFeatureDefn ( pszLayerName );
      96              46 :     m_poOgrFeatureDefn->Reference (  );
      97              46 :     m_poOgrFeatureDefn->SetGeomType ( eGType );
      98                 : 
      99                 :     /***** store the root element pointer *****/
     100                 : 
     101              46 :     m_poKmlLayerRoot = poKmlRoot;
     102                 :     
     103                 :     /***** store the layers container *****/
     104                 : 
     105              46 :     m_poKmlLayer = poKmlContainer;
     106                 : 
     107                 :     /***** was the layer created from a DS::Open *****/
     108                 : 
     109              46 :     if ( !bNew ) {
     110                 : 
     111                 :         /***** get the number of features on the layer *****/
     112                 : 
     113              40 :         nFeatures = m_poKmlLayer->get_feature_array_size (  );
     114                 : 
     115                 :         /***** add the name and desc fields *****/
     116                 : 
     117                 :         const char *namefield =
     118              40 :             CPLGetConfigOption ( "LIBKML_NAME_FIELD", "Name" );
     119                 :         const char *descfield =
     120              40 :             CPLGetConfigOption ( "LIBKML_DESCRIPTION_FIELD", "description" );
     121                 :         const char *tsfield =
     122              40 :             CPLGetConfigOption ( "LIBKML_TIMESTAMP_FIELD", "timestamp" );
     123                 :         const char *beginfield =
     124              40 :             CPLGetConfigOption ( "LIBKML_BEGIN_FIELD", "begin" );
     125                 :         const char *endfield =
     126              40 :             CPLGetConfigOption ( "LIBKML_END_FIELD", "end" );
     127                 :         const char *altitudeModefield =
     128              40 :             CPLGetConfigOption ( "LIBKML_ALTITUDEMODE_FIELD", "altitudeMode" );
     129                 :         const char *tessellatefield =
     130              40 :             CPLGetConfigOption ( "LIBKML_TESSELLATE_FIELD", "tessellate" );
     131                 :         const char *extrudefield =
     132              40 :             CPLGetConfigOption ( "LIBKML_EXTRUDE_FIELD", "extrude" );
     133                 :         const char *visibilityfield =
     134              40 :             CPLGetConfigOption ( "LIBKML_VISIBILITY_FIELD", "visibility" );
     135                 : 
     136                 :         OGRFieldDefn oOgrFieldName (
     137                 :     namefield,
     138              40 :     OFTString );
     139                 : 
     140              40 :         m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldName );
     141                 : 
     142                 :         OGRFieldDefn oOgrFieldDesc (
     143                 :     descfield,
     144              40 :     OFTString );
     145                 : 
     146              40 :         m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldDesc );
     147                 : 
     148                 :         OGRFieldDefn oOgrFieldTs (
     149                 :     tsfield,
     150              40 :     OFTDateTime );
     151                 : 
     152              40 :         m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldTs );
     153                 : 
     154                 :         OGRFieldDefn oOgrFieldBegin (
     155                 :     beginfield,
     156              40 :     OFTDateTime );
     157                 : 
     158              40 :         m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldBegin );
     159                 : 
     160                 :         OGRFieldDefn oOgrFieldEnd (
     161                 :     endfield,
     162              40 :     OFTDateTime );
     163                 : 
     164              40 :         m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldEnd );
     165                 : 
     166                 :         OGRFieldDefn oOgrFieldAltitudeMode (
     167                 :     altitudeModefield,
     168              40 :     OFTString );
     169                 : 
     170              40 :         m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldAltitudeMode );
     171                 : 
     172                 :         OGRFieldDefn oOgrFieldTessellate (
     173                 :     tessellatefield,
     174              40 :     OFTInteger );
     175                 : 
     176              40 :         m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldTessellate );
     177                 : 
     178                 :         OGRFieldDefn oOgrFieldExtrude (
     179                 :     extrudefield,
     180              40 :     OFTInteger );
     181                 : 
     182              40 :         m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldExtrude );
     183                 : 
     184                 :         OGRFieldDefn oOgrFieldVisibility (
     185                 :     visibilityfield,
     186              40 :     OFTInteger );
     187                 : 
     188              40 :         m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldVisibility );
     189                 : 
     190                 :         /***** get the styles *****/
     191                 : 
     192              40 :         if ( m_poKmlLayer->IsA ( kmldom::Type_Document ) )
     193              12 :             ParseStyles ( AsDocument ( m_poKmlLayer ), &m_poStyleTable );
     194                 : 
     195                 :         /***** get the schema if the layer is a Document *****/
     196                 : 
     197              40 :         m_poKmlSchema = NULL;
     198                 : 
     199              40 :         if ( m_poKmlLayer->IsA ( kmldom::Type_Document ) ) {
     200              12 :             DocumentPtr poKmlDocument = AsDocument ( m_poKmlLayer );
     201                 : 
     202              12 :             if ( poKmlDocument->get_schema_array_size (  ) ) {
     203               2 :                 m_poKmlSchema = poKmlDocument->get_schema_array_at ( 0 );
     204               2 :                 kml2FeatureDef ( m_poKmlSchema, m_poOgrFeatureDefn );
     205              12 :             }
     206                 :         }
     207                 : 
     208                 :         /***** the schema is somewhere else *****/
     209                 : 
     210              40 :         if (m_poKmlSchema == NULL) {
     211                 : 
     212                 :             /***** try to find the correct schema *****/
     213                 : 
     214              38 :             FeaturePtr poKmlFeature;
     215                 : 
     216                 :             /***** find the first placemark *****/
     217                 : 
     218             132 :             do {
     219              76 :                 if ( iFeature >= nFeatures )
     220              10 :                     break;
     221                 : 
     222                 :                 poKmlFeature =
     223              66 :                     m_poKmlLayer->get_feature_array_at ( iFeature++ );
     224                 : 
     225              66 :             } while ( poKmlFeature->Type (  ) != kmldom::Type_Placemark );
     226                 : 
     227              76 :             if ( iFeature <= nFeatures && poKmlFeature &&
     228              38 :                  poKmlFeature->Type (  ) == kmldom::Type_Placemark &&
     229                 :                  poKmlFeature->has_extendeddata (  ) ) {
     230                 : 
     231                 :                 ExtendedDataPtr poKmlExtendedData = poKmlFeature->
     232               1 :                     get_extendeddata (  );
     233                 : 
     234               1 :                 if ( poKmlExtendedData->get_schemadata_array_size (  ) > 0 ) {
     235                 :                     SchemaDataPtr poKmlSchemaData = poKmlExtendedData->
     236               1 :                         get_schemadata_array_at ( 0 );
     237                 : 
     238               1 :                     if ( poKmlSchemaData->has_schemaurl (  ) ) {
     239                 : 
     240                 :                         std::string oKmlSchemaUrl = poKmlSchemaData->
     241               1 :                             get_schemaurl (  );
     242               1 :                         if ( ( m_poKmlSchema =
     243                 :                                m_poOgrDS->FindSchema ( oKmlSchemaUrl.
     244                 :                                                        c_str (  ) ) ) ) {
     245                 :                             kml2FeatureDef ( m_poKmlSchema,
     246               1 :                                              m_poOgrFeatureDefn );
     247               1 :                         }
     248               1 :                     }
     249                 :                 }
     250               0 :                 else if ( poKmlExtendedData->get_data_array_size() > 0 )
     251                 :                 {
     252                 :                     /* Use the <Data> of the first placemark to build the feature definition */
     253                 :                     /* If others have different fields, too bad... */
     254                 :                     int bLaunderFieldNames =
     255               0 :                         CSLTestBoolean(CPLGetConfigOption("LIBKML_LAUNDER_FIELD_NAMES", "YES"));
     256               0 :                     size_t nDataArraySize = poKmlExtendedData->get_data_array_size();
     257               0 :                     for(size_t i=0; i < nDataArraySize; i++)
     258                 :                     {
     259               0 :                         const DataPtr& data = poKmlExtendedData->get_data_array_at(i);
     260               0 :                         if (data->has_name())
     261                 :                         {
     262               0 :                             CPLString osName = data->get_name();
     263               0 :                             if (bLaunderFieldNames)
     264               0 :                                 osName = LaunderFieldNames(osName);
     265                 :                             OGRFieldDefn oOgrField ( osName,
     266               0 :                                                     OFTString );
     267               0 :                             m_poOgrFeatureDefn->AddFieldDefn ( &oOgrField );
     268                 :                         }
     269                 :                     }
     270               1 :                 }
     271                 :             }
     272                 : 
     273              38 :             iFeature = 0;
     274                 : 
     275                 :         }
     276                 : 
     277                 : 
     278                 : 
     279                 :         /***** check if any features are another layer *****/
     280                 : 
     281              40 :         m_poOgrDS->ParseLayers ( m_poKmlLayer, poSpatialRef );
     282                 : 
     283                 :     }
     284                 : 
     285                 :     /***** it was from a DS::CreateLayer *****/
     286                 : 
     287                 :     else {
     288                 : 
     289                 :         /***** mark the layer as updated *****/
     290                 : 
     291               6 :         bUpdated = TRUE;
     292                 : 
     293                 :         /***** create a new schema *****/
     294                 : 
     295               6 :         KmlFactory *poKmlFactory = m_poOgrDS->GetKmlFactory (  );
     296                 : 
     297               6 :         m_poKmlSchema = poKmlFactory->CreateSchema (  );
     298                 : 
     299                 :         /***** set the id on the new schema *****/
     300                 : 
     301               6 :         std::string oKmlSchemaID = m_pszName;
     302               6 :         oKmlSchemaID.append ( ".schema" );
     303               6 :         m_poKmlSchema->set_id ( oKmlSchemaID );
     304                 :     }
     305                 : 
     306                 : 
     307                 : 
     308                 : 
     309              46 : }
     310                 : 
     311                 : /******************************************************************************
     312                 :  OGRLIBKMLLayer Destructor
     313                 : 
     314                 :  Args:          none
     315                 :  
     316                 :  Returns:       nothing
     317                 :                 
     318                 : ******************************************************************************/
     319                 : 
     320              46 : OGRLIBKMLLayer::~OGRLIBKMLLayer (  )
     321                 : {
     322                 : 
     323              46 :     CPLFree ( ( void * )m_pszName );
     324              46 :     CPLFree ( ( void * )m_pszFileName );
     325              46 :     delete m_poOgrSRS;
     326                 : 
     327              46 :     m_poOgrFeatureDefn->Release (  );
     328                 : 
     329                 : 
     330              46 : }
     331                 : 
     332                 : 
     333                 : /******************************************************************************
     334                 :  Method to get the next feature on the layer
     335                 : 
     336                 :  Args:          none
     337                 :  
     338                 :  Returns:       The next feature, or NULL if there is no more
     339                 : 
     340                 :  this function copyed from the sqlite driver
     341                 : ******************************************************************************/
     342                 : 
     343             354 : OGRFeature *OGRLIBKMLLayer::GetNextFeature()
     344                 : 
     345                 : {
     346              65 :     for( ; TRUE; )
     347                 :     {
     348                 :         OGRFeature      *poFeature;
     349                 : 
     350             354 :         poFeature = GetNextRawFeature();
     351             354 :         if( poFeature == NULL )
     352              78 :             return NULL;
     353                 : 
     354             276 :         if( (m_poFilterGeom == NULL
     355                 :             || FilterGeometry( poFeature->GetGeometryRef() ) )
     356                 :             && (m_poAttrQuery == NULL
     357                 :                 || m_poAttrQuery->Evaluate( poFeature )) )
     358             211 :             return poFeature;
     359                 : 
     360              65 :         delete poFeature;
     361                 :     }
     362                 : }
     363                 : 
     364                 : /******************************************************************************
     365                 :  Method to get the next feature on the layer
     366                 : 
     367                 :  Args:          none
     368                 :  
     369                 :  Returns:       The next feature, or NULL if there is no more
     370                 :                 
     371                 : ******************************************************************************/
     372                 : 
     373             354 : OGRFeature *OGRLIBKMLLayer::GetNextRawFeature (
     374                 :      )
     375                 : {
     376             354 :     FeaturePtr poKmlFeature;
     377             354 :     OGRFeature *poOgrFeature = NULL;
     378                 : 
     379             680 :     do {
     380             418 :         if ( iFeature >= nFeatures )
     381              78 :             break;
     382                 : 
     383             340 :         poKmlFeature = m_poKmlLayer->get_feature_array_at ( iFeature++ );
     384                 : 
     385             340 :     } while ( poKmlFeature->Type (  ) != kmldom::Type_Placemark );
     386                 : 
     387                 : 
     388             645 :     if ( iFeature <= nFeatures && poKmlFeature
     389             291 :          && poKmlFeature->Type (  ) == kmldom::Type_Placemark ) {
     390                 :         poOgrFeature =
     391                 :             kml2feat ( AsPlacemark ( poKmlFeature ), m_poOgrDS, this,
     392             276 :                        m_poOgrFeatureDefn, m_poOgrSRS );
     393             276 :         poOgrFeature->SetFID(nFID ++);
     394                 :     }
     395                 : 
     396             354 :     return poOgrFeature;
     397                 : }
     398                 : 
     399                 : /******************************************************************************
     400                 :  method to add a feature to a layer
     401                 : 
     402                 :  Args:          poOgrFeat   pointer to the feature to add
     403                 :  
     404                 :  Returns:       OGRERR_NONE, or OGRERR_UNSUPPORTED_OPERATION of the layer is
     405                 :                 not writeable
     406                 :                 
     407                 : ******************************************************************************/
     408                 : 
     409              27 : OGRErr OGRLIBKMLLayer::CreateFeature (
     410                 :     OGRFeature * poOgrFeat )
     411                 : {
     412                 : 
     413              27 :     if ( !bUpdate )
     414               0 :         return OGRERR_UNSUPPORTED_OPERATION;
     415                 : 
     416                 :     PlacemarkPtr poKmlPlacemark =
     417              27 :         feat2kml ( m_poOgrDS, this, poOgrFeat, m_poOgrDS->GetKmlFactory (  ) );
     418                 : 
     419              27 :     m_poKmlLayer->add_feature ( poKmlPlacemark );
     420                 : 
     421                 :     /***** mark the layer as updated *****/
     422                 : 
     423              27 :     bUpdated = TRUE;
     424              27 :     m_poOgrDS->Updated (  );
     425                 : 
     426              27 :     return OGRERR_NONE;
     427                 : }
     428                 : 
     429                 : /******************************************************************************
     430                 :  method to get the number of features on the layer
     431                 : 
     432                 :  Args:          bForce      no effect as of now
     433                 :  
     434                 :  Returns:       the number of feateres on the layer
     435                 : 
     436                 :  Note:          the result can include links, folders and other items that are
     437                 :                 not supported by OGR
     438                 :                 
     439                 : ******************************************************************************/
     440                 : 
     441              68 : int OGRLIBKMLLayer::GetFeatureCount (
     442                 :     int bForce )
     443                 : {
     444                 : 
     445                 : 
     446              68 :     int i = 0; 
     447              94 :     if (m_poFilterGeom != NULL || m_poAttrQuery != NULL ) {
     448              26 :         i = OGRLayer::GetFeatureCount( bForce );
     449                 :     }
     450                 : 
     451                 :     else {
     452                 :         size_t iKmlFeature; 
     453              42 :       size_t nKmlFeatures = m_poKmlLayer->get_feature_array_size (  ); 
     454                 :        
     455             188 :       for ( iKmlFeature = 0; iKmlFeature < nKmlFeatures; iKmlFeature++ ) { 
     456             292 :           if ( m_poKmlLayer->get_feature_array_at ( iKmlFeature )-> 
     457             146 :                IsA ( kmldom::Type_Placemark ) ) { 
     458             108 :               i++; 
     459                 :           } 
     460                 :       }
     461                 :     }
     462                 :     
     463              68 :     return i;
     464                 : }
     465                 : 
     466                 : /******************************************************************************
     467                 :  GetExtent()
     468                 : 
     469                 :  Args:          psExtent    pointer to the Envelope to store the result in
     470                 :                 bForce      no effect as of now 
     471                 :  
     472                 :  Returns:       nothing
     473                 :                 
     474                 : ******************************************************************************/
     475                 : 
     476              10 : OGRErr OGRLIBKMLLayer::GetExtent (
     477                 :     OGREnvelope * psExtent,
     478                 :     int bForce )
     479                 : {
     480              10 :     Bbox oKmlBbox;
     481                 : 
     482              10 :     if ( kmlengine::
     483                 :          GetFeatureBounds ( AsFeature ( m_poKmlLayer ), &oKmlBbox ) ) {
     484               8 :         psExtent->MinX = oKmlBbox.get_west (  );
     485               8 :         psExtent->MinY = oKmlBbox.get_south (  );
     486               8 :         psExtent->MaxX = oKmlBbox.get_east (  );
     487               8 :         psExtent->MaxY = oKmlBbox.get_north (  );
     488                 : 
     489               8 :         return OGRERR_NONE;
     490                 :     }
     491                 : 
     492               2 :     return OGRERR_FAILURE;
     493                 : }
     494                 : 
     495                 : 
     496                 : 
     497                 : 
     498                 : /******************************************************************************
     499                 :  Method to create a field on a layer
     500                 : 
     501                 :  Args:          poField     pointer to the Field Definition to add
     502                 :                 bApproxOK   no effect as of now 
     503                 : 
     504                 :  Returns:       OGRERR_NONE on success or OGRERR_UNSUPPORTED_OPERATION if the
     505                 :                 layer is not writeable
     506                 :                 
     507                 : ******************************************************************************/
     508                 : 
     509               9 : OGRErr OGRLIBKMLLayer::CreateField (
     510                 :     OGRFieldDefn * poField,
     511                 :     int bApproxOK )
     512                 : {
     513                 : 
     514               9 :     if ( !bUpdate )
     515               0 :         return OGRERR_UNSUPPORTED_OPERATION;
     516                 : 
     517               9 :     SimpleFieldPtr poKmlSimpleField = NULL;
     518                 : 
     519               9 :     if ( (poKmlSimpleField =
     520                 :          FieldDef2kml ( poField, m_poOgrDS->GetKmlFactory (  ) )) != NULL )
     521               3 :         m_poKmlSchema->add_simplefield ( poKmlSimpleField );
     522                 : 
     523               9 :     m_poOgrFeatureDefn->AddFieldDefn ( poField );
     524                 : 
     525                 :     /***** mark the layer as updated *****/
     526                 : 
     527               9 :     bUpdated = TRUE;
     528               9 :     m_poOgrDS->Updated (  );
     529                 : 
     530               9 :     return OGRERR_NONE;
     531                 : }
     532                 : 
     533                 : 
     534                 : /******************************************************************************
     535                 :  method to write the datasource to disk
     536                 : 
     537                 :  Args:      none
     538                 : 
     539                 :  Returns    nothing
     540                 :                 
     541                 : ******************************************************************************/
     542                 : 
     543               0 : OGRErr OGRLIBKMLLayer::SyncToDisk (
     544                 :      )
     545                 : {
     546                 : 
     547               0 :     return OGRERR_NONE;
     548                 : }
     549                 : 
     550                 : /******************************************************************************
     551                 :  method to get a layers style table
     552                 :  
     553                 :  Args:          none
     554                 :  
     555                 :  Returns:       pointer to the layers style table, or NULL if it does
     556                 :                 not have one
     557                 :                 
     558                 : ******************************************************************************/
     559                 : 
     560             162 : OGRStyleTable *OGRLIBKMLLayer::GetStyleTable (
     561                 :      )
     562                 : {
     563                 : 
     564             162 :     return m_poStyleTable;
     565                 : }
     566                 : 
     567                 : /******************************************************************************
     568                 :  method to write a style table to a layer
     569                 :  
     570                 :  Args:          poStyleTable    pointer to the style table to add
     571                 :  
     572                 :  Returns:       nothing
     573                 : 
     574                 :  note: this method assumes ownership of the style table
     575                 : ******************************************************************************/
     576                 : 
     577               0 : void OGRLIBKMLLayer::SetStyleTableDirectly (
     578                 :     OGRStyleTable * poStyleTable )
     579                 : {
     580                 : 
     581               0 :     if ( !bUpdate )
     582               0 :         return;
     583                 : 
     584               0 :     KmlFactory *poKmlFactory = m_poOgrDS->GetKmlFactory (  );
     585                 : 
     586               0 :     if ( m_poStyleTable )
     587               0 :         delete m_poStyleTable;
     588                 : 
     589               0 :     m_poStyleTable = poStyleTable;
     590                 : 
     591               0 :     if ( m_poKmlLayer->IsA ( kmldom::Type_Document ) ) {
     592                 : 
     593                 :         /***** delete all the styles *****/
     594                 : 
     595               0 :         DocumentPtr poKmlDocument = AsDocument ( m_poKmlLayer );
     596               0 :         size_t nKmlStyles = poKmlDocument->get_schema_array_size (  );
     597                 :         int iKmlStyle;
     598                 : 
     599               0 :         for ( iKmlStyle = nKmlStyles - 1; iKmlStyle >= 0; iKmlStyle-- ) {
     600               0 :             poKmlDocument->DeleteStyleSelectorAt ( iKmlStyle );
     601                 :         }
     602                 : 
     603                 :         /***** add the new style table to the document *****/
     604                 : 
     605                 :         styletable2kml ( poStyleTable, poKmlFactory,
     606               0 :                          AsContainer ( poKmlDocument ) );
     607                 : 
     608                 :     }
     609                 : 
     610                 :     /***** mark the layer as updated *****/
     611                 : 
     612               0 :     bUpdated = TRUE;
     613               0 :     m_poOgrDS->Updated (  );
     614                 : 
     615               0 :     return;
     616                 : }
     617                 : 
     618                 : /******************************************************************************
     619                 :  method to write a style table to a layer
     620                 :  
     621                 :  Args:          poStyleTable    pointer to the style table to add
     622                 :  
     623                 :  Returns:       nothing
     624                 : 
     625                 :  note:  this method copys the style table, and the user will still be
     626                 :         responsible for its destruction
     627                 : ******************************************************************************/
     628                 : 
     629               0 : void OGRLIBKMLLayer::SetStyleTable (
     630                 :     OGRStyleTable * poStyleTable )
     631                 : {
     632                 : 
     633               0 :     if ( !bUpdate )
     634               0 :         return;
     635                 : 
     636               0 :     if ( poStyleTable )
     637               0 :         SetStyleTableDirectly ( poStyleTable->Clone (  ) );
     638                 :     else
     639               0 :         SetStyleTableDirectly ( NULL );
     640               0 :     return;
     641                 : }
     642                 : 
     643                 : /******************************************************************************
     644                 :  Test if capability is available.
     645                 : 
     646                 :  Args:          pszCap  layer capability name to test
     647                 :  
     648                 :  Returns:       True if the layer supports the capability, otherwise false
     649                 : 
     650                 : ******************************************************************************/
     651                 : 
     652              40 : int OGRLIBKMLLayer::TestCapability (
     653                 :     const char *pszCap )
     654                 : {
     655              40 :     int result = FALSE;
     656                 : 
     657              40 :     if ( EQUAL ( pszCap, OLCRandomRead ) )
     658              10 :         result = FALSE;
     659              30 :     else if ( EQUAL ( pszCap, OLCSequentialWrite ) )
     660               0 :         result = bUpdate;
     661              30 :     else if ( EQUAL ( pszCap, OLCRandomWrite ) )
     662              10 :         result = FALSE;
     663              20 :     else if ( EQUAL ( pszCap, OLCFastFeatureCount ) )
     664               0 :         result = FALSE;
     665              20 :     else if ( EQUAL ( pszCap, OLCFastSetNextByIndex ) )
     666              10 :         result = FALSE;
     667              10 :     else if ( EQUAL ( pszCap, OLCCreateField ) )
     668               0 :         result = bUpdate;
     669              10 :     else if ( EQUAL ( pszCap, OLCDeleteFeature ) )
     670               0 :         result = FALSE;
     671              10 :     else if ( EQUAL(pszCap, OLCStringsAsUTF8) )
     672              10 :         result = TRUE;
     673                 : 
     674              40 :     return result;
     675                 : }
     676                 : 
     677                 : /************************************************************************/
     678                 : /*                        LaunderFieldNames()                           */
     679                 : /************************************************************************/
     680                 : 
     681               0 : CPLString OGRLIBKMLLayer::LaunderFieldNames(CPLString osName)
     682                 : {
     683               0 :     CPLString osLaunderedName;
     684               0 :     for(int i=0;i<(int)osName.size();i++)
     685                 :     {
     686               0 :         char ch = osName[i];
     687               0 :         if ((ch >= '0' && ch <= '9') ||
     688                 :             (ch >= 'a' && ch <= 'z') ||
     689                 :             (ch >= 'A' && ch <= 'Z') ||
     690                 :             (ch == '_'))
     691               0 :             osLaunderedName += ch;
     692                 :         else
     693               0 :             osLaunderedName += "_";
     694                 :     }
     695               0 :     return osLaunderedName;
     696                 : }

Generated by: LCOV version 1.7