LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/kml - ogrkmllayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 246 173 70.3 %
Date: 2012-04-28 Functions: 17 12 70.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrkmllayer.cpp 22872 2011-08-06 20:32:14Z rouault $
       3                 :  *
       4                 :  * Project:  KML Driver
       5                 :  * Purpose:  Implementation of OGRKMLLayer class.
       6                 :  * Author:   Christopher Condit, condit@sdsc.edu
       7                 :  *           Jens Oberender, j.obi@troja.net
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2006, Christopher Condit
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include "ogr_kml.h"
      32                 : #include "ogr_api.h"
      33                 : #include "cpl_conv.h"
      34                 : #include "cpl_string.h"
      35                 : #include "ogr_p.h"
      36                 : 
      37                 : /* Function utility to dump OGRGeometry to KML text. */
      38                 : char *OGR_G_ExportToKML( OGRGeometryH hGeometry, const char* pszAltitudeMode );
      39                 : 
      40                 : /************************************************************************/
      41                 : /*                           OGRKMLLayer()                              */
      42                 : /************************************************************************/
      43                 : 
      44              58 : OGRKMLLayer::OGRKMLLayer( const char * pszName,
      45                 :                           OGRSpatialReference *poSRSIn, int bWriterIn,
      46                 :                           OGRwkbGeometryType eReqType,
      47              58 :                           OGRKMLDataSource *poDSIn )
      48                 : {     
      49              58 :     poCT_ = NULL;
      50                 : 
      51                 :     /* KML should be created as WGS84. */
      52              58 :     if( poSRSIn != NULL )
      53                 :     {
      54              52 :         poSRS_ = new OGRSpatialReference(NULL);   
      55              52 :         poSRS_->SetWellKnownGeogCS( "WGS84" );
      56              52 :         if (!poSRS_->IsSame(poSRSIn))
      57                 :         {
      58               2 :             poCT_ = OGRCreateCoordinateTransformation( poSRSIn, poSRS_ );
      59               2 :             if( poCT_ == NULL && poDSIn->IsFirstCTError() )
      60                 :             {
      61                 :                 /* If we can't create a transformation, issue a warning - but continue the transformation*/
      62               0 :                 char *pszWKT = NULL;
      63                 : 
      64               0 :                 poSRSIn->exportToPrettyWkt( &pszWKT, FALSE );
      65                 : 
      66                 :                 CPLError( CE_Warning, CPLE_AppDefined,
      67                 :                         "Failed to create coordinate transformation between the\n"
      68                 :                         "input coordinate system and WGS84.  This may be because they\n"
      69                 :                         "are not transformable, or because projection services\n"
      70                 :                         "(PROJ.4 DLL/.so) could not be loaded.\n" 
      71                 :                         "KML geometries may not render correctly.\n"
      72                 :                         "This message will not be issued any more. \n"
      73                 :                         "\nSource:\n%s\n", 
      74               0 :                         pszWKT );
      75                 : 
      76               0 :                 CPLFree( pszWKT );
      77               0 :                 poDSIn->IssuedFirstCTError(); 
      78                 :             }
      79                 :         }
      80                 :     }
      81                 :     else
      82                 :     {
      83               6 :         poSRS_ = NULL;
      84                 :     }
      85                 : 
      86              58 :     iNextKMLId_ = 0;
      87              58 :     nTotalKMLCount_ = -1;
      88              58 :     nLastAsked = -1;
      89              58 :     nLastCount = -1;
      90                 : 
      91              58 :     poDS_ = poDSIn;
      92                 :     
      93              58 :     poFeatureDefn_ = new OGRFeatureDefn( pszName );
      94              58 :     poFeatureDefn_->Reference();
      95              58 :     poFeatureDefn_->SetGeomType( eReqType );
      96                 : 
      97              58 :     OGRFieldDefn oFieldName( "Name", OFTString );
      98              58 :     poFeatureDefn_->AddFieldDefn( &oFieldName );
      99                 :     
     100              58 :     OGRFieldDefn oFieldDesc( "Description", OFTString );
     101              58 :     poFeatureDefn_->AddFieldDefn( &oFieldDesc );
     102                 : 
     103              58 :     bWriter_ = bWriterIn;
     104              58 :     nWroteFeatureCount_ = 0;
     105              58 :     bClosedForWriting = (bWriterIn == FALSE);
     106                 : 
     107              58 :     pszName_ = CPLStrdup(pszName);
     108              58 : }
     109                 : 
     110                 : /************************************************************************/
     111                 : /*                           ~OGRKMLLayer()                             */
     112                 : /************************************************************************/
     113                 : 
     114              58 : OGRKMLLayer::~OGRKMLLayer()
     115                 : {
     116              58 :     if( NULL != poFeatureDefn_ )
     117              58 :         poFeatureDefn_->Release();
     118                 : 
     119              58 :     if( NULL != poSRS_ )
     120              52 :         poSRS_->Release();
     121                 :   
     122              58 :     if( NULL != poCT_ )
     123               2 :         delete poCT_;
     124                 :   
     125              58 :     CPLFree( pszName_ );
     126              58 : }
     127                 : 
     128                 : /************************************************************************/
     129                 : /*                            GetLayerDefn()                            */
     130                 : /************************************************************************/
     131                 : 
     132             478 : OGRFeatureDefn* OGRKMLLayer::GetLayerDefn()
     133                 : {
     134             478 :     return poFeatureDefn_;
     135                 : }
     136                 : 
     137                 : /************************************************************************/
     138                 : /*                            ResetReading()                            */
     139                 : /************************************************************************/
     140                 : 
     141             342 : void OGRKMLLayer::ResetReading()
     142                 : {
     143             342 :     iNextKMLId_ = 0;    
     144             342 :     nLastAsked = -1;
     145             342 :     nLastCount = -1;
     146             342 : }
     147                 : 
     148                 : /************************************************************************/
     149                 : /*                           GetNextFeature()                           */
     150                 : /************************************************************************/
     151                 : 
     152             534 : OGRFeature *OGRKMLLayer::GetNextFeature()
     153                 : {
     154                 : #ifndef HAVE_EXPAT
     155                 :     return NULL;
     156                 : #else
     157                 :     /* -------------------------------------------------------------------- */
     158                 :     /*      Loop till we find a feature matching our criteria.              */
     159                 :     /* -------------------------------------------------------------------- */
     160             534 :     KML *poKMLFile = poDS_->GetKMLFile();
     161             534 :     poKMLFile->selectLayer(nLayerNumber_);
     162                 : 
     163             126 :     while(TRUE)
     164                 :     {
     165             660 :         Feature *poFeatureKML = NULL;
     166             660 :         poFeatureKML = poKMLFile->getFeature(iNextKMLId_++, nLastAsked, nLastCount);
     167                 :     
     168             660 :         if(poFeatureKML == NULL)
     169             126 :             return NULL;
     170                 :     
     171             534 :         CPLAssert( poFeatureKML != NULL );
     172                 :     
     173             534 :         OGRFeature *poFeature = new OGRFeature( poFeatureDefn_ );
     174                 :         
     175             534 :         if(poFeatureKML->poGeom)
     176                 :         {
     177             534 :             poFeature->SetGeometryDirectly(poFeatureKML->poGeom);
     178             534 :             poFeatureKML->poGeom = NULL;
     179                 :         }
     180                 :     
     181                 :         // Add fields
     182             534 :         poFeature->SetField( poFeatureDefn_->GetFieldIndex("Name"), poFeatureKML->sName.c_str() );
     183             534 :         poFeature->SetField( poFeatureDefn_->GetFieldIndex("Description"), poFeatureKML->sDescription.c_str() );
     184             534 :         poFeature->SetFID( iNextKMLId_ - 1 );
     185                 :     
     186                 :         // Clean up
     187             534 :         delete poFeatureKML;
     188                 :     
     189             534 :         if( poFeature->GetGeometryRef() != NULL && poSRS_ != NULL)
     190                 :         {
     191             534 :             poFeature->GetGeometryRef()->assignSpatialReference( poSRS_ );
     192                 :         }
     193                 :     
     194                 :         /* Check spatial/attribute filters */
     195             534 :         if ((m_poFilterGeom == NULL || FilterGeometry( poFeature->GetGeometryRef() ) ) &&
     196                 :             (m_poAttrQuery == NULL || m_poAttrQuery->Evaluate( poFeature )) )
     197                 :         {
     198                 :         // Return the feature
     199             408 :             return poFeature;
     200                 :         }
     201                 :         else
     202                 :         {
     203             126 :             delete poFeature;
     204                 :         }
     205                 :     }
     206                 : 
     207                 : #endif /* HAVE_EXPAT */
     208                 : }
     209                 : 
     210                 : /************************************************************************/
     211                 : /*                          GetFeatureCount()                           */
     212                 : /************************************************************************/
     213                 : 
     214             106 : int OGRKMLLayer::GetFeatureCount( int bForce )
     215                 : {
     216             106 :     int nCount = 0;
     217                 : 
     218                 : #ifdef HAVE_EXPAT
     219             106 :     if (m_poFilterGeom == NULL && m_poAttrQuery == NULL)
     220                 :     {
     221              58 :         KML *poKMLFile = poDS_->GetKMLFile();
     222              58 :         if( NULL != poKMLFile )
     223                 :         {
     224              58 :             poKMLFile->selectLayer(nLayerNumber_);
     225              58 :             nCount = poKMLFile->getNumFeatures();
     226                 :         }
     227                 :     }
     228                 :     else
     229              48 :         return OGRLayer::GetFeatureCount(bForce);
     230                 : #endif
     231                 : 
     232              58 :     return nCount;
     233                 : }
     234                 : 
     235                 : /************************************************************************/
     236                 : /*                           CreateFeature()                            */
     237                 : /************************************************************************/
     238                 : 
     239              20 : OGRErr OGRKMLLayer::CreateFeature( OGRFeature* poFeature )
     240                 : {
     241              20 :     CPLAssert( NULL != poFeature );
     242              20 :     CPLAssert( NULL != poDS_ );
     243                 : 
     244              20 :     if( !bWriter_ )
     245               0 :         return OGRERR_FAILURE;
     246                 : 
     247              20 :     if( bClosedForWriting )
     248                 :     {
     249                 :         CPLError(CE_Failure, CPLE_NotSupported,
     250               2 :                  "Interleaved feature adding to different layers is not supported");
     251               2 :         return OGRERR_FAILURE;
     252                 :     }
     253                 : 
     254              18 :     VSILFILE *fp = poDS_->GetOutputFP();
     255              18 :     CPLAssert( NULL != fp );
     256                 : 
     257                 :     // If we haven't writen any features yet, output the layer's schema
     258              18 :     if (0 == nWroteFeatureCount_)
     259                 :     {
     260               4 :         VSIFPrintfL( fp, "<Schema name=\"%s\" id=\"%s\">\n", pszName_, pszName_ );
     261               4 :         OGRFeatureDefn *featureDefinition = GetLayerDefn();
     262              12 :         for (int j=0; j < featureDefinition->GetFieldCount(); j++)
     263                 :         {
     264               8 :             OGRFieldDefn *fieldDefinition = featureDefinition->GetFieldDefn(j);      
     265               8 :             const char* pszKMLType = NULL;
     266               8 :             const char* pszKMLEltName = NULL;
     267                 :             // Match the OGR type to the GDAL type
     268               8 :             switch (fieldDefinition->GetType())
     269                 :             {
     270                 :               case OFTInteger:
     271               0 :                 pszKMLType = "int";
     272               0 :                 pszKMLEltName = "SimpleField";
     273               0 :                 break;
     274                 :               case OFTIntegerList:
     275               0 :                 pszKMLType = "int";
     276               0 :                 pszKMLEltName = "SimpleArrayField";
     277               0 :                 break;
     278                 :               case OFTReal:
     279               0 :                 pszKMLType = "float";
     280               0 :                 pszKMLEltName = "SimpleField";
     281               0 :                 break;
     282                 :               case OFTRealList:
     283               0 :                 pszKMLType = "float";
     284               0 :                 pszKMLEltName = "SimpleArrayField";
     285               0 :                 break;
     286                 :               case OFTString:
     287               8 :                 pszKMLType = "string";
     288               8 :                 pszKMLEltName = "SimpleField";
     289               8 :                 break;
     290                 :               case OFTStringList:
     291               0 :                 pszKMLType = "string";
     292               0 :                 pszKMLEltName = "SimpleArrayField";
     293               0 :                 break;
     294                 :               case OFTBinary:
     295               0 :                 pszKMLType = "bool";
     296               0 :                 pszKMLEltName = "SimpleField";
     297               0 :                 break;
     298                 :                 //TODO: KML doesn't handle these data types yet...
     299                 :               case OFTDate:                
     300                 :               case OFTTime:                
     301                 :               case OFTDateTime:
     302               0 :                 pszKMLType = "string";
     303               0 :                 pszKMLEltName = "SimpleField";                
     304               0 :                 break;
     305                 : 
     306                 :               default:
     307               0 :                 pszKMLType = "string";
     308               0 :                 pszKMLEltName = "SimpleField";
     309                 :                 break;
     310                 :             }
     311                 :             VSIFPrintfL( fp, "\t<%s name=\"%s\" type=\"%s\"></%s>\n", 
     312               8 :                         pszKMLEltName, fieldDefinition->GetNameRef() ,pszKMLType, pszKMLEltName );
     313                 :         }
     314               4 :         VSIFPrintfL( fp, "</Schema>\n" );
     315                 :     }
     316                 : 
     317              18 :     VSIFPrintfL( fp, "  <Placemark>\n" );
     318                 : 
     319              18 :     if( poFeature->GetFID() == OGRNullFID )
     320              18 :         poFeature->SetFID( iNextKMLId_++ );
     321                 : 
     322                 :     // Find and write the name element
     323              18 :     if (NULL != poDS_->GetNameField())
     324                 :     {
     325              54 :         for( int iField = 0; iField < poFeatureDefn_->GetFieldCount(); iField++ )
     326                 :         {        
     327              36 :             OGRFieldDefn *poField = poFeatureDefn_->GetFieldDefn( iField );
     328                 : 
     329              36 :             if( poFeature->IsFieldSet( iField )
     330                 :                 && EQUAL(poField->GetNameRef(), poDS_->GetNameField()) )
     331                 :             {           
     332               2 :                 const char *pszRaw = poFeature->GetFieldAsString( iField );
     333               4 :                 while( *pszRaw == ' ' )
     334               0 :                     pszRaw++;
     335                 : 
     336               2 :                 char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw );
     337                 : 
     338               2 :                 VSIFPrintfL( fp, "\t<name>%s</name>\n", pszEscaped);
     339               2 :                 CPLFree( pszEscaped );
     340                 :             }
     341                 :         }
     342                 :     }
     343                 : 
     344              18 :     if (NULL != poDS_->GetDescriptionField())
     345                 :     {
     346              54 :         for( int iField = 0; iField < poFeatureDefn_->GetFieldCount(); iField++ )
     347                 :         {        
     348              36 :             OGRFieldDefn *poField = poFeatureDefn_->GetFieldDefn( iField );
     349                 : 
     350              36 :             if( poFeature->IsFieldSet( iField )
     351                 :                 && EQUAL(poField->GetNameRef(), poDS_->GetDescriptionField()) )
     352                 :             {           
     353               2 :                 const char *pszRaw = poFeature->GetFieldAsString( iField );
     354               4 :                 while( *pszRaw == ' ' )
     355               0 :                     pszRaw++;
     356                 : 
     357               2 :                 char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw );
     358                 : 
     359               2 :                 VSIFPrintfL( fp, "\t<description>%s</description>\n", pszEscaped);
     360               2 :                 CPLFree( pszEscaped );
     361                 :             }
     362                 :         }
     363                 :     }
     364                 : 
     365              18 :     OGRwkbGeometryType eGeomType = wkbNone;
     366              18 :     if (poFeature->GetGeometryRef() != NULL)
     367              18 :         eGeomType = wkbFlatten(poFeature->GetGeometryRef()->getGeometryType());
     368              18 :     if ( wkbPolygon == eGeomType
     369                 :          || wkbMultiPolygon == eGeomType
     370                 :          || wkbLineString == eGeomType
     371                 :          || wkbMultiLineString == eGeomType )
     372                 :     {
     373               8 :         OGRStylePen *poPen = NULL;
     374               8 :         OGRStyleMgr oSM;
     375                 : 
     376               8 :         if( poFeature->GetStyleString() != NULL )
     377                 :         {
     378               0 :             oSM.InitFromFeature( poFeature );
     379                 : 
     380                 :             int i;
     381               0 :             for(i=0; i<oSM.GetPartCount();i++)
     382                 :             {
     383               0 :                 OGRStyleTool *poTool = oSM.GetPart(i);
     384               0 :                 if (poTool && poTool->GetType() == OGRSTCPen )
     385                 :                 {
     386               0 :                     poPen = (OGRStylePen*) poTool;
     387               0 :                     break;
     388                 :                 }
     389               0 :                 delete poTool;
     390                 :             }
     391                 :         }
     392                 : 
     393               8 :         VSIFPrintfL( fp, "\t<Style>");
     394               8 :         if( poPen != NULL )
     395                 :         {
     396                 :             GBool  bDefault;
     397               0 :             int    bHasWidth = FALSE;
     398                 : 
     399                 :             /* Require width to be returned in pixel */
     400               0 :             poPen->SetUnit(OGRSTUPixel);
     401               0 :             double fW = poPen->Width(bDefault);
     402               0 :             if( bDefault )
     403               0 :                 fW = 1;
     404                 :             else
     405               0 :                 bHasWidth = TRUE;
     406               0 :             const char* pszColor = poPen->Color(bDefault);
     407               0 :             int nColorLen = CPLStrnlen(pszColor, 10);
     408               0 :             if( pszColor != NULL && pszColor[0] == '#' && !bDefault && nColorLen >= 7)
     409                 :             {
     410               0 :                 char acColor[9] = {0};
     411                 :                 /* Order of KML color is aabbggrr, whereas OGR color is #rrggbb[aa] ! */
     412               0 :                 if(nColorLen == 9)
     413                 :                 {
     414               0 :                     acColor[0] = pszColor[7]; /* A */
     415               0 :                     acColor[1] = pszColor[8];
     416                 :                 }
     417                 :                 else
     418                 :                 {
     419               0 :                     acColor[0] = 'F';
     420               0 :                     acColor[1] = 'F';
     421                 :                 }
     422               0 :                 acColor[2] = pszColor[5]; /* B */
     423               0 :                 acColor[3] = pszColor[6];
     424               0 :                 acColor[4] = pszColor[3]; /* G */
     425               0 :                 acColor[5] = pszColor[4];
     426               0 :                 acColor[6] = pszColor[1]; /* R */
     427               0 :                 acColor[7] = pszColor[2];
     428               0 :                 VSIFPrintfL( fp, "<LineStyle><color>%s</color>", acColor);
     429               0 :                 if (bHasWidth)
     430               0 :                     VSIFPrintfL( fp, "<width>%g</width>", fW);
     431               0 :                 VSIFPrintfL( fp, "</LineStyle>");
     432                 :             }
     433                 :             else
     434               0 :                 VSIFPrintfL( fp, "<LineStyle><color>ff0000ff</color></LineStyle>");
     435                 :         }
     436                 :         else
     437               8 :             VSIFPrintfL( fp, "<LineStyle><color>ff0000ff</color></LineStyle>");
     438               8 :         delete poPen;
     439                 :         //If we're dealing with a polygon, add a line style that will stand out a bit
     440               8 :         VSIFPrintfL( fp, "<PolyStyle><fill>0</fill></PolyStyle></Style>\n" );
     441                 :     }
     442                 : 
     443              18 :     int bHasFoundOtherField = FALSE;
     444                 : 
     445                 :     // Write all fields as SchemaData
     446              54 :     for( int iField = 0; iField < poFeatureDefn_->GetFieldCount(); iField++ )
     447                 :     {
     448              36 :         OGRFieldDefn *poField = poFeatureDefn_->GetFieldDefn( iField );
     449                 : 
     450              36 :         if( poFeature->IsFieldSet( iField ))
     451                 :         {
     452               4 :             if (!bHasFoundOtherField)
     453                 :             {                
     454               2 :                 VSIFPrintfL( fp, "\t<ExtendedData><SchemaData schemaUrl=\"#%s\">\n", pszName_ );
     455               2 :                 bHasFoundOtherField = TRUE;
     456                 :             }
     457               4 :             const char *pszRaw = poFeature->GetFieldAsString( iField );
     458                 : 
     459               8 :             while( *pszRaw == ' ' )
     460               0 :                 pszRaw++;
     461                 : 
     462               4 :             char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw );
     463                 : 
     464                 :             VSIFPrintfL( fp, "\t\t<SimpleData name=\"%s\">%s</SimpleData>\n", 
     465               4 :                         poField->GetNameRef(), pszEscaped);
     466                 : 
     467               4 :             CPLFree( pszEscaped );
     468                 :         }
     469                 :     }
     470                 : 
     471              18 :     if (bHasFoundOtherField)
     472                 :     {
     473               2 :         VSIFPrintfL( fp, "\t</SchemaData></ExtendedData>\n" );
     474                 :     }
     475                 : 
     476                 :     // Write out Geometry - for now it isn't indented properly.
     477              18 :     if( poFeature->GetGeometryRef() != NULL )
     478                 :     {
     479              18 :         char* pszGeometry = NULL;
     480              18 :         OGREnvelope sGeomBounds;
     481                 :         OGRGeometry* poWGS84Geom; 
     482                 : 
     483              18 :         if (NULL != poCT_)
     484                 :         {
     485               2 :             poWGS84Geom = poFeature->GetGeometryRef()->clone();
     486               2 :             poWGS84Geom->transform( poCT_ );
     487                 :         }
     488                 :         else
     489                 :         {
     490              16 :             poWGS84Geom = poFeature->GetGeometryRef();
     491                 :         }
     492                 :   
     493                 :         // TODO - porting
     494                 :         // pszGeometry = poFeature->GetGeometryRef()->exportToKML();
     495                 :         pszGeometry = 
     496                 :             OGR_G_ExportToKML( (OGRGeometryH)poWGS84Geom,
     497              18 :                                poDS_->GetAltitudeMode());
     498                 :         
     499              18 :         VSIFPrintfL( fp, "      %s\n", pszGeometry );
     500              18 :         CPLFree( pszGeometry );
     501                 : 
     502              18 :         poWGS84Geom->getEnvelope( &sGeomBounds );
     503              18 :         poDS_->GrowExtents( &sGeomBounds );
     504                 : 
     505              18 :         if (NULL != poCT_)
     506                 :         {
     507               2 :             delete poWGS84Geom;
     508                 :         }
     509                 :     }
     510                 :     
     511              18 :     VSIFPrintfL( fp, "  </Placemark>\n" );
     512              18 :     nWroteFeatureCount_++;
     513              18 :     return OGRERR_NONE;
     514                 : }
     515                 : 
     516                 : /************************************************************************/
     517                 : /*                           TestCapability()                           */
     518                 : /************************************************************************/
     519                 : 
     520              72 : int OGRKMLLayer::TestCapability( const char * pszCap )
     521                 : {
     522              72 :     if( EQUAL(pszCap, OLCSequentialWrite) )
     523                 :     {
     524              12 :         return bWriter_;
     525                 :     }
     526              60 :     else if( EQUAL(pszCap, OLCCreateField) )
     527                 :     {
     528               0 :         return bWriter_ && iNextKMLId_ == 0;
     529                 :     }
     530              60 :     else if( EQUAL(pszCap,OLCFastFeatureCount) )
     531                 :     {
     532                 : //        if( poFClass == NULL 
     533                 : //            || m_poFilterGeom != NULL 
     534                 : //            || m_poAttrQuery != NULL )
     535               0 :             return FALSE;
     536                 : 
     537                 : //        return poFClass->GetFeatureCount() != -1;
     538                 :     }
     539                 : 
     540              60 :     else if (EQUAL(pszCap, OLCStringsAsUTF8))
     541              12 :         return TRUE;
     542                 : 
     543              48 :     return FALSE;
     544                 : }
     545                 : 
     546                 : /************************************************************************/
     547                 : /*                            CreateField()                             */
     548                 : /************************************************************************/
     549                 : 
     550               0 : OGRErr OGRKMLLayer::CreateField( OGRFieldDefn *poField, int bApproxOK )
     551                 : {
     552               0 :     if( !bWriter_ || iNextKMLId_ != 0 )
     553               0 :         return OGRERR_FAILURE;
     554                 :       
     555               0 :   OGRFieldDefn oCleanCopy( poField );
     556               0 :     poFeatureDefn_->AddFieldDefn( &oCleanCopy );
     557                 : 
     558               0 :     return OGRERR_NONE;
     559                 : }
     560                 : 
     561                 : /************************************************************************/
     562                 : /*                           GetSpatialRef()                            */
     563                 : /************************************************************************/
     564                 : 
     565              12 : OGRSpatialReference *OGRKMLLayer::GetSpatialRef()
     566                 : {
     567              12 :     return poSRS_;
     568                 : }
     569                 : 
     570                 : /************************************************************************/
     571                 : /*                           SetLayerNumber()                           */
     572                 : /************************************************************************/
     573                 : 
     574              50 : void OGRKMLLayer::SetLayerNumber( int nLayer )
     575                 : {
     576              50 :     nLayerNumber_ = nLayer;
     577            4079 : }
     578                 : 

Generated by: LCOV version 1.7