OGRErr OGRLIBKMLLayer::CreateField (
    OGRFieldDefn * poField,
    int bApproxOK )
{

    if ( !bUpdate )
        return OGRERR_UNSUPPORTED_OPERATION;

    if( m_bUseSimpleField )
    {
        SimpleFieldPtr poKmlSimpleField = NULL;

        if ( (poKmlSimpleField =
            FieldDef2kml ( poField, m_poOgrDS->GetKmlFactory (  ) )) != NULL )
        {
            if( m_poKmlSchema == NULL )
            {
                /***** create a new schema *****/

                KmlFactory *poKmlFactory = m_poOgrDS->GetKmlFactory (  );

                m_poKmlSchema = poKmlFactory->CreateSchema (  );

                /***** set the id on the new schema *****/

                std::string oKmlSchemaID = OGRLIBKMLGetSanitizedNCName(m_pszName);
                oKmlSchemaID.append ( ".schema" );
                m_poKmlSchema->set_id ( oKmlSchemaID );
            }

            m_poKmlSchema->add_simplefield ( poKmlSimpleField );
        }
    }

    m_poOgrFeatureDefn->AddFieldDefn ( poField );

    /***** mark the layer as updated *****/

    bUpdated = TRUE;
    m_poOgrDS->Updated (  );

    return OGRERR_NONE;
}
OGRLIBKMLLayer::OGRLIBKMLLayer ( const char *pszLayerName,
                                 OGRSpatialReference * poSpatialRef,
                                 OGRwkbGeometryType eGType,
                                 OGRLIBKMLDataSource * poOgrDS,
                                 ElementPtr poKmlRoot,
                                 ContainerPtr poKmlContainer,
                                 const char *pszFileName,
                                 int bNew,
                                 int bUpdate )
{

    m_poStyleTable = NULL;
    iFeature = 0;
    nFeatures = 0;
    nFID = 1;

    this->bUpdate = bUpdate;
    m_pszName = CPLStrdup ( pszLayerName );
    m_pszFileName = CPLStrdup ( pszFileName );
    m_poOgrDS = poOgrDS;

    m_poOgrSRS = new OGRSpatialReference ( NULL );
    m_poOgrSRS->SetWellKnownGeogCS ( "WGS84" );

    m_poOgrFeatureDefn = new OGRFeatureDefn ( pszLayerName );
    m_poOgrFeatureDefn->Reference (  );
    m_poOgrFeatureDefn->SetGeomType ( eGType );

    /***** store the root element pointer *****/

    m_poKmlLayerRoot = poKmlRoot;
    
    /***** store the layers container *****/

    m_poKmlLayer = poKmlContainer;

    /***** was the layer created from a DS::Open *****/

    if ( !bNew ) {

        /***** get the number of features on the layer *****/

        nFeatures = m_poKmlLayer->get_feature_array_size (  );

        /***** add the name and desc fields *****/

        const char *namefield =
            CPLGetConfigOption ( "LIBKML_NAME_FIELD", "Name" );
        const char *descfield =
            CPLGetConfigOption ( "LIBKML_DESCRIPTION_FIELD", "description" );
        const char *tsfield =
            CPLGetConfigOption ( "LIBKML_TIMESTAMP_FIELD", "timestamp" );
        const char *beginfield =
            CPLGetConfigOption ( "LIBKML_BEGIN_FIELD", "begin" );
        const char *endfield =
            CPLGetConfigOption ( "LIBKML_END_FIELD", "end" );
        const char *altitudeModefield =
            CPLGetConfigOption ( "LIBKML_ALTITUDEMODE_FIELD", "altitudeMode" );
        const char *tessellatefield =
            CPLGetConfigOption ( "LIBKML_TESSELLATE_FIELD", "tessellate" );
        const char *extrudefield =
            CPLGetConfigOption ( "LIBKML_EXTRUDE_FIELD", "extrude" );
        const char *visibilityfield =
            CPLGetConfigOption ( "LIBKML_VISIBILITY_FIELD", "visibility" );

        OGRFieldDefn oOgrFieldName (
    namefield,
    OFTString );

        m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldName );

        OGRFieldDefn oOgrFieldDesc (
    descfield,
    OFTString );

        m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldDesc );

        OGRFieldDefn oOgrFieldTs (
    tsfield,
    OFTDateTime );

        m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldTs );

        OGRFieldDefn oOgrFieldBegin (
    beginfield,
    OFTDateTime );

        m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldBegin );

        OGRFieldDefn oOgrFieldEnd (
    endfield,
    OFTDateTime );

        m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldEnd );

        OGRFieldDefn oOgrFieldAltitudeMode (
    altitudeModefield,
    OFTString );

        m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldAltitudeMode );

        OGRFieldDefn oOgrFieldTessellate (
    tessellatefield,
    OFTInteger );

        m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldTessellate );

        OGRFieldDefn oOgrFieldExtrude (
    extrudefield,
    OFTInteger );

        m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldExtrude );

        OGRFieldDefn oOgrFieldVisibility (
    visibilityfield,
    OFTInteger );

        m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldVisibility );

        /***** get the styles *****/

        if ( m_poKmlLayer->IsA ( kmldom::Type_Document ) )
            ParseStyles ( AsDocument ( m_poKmlLayer ), &m_poStyleTable );

        /***** get the schema if the layer is a Document *****/

        m_poKmlSchema = NULL;

        if ( m_poKmlLayer->IsA ( kmldom::Type_Document ) ) {
            DocumentPtr poKmlDocument = AsDocument ( m_poKmlLayer );

            if ( poKmlDocument->get_schema_array_size (  ) ) {
                m_poKmlSchema = poKmlDocument->get_schema_array_at ( 0 );
                kml2FeatureDef ( m_poKmlSchema, m_poOgrFeatureDefn );
            }
        }

        /***** the schema is somewhere else *****/

        if (m_poKmlSchema == NULL) {

            /***** try to find the correct schema *****/

            FeaturePtr poKmlFeature;

            /***** find the first placemark *****/

            do {
                if ( iFeature >= nFeatures )
                    break;

                poKmlFeature =
                    m_poKmlLayer->get_feature_array_at ( iFeature++ );

            } while ( poKmlFeature->Type (  ) != kmldom::Type_Placemark );

            if ( iFeature <= nFeatures && poKmlFeature &&
                 poKmlFeature->Type (  ) == kmldom::Type_Placemark &&
                 poKmlFeature->has_extendeddata (  ) ) {

                ExtendedDataPtr poKmlExtendedData = poKmlFeature->
                    get_extendeddata (  );

                if ( poKmlExtendedData->get_schemadata_array_size (  ) > 0 ) {
                    SchemaDataPtr poKmlSchemaData = poKmlExtendedData->
                        get_schemadata_array_at ( 0 );

                    if ( poKmlSchemaData->has_schemaurl (  ) ) {

                        std::string oKmlSchemaUrl = poKmlSchemaData->
                            get_schemaurl (  );
                        if ( ( m_poKmlSchema =
                               m_poOgrDS->FindSchema ( oKmlSchemaUrl.
                                                       c_str (  ) ) ) ) {
                            kml2FeatureDef ( m_poKmlSchema,
                                             m_poOgrFeatureDefn );
                        }
                    }
                }
                else if ( poKmlExtendedData->get_data_array_size() > 0 )
                {
                    /* Use the <Data> of the first placemark to build the feature definition */
                    /* If others have different fields, too bad... */
                    int bLaunderFieldNames =
                        CSLTestBoolean(CPLGetConfigOption("LIBKML_LAUNDER_FIELD_NAMES", "YES"));
                    size_t nDataArraySize = poKmlExtendedData->get_data_array_size();
                    for(size_t i=0; i < nDataArraySize; i++)
                    {
                        const DataPtr& data = poKmlExtendedData->get_data_array_at(i);
                        if (data->has_name())
                        {
                            CPLString osName = data->get_name();
                            if (bLaunderFieldNames)
                                osName = LaunderFieldNames(osName);
                            OGRFieldDefn oOgrField ( osName,
                                                    OFTString );
                            m_poOgrFeatureDefn->AddFieldDefn ( &oOgrField );
                        }
                    }
                }
            }

            iFeature = 0;

        }



        /***** check if any features are another layer *****/

        m_poOgrDS->ParseLayers ( m_poKmlLayer, poSpatialRef );

    }

    /***** it was from a DS::CreateLayer *****/

    else {

        /***** mark the layer as updated *****/

        bUpdated = TRUE;

        /***** create a new schema *****/

        KmlFactory *poKmlFactory = m_poOgrDS->GetKmlFactory (  );

        m_poKmlSchema = poKmlFactory->CreateSchema (  );

        /***** set the id on the new schema *****/

        std::string oKmlSchemaID = m_pszName;
        oKmlSchemaID.append ( ".schema" );
        m_poKmlSchema->set_id ( oKmlSchemaID );
    }




}