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

Generated by: LCOV version 1.7