Index: ogr/ogrsf_frmts/kml/drv_kml.html
===================================================================
--- ogr/ogrsf_frmts/kml/drv_kml.html (revision 11777)
+++ ogr/ogrsf_frmts/kml/drv_kml.html (working copy)
@@ -24,6 +24,12 @@
NameField: Allows you to specify the field to use for the KML <name> element.
ogr2ogr -f KML output.kml input.shp -dsco NameField=RegionName
+AltitudeMode: Allows you to specify the AltitudeMode to use for KML geometries. This will only affect 3D geometries
+and must be one of the valid KML options.
+See the relevant KML reference material
+for further information.
+ogr2ogr -f KML output.kml input.shp -dsco AltitudeMode=absolute
+
Index: ogr/ogrsf_frmts/kml/ogr2kmlgeometry.cpp
===================================================================
--- ogr/ogrsf_frmts/kml/ogr2kmlgeometry.cpp (revision 11777)
+++ ogr/ogrsf_frmts/kml/ogr2kmlgeometry.cpp (working copy)
@@ -153,7 +153,7 @@
static int OGR2KMLGeometryAppend( OGRGeometry *poGeometry,
char **ppszText, int *pnLength,
- int *pnMaxLength )
+ int *pnMaxLength, char * szAltitudeMode )
{
/* -------------------------------------------------------------------- */
@@ -191,9 +191,18 @@
_GrowBuffer( *pnLength + strlen(szCoordinate) + 70,
ppszText, pnMaxLength );
- sprintf( *ppszText + *pnLength,
+ if (NULL == szAltitudeMode)
+ {
+ sprintf( *ppszText + *pnLength,
"%s",
szCoordinate );
+ }
+ else
+ {
+ sprintf( *ppszText + *pnLength,
+ "%s",
+ szAltitudeMode, szCoordinate );
+ }
*pnLength += strlen( *ppszText + *pnLength );
}
@@ -213,6 +222,10 @@
AppendString( ppszText, pnLength, pnMaxLength,
"" );
+ if (NULL != szAltitudeMode)
+ {
+ AppendString( ppszText, pnLength, pnMaxLength, szAltitudeMode);
+ }
AppendCoordinateList( (OGRLineString *) poGeometry,
ppszText, pnLength, pnMaxLength );
@@ -234,6 +247,10 @@
AppendString( ppszText, pnLength, pnMaxLength,
"" );
+ if (NULL != szAltitudeMode)
+ {
+ AppendString( ppszText, pnLength, pnMaxLength, szAltitudeMode);
+ }
if( poPolygon->getExteriorRing() != NULL )
{
@@ -241,7 +258,7 @@
"" );
if( !OGR2KMLGeometryAppend( poPolygon->getExteriorRing(),
- ppszText, pnLength, pnMaxLength ) )
+ ppszText, pnLength, pnMaxLength, szAltitudeMode ) )
return FALSE;
AppendString( ppszText, pnLength, pnMaxLength,
@@ -256,7 +273,7 @@
"" );
if( !OGR2KMLGeometryAppend( poRing, ppszText, pnLength,
- pnMaxLength ) )
+ pnMaxLength, szAltitudeMode ) )
return FALSE;
AppendString( ppszText, pnLength, pnMaxLength,
@@ -303,6 +320,11 @@
AppendString( ppszText, pnLength, pnMaxLength, "<" );
AppendString( ppszText, pnLength, pnMaxLength, pszElem );
+ if (NULL != szAltitudeMode)
+ {
+ AppendString( ppszText, pnLength, pnMaxLength, szAltitudeMode);
+ }
+
for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
{
OGRGeometry *poMember = poGC->getGeometryRef( iMember );
@@ -311,7 +333,7 @@
AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );
if( !OGR2KMLGeometryAppend( poMember,
- ppszText, pnLength, pnMaxLength ) )
+ ppszText, pnLength, pnMaxLength, szAltitudeMode ) )
return FALSE;
AppendString( ppszText, pnLength, pnMaxLength, "" );
@@ -387,10 +409,11 @@
/************************************************************************/
/* OGR_G_ExportToKML() */
/************************************************************************/
-char *OGR_G_ExportToKML( OGRGeometryH hGeometry )
+char *OGR_G_ExportToKML( OGRGeometryH hGeometry, const char *pszAltitudeMode )
{
char *pszText;
int nLength = 0, nMaxLength = 1;
+ char szAltitudeMode[128];
if( hGeometry == NULL )
return CPLStrdup( "" );
@@ -398,8 +421,17 @@
pszText = (char *) CPLMalloc(nMaxLength);
pszText[0] = '\0';
+ if (NULL != pszAltitudeMode)
+ {
+ sprintf(szAltitudeMode, "%s", pszAltitudeMode);
+ }
+ else
+ {
+ szAltitudeMode[0] = 0;
+ }
+
if( !OGR2KMLGeometryAppend( (OGRGeometry *) hGeometry, &pszText,
- &nLength, &nMaxLength ))
+ &nLength, &nMaxLength, szAltitudeMode ))
{
CPLFree( pszText );
return NULL;
@@ -417,7 +449,7 @@
char *pszText;
CPLXMLNode *psTree;
- pszText = OGR_G_ExportToKML( hGeometry );
+ pszText = OGR_G_ExportToKML( hGeometry, NULL );
if( pszText == NULL )
return NULL;
Index: ogr/ogrsf_frmts/kml/ogr_kml.h
===================================================================
--- ogr/ogrsf_frmts/kml/ogr_kml.h (revision 11777)
+++ ogr/ogrsf_frmts/kml/ogr_kml.h (working copy)
@@ -93,9 +93,11 @@
OGRKMLLayer *TranslateKMLSchema( KMLFeatureClass * );
- //The name of the field to use for
+ //The name of the field to use for the KML name element
char *pszNameField;
-
+ //The KML altitude mode to use
+ char *pszAltitudeMode;
+
char **papszCreateOptions;
// output related parameters
@@ -120,6 +122,7 @@
const char *GetName() { return pszName; }
const char *GetNameField() { return pszNameField; }
+ const char *GetAltitudeMode() { return pszAltitudeMode; }
int GetLayerCount() { return nLayers; }
OGRLayer *GetLayer( int );
Index: ogr/ogrsf_frmts/kml/ogrkmldatasource.cpp
===================================================================
--- ogr/ogrsf_frmts/kml/ogrkmldatasource.cpp (revision 11777)
+++ ogr/ogrsf_frmts/kml/ogrkmldatasource.cpp (working copy)
@@ -38,6 +38,7 @@
{
pszName = NULL;
pszNameField = NULL;
+ pszAltitudeMode = NULL;
papoLayers = NULL;
nLayers = 0;
@@ -63,6 +64,7 @@
CSLDestroy( papszCreateOptions );
CPLFree( pszName );
CPLFree( pszNameField );
+ CPLFree( pszAltitudeMode );
for( int i = 0; i < nLayers; i++ )
{
@@ -152,6 +154,28 @@
pszNameField = CPLStrdup(CSLFetchNameValue(papszOptions, "NameField"));
CPLDebug("KML", "Using the field '%s' for name element", pszNameField);
+
+ pszAltitudeMode = CPLStrdup(CSLFetchNameValue(papszOptions, "AltitudeMode"));
+ if ((NULL != pszAltitudeMode) && strlen(pszAltitudeMode))
+ { //Check to see that the specified AltitudeMode is valid
+ if ( EQUAL(pszAltitudeMode, "clampToGround") ||
+ EQUAL(pszAltitudeMode, "relativeToGround") ||
+ EQUAL(pszAltitudeMode, "absolute"))
+ {
+ CPLDebug("KML", "Using '%s' for AltitudeMode", pszAltitudeMode);
+ }
+ else
+ {
+ CPLFree( pszAltitudeMode );
+ pszAltitudeMode = NULL;
+ CPLError( CE_Warning, CPLE_AppDefined, "Invalide AltitideMode specified, ignoring" );
+ }
+ }
+ else
+ {
+ CPLFree( pszAltitudeMode );
+ pszAltitudeMode = NULL;
+ }
/* -------------------------------------------------------------------- */
/* Create the output file. */
Index: ogr/ogrsf_frmts/kml/ogrkmllayer.cpp
===================================================================
--- ogr/ogrsf_frmts/kml/ogrkmllayer.cpp (revision 11777)
+++ ogr/ogrsf_frmts/kml/ogrkmllayer.cpp (working copy)
@@ -33,7 +33,7 @@
#include "cpl_string.h"
// Function utility to dump OGRGeoemtry to KML text
-char *OGR_G_ExportToKML( OGRGeometryH hGeometry );
+char *OGR_G_ExportToKML( OGRGeometryH hGeometry, const char * pszAltitudeMode);
/************************************************************************/
/* OGRKMLLayer() */
@@ -190,7 +190,7 @@
// TODO - porting
// pszGeometry = poFeature->GetGeometryRef()->exportToKML();
- pszGeometry = OGR_G_ExportToKML( static_cast( poFeature->GetGeometryRef() ) );
+ pszGeometry = OGR_G_ExportToKML( static_cast( poFeature->GetGeometryRef() ), poDS->GetAltitudeMode());
VSIFPrintf( fp, " %s\n", pszGeometry );
CPLFree( pszGeometry );