StyleSelectorPtr StyleFromStyleSelector( const StyleSelectorPtr& poKmlStyleSelector, OGRStyleTable * poStyleTable) { /***** is it a style? *****/ if ( poKmlStyleSelector->IsA( kmldom::Type_Style) ) return poKmlStyleSelector; /***** is it a style map? *****/ else if ( poKmlStyleSelector->IsA( kmldom::Type_StyleMap) ) return StyleFromStyleMap(kmldom::AsStyleMap(poKmlStyleSelector), poStyleTable); /***** not a style or a style map *****/ return NULL; }
void ParseStyles ( DocumentPtr poKmlDocument, OGRStyleTable ** poStyleTable ) { /***** if document is null just bail now *****/ if ( !poKmlDocument ) return; /***** loop over the Styles *****/ size_t nKmlStyles = poKmlDocument->get_styleselector_array_size ( ); size_t iKmlStyle; /***** Lets first build the style table. *****/ /***** to begin this is just proper styles. *****/ for ( iKmlStyle = 0; iKmlStyle < nKmlStyles; iKmlStyle++ ) { StyleSelectorPtr poKmlStyle = poKmlDocument->get_styleselector_array_at ( iKmlStyle ); /***** Everything that is not a style you skip *****/ if ( !poKmlStyle->IsA ( kmldom::Type_Style ) ) continue; /***** We need to check to see if this is the first style. if it *****/ /***** is we will not have a style table and need to create one *****/ if ( !*poStyleTable ) *poStyleTable = new OGRStyleTable ( ); /***** TODO:: Not sure we need to do this as we seem *****/ /***** to cast to element and then back to style. *****/ ElementPtr poKmlElement = AsElement ( poKmlStyle ); kml2styletable ( *poStyleTable, AsStyle ( poKmlElement ) ); } /***** Now we have to loop back around and get the style maps. We *****/ /***** have to do this a second time since the stylemap might matter *****/ /***** and we are just looping reference styles that are farther *****/ /***** down in the file. Order through the XML as it is parsed. *****/ for ( iKmlStyle = 0; iKmlStyle < nKmlStyles; iKmlStyle++ ) { StyleSelectorPtr poKmlStyle = poKmlDocument->get_styleselector_array_at ( iKmlStyle ); /***** Everything that is not a stylemap you skip *****/ if ( !poKmlStyle->IsA ( kmldom::Type_StyleMap ) ) continue; /***** We need to check to see if this is the first style. if it *****/ /***** is we will not have a style table and need to create one *****/ if ( !*poStyleTable ) *poStyleTable = new OGRStyleTable ( ); /***** copy the style the style map points to since *****/ char *pszStyleMapId = CPLStrdup ( poKmlStyle->get_id().c_str ( ) ); poKmlStyle = StyleFromStyleMap(kmldom::AsStyleMap(poKmlStyle), *poStyleTable); if (poKmlStyle == NULL) { CPLFree(pszStyleMapId); continue; } char *pszStyleId = CPLStrdup ( poKmlStyle->get_id().c_str ( ) ); /***** TODO:: Not sure we need to do this as we seem *****/ /***** to cast to element and then back to style. *****/ ElementPtr poKmlElement = AsElement ( poKmlStyle ); kml2styletable ( *poStyleTable, AsStyle ( poKmlElement ) ); // Change the name of the new style in the style table const char *pszTest = NULL; pszTest = (*poStyleTable)->Find(pszStyleId); // If we found the style we want in the style table we... if ( pszTest ) { (*poStyleTable)->AddStyle(pszStyleMapId, pszTest); (*poStyleTable)->RemoveStyle ( pszStyleId ); } CPLFree ( pszStyleId ); CPLFree ( pszStyleMapId ); } return; }
void kml2featurestyle ( FeaturePtr poKmlFeature, OGRLIBKMLDataSource * poOgrDS, OGRLayer * poOgrLayer, OGRFeature * poOgrFeat ) { /***** does the placemark have a style url? *****/ if ( poKmlFeature->has_styleurl ( ) ) { const string poKmlStyleUrl = poKmlFeature->get_styleurl ( ); /***** is the name in the layer style table *****/ char *pszUrl = CPLStrdup ( poKmlStyleUrl.c_str ( ) ); OGRStyleTable *poOgrSTBLLayer; const char *pszTest = NULL; /***** is it a layer style ? *****/ if ( *pszUrl == '#' && ( poOgrSTBLLayer = poOgrLayer->GetStyleTable ( ) ) != NULL ) { pszTest = poOgrSTBLLayer->Find ( pszUrl + 1 ); } if ( pszTest ) { /***** should we resolve the style *****/ const char *pszResolve = CPLGetConfigOption ( "LIBKML_RESOLVE_STYLE", "no" ); if (CPLTestBool(pszResolve)) { poOgrFeat->SetStyleString ( pszTest ); } else { *pszUrl = '@'; poOgrFeat->SetStyleString( pszUrl ); } } /***** is it a dataset style? *****/ else { int nPathLen = static_cast<int>(strlen ( poOgrDS->GetStylePath ( ) )); if ( nPathLen == 0 || EQUALN ( pszUrl, poOgrDS->GetStylePath ( ), nPathLen )) { /***** should we resolve the style *****/ const char *pszResolve = CPLGetConfigOption ( "LIBKML_RESOLVE_STYLE", "no" ); if ( CPLTestBool(pszResolve) && ( poOgrSTBLLayer = poOgrDS->GetStyleTable ( ) ) != NULL && ( pszTest = poOgrSTBLLayer->Find ( pszUrl + nPathLen + 1) ) != NULL ) { poOgrFeat->SetStyleString ( pszTest ); } else { pszUrl[nPathLen] = '@'; poOgrFeat->SetStyleString ( pszUrl + nPathLen ); } } /**** its someplace else *****/ else { const char *pszFetch = CPLGetConfigOption ( "LIBKML_EXTERNAL_STYLE", "no" ); if ( CPLTestBool(pszFetch) ) { /***** load up the style table *****/ char *pszUrlTmp = CPLStrdup(pszUrl); char *pszPound = strchr(pszUrlTmp, '#'); if (pszPound != NULL) { *pszPound = '\0'; } /***** try it as a url then a file *****/ VSILFILE *fp = NULL; if ( (fp = VSIFOpenL( CPLFormFilename( "/vsicurl/", pszUrlTmp, NULL), "r" )) != NULL || (fp = VSIFOpenL( pszUrlTmp, "r" )) != NULL ) { char szbuf[1025]; std::string oStyle = ""; /***** loop, read and copy to a string *****/ size_t nRead; do { nRead = VSIFReadL(szbuf, 1, sizeof(szbuf) - 1, fp); if (nRead == 0) break; /***** copy buf to the string *****/ szbuf[nRead] = '\0'; oStyle.append( szbuf ); } while (!VSIFEofL(fp)); VSIFCloseL(fp); /***** parse the kml into the ds style table *****/ if ( poOgrDS->ParseIntoStyleTable (&oStyle, pszUrlTmp)) { kml2featurestyle (poKmlFeature, poOgrDS, poOgrLayer, poOgrFeat ); } else { /***** if failed just store the url *****/ poOgrFeat->SetStyleString ( pszUrl ); } } CPLFree(pszUrlTmp); } else { poOgrFeat->SetStyleString ( pszUrl ); } } } CPLFree ( pszUrl ); } /***** does the placemark have a style selector *****/ if ( poKmlFeature->has_styleselector ( ) ) { StyleSelectorPtr poKmlStyleSelector = poKmlFeature->get_styleselector ( ); /***** is the style a style? *****/ if ( poKmlStyleSelector->IsA ( kmldom::Type_Style ) ) { StylePtr poKmlStyle = AsStyle ( poKmlStyleSelector ); OGRStyleMgr *poOgrSM = new OGRStyleMgr; /***** if were resolving style the feature *****/ /***** might already have styling to add too *****/ const char *pszResolve = CPLGetConfigOption ( "LIBKML_RESOLVE_STYLE", "no" ); if (CPLTestBool(pszResolve)) { poOgrSM->InitFromFeature ( poOgrFeat ); } else { /***** if featyurestyle gets a name tool this needs changed to the above *****/ poOgrSM->InitStyleString ( NULL ); } /***** read the style *****/ kml2stylestring ( poKmlStyle, poOgrSM ); /***** add the style to the feature *****/ poOgrFeat->SetStyleString(poOgrSM->GetStyleString(NULL)); delete poOgrSM; } /***** is the style a stylemap? *****/ else if ( poKmlStyleSelector->IsA ( kmldom::Type_StyleMap ) ) { /* todo need to figure out what to do with a style map */ } } }