OGRLIBKMLLayer::OGRLIBKMLLayer ( const char *pszLayerName, OGRSpatialReference * poSpatialRef, OGRwkbGeometryType eGType, OGRLIBKMLDataSource * poOgrDS, ElementPtr poKmlRoot, ContainerPtr poKmlContainer, UpdatePtr poKmlUpdate, const char *pszFileName, int bNew, int bUpdateIn ) { m_poStyleTable = NULL; iFeature = 0; nFeatures = 0; nFID = 1; this->bUpdate = bUpdateIn; bUpdated = FALSE; 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 ); SetDescription( m_poOgrFeatureDefn->GetName() ); m_poOgrFeatureDefn->Reference ( ); m_poOgrFeatureDefn->SetGeomType ( eGType ); if( m_poOgrFeatureDefn->GetGeomFieldCount() != 0 ) m_poOgrFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(m_poOgrSRS); /***** store the root element pointer *****/ m_poKmlLayerRoot = poKmlRoot; /***** store the layers container *****/ m_poKmlLayer = poKmlContainer; /* update container */ m_poKmlUpdate = poKmlUpdate; m_poKmlSchema = NULL; /***** related to Region *****/ m_bWriteRegion = FALSE; m_bRegionBoundsAuto = FALSE; m_dfRegionMinLodPixels = 0; m_dfRegionMaxLodPixels = -1; m_dfRegionMinFadeExtent = 0; m_dfRegionMaxFadeExtent = 0; m_dfRegionMinX = 200; m_dfRegionMinY = 200; m_dfRegionMaxX = -200; m_dfRegionMaxY = -200; m_bReadGroundOverlay = CPLTestBool( CPLGetConfigOption("LIBKML_READ_GROUND_OVERLAY", "YES")); m_bUseSimpleField = CPLTestBool( CPLGetConfigOption("LIBKML_USE_SIMPLEFIELD", "YES")); m_bUpdateIsFolder = FALSE; /***** was the layer created from a DS::Open *****/ if ( !bNew ) { /***** get the number of features on the layer *****/ nFeatures = static_cast<int>(m_poKmlLayer->get_feature_array_size ( )); /***** get the field config *****/ struct fieldconfig oFC; get_fieldconfig( &oFC ); /***** name field *****/ OGRFieldDefn oOgrFieldName ( oFC.namefield,OFTString ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldName ); /***** description field *****/ OGRFieldDefn oOgrFieldDesc ( oFC.descfield, OFTString ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldDesc ); /***** timestamp field *****/ OGRFieldDefn oOgrFieldTs ( oFC.tsfield, OFTDateTime ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldTs ); /***** timespan begin field *****/ OGRFieldDefn oOgrFieldBegin ( oFC.beginfield, OFTDateTime ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldBegin ); /***** timespan end field *****/ OGRFieldDefn oOgrFieldEnd ( oFC.endfield, OFTDateTime ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldEnd ); /***** altitudeMode field *****/ OGRFieldDefn oOgrFieldAltitudeMode ( oFC.altitudeModefield, OFTString ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldAltitudeMode ); /***** tessellate field *****/ OGRFieldDefn oOgrFieldTessellate ( oFC.tessellatefield, OFTInteger ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldTessellate ); /***** extrude field *****/ OGRFieldDefn oOgrFieldExtrude ( oFC.extrudefield, OFTInteger ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldExtrude ); /***** visibility field *****/ OGRFieldDefn oOgrFieldVisibility ( oFC.visibilityfield, OFTInteger ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldVisibility ); /***** draw order field *****/ OGRFieldDefn oOgrFieldDrawOrder ( oFC.drawOrderfield, OFTInteger ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldDrawOrder ); /***** icon field *****/ OGRFieldDefn oOgrFieldIcon ( oFC.iconfield, OFTString ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrFieldIcon ); /***** 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 *****/ 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 *****/ int bHasHeading = FALSE, bHasTilt = FALSE, bHasRoll = FALSE; int bHasSnippet = FALSE; FeaturePtr poKmlFeature; /***** find the first placemark *****/ do { if ( iFeature >= nFeatures ) break; poKmlFeature = m_poKmlLayer->get_feature_array_at ( iFeature++ ); if( poKmlFeature->Type() == kmldom::Type_Placemark ) { PlacemarkPtr poKmlPlacemark = AsPlacemark ( poKmlFeature ); if( !poKmlPlacemark->has_geometry ( ) && poKmlPlacemark->has_abstractview ( ) && poKmlPlacemark->get_abstractview()->IsA( kmldom::Type_Camera) ) { const CameraPtr& camera = AsCamera(poKmlPlacemark->get_abstractview()); if( camera->has_heading() && !bHasHeading ) { bHasHeading = TRUE; OGRFieldDefn oOgrField ( oFC.headingfield, OFTReal ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrField ); } if( camera->has_tilt() && !bHasTilt ) { bHasTilt = TRUE; OGRFieldDefn oOgrField ( oFC.tiltfield, OFTReal ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrField ); } if( camera->has_roll() && !bHasRoll ) { bHasRoll = TRUE; OGRFieldDefn oOgrField ( oFC.rollfield, OFTReal ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrField ); } } } if( !bHasSnippet && poKmlFeature->has_snippet() ) { bHasSnippet = TRUE; OGRFieldDefn oOgrField ( oFC.snippetfield, OFTString ); m_poOgrFeatureDefn->AddFieldDefn ( &oOgrField ); } } 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 = CPLTestBool(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; } }
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 ); } }
OGRLIBKMLLayer::OGRLIBKMLLayer( const char *pszLayerName, OGRwkbGeometryType eGType, OGRLIBKMLDataSource * poOgrDS, ElementPtr poKmlRoot, ContainerPtr poKmlContainer, UpdatePtr poKmlUpdate, const char *pszFileName, int bNew, int bUpdateIn ) : bUpdate(CPL_TO_BOOL(bUpdateIn)), nFeatures(0), iFeature(0), nFID(1), m_pszName(CPLStrdup(pszLayerName)), m_pszFileName(CPLStrdup(pszFileName)), m_poKmlLayer(poKmlContainer), // Store the layers container. m_poKmlLayerRoot(poKmlRoot), // Store the root element pointer. m_poKmlUpdate(poKmlUpdate), m_poOgrDS(poOgrDS), m_poOgrFeatureDefn(new OGRFeatureDefn(pszLayerName)), m_poKmlSchema(nullptr), m_poOgrSRS(new OGRSpatialReference(nullptr)), m_bReadGroundOverlay(CPLTestBool( CPLGetConfigOption("LIBKML_READ_GROUND_OVERLAY", "YES"))), m_bUseSimpleField(CPLTestBool( CPLGetConfigOption("LIBKML_USE_SIMPLEFIELD", "YES"))), m_bWriteRegion(false), m_bRegionBoundsAuto(false), m_dfRegionMinLodPixels(0), m_dfRegionMaxLodPixels(-1), m_dfRegionMinFadeExtent(0), m_dfRegionMaxFadeExtent(0), m_dfRegionMinX(200), m_dfRegionMinY(200), m_dfRegionMaxX(-200), m_dfRegionMaxY(-200), m_bUpdateIsFolder(false) { m_poStyleTable = nullptr; m_poOgrSRS->SetWellKnownGeogCS( "WGS84" ); m_poOgrSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); SetDescription( m_poOgrFeatureDefn->GetName() ); m_poOgrFeatureDefn->Reference(); m_poOgrFeatureDefn->SetGeomType( eGType ); if( m_poOgrFeatureDefn->GetGeomFieldCount() != 0 ) m_poOgrFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(m_poOgrSRS); /***** was the layer created from a DS::Open *****/ if( !bNew ) { /***** get the number of features on the layer *****/ nFeatures = static_cast<int>(m_poKmlLayer->get_feature_array_size()); /***** get the field config *****/ struct fieldconfig oFC; get_fieldconfig( &oFC ); /***** name field *****/ OGRFieldDefn oOgrFieldName( oFC.namefield,OFTString ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldName ); /***** description field *****/ OGRFieldDefn oOgrFieldDesc( oFC.descfield, OFTString ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldDesc ); /***** timestamp field *****/ OGRFieldDefn oOgrFieldTs( oFC.tsfield, OFTDateTime ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldTs ); /***** timespan begin field *****/ OGRFieldDefn oOgrFieldBegin( oFC.beginfield, OFTDateTime ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldBegin ); /***** timespan end field *****/ OGRFieldDefn oOgrFieldEnd( oFC.endfield, OFTDateTime ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldEnd ); /***** altitudeMode field *****/ OGRFieldDefn oOgrFieldAltitudeMode( oFC.altitudeModefield, OFTString ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldAltitudeMode ); /***** tessellate field *****/ OGRFieldDefn oOgrFieldTessellate( oFC.tessellatefield, OFTInteger ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldTessellate ); /***** extrude field *****/ OGRFieldDefn oOgrFieldExtrude( oFC.extrudefield, OFTInteger ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldExtrude ); /***** visibility field *****/ OGRFieldDefn oOgrFieldVisibility( oFC.visibilityfield, OFTInteger ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldVisibility ); /***** draw order field *****/ OGRFieldDefn oOgrFieldDrawOrder( oFC.drawOrderfield, OFTInteger ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldDrawOrder ); /***** icon field *****/ OGRFieldDefn oOgrFieldIcon( oFC.iconfield, OFTString ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldIcon ); /***** get the styles *****/ if( m_poKmlLayer->IsA( kmldom::Type_Document ) ) ParseStyles( AsDocument ( m_poKmlLayer ), &m_poStyleTable ); bool bCanSetKmlSchema = true; /***** get the schema if the layer is a Document *****/ if( m_poKmlLayer->IsA( kmldom::Type_Document ) ) { DocumentPtr poKmlDocument = AsDocument( m_poKmlLayer ); if( poKmlDocument->get_schema_array_size() ) { for(size_t i = 0; i < poKmlDocument->get_schema_array_size(); i++ ) { auto schema = poKmlDocument->get_schema_array_at( i ); if( bCanSetKmlSchema && !m_poKmlSchema ) { m_poKmlSchema = schema; bCanSetKmlSchema = false; } else { m_poKmlSchema = nullptr; } kml2FeatureDef( schema, m_poOgrFeatureDefn ); } } } /***** the schema is somewhere else *****/ if( bCanSetKmlSchema ) { /***** try to find the correct schema *****/ bool bHasHeading = false; bool bHasTilt = false; bool bHasRoll = false; bool bHasSnippet = false; FeaturePtr poKmlFeature = nullptr; const bool bLaunderFieldNames = CPLTestBool(CPLGetConfigOption( "LIBKML_LAUNDER_FIELD_NAMES", "YES")); std::set<std::string> oSetSchemaAlreadyVisited; /***** find the first placemark *****/ for( iFeature = 0; iFeature < nFeatures; iFeature++ ) { poKmlFeature = m_poKmlLayer->get_feature_array_at( iFeature ); if( poKmlFeature->Type() == kmldom::Type_Placemark ) { PlacemarkPtr poKmlPlacemark = AsPlacemark( poKmlFeature ); if( !poKmlPlacemark->has_geometry() && poKmlPlacemark->has_abstractview() && poKmlPlacemark->get_abstractview()-> IsA( kmldom::Type_Camera) ) { const CameraPtr& camera = AsCamera(poKmlPlacemark->get_abstractview()); if( camera->has_heading() && !bHasHeading ) { bHasHeading = true; OGRFieldDefn oOgrField( oFC.headingfield, OFTReal ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrField ); } if( camera->has_tilt() && !bHasTilt ) { bHasTilt = true; OGRFieldDefn oOgrField( oFC.tiltfield, OFTReal ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrField ); } if( camera->has_roll() && !bHasRoll ) { bHasRoll = true; OGRFieldDefn oOgrField( oFC.rollfield, OFTReal ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrField ); } } if( poKmlFeature->has_extendeddata() ) { const ExtendedDataPtr poKmlExtendedData = poKmlFeature->get_extendeddata(); if( poKmlExtendedData->get_schemadata_array_size() > 0 ) { const SchemaDataPtr poKmlSchemaData = poKmlExtendedData->get_schemadata_array_at( 0 ); if( poKmlSchemaData->has_schemaurl() ) { std::string oKmlSchemaUrl = poKmlSchemaData->get_schemaurl(); if( oSetSchemaAlreadyVisited.find( oKmlSchemaUrl) == oSetSchemaAlreadyVisited.end() ) { oSetSchemaAlreadyVisited.insert( oKmlSchemaUrl); auto schema = m_poOgrDS->FindSchema( oKmlSchemaUrl.c_str() ); if( schema ) { if( bCanSetKmlSchema && !m_poKmlSchema ) { m_poKmlSchema = schema; bCanSetKmlSchema = false; } else { m_poKmlSchema = nullptr; } kml2FeatureDef( schema, m_poOgrFeatureDefn ); } } } } else if( poKmlExtendedData->get_data_array_size() > 0 ) { const 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 = std::string(data->get_name()); if( bLaunderFieldNames ) osName = LaunderFieldNames(osName); if( m_poOgrFeatureDefn->GetFieldIndex(osName) < 0 ) { OGRFieldDefn oOgrField( osName, OFTString ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrField ); } } } } } } if( !bHasSnippet && poKmlFeature->has_snippet() ) { bHasSnippet = true; OGRFieldDefn oOgrField( oFC.snippetfield, OFTString ); m_poOgrFeatureDefn->AddFieldDefn( &oOgrField ); } } iFeature = 0; } } }