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 ); } }