LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/libkml - ogrlibkmlfield.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 490
Code covered: 37.8 % Executed lines: 185

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Project:  KML Translator
       4                 :  * Purpose:  Implements OGRLIBKMLDriver
       5                 :  * Author:   Brian Case, rush at winkey dot org
       6                 :  *
       7                 :  ******************************************************************************
       8                 :  * Copyright (c) 2010, Brian Case
       9                 :  *
      10                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      11                 :  * copy of this software and associated documentation files (the "Software"),
      12                 :  * to deal in the Software without restriction, including without limitation
      13                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14                 :  * and/or sell copies of the Software, and to permit persons to whom the
      15                 :  * Software is furnished to do so, subject to the following conditions:
      16                 :  *
      17                 :  * The above copyright notice and this permission notice shall be included
      18                 :  * in all copies or substantial portions of the Software.
      19                 :  *
      20                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26                 :  * DEALINGS IN THE SOFTWARE.
      27                 :  *****************************************************************************/
      28                 : 
      29                 : #include  <ogrsf_frmts.h>
      30                 : #include <ogr_feature.h>
      31                 : #include "ogr_p.h"
      32                 : 
      33                 : #include <kml/dom.h>
      34                 : #include <iostream>
      35                 : 
      36                 : using kmldom::ExtendedDataPtr;
      37                 : using kmldom::SchemaPtr;
      38                 : using kmldom::SchemaDataPtr;
      39                 : using kmldom::SimpleDataPtr;
      40                 : 
      41                 : using kmldom::TimeStampPtr;
      42                 : using kmldom::TimeSpanPtr;
      43                 : using kmldom::TimePrimitivePtr;
      44                 : 
      45                 : using kmldom::PointPtr;
      46                 : using kmldom::LineStringPtr;
      47                 : using kmldom::PolygonPtr;
      48                 : using kmldom::MultiGeometryPtr;
      49                 : using kmldom::GeometryPtr;
      50                 : 
      51                 : 
      52                 : #include "ogr_libkml.h"
      53                 : 
      54                 : #include "ogrlibkmlfield.h"
      55                 : 
      56                 : void ogr2altitudemode_rec (
      57                 :     GeometryPtr poKmlGeometry,
      58                 :     int iAltitudeMode,
      59               0 :     int isGX )
      60                 : {
      61                 : 
      62               0 :     PointPtr poKmlPoint;
      63               0 :     LineStringPtr poKmlLineString;
      64               0 :     PolygonPtr poKmlPolygon;
      65               0 :     MultiGeometryPtr poKmlMultiGeometry;
      66                 : 
      67                 :     size_t nGeom;
      68                 :     size_t i;
      69                 : 
      70               0 :     switch ( poKmlGeometry->Type (  ) ) {
      71                 : 
      72                 :     case kmldom::Type_Point:
      73               0 :         poKmlPoint = AsPoint ( poKmlGeometry );
      74                 : 
      75               0 :         if ( !isGX )
      76               0 :             poKmlPoint->set_altitudemode ( iAltitudeMode );
      77                 :         else
      78               0 :             poKmlPoint->set_gx_altitudemode ( iAltitudeMode );
      79                 : 
      80               0 :         break;
      81                 : 
      82                 :     case kmldom::Type_LineString:
      83               0 :         poKmlLineString = AsLineString ( poKmlGeometry );
      84                 : 
      85               0 :         if ( !isGX )
      86               0 :             poKmlLineString->set_altitudemode ( iAltitudeMode );
      87                 :         else
      88               0 :             poKmlLineString->set_gx_altitudemode ( iAltitudeMode );
      89                 : 
      90               0 :         break;
      91                 : 
      92                 :     case kmldom::Type_LinearRing:
      93               0 :         break;
      94                 : 
      95                 :     case kmldom::Type_Polygon:
      96               0 :         poKmlPolygon = AsPolygon ( poKmlGeometry );
      97                 : 
      98               0 :         if ( !isGX )
      99               0 :             poKmlPolygon->set_altitudemode ( iAltitudeMode );
     100                 :         else
     101               0 :             poKmlPolygon->set_gx_altitudemode ( iAltitudeMode );
     102                 : 
     103               0 :         break;
     104                 : 
     105                 :     case kmldom::Type_MultiGeometry:
     106               0 :         poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );
     107                 : 
     108               0 :         nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
     109               0 :         for ( i = 0; i < nGeom; i++ ) {
     110                 :             ogr2altitudemode_rec ( poKmlMultiGeometry->
     111                 :                                    get_geometry_array_at ( i ), iAltitudeMode,
     112               0 :                                    isGX );
     113                 :         }
     114                 : 
     115                 :         break;
     116                 : 
     117                 :     default:
     118                 :         break;
     119                 : 
     120               0 :     }
     121                 : 
     122               0 : }
     123                 : 
     124                 : void ogr2extrude_rec (
     125                 :     int nExtrude,
     126               0 :     GeometryPtr poKmlGeometry )
     127                 : {
     128                 : 
     129               0 :     PointPtr poKmlPoint;
     130               0 :     LineStringPtr poKmlLineString;
     131               0 :     PolygonPtr poKmlPolygon;
     132               0 :     MultiGeometryPtr poKmlMultiGeometry;
     133                 : 
     134                 :     size_t nGeom;
     135                 :     size_t i;
     136                 : 
     137               0 :     switch ( poKmlGeometry->Type (  ) ) {
     138                 :     case kmldom::Type_Point:
     139               0 :         poKmlPoint = AsPoint ( poKmlGeometry );
     140               0 :         poKmlPoint->set_extrude ( nExtrude );
     141               0 :         break;
     142                 : 
     143                 :     case kmldom::Type_LineString:
     144               0 :         poKmlLineString = AsLineString ( poKmlGeometry );
     145               0 :         poKmlLineString->set_extrude ( nExtrude );
     146               0 :         break;
     147                 : 
     148                 :     case kmldom::Type_LinearRing:
     149               0 :         break;
     150                 : 
     151                 :     case kmldom::Type_Polygon:
     152               0 :         poKmlPolygon = AsPolygon ( poKmlGeometry );
     153               0 :         poKmlPolygon->set_extrude ( nExtrude );
     154               0 :         break;
     155                 : 
     156                 :     case kmldom::Type_MultiGeometry:
     157               0 :         poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );
     158                 : 
     159               0 :         nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
     160               0 :         for ( i = 0; i < nGeom; i++ ) {
     161                 :             ogr2extrude_rec ( nExtrude,
     162                 :                               poKmlMultiGeometry->
     163               0 :                               get_geometry_array_at ( i ) );
     164                 :         }
     165                 :         break;
     166                 : 
     167                 :     default:
     168                 :         break;
     169                 : 
     170               0 :     }
     171               0 : }
     172                 : 
     173                 : void ogr2tessellate_rec (
     174                 :     int nTessellate,
     175               0 :     GeometryPtr poKmlGeometry )
     176                 : {
     177                 : 
     178               0 :     LineStringPtr poKmlLineString;
     179               0 :     PolygonPtr poKmlPolygon;
     180               0 :     MultiGeometryPtr poKmlMultiGeometry;
     181                 : 
     182                 :     size_t nGeom;
     183                 :     size_t i;
     184                 : 
     185               0 :     switch ( poKmlGeometry->Type (  ) ) {
     186                 : 
     187                 :     case kmldom::Type_Point:
     188               0 :         break;
     189                 : 
     190                 :     case kmldom::Type_LineString:
     191               0 :         poKmlLineString = AsLineString ( poKmlGeometry );
     192               0 :         poKmlLineString->set_tessellate ( nTessellate );
     193               0 :         break;
     194                 : 
     195                 :     case kmldom::Type_LinearRing:
     196               0 :         break;
     197                 : 
     198                 :     case kmldom::Type_Polygon:
     199               0 :         poKmlPolygon = AsPolygon ( poKmlGeometry );
     200                 : 
     201               0 :         poKmlPolygon->set_tessellate ( nTessellate );
     202               0 :         break;
     203                 : 
     204                 :     case kmldom::Type_MultiGeometry:
     205               0 :         poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );
     206                 : 
     207               0 :         nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
     208               0 :         for ( i = 0; i < nGeom; i++ ) {
     209                 :             ogr2tessellate_rec ( nTessellate,
     210                 :                                  poKmlMultiGeometry->
     211               0 :                                  get_geometry_array_at ( i ) );
     212                 :         }
     213                 : 
     214                 :         break;
     215                 : 
     216                 :     default:
     217                 :         break;
     218                 : 
     219               0 :     }
     220               0 : }
     221                 : 
     222                 : /******************************************************************************
     223                 :  function to output ogr fields in kml
     224                 : 
     225                 :  args:
     226                 :         poOgrFeat       pointer to the feature the field is in
     227                 :         poOgrLayer      pointer to the layer the feature is in
     228                 :         poKmlFactory    pointer to the libkml dom factory
     229                 :         poKmlPlacemark  pointer to the placemark to add to
     230                 :  
     231                 :  returns:
     232                 :         nothing
     233                 : 
     234                 :  env vars:
     235                 :   LIBKML_TIMESTAMP_FIELD         default: OFTDate or OFTDateTime named timestamp
     236                 :   LIBKML_TIMESPAN_BEGIN_FIELD    default: OFTDate or OFTDateTime named begin
     237                 :   LIBKML_TIMESPAN_END_FIELD      default: OFTDate or OFTDateTime named end
     238                 :   LIBKML_DESCRIPTION_FIELD       default: none
     239                 :   LIBKML_NAME_FIELD              default: OFTString field named name
     240                 : 
     241                 : 
     242                 : ******************************************************************************/
     243                 : 
     244                 : 
     245                 : 
     246                 : void field2kml (
     247                 :     OGRFeature * poOgrFeat,
     248                 :     OGRLIBKMLLayer * poOgrLayer,
     249                 :     KmlFactory * poKmlFactory,
     250               9 :     PlacemarkPtr poKmlPlacemark )
     251                 : {
     252                 :     int i;
     253                 : 
     254               9 :     SchemaDataPtr poKmlSchemaData = poKmlFactory->CreateSchemaData (  );
     255               9 :     SchemaPtr poKmlSchema = poOgrLayer->GetKmlSchema (  );
     256                 : 
     257                 :     /***** set the url to the schema *****/
     258                 : 
     259               9 :     if ( poKmlSchema && poKmlSchema->has_id (  ) ) {
     260               9 :         std::string oKmlSchemaID = poKmlSchema->get_id (  );
     261                 : 
     262                 : 
     263               9 :         std::string oKmlSchemaURL = "#";
     264               9 :         oKmlSchemaURL.append ( oKmlSchemaID );
     265                 : 
     266               9 :         poKmlSchemaData->set_schemaurl ( oKmlSchemaURL );
     267                 :     }
     268                 : 
     269               9 :     const char *namefield = CPLGetConfigOption ( "LIBKML_NAME_FIELD", "Name" );
     270                 :     const char *descfield =
     271               9 :         CPLGetConfigOption ( "LIBKML_DESCRIPTION_FIELD", "description" );
     272                 :     const char *tsfield =
     273               9 :         CPLGetConfigOption ( "LIBKML_TIMESTAMP_FIELD", "timestamp" );
     274                 :     const char *beginfield =
     275               9 :         CPLGetConfigOption ( "LIBKML_BEGIN_FIELD", "begin" );
     276               9 :     const char *endfield = CPLGetConfigOption ( "LIBKML_END_FIELD", "end" );
     277                 :     const char *altitudeModefield =
     278               9 :         CPLGetConfigOption ( "LIBKML_ALTITUDEMODE_FIELD", "altitudeMode" );
     279                 :     const char *tessellatefield =
     280               9 :         CPLGetConfigOption ( "LIBKML_TESSELLATE_FIELD", "tessellate" );
     281                 :     const char *extrudefield =
     282               9 :         CPLGetConfigOption ( "LIBKML_EXTRUDE_FIELD", "extrude" );
     283                 :     const char *visibilityfield =
     284               9 :         CPLGetConfigOption ( "LIBKML_VISIBILITY_FIELD", "visibility" );
     285                 : 
     286               9 :     TimeSpanPtr poKmlTimeSpan = NULL;
     287                 : 
     288               9 :     int nFields = poOgrFeat->GetFieldCount (  );
     289               9 :     int iSkip1 = -1;
     290               9 :     int iSkip2 = -1;
     291                 : 
     292              25 :     for ( i = 0; i < nFields; i++ ) {
     293                 : 
     294                 :         /***** if the field is set to skip, do so *****/
     295                 : 
     296              16 :         if ( i == iSkip1 || i == iSkip2 )
     297               0 :             continue;
     298                 : 
     299                 :         /***** if the field isn't set just bail now *****/
     300                 : 
     301              16 :         if ( !poOgrFeat->IsFieldSet ( i ) )
     302              14 :             continue;
     303                 : 
     304               2 :         OGRFieldDefn *poOgrFieldDef = poOgrFeat->GetFieldDefnRef ( i );
     305               2 :         OGRFieldType type = poOgrFieldDef->GetType (  );
     306               2 :         const char *name = poOgrFieldDef->GetNameRef (  );
     307                 : 
     308               2 :         SimpleDataPtr poKmlSimpleData = NULL;
     309                 :         int year,
     310                 :             month,
     311                 :             day,
     312                 :             hour,
     313                 :             min,
     314                 :             sec,
     315                 :             tz;
     316                 : 
     317               2 :         switch ( type ) {
     318                 : 
     319                 :         case OFTString:        //     String of ASCII chars
     320                 :             {
     321                 : 
     322                 :                 /***** name *****/
     323                 : 
     324               2 :                 if ( EQUAL ( name, namefield ) ) {
     325                 :                     poKmlPlacemark->set_name ( poOgrFeat->
     326               1 :                                                GetFieldAsString ( i ) );
     327               2 :                     continue;
     328                 :                 }
     329                 : 
     330                 :                 /***** description *****/
     331                 : 
     332               1 :                 else if ( EQUAL ( name, descfield ) ) {
     333                 :                     poKmlPlacemark->set_description ( poOgrFeat->
     334               1 :                                                       GetFieldAsString ( i ) );
     335                 :                     continue;
     336                 :                 }
     337                 : 
     338                 :                 /***** altitudemode *****/
     339                 : 
     340               0 :                 else if ( EQUAL ( name, altitudeModefield ) ) {
     341                 :                     const char *pszAltitudeMode =
     342               0 :                         poOgrFeat->GetFieldAsString ( i );
     343                 : 
     344               0 :                     int isGX = FALSE;
     345               0 :                     int iAltitudeMode = kmldom::ALTITUDEMODE_CLAMPTOGROUND;
     346                 : 
     347               0 :                     if ( EQUAL ( pszAltitudeMode, "clampToGround" ) )
     348               0 :                         iAltitudeMode = kmldom::ALTITUDEMODE_CLAMPTOGROUND;
     349                 : 
     350               0 :                     else if ( EQUAL ( pszAltitudeMode, "relativeToGround" ) )
     351               0 :                         iAltitudeMode = kmldom::ALTITUDEMODE_RELATIVETOGROUND;
     352                 : 
     353               0 :                     else if ( EQUAL ( pszAltitudeMode, "absolute" ) )
     354               0 :                         iAltitudeMode = kmldom::ALTITUDEMODE_ABSOLUTE;
     355                 : 
     356               0 :                     else if ( EQUAL ( pszAltitudeMode, "relativeToSeaFloor" ) ) {
     357                 :                         iAltitudeMode =
     358               0 :                             kmldom::GX_ALTITUDEMODE_RELATIVETOSEAFLOOR;
     359               0 :                         isGX = TRUE;
     360                 :                     }
     361                 : 
     362               0 :                     else if ( EQUAL ( pszAltitudeMode, "clampToSeaFloor" ) ) {
     363                 :                         iAltitudeMode =
     364               0 :                             kmldom::GX_ALTITUDEMODE_CLAMPTOSEAFLOOR;
     365               0 :                         isGX = TRUE;
     366                 :                     }
     367                 : 
     368                 : 
     369               0 :                     if ( poKmlPlacemark->has_geometry (  ) ) {
     370                 :                         GeometryPtr poKmlGeometry =
     371               0 :                             poKmlPlacemark->get_geometry (  );
     372                 : 
     373                 :                         ogr2altitudemode_rec ( poKmlGeometry, iAltitudeMode,
     374               0 :                                                isGX );
     375                 : 
     376                 :                     }
     377                 : 
     378                 :                     continue;
     379                 :                 }
     380                 :                 
     381                 :                 /***** timestamp *****/
     382                 : 
     383               0 :                 else if ( EQUAL ( name, tsfield ) ) {
     384                 : 
     385                 :                     TimeStampPtr poKmlTimeStamp =
     386               0 :                         poKmlFactory->CreateTimeStamp (  );
     387               0 :                     poKmlTimeStamp->set_when ( poOgrFeat->GetFieldAsString ( i )  );
     388               0 :                     poKmlPlacemark->set_timeprimitive ( poKmlTimeStamp );
     389                 : 
     390               0 :                     continue;
     391                 :                 }
     392                 : 
     393                 :                 /***** begin *****/
     394                 : 
     395               0 :                 if ( EQUAL ( name, beginfield ) ) {
     396                 : 
     397               0 :                     if ( !poKmlTimeSpan ) {
     398               0 :                         poKmlTimeSpan = poKmlFactory->CreateTimeSpan (  );
     399               0 :                         poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan );
     400                 :                     }
     401                 : 
     402               0 :                     poKmlTimeSpan->set_begin ( poOgrFeat->GetFieldAsString ( i ) );
     403                 : 
     404                 :                     continue;
     405                 : 
     406                 :                 }
     407                 : 
     408                 :                 /***** end *****/
     409                 : 
     410               0 :                 else if ( EQUAL ( name, endfield ) ) {
     411                 : 
     412               0 :                     if ( !poKmlTimeSpan ) {
     413               0 :                         poKmlTimeSpan = poKmlFactory->CreateTimeSpan (  );
     414               0 :                         poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan );
     415                 :                     }
     416                 : 
     417               0 :                     poKmlTimeSpan->set_end ( poOgrFeat->GetFieldAsString ( i ) );
     418                 : 
     419                 :                     continue;
     420                 :                 }
     421                 :                 
     422                 :                 /***** other *****/
     423                 : 
     424               0 :                 poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
     425               0 :                 poKmlSimpleData->set_name ( name );
     426                 :                 poKmlSimpleData->set_text ( poOgrFeat->
     427               0 :                                             GetFieldAsString ( i ) );
     428                 : 
     429               0 :                 break;
     430                 :             }
     431                 : 
     432                 :         case OFTDate:          //   Date
     433                 :             {
     434                 :                 poOgrFeat->GetFieldAsDateTime ( i, &year, &month, &day,
     435               0 :                                                 &hour, &min, &sec, &tz );
     436                 : 
     437                 :                 int iTimeField;
     438                 : 
     439               0 :                 for ( iTimeField = i + 1; iTimeField < nFields; iTimeField++ ) {
     440               0 :                     if ( iTimeField == iSkip1 || iTimeField == iSkip2 )
     441               0 :                         continue;
     442                 : 
     443                 :                     OGRFieldDefn *poOgrFieldDef2 =
     444               0 :                         poOgrFeat->GetFieldDefnRef ( i );
     445               0 :                     OGRFieldType type2 = poOgrFieldDef2->GetType (  );
     446               0 :                     const char *name2 = poOgrFieldDef2->GetNameRef (  );
     447                 : 
     448               0 :                     if ( EQUAL ( name2, name ) && type2 == OFTTime &&
     449                 :                          ( EQUAL ( name, tsfield ) ||
     450                 :                            EQUAL ( name, beginfield ) ||
     451                 :                            EQUAL ( name, endfield ) ) ) {
     452                 : 
     453                 :                         int year2,
     454                 :                             month2,
     455                 :                             day2,
     456                 :                             hour2,
     457                 :                             min2,
     458                 :                             sec2,
     459                 :                             tz2;
     460                 : 
     461                 :                         poOgrFeat->GetFieldAsDateTime ( iTimeField, &year2,
     462                 :                                                         &month2, &day2, &hour2,
     463               0 :                                                         &min2, &sec2, &tz2 );
     464                 : 
     465               0 :                         hour = hour2;
     466               0 :                         min = min2;
     467               0 :                         sec = sec2;
     468               0 :                         tz = tz2;
     469                 : 
     470               0 :                         if ( 0 > iSkip1 )
     471               0 :                             iSkip1 = iTimeField;
     472                 :                         else
     473               0 :                             iSkip2 = iTimeField;
     474                 :                     }
     475                 :                 }
     476                 : 
     477               0 :                 goto Do_DateTime;
     478                 : 
     479                 :             }
     480                 : 
     481                 : 
     482                 :         case OFTTime:          //   Time
     483                 :             {
     484                 :                 poOgrFeat->GetFieldAsDateTime ( i, &year, &month, &day,
     485               0 :                                                 &hour, &min, &sec, &tz );
     486                 : 
     487                 :                 int iTimeField;
     488                 : 
     489               0 :                 for ( iTimeField = i + 1; iTimeField < nFields; iTimeField++ ) {
     490               0 :                     if ( iTimeField == iSkip1 || iTimeField == iSkip2 )
     491               0 :                         continue;
     492                 : 
     493                 :                     OGRFieldDefn *poOgrFieldDef2 =
     494               0 :                         poOgrFeat->GetFieldDefnRef ( i );
     495               0 :                     OGRFieldType type2 = poOgrFieldDef2->GetType (  );
     496               0 :                     const char *name2 = poOgrFieldDef2->GetNameRef (  );
     497                 : 
     498               0 :                     if ( EQUAL ( name2, name ) && type2 == OFTTime &&
     499                 :                          ( EQUAL ( name, tsfield ) ||
     500                 :                            EQUAL ( name, beginfield ) ||
     501                 :                            EQUAL ( name, endfield ) ) ) {
     502                 : 
     503                 :                         int year2,
     504                 :                             month2,
     505                 :                             day2,
     506                 :                             hour2,
     507                 :                             min2,
     508                 :                             sec2,
     509                 :                             tz2;
     510                 : 
     511                 :                         poOgrFeat->GetFieldAsDateTime ( iTimeField, &year2,
     512                 :                                                         &month2, &day2, &hour2,
     513               0 :                                                         &min2, &sec2, &tz2 );
     514                 : 
     515               0 :                         year = year2;
     516               0 :                         month = month2;
     517               0 :                         day = day2;
     518                 : 
     519               0 :                         if ( 0 > iSkip1 )
     520               0 :                             iSkip1 = iTimeField;
     521                 :                         else
     522               0 :                             iSkip2 = iTimeField;
     523                 :                     }
     524                 :                 }
     525                 : 
     526               0 :                 goto Do_DateTime;
     527                 : 
     528                 :             }
     529                 : 
     530                 :         case OFTDateTime:      //  Date and Time
     531                 :             {
     532                 :                 poOgrFeat->GetFieldAsDateTime ( i, &year, &month, &day,
     533               0 :                                                 &hour, &min, &sec, &tz );
     534                 : 
     535               0 :               Do_DateTime:
     536                 :                 /***** timestamp *****/
     537                 : 
     538               0 :                 if ( EQUAL ( name, tsfield ) ) {
     539                 : 
     540                 :                     char *timebuf = OGRGetXMLDateTime ( year, month, day, hour,
     541               0 :                                                         min, sec, tz );
     542                 : 
     543                 :                     TimeStampPtr poKmlTimeStamp =
     544               0 :                         poKmlFactory->CreateTimeStamp (  );
     545               0 :                     poKmlTimeStamp->set_when ( timebuf );
     546               0 :                     poKmlPlacemark->set_timeprimitive ( poKmlTimeStamp );
     547               0 :                     CPLFree( timebuf );
     548                 : 
     549               0 :                     continue;
     550                 :                 }
     551                 : 
     552                 :                 /***** begin *****/
     553                 : 
     554               0 :                 if ( EQUAL ( name, beginfield ) ) {
     555                 : 
     556                 :                     char *timebuf = OGRGetXMLDateTime ( year, month, day, hour,
     557               0 :                                                         min, sec, tz );
     558                 : 
     559               0 :                     if ( !poKmlTimeSpan ) {
     560               0 :                         poKmlTimeSpan = poKmlFactory->CreateTimeSpan (  );
     561               0 :                         poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan );
     562                 :                     }
     563                 : 
     564               0 :                     poKmlTimeSpan->set_begin ( timebuf );
     565               0 :                     CPLFree( timebuf );
     566                 : 
     567                 :                     continue;
     568                 : 
     569                 :                 }
     570                 : 
     571                 :                 /***** end *****/
     572                 : 
     573               0 :                 else if ( EQUAL ( name, endfield ) ) {
     574                 : 
     575                 :                     char *timebuf = OGRGetXMLDateTime ( year, month, day, hour,
     576               0 :                                                         min, sec, tz );
     577                 : 
     578                 : 
     579               0 :                     if ( !poKmlTimeSpan ) {
     580               0 :                         poKmlTimeSpan = poKmlFactory->CreateTimeSpan (  );
     581               0 :                         poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan );
     582                 :                     }
     583                 : 
     584               0 :                     poKmlTimeSpan->set_end ( timebuf );
     585               0 :                     CPLFree( timebuf );
     586                 : 
     587                 :                     continue;
     588                 :                 }
     589                 : 
     590                 :                 /***** other *****/
     591                 : 
     592               0 :                 poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
     593               0 :                 poKmlSimpleData->set_name ( name );
     594                 :                 poKmlSimpleData->set_text ( poOgrFeat->
     595               0 :                                             GetFieldAsString ( i ) );
     596                 : 
     597               0 :                 break;
     598                 :             }
     599                 : 
     600                 :         case OFTStringList:    //     Array of strings
     601                 :         case OFTBinary:        //     Raw Binary data
     602                 : 
     603                 :             /***** other *****/
     604                 : 
     605               0 :             poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
     606               0 :             poKmlSimpleData->set_name ( name );
     607               0 :             poKmlSimpleData->set_text ( poOgrFeat->GetFieldAsString ( i ) );
     608                 : 
     609               0 :             break;
     610                 :         case OFTInteger:       //    Simple 32bit integer
     611                 : 
     612                 :             /***** extrude *****/
     613                 : 
     614               0 :             if ( EQUAL ( name, extrudefield ) ) {
     615                 : 
     616               0 :                 if ( poKmlPlacemark->has_geometry (  )
     617                 :                      && -1 < poOgrFeat->GetFieldAsInteger ( i ) ) {
     618                 :                     GeometryPtr poKmlGeometry =
     619               0 :                         poKmlPlacemark->get_geometry (  );
     620                 :                     ogr2extrude_rec ( poOgrFeat->GetFieldAsInteger ( i ),
     621               0 :                                       poKmlGeometry );
     622                 :                 }
     623                 :                 continue;
     624                 :             }
     625                 : 
     626                 :             /***** tessellate *****/
     627                 : 
     628                 : 
     629               0 :             if ( EQUAL ( name, tessellatefield ) ) {
     630                 : 
     631               0 :                 if ( poKmlPlacemark->has_geometry (  )
     632                 :                      && -1 < poOgrFeat->GetFieldAsInteger ( i ) ) {
     633                 :                     GeometryPtr poKmlGeometry =
     634               0 :                         poKmlPlacemark->get_geometry (  );
     635                 :                     ogr2tessellate_rec ( poOgrFeat->GetFieldAsInteger ( i ),
     636               0 :                                          poKmlGeometry );
     637                 :                 }
     638                 : 
     639                 :                 continue;
     640                 :             }
     641                 : 
     642                 : 
     643                 :             /***** visibility *****/
     644                 : 
     645               0 :             if ( EQUAL ( name, visibilityfield ) ) {
     646               0 :                 if ( -1 < poOgrFeat->GetFieldAsInteger ( i ) )
     647                 :                     poKmlPlacemark->set_visibility ( poOgrFeat->
     648               0 :                                                      GetFieldAsInteger ( i ) );
     649                 : 
     650                 :                 continue;
     651                 :             }
     652                 : 
     653                 :             /***** other *****/
     654                 : 
     655               0 :             poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
     656               0 :             poKmlSimpleData->set_name ( name );
     657               0 :             poKmlSimpleData->set_text ( poOgrFeat->GetFieldAsString ( i ) );
     658                 : 
     659               0 :             break;
     660                 :         case OFTIntegerList:   //    List of 32bit integers
     661                 :         case OFTReal:          //   Double Precision floating point
     662                 : 
     663                 :             /***** other *****/
     664                 : 
     665               0 :             poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
     666               0 :             poKmlSimpleData->set_name ( name );
     667               0 :             poKmlSimpleData->set_text ( poOgrFeat->GetFieldAsString ( i ) );
     668                 : 
     669               0 :             break;
     670                 :         case OFTRealList:      //   List of doubles
     671                 : 
     672                 :         case OFTWideStringList:    //     deprecated
     673                 :         default:
     674                 : 
     675                 :         /***** other *****/
     676                 : 
     677               0 :             poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
     678               0 :             poKmlSimpleData->set_name ( name );
     679               0 :             poKmlSimpleData->set_text ( poOgrFeat->GetFieldAsString ( i ) );
     680                 : 
     681                 :             break;
     682                 :         }
     683               0 :         poKmlSchemaData->add_simpledata ( poKmlSimpleData );
     684                 :     }
     685                 : 
     686                 :     /***** dont add it to the placemark unless there is data *****/
     687                 : 
     688               9 :     if ( poKmlSchemaData->get_simpledata_array_size (  ) > 0 ) {
     689                 :         ExtendedDataPtr poKmlExtendedData =
     690               0 :             poKmlFactory->CreateExtendedData (  );
     691               0 :         poKmlExtendedData->add_schemadata ( poKmlSchemaData );
     692               0 :         poKmlPlacemark->set_extendeddata ( poKmlExtendedData );
     693                 :     }
     694                 : 
     695               9 :     return;
     696                 : }
     697                 : 
     698                 : /******************************************************************************
     699                 :  recursive function to read altitude mode from the geometry
     700                 : ******************************************************************************/
     701                 : 
     702                 : int kml2altitudemode_rec (
     703                 :     GeometryPtr poKmlGeometry,
     704                 :     int *pnAltitudeMode,
     705              69 :     int *pbIsGX )
     706                 : {
     707                 : 
     708              69 :     PointPtr poKmlPoint;
     709              69 :     LineStringPtr poKmlLineString;
     710              69 :     PolygonPtr poKmlPolygon;
     711              69 :     MultiGeometryPtr poKmlMultiGeometry;
     712                 : 
     713                 :     size_t nGeom;
     714                 :     size_t i;
     715                 : 
     716              69 :     switch ( poKmlGeometry->Type (  ) ) {
     717                 : 
     718                 :     case kmldom::Type_Point:
     719              19 :         poKmlPoint = AsPoint ( poKmlGeometry );
     720                 : 
     721              19 :         if ( poKmlPoint->has_altitudemode (  ) ) {
     722               4 :             *pnAltitudeMode = poKmlPoint->get_altitudemode (  );
     723               4 :             return TRUE;
     724                 :         }
     725              15 :         else if ( poKmlPoint->has_gx_altitudemode (  ) ) {
     726               0 :             *pnAltitudeMode = poKmlPoint->get_gx_altitudemode (  );
     727               0 :             *pbIsGX = TRUE;
     728               0 :             return TRUE;
     729                 :         }
     730                 : 
     731              15 :         break;
     732                 : 
     733                 :     case kmldom::Type_LineString:
     734              15 :         poKmlLineString = AsLineString ( poKmlGeometry );
     735                 : 
     736              15 :         if ( poKmlLineString->has_altitudemode (  ) ) {
     737               2 :             *pnAltitudeMode = poKmlLineString->get_altitudemode (  );
     738               2 :             return TRUE;
     739                 :         }
     740              13 :         else if ( poKmlLineString->has_gx_altitudemode (  ) ) {
     741               0 :             *pnAltitudeMode = poKmlLineString->get_gx_altitudemode (  );
     742               0 :             *pbIsGX = TRUE;
     743               0 :             return TRUE;
     744                 :         }
     745              13 :         break;
     746                 : 
     747                 :     case kmldom::Type_LinearRing:
     748               3 :         break;
     749                 : 
     750                 :     case kmldom::Type_Polygon:
     751              21 :         poKmlPolygon = AsPolygon ( poKmlGeometry );
     752                 : 
     753              21 :         if ( poKmlPolygon->has_altitudemode (  ) ) {
     754               8 :             *pnAltitudeMode = poKmlPolygon->get_altitudemode (  );
     755               8 :             return TRUE;
     756                 :         }
     757              13 :         else if ( poKmlPolygon->has_gx_altitudemode (  ) ) {
     758               0 :             *pnAltitudeMode = poKmlPolygon->get_gx_altitudemode (  );
     759               0 :             *pbIsGX = TRUE;
     760               0 :             return TRUE;
     761                 :         }
     762                 : 
     763              13 :         break;
     764                 : 
     765                 :     case kmldom::Type_MultiGeometry:
     766              11 :         poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );
     767                 : 
     768              11 :         nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
     769              26 :         for ( i = 0; i < nGeom; i++ ) {
     770              15 :             if ( kml2altitudemode_rec ( poKmlMultiGeometry->
     771                 :                                         get_geometry_array_at ( i ),
     772                 :                                         pnAltitudeMode, pbIsGX ) )
     773               0 :                 return TRUE;
     774                 :         }
     775                 : 
     776                 :         break;
     777                 : 
     778                 :     default:
     779                 :         break;
     780                 : 
     781                 :     }
     782                 : 
     783              55 :     return FALSE;
     784                 : }
     785                 : 
     786                 : /******************************************************************************
     787                 :  recursive function to read extrude from the geometry
     788                 : ******************************************************************************/
     789                 : 
     790                 : int kml2extrude_rec (
     791                 :     GeometryPtr poKmlGeometry,
     792              69 :     int *pnExtrude )
     793                 : {
     794                 : 
     795              69 :     PointPtr poKmlPoint;
     796              69 :     LineStringPtr poKmlLineString;
     797              69 :     PolygonPtr poKmlPolygon;
     798              69 :     MultiGeometryPtr poKmlMultiGeometry;
     799                 : 
     800                 :     size_t nGeom;
     801                 :     size_t i;
     802                 : 
     803              69 :     switch ( poKmlGeometry->Type (  ) ) {
     804                 : 
     805                 :     case kmldom::Type_Point:
     806              19 :         poKmlPoint = AsPoint ( poKmlGeometry );
     807                 : 
     808              19 :         if ( poKmlPoint->has_extrude (  ) ) {
     809               2 :             *pnExtrude = poKmlPoint->get_extrude (  );
     810               2 :             return TRUE;
     811                 :         }
     812                 : 
     813              17 :         break;
     814                 : 
     815                 :     case kmldom::Type_LineString:
     816              15 :         poKmlLineString = AsLineString ( poKmlGeometry );
     817                 : 
     818              15 :         if ( poKmlLineString->has_extrude (  ) ) {
     819               0 :             *pnExtrude = poKmlLineString->get_extrude (  );
     820               0 :             return TRUE;
     821                 :         }
     822                 : 
     823              15 :         break;
     824                 : 
     825                 :     case kmldom::Type_LinearRing:
     826               3 :         break;
     827                 : 
     828                 :     case kmldom::Type_Polygon:
     829              21 :         poKmlPolygon = AsPolygon ( poKmlGeometry );
     830                 : 
     831              21 :         if ( poKmlPolygon->has_extrude (  ) ) {
     832               8 :             *pnExtrude = poKmlPolygon->get_extrude (  );
     833               8 :             return TRUE;
     834                 :         }
     835                 : 
     836              13 :         break;
     837                 : 
     838                 :     case kmldom::Type_MultiGeometry:
     839              11 :         poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );
     840                 : 
     841              11 :         nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
     842              26 :         for ( i = 0; i < nGeom; i++ ) {
     843              15 :             if ( kml2extrude_rec ( poKmlMultiGeometry->
     844                 :                                    get_geometry_array_at ( i ), pnExtrude ) )
     845               0 :                 return TRUE;
     846                 :         }
     847                 : 
     848                 :         break;
     849                 : 
     850                 :     default:
     851                 :         break;
     852                 : 
     853                 :     }
     854                 : 
     855              59 :     return FALSE;
     856                 : }
     857                 : 
     858                 : /******************************************************************************
     859                 :  recursive function to read tessellate from the geometry
     860                 : ******************************************************************************/
     861                 : 
     862                 : int kml2tessellate_rec (
     863                 :     GeometryPtr poKmlGeometry,
     864              69 :     int *pnTessellate )
     865                 : {
     866                 : 
     867              69 :     LineStringPtr poKmlLineString;
     868              69 :     PolygonPtr poKmlPolygon;
     869              69 :     MultiGeometryPtr poKmlMultiGeometry;
     870                 : 
     871                 :     size_t nGeom;
     872                 :     size_t i;
     873                 : 
     874              69 :     switch ( poKmlGeometry->Type (  ) ) {
     875                 : 
     876                 :     case kmldom::Type_Point:
     877              19 :         break;
     878                 : 
     879                 :     case kmldom::Type_LineString:
     880              15 :         poKmlLineString = AsLineString ( poKmlGeometry );
     881                 : 
     882              15 :         if ( poKmlLineString->has_tessellate (  ) ) {
     883               6 :             *pnTessellate = poKmlLineString->get_tessellate (  );
     884               6 :             return TRUE;
     885                 :         }
     886                 : 
     887               9 :         break;
     888                 : 
     889                 :     case kmldom::Type_LinearRing:
     890               3 :         break;
     891                 : 
     892                 :     case kmldom::Type_Polygon:
     893              21 :         poKmlPolygon = AsPolygon ( poKmlGeometry );
     894                 : 
     895              21 :         if ( poKmlPolygon->has_tessellate (  ) ) {
     896               0 :             *pnTessellate = poKmlPolygon->get_tessellate (  );
     897               0 :             return TRUE;
     898                 :         }
     899                 : 
     900              21 :         break;
     901                 : 
     902                 :     case kmldom::Type_MultiGeometry:
     903              11 :         poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry );
     904                 : 
     905              11 :         nGeom = poKmlMultiGeometry->get_geometry_array_size (  );
     906              26 :         for ( i = 0; i < nGeom; i++ ) {
     907              15 :             if ( kml2tessellate_rec ( poKmlMultiGeometry->
     908                 :                                       get_geometry_array_at ( i ),
     909                 :                                       pnTessellate ) )
     910               0 :                 return TRUE;
     911                 :         }
     912                 : 
     913                 :         break;
     914                 : 
     915                 :     default:
     916                 :         break;
     917                 : 
     918                 :     }
     919                 : 
     920              63 :     return FALSE;
     921                 : }
     922                 : 
     923                 : /******************************************************************************
     924                 :  function to read kml into ogr fields
     925                 : ******************************************************************************/
     926                 : 
     927                 : void kml2field (
     928                 :     OGRFeature * poOgrFeat,
     929              54 :     PlacemarkPtr poKmlPlacemark )
     930                 : {
     931                 : 
     932              54 :     const char *namefield = CPLGetConfigOption ( "LIBKML_NAME_FIELD", "Name" );
     933                 :     const char *descfield =
     934              54 :         CPLGetConfigOption ( "LIBKML_DESCRIPTION_FIELD", "description" );
     935                 :     const char *tsfield =
     936              54 :         CPLGetConfigOption ( "LIBKML_TIMESTAMP_FIELD", "timestamp" );
     937                 :     const char *beginfield =
     938              54 :         CPLGetConfigOption ( "LIBKML_BEGIN_FIELD", "begin" );
     939              54 :     const char *endfield = CPLGetConfigOption ( "LIBKML_END_FIELD", "end" );
     940                 :     const char *altitudeModefield =
     941              54 :         CPLGetConfigOption ( "LIBKML_ALTITUDEMODE_FIELD", "altitudeMode" );
     942                 :     const char *tessellatefield =
     943              54 :         CPLGetConfigOption ( "LIBKML_TESSELLATE_FIELD", "tessellate" );
     944                 :     const char *extrudefield =
     945              54 :         CPLGetConfigOption ( "LIBKML_EXTRUDE_FIELD", "extrude" );
     946                 :     const char *visibilityfield =
     947              54 :         CPLGetConfigOption ( "LIBKML_VISIBILITY_FIELD", "visibility" );
     948                 : 
     949                 :     /***** name *****/
     950                 : 
     951              54 :     if ( poKmlPlacemark->has_name (  ) ) {
     952              22 :         const std::string oKmlName = poKmlPlacemark->get_name (  );
     953              22 :         int iField = poOgrFeat->GetFieldIndex ( namefield );
     954                 : 
     955              22 :         if ( iField > -1 )
     956              22 :             poOgrFeat->SetField ( iField, oKmlName.c_str (  ) );
     957                 :     }
     958                 : 
     959                 :     /***** description *****/
     960                 : 
     961              54 :     if ( poKmlPlacemark->has_description (  ) ) {
     962              13 :         const std::string oKmlDesc = poKmlPlacemark->get_description (  );
     963              13 :         int iField = poOgrFeat->GetFieldIndex ( descfield );
     964                 : 
     965              13 :         if ( iField > -1 )
     966              13 :             poOgrFeat->SetField ( iField, oKmlDesc.c_str (  ) );
     967                 :     }
     968                 : 
     969              54 :     if ( poKmlPlacemark->has_timeprimitive (  ) ) {
     970                 :         TimePrimitivePtr poKmlTimePrimitive =
     971               0 :             poKmlPlacemark->get_timeprimitive (  );
     972                 : 
     973                 :         /***** timestamp *****/
     974                 : 
     975               0 :         if ( poKmlTimePrimitive->IsA ( kmldom::Type_TimeStamp ) ) {
     976               0 :             TimeStampPtr poKmlTimeStamp = AsTimeStamp ( poKmlTimePrimitive );
     977                 : 
     978               0 :             if ( poKmlTimeStamp->has_when (  ) ) {
     979               0 :                 const std::string oKmlWhen = poKmlTimeStamp->get_when (  );
     980                 : 
     981                 : 
     982               0 :                 int iField = poOgrFeat->GetFieldIndex ( tsfield );
     983                 : 
     984               0 :                 if ( iField > -1 ) {
     985                 :                     int nYear,
     986                 :                         nMonth,
     987                 :                         nDay,
     988                 :                         nHour,
     989                 :                         nMinute,
     990                 :                         nTZ;
     991                 :                     float fSecond;
     992                 : 
     993               0 :                     if ( OGRParseXMLDateTime
     994                 :                          ( oKmlWhen.c_str (  ), &nYear, &nMonth, &nDay, &nHour,
     995                 :                            &nMinute, &fSecond, &nTZ ) )
     996                 :                         poOgrFeat->SetField ( iField, nYear, nMonth, nDay,
     997                 :                                               nHour, nMinute, ( int )fSecond,
     998               0 :                                               nTZ );
     999               0 :                 }
    1000               0 :             }
    1001                 :         }
    1002                 : 
    1003                 :         /***** timespan *****/
    1004                 : 
    1005               0 :         if ( poKmlTimePrimitive->IsA ( kmldom::Type_TimeSpan ) ) {
    1006               0 :             TimeSpanPtr poKmlTimeSpan = AsTimeSpan ( poKmlTimePrimitive );
    1007                 : 
    1008                 :             /***** begin *****/
    1009                 : 
    1010               0 :             if ( poKmlTimeSpan->has_begin (  ) ) {
    1011               0 :                 const std::string oKmlWhen = poKmlTimeSpan->get_begin (  );
    1012                 : 
    1013                 : 
    1014               0 :                 int iField = poOgrFeat->GetFieldIndex ( beginfield );
    1015                 : 
    1016               0 :                 if ( iField > -1 ) {
    1017                 :                     int nYear,
    1018                 :                         nMonth,
    1019                 :                         nDay,
    1020                 :                         nHour,
    1021                 :                         nMinute,
    1022                 :                         nTZ;
    1023                 :                     float fSecond;
    1024                 : 
    1025               0 :                     if ( OGRParseXMLDateTime
    1026                 :                          ( oKmlWhen.c_str (  ), &nYear, &nMonth, &nDay, &nHour,
    1027                 :                            &nMinute, &fSecond, &nTZ ) )
    1028                 :                         poOgrFeat->SetField ( iField, nYear, nMonth, nDay,
    1029                 :                                               nHour, nMinute, ( int )fSecond,
    1030               0 :                                               nTZ );
    1031               0 :                 }
    1032                 :             }
    1033                 : 
    1034                 :             /***** end *****/
    1035                 : 
    1036               0 :             if ( poKmlTimeSpan->has_end (  ) ) {
    1037               0 :                 const std::string oKmlWhen = poKmlTimeSpan->get_end (  );
    1038                 : 
    1039                 : 
    1040               0 :                 int iField = poOgrFeat->GetFieldIndex ( endfield );
    1041                 : 
    1042               0 :                 if ( iField > -1 ) {
    1043                 :                     int nYear,
    1044                 :                         nMonth,
    1045                 :                         nDay,
    1046                 :                         nHour,
    1047                 :                         nMinute,
    1048                 :                         nTZ;
    1049                 :                     float fSecond;
    1050                 : 
    1051               0 :                     if ( OGRParseXMLDateTime
    1052                 :                          ( oKmlWhen.c_str (  ), &nYear, &nMonth, &nDay, &nHour,
    1053                 :                            &nMinute, &fSecond, &nTZ ) )
    1054                 :                         poOgrFeat->SetField ( iField, nYear, nMonth, nDay,
    1055                 :                                               nHour, nMinute, ( int )fSecond,
    1056               0 :                                               nTZ );
    1057               0 :                 }
    1058               0 :             }
    1059               0 :         }
    1060                 :     }
    1061                 : 
    1062                 : 
    1063              54 :     if ( poKmlPlacemark->has_geometry (  ) ) {
    1064              54 :         GeometryPtr poKmlGeometry = poKmlPlacemark->get_geometry (  );
    1065                 : 
    1066                 :         /***** altitudeMode *****/
    1067                 : 
    1068                 : 
    1069              54 :         int bIsGX = FALSE;
    1070              54 :         int nAltitudeMode = -1;
    1071                 : 
    1072              54 :         int iField = poOgrFeat->GetFieldIndex ( altitudeModefield );
    1073                 : 
    1074              54 :         if ( iField > -1 ) {
    1075                 : 
    1076              54 :             if ( kml2altitudemode_rec ( poKmlGeometry,
    1077                 :                                         &nAltitudeMode, &bIsGX ) ) {
    1078                 : 
    1079              14 :                 if ( !bIsGX ) {
    1080                 : 
    1081              14 :                     switch ( nAltitudeMode ) {
    1082                 :                     case kmldom::ALTITUDEMODE_CLAMPTOGROUND:
    1083               0 :                         poOgrFeat->SetField ( iField, "clampToGround" );
    1084               0 :                         break;
    1085                 : 
    1086                 :                     case kmldom::ALTITUDEMODE_RELATIVETOGROUND:
    1087              12 :                         poOgrFeat->SetField ( iField, "relativeToGround" );
    1088              12 :                         break;
    1089                 : 
    1090                 :                     case kmldom::ALTITUDEMODE_ABSOLUTE:
    1091               2 :                         poOgrFeat->SetField ( iField, "absolute" );
    1092                 :                         break;
    1093                 : 
    1094                 :                     }
    1095                 :                 }
    1096                 : 
    1097                 :                 else {
    1098               0 :                     switch ( nAltitudeMode ) {
    1099                 :                     case kmldom::GX_ALTITUDEMODE_RELATIVETOSEAFLOOR:
    1100               0 :                         poOgrFeat->SetField ( iField, "relativeToSeaFloor" );
    1101               0 :                         break;
    1102                 : 
    1103                 :                     case kmldom::GX_ALTITUDEMODE_CLAMPTOSEAFLOOR:
    1104               0 :                         poOgrFeat->SetField ( iField, "clampToSeaFloor" );
    1105                 :                         break;
    1106                 :                     }
    1107                 : 
    1108                 :                 }
    1109                 :             }
    1110                 : 
    1111                 :         }
    1112                 : 
    1113                 :         /***** tessellate *****/
    1114                 : 
    1115              54 :         int nTessellate = -1;
    1116                 : 
    1117              54 :         kml2tessellate_rec ( poKmlGeometry, &nTessellate );
    1118                 : 
    1119              54 :         iField = poOgrFeat->GetFieldIndex ( tessellatefield );
    1120              54 :         if ( iField > -1 )
    1121              54 :             poOgrFeat->SetField ( iField, nTessellate );
    1122                 : 
    1123                 :         /***** extrude *****/
    1124                 : 
    1125              54 :         int nExtrude = -1;
    1126                 : 
    1127              54 :         kml2extrude_rec ( poKmlGeometry, &nExtrude );
    1128                 : 
    1129              54 :         iField = poOgrFeat->GetFieldIndex ( extrudefield );
    1130              54 :         if ( iField > -1 )
    1131              54 :             poOgrFeat->SetField ( iField, nExtrude );
    1132                 : 
    1133                 :     }
    1134                 : 
    1135                 :     /***** visibility *****/
    1136                 : 
    1137              54 :     int nVisibility = -1;
    1138                 : 
    1139              54 :     if ( poKmlPlacemark->has_visibility (  ) )
    1140              19 :         nVisibility = poKmlPlacemark->get_visibility (  );
    1141                 : 
    1142              54 :     int iField = poOgrFeat->GetFieldIndex ( visibilityfield );
    1143                 : 
    1144              54 :     if ( iField > -1 )
    1145              54 :         poOgrFeat->SetField ( iField, nVisibility );
    1146                 : 
    1147              54 :     ExtendedDataPtr poKmlExtendedData = NULL;
    1148                 : 
    1149              54 :     if ( poKmlPlacemark->has_extendeddata (  ) ) {
    1150               0 :         poKmlExtendedData = poKmlPlacemark->get_extendeddata (  );
    1151                 : 
    1152                 :         /***** loop over the schemadata_arrays *****/
    1153                 : 
    1154               0 :         size_t nSchemaData = poKmlExtendedData->get_schemadata_array_size (  );
    1155                 : 
    1156                 :         size_t iSchemaData;
    1157                 : 
    1158               0 :         for ( iSchemaData = 0; iSchemaData < nSchemaData; iSchemaData++ ) {
    1159                 :             SchemaDataPtr poKmlSchemaData =
    1160               0 :                 poKmlExtendedData->get_schemadata_array_at ( iSchemaData );
    1161                 : 
    1162                 :             /***** loop over the simpledata array *****/
    1163                 : 
    1164                 :             size_t nSimpleData =
    1165               0 :                 poKmlSchemaData->get_simpledata_array_size (  );
    1166                 : 
    1167                 :             size_t iSimpleData;
    1168                 : 
    1169               0 :             for ( iSimpleData = 0; iSimpleData < nSimpleData; iSimpleData++ ) {
    1170                 :                 SimpleDataPtr poKmlSimpleData =
    1171               0 :                     poKmlSchemaData->get_simpledata_array_at ( iSimpleData );
    1172                 : 
    1173                 :                 /***** find the field index *****/
    1174                 : 
    1175               0 :                 int iField = -1;
    1176                 : 
    1177               0 :                 if ( poKmlSimpleData->has_name (  ) ) {
    1178               0 :                     const string oName = poKmlSimpleData->get_name (  );
    1179               0 :                     const char *pszName = oName.c_str (  );
    1180                 : 
    1181               0 :                     iField = poOgrFeat->GetFieldIndex ( pszName );
    1182                 :                 }
    1183                 : 
    1184                 :                 /***** if it has trxt set the field *****/
    1185                 : 
    1186               0 :                 if ( iField > -1 && poKmlSimpleData->has_text (  ) ) {
    1187               0 :                     const string oText = poKmlSimpleData->get_text (  );
    1188                 : 
    1189               0 :                     poOgrFeat->SetField ( iField, oText.c_str (  ) );
    1190                 :                 }
    1191                 :             }
    1192                 :         }
    1193              54 :     }
    1194                 : 
    1195              54 : }
    1196                 : 
    1197                 : /******************************************************************************
    1198                 :  function create a simplefield from a FieldDefn
    1199                 : ******************************************************************************/
    1200                 : 
    1201                 : SimpleFieldPtr FieldDef2kml (
    1202                 :     OGRFieldDefn * poOgrFieldDef,
    1203               2 :     KmlFactory * poKmlFactory )
    1204                 : {
    1205                 : 
    1206               2 :     SimpleFieldPtr poKmlSimpleField = poKmlFactory->CreateSimpleField (  );
    1207               2 :     const char *pszFieldName = poOgrFieldDef->GetNameRef (  );
    1208                 : 
    1209               2 :     poKmlSimpleField->set_name ( pszFieldName );
    1210                 : 
    1211               4 :     const char *namefield = CPLGetConfigOption ( "LIBKML_NAME_FIELD", "Name" );
    1212                 :     const char *descfield =
    1213               2 :         CPLGetConfigOption ( "LIBKML_DESCRIPTION_FIELD", "description" );
    1214                 :     const char *tsfield =
    1215               2 :         CPLGetConfigOption ( "LIBKML_TIMESTAMP_FIELD", "timestamp" );
    1216                 :     const char *beginfield =
    1217               2 :         CPLGetConfigOption ( "LIBKML_BEGIN_FIELD", "begin" );
    1218               2 :     const char *endfield = CPLGetConfigOption ( "LIBKML_END_FIELD", "end" );
    1219                 :     const char *altitudeModefield =
    1220               2 :         CPLGetConfigOption ( "LIBKML_ALTITUDEMODE_FIELD", "altitudeMode" );
    1221                 :     const char *tessellatefield =
    1222               2 :         CPLGetConfigOption ( "LIBKML_TESSELLATE_FIELD", "tessellate" );
    1223                 :     const char *extrudefield =
    1224               2 :         CPLGetConfigOption ( "LIBKML_EXTRUDE_FIELD", "extrude" );
    1225                 :     const char *visibilityfield =
    1226               2 :         CPLGetConfigOption ( "LIBKML_VISIBILITY_FIELD", "visibility" );
    1227                 : 
    1228                 : 
    1229               2 :     SimpleDataPtr poKmlSimpleData = NULL;
    1230                 : 
    1231               2 :     switch ( poOgrFieldDef->GetType (  ) ) {
    1232                 : 
    1233                 :     case OFTInteger:
    1234                 :     case OFTIntegerList:
    1235               0 :         if ( EQUAL ( pszFieldName, tessellatefield ) ||
    1236                 :              EQUAL ( pszFieldName, extrudefield ) ||
    1237                 :              EQUAL ( pszFieldName, visibilityfield ) )
    1238               0 :             break;
    1239               0 :         poKmlSimpleField->set_type ( "int" );
    1240               0 :         return poKmlSimpleField;
    1241                 :     case OFTReal:
    1242                 :     case OFTRealList:
    1243               0 :         poKmlSimpleField->set_type ( "float" );
    1244               0 :         return poKmlSimpleField;
    1245                 :     case OFTBinary:
    1246               0 :         poKmlSimpleField->set_type ( "bool" );
    1247               0 :         return poKmlSimpleField;
    1248                 :     case OFTString:
    1249                 :     case OFTStringList:
    1250               2 :         if ( EQUAL ( pszFieldName, namefield ) ||
    1251                 :              EQUAL ( pszFieldName, descfield ) ||
    1252                 :              EQUAL ( pszFieldName, altitudeModefield ) )
    1253               2 :             break;
    1254               0 :         poKmlSimpleField->set_type ( "string" );
    1255               0 :         return poKmlSimpleField;
    1256                 : 
    1257                 :     /***** kml has these types but as timestamp/timespan *****/
    1258                 : 
    1259                 :     case OFTDate:
    1260                 :     case OFTTime:
    1261                 :     case OFTDateTime:
    1262               0 :         if ( EQUAL ( pszFieldName, tsfield )
    1263                 :              || EQUAL ( pszFieldName, beginfield )
    1264                 :              || EQUAL ( pszFieldName, endfield ) )
    1265               0 :             break;
    1266                 :     default:
    1267               0 :         poKmlSimpleField->set_type ( "string" );
    1268               0 :         return poKmlSimpleField;
    1269                 :     }
    1270                 : 
    1271               2 :     return NULL;
    1272                 : }
    1273                 : 
    1274                 : /******************************************************************************
    1275                 :  function to add the simpleFields in a schema to a featuredefn
    1276                 : ******************************************************************************/
    1277                 : 
    1278                 : void kml2FeatureDef (
    1279                 :     SchemaPtr poKmlSchema,
    1280               0 :     OGRFeatureDefn * poOgrFeatureDefn )
    1281                 : {
    1282                 : 
    1283               0 :     size_t nSimpleFields = poKmlSchema->get_simplefield_array_size (  );
    1284                 :     size_t iSimpleField;
    1285                 : 
    1286               0 :     for ( iSimpleField = 0; iSimpleField < nSimpleFields; iSimpleField++ ) {
    1287                 :         SimpleFieldPtr poKmlSimpleField =
    1288               0 :             poKmlSchema->get_simplefield_array_at ( iSimpleField );
    1289                 : 
    1290               0 :         const char *pszType = "string";
    1291               0 :         const char *pszName = "Unknown";
    1292                 : 
    1293               0 :         if ( poKmlSimpleField->has_type (  ) ) {
    1294               0 :             const string oType = poKmlSimpleField->get_type (  );
    1295                 : 
    1296               0 :             pszType = oType.c_str (  );
    1297                 :         }
    1298                 : 
    1299               0 :         if ( poKmlSimpleField->has_displayname (  ) ) {
    1300               0 :             const string oName = poKmlSimpleField->get_displayname (  );
    1301                 : 
    1302               0 :             pszName = oName.c_str (  );
    1303                 :         }
    1304                 : 
    1305               0 :         else if ( poKmlSimpleField->has_name (  ) ) {
    1306               0 :             const string oName = poKmlSimpleField->get_name (  );
    1307                 : 
    1308               0 :             pszName = oName.c_str (  );
    1309                 :         }
    1310                 : 
    1311               0 :         if ( EQUAL ( pszType, "string" ) ) {
    1312                 :             OGRFieldDefn oOgrFieldName (
    1313                 :     pszName,
    1314               0 :     OFTString );
    1315                 : 
    1316               0 :             poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldName );
    1317                 :         }
    1318               0 :         if ( EQUAL ( pszType, "int" ) ) {
    1319                 :             OGRFieldDefn oOgrFieldName (
    1320                 :     pszName,
    1321               0 :     OFTInteger );
    1322                 : 
    1323               0 :             poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldName );
    1324                 :         }
    1325               0 :         if ( EQUAL ( pszType, "float" ) ) {
    1326                 :             OGRFieldDefn oOgrFieldName (
    1327                 :     pszName,
    1328               0 :     OFTReal );
    1329                 : 
    1330               0 :             poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldName );
    1331                 :         }
    1332               0 :         if ( EQUAL ( pszType, "bool" ) ) {
    1333                 :             OGRFieldDefn oOgrFieldName (
    1334                 :     pszName,
    1335               0 :     OFTBinary );
    1336                 : 
    1337               0 :             poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldName );
    1338                 :         }
    1339                 : 
    1340                 : 
    1341                 :     }
    1342                 : 
    1343                 : 
    1344                 :     return;
    1345             896 : }

Generated by: LTP GCOV extension version 1.5