StyleSelectorPtr StyleFromStyleMap( const StyleMapPtr& poKmlStyleMap, OGRStyleTable * poStyleTable) { /***** check the config option to see if the *****/ /***** user wants normal or highlighted mapping *****/ const char *pszStyleMapKey = CPLGetConfigOption ( "LIBKML_STYLEMAP_KEY", "normal" ); int nStyleMapKey = STYLESTATE_NORMAL; if ( EQUAL (pszStyleMapKey, "highlight")) nStyleMapKey = STYLESTATE_HIGHLIGHT; /***** Loop through the stylemap pairs and look for the "normal" one *****/ for (size_t i = 0; i < poKmlStyleMap->get_pair_array_size(); ++i) { PairPtr myPair = poKmlStyleMap->get_pair_array_at(i); /***** is it the right one of the pair? *****/ if ( myPair->get_key() == nStyleMapKey ) { if (myPair->has_styleselector()) return StyleFromStyleSelector(myPair->get_styleselector(), poStyleTable); else if (myPair->has_styleurl()) return StyleFromStyleURL(poKmlStyleMap, myPair->get_styleurl(), poStyleTable); } } return NULL; }
StyleSelectorPtr StyleFromStyleURL( const StyleMapPtr& stylemap, const string styleurl, OGRStyleTable * poStyleTable) { // TODO:: Parse the styleURL char *pszUrl = CPLStrdup ( styleurl.c_str ( ) ); char *pszStyleMapId = CPLStrdup ( stylemap->get_id().c_str ( ) ); /***** is it an interenal style ref that starts with a # *****/ if ( *pszUrl == '#' && poStyleTable ) { /***** searh the style table for the style we *****/ /***** want and copy it back into the table *****/ const char *pszTest = NULL; pszTest = poStyleTable->Find ( pszUrl + 1 ); if ( pszTest ) { poStyleTable->AddStyle(pszStyleMapId, pszTest); } } /***** We have a real URL and need to go out and fetch it *****/ /***** FIXME this could be a relative path in a kmz *****/ else if ( strchr(pszUrl, '#') ) { const char *pszFetch = CPLGetConfigOption ( "LIBKML_EXTERNAL_STYLE", "no" ); if ( EQUAL(pszFetch, "yes") ) { /***** Lets go out and fetch the style from the external URL *****/ char *pszUrlTmp = CPLStrdup(pszUrl); char *pszPound; char *pszRemoteStyleName = NULL; // Chop off the stuff (style id) after the URL if ((pszPound = strchr(pszUrlTmp, '#'))) { *pszPound = '\0'; pszRemoteStyleName = pszPound + 1; } /***** try it as a url then a file *****/ VSILFILE *fp = NULL; if ( (fp = VSIFOpenL( CPLFormFilename( "/vsicurl/", pszUrlTmp, NULL), "r" )) || (fp = VSIFOpenL( pszUrlTmp, "r" )) ) { 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 dom *****/ std::string oKmlErrors; ElementPtr poKmlRoot = kmldom::Parse ( oStyle, &oKmlErrors ); if ( !poKmlRoot ) { CPLError ( CE_Failure, CPLE_OpenFailed, "ERROR Parseing style kml %s :%s", pszUrlTmp, oKmlErrors.c_str ( ) ); CPLFree(pszUrlTmp); CPLFree ( pszUrl ); CPLFree ( pszStyleMapId ); return NULL; } /***** get the root container *****/ ContainerPtr poKmlContainer; kmldom::KmlFactory* poKmlFactory = kmldom::KmlFactory::GetFactory(); if ( !( poKmlContainer = MyGetContainerFromRoot ( poKmlFactory, poKmlRoot ) ) ) { CPLFree(pszUrlTmp); CPLFree ( pszUrl ); CPLFree ( pszStyleMapId ); return NULL; } /**** parse the styles into the table *****/ ParseStyles ( AsDocument ( poKmlContainer ), &poStyleTable ); /***** look for the style we leed to map to in the table *****/ const char *pszTest = NULL; pszTest = poStyleTable->Find(pszRemoteStyleName); /***** if found copy it to the table as a new style *****/ if ( pszTest ) poStyleTable->AddStyle(pszStyleMapId, pszTest); } CPLFree(pszUrlTmp); } } /***** FIXME add suport here for relative links inside kml *****/ CPLFree ( pszUrl ); CPLFree ( pszStyleMapId ); return NULL; }
void styletable2kml ( OGRStyleTable * poOgrStyleTable, KmlFactory * poKmlFactory, ContainerPtr poKmlContainer, char** papszOptions ) { /***** just return if the styletable is null *****/ if ( !poOgrStyleTable ) return; std::set<CPLString> aoSetNormalStyles; std::set<CPLString> aoSetHighlightStyles; poOgrStyleTable->ResetStyleStringReading ( ); const char *pszStyleString; /* Collect styles that end with _normal or _highlight */ while ( poOgrStyleTable->GetNextStyle ( ) != NULL ) { const char *pszStyleName = poOgrStyleTable->GetLastStyleName ( ); if( strlen(pszStyleName) > strlen("_normal") && EQUAL(pszStyleName + strlen(pszStyleName) - strlen("_normal"), "_normal") ) { CPLString osName(pszStyleName); osName.resize(strlen(pszStyleName) - strlen("_normal")); aoSetNormalStyles.insert(osName); } else if( strlen(pszStyleName) > strlen("_highlight") && EQUAL(pszStyleName + strlen(pszStyleName) - strlen("_highlight"), "_highlight") ) { CPLString osName(pszStyleName); osName.resize(strlen(pszStyleName) - strlen("_highlight")); aoSetHighlightStyles.insert(osName); } } /***** parse the style table *****/ poOgrStyleTable->ResetStyleStringReading ( ); while ( ( pszStyleString = poOgrStyleTable->GetNextStyle ( ) ) != NULL ) { const char *pszStyleName = poOgrStyleTable->GetLastStyleName ( ); if( aoSetNormalStyles.find(pszStyleName) != aoSetNormalStyles.end() && aoSetHighlightStyles.find(pszStyleName) != aoSetHighlightStyles.end() ) { continue; } /***** add the style header to the kml *****/ StylePtr poKmlStyle = poKmlFactory->CreateStyle ( ); poKmlStyle->set_id ( pszStyleName ); /***** parse the style string *****/ addstylestring2kml ( pszStyleString, poKmlStyle, poKmlFactory, NULL ); /***** add balloon style *****/ const char* pszBalloonStyleBgColor = CSLFetchNameValue(papszOptions, CPLSPrintf("%s_balloonstyle_bgcolor", pszStyleName)); const char* pszBalloonStyleText = CSLFetchNameValue(papszOptions, CPLSPrintf("%s_balloonstyle_text", pszStyleName)); int nR, nG, nB, nA; OGRStylePen oStyleTool; if( (pszBalloonStyleBgColor != NULL && oStyleTool.GetRGBFromString ( pszBalloonStyleBgColor, nR, nG, nB, nA ) ) || pszBalloonStyleText != NULL ) { BalloonStylePtr poKmlBalloonStyle = poKmlFactory->CreateBalloonStyle(); if( pszBalloonStyleBgColor != NULL && oStyleTool.GetRGBFromString ( pszBalloonStyleBgColor, nR, nG, nB, nA ) ) poKmlBalloonStyle->set_bgcolor ( Color32 ( static_cast<GByte>(nA), static_cast<GByte>(nB), static_cast<GByte>(nG), static_cast<GByte>(nR) ) ); if( pszBalloonStyleText != NULL ) poKmlBalloonStyle->set_text(pszBalloonStyleText); poKmlStyle->set_balloonstyle ( poKmlBalloonStyle ); } /***** add the style to the container *****/ DocumentPtr poKmlDocument = AsDocument ( poKmlContainer ); poKmlDocument->add_styleselector ( poKmlStyle ); } /* Find style name that end with _normal and _highlight to create */ /* a StyleMap from both */ std::set<CPLString>::iterator aoSetNormalStylesIter = aoSetNormalStyles.begin(); for( ; aoSetNormalStylesIter != aoSetNormalStyles.end(); ++aoSetNormalStylesIter ) { CPLString osStyleName(*aoSetNormalStylesIter); if( aoSetHighlightStyles.find(osStyleName) != aoSetHighlightStyles.end() ) { StyleMapPtr poKmlStyleMap = poKmlFactory->CreateStyleMap ( ); poKmlStyleMap->set_id ( osStyleName ); PairPtr poKmlPairNormal = poKmlFactory->CreatePair ( ); poKmlPairNormal->set_key(STYLESTATE_NORMAL); poKmlPairNormal->set_styleurl(CPLSPrintf("#%s_normal", osStyleName.c_str())); poKmlStyleMap->add_pair(poKmlPairNormal); PairPtr poKmlPairHightlight = poKmlFactory->CreatePair ( ); poKmlPairHightlight->set_key(STYLESTATE_HIGHLIGHT); poKmlPairHightlight->set_styleurl(CPLSPrintf("#%s_highlight", osStyleName.c_str())); poKmlStyleMap->add_pair(poKmlPairHightlight); /***** add the style to the container *****/ DocumentPtr poKmlDocument = AsDocument ( poKmlContainer ); poKmlDocument->add_styleselector ( poKmlStyleMap ); } } return; }
/** * @brief KmlExport::CreateLineStringPlacemark Adds a line segment which is colored according to the * vehicle's speed. * @param startPoint Beginning point along line * @param endPoint End point point along line * @return Returns the placemark containing the line segment */ PlacemarkPtr KmlExport::CreateLineStringPlacemark(const LLAVCoordinates &startPoint, const LLAVCoordinates &endPoint, quint32 newPlacemarkTime) { CoordinatesPtr coordinates = factory->CreateCoordinates(); coordinates->add_latlngalt(startPoint.latitude, startPoint.longitude, startPoint.altitude); coordinates->add_latlngalt(endPoint.latitude, endPoint.longitude, endPoint.altitude); LineStringPtr linestring = factory->CreateLineString(); linestring->set_extrude(true); // Extrude to ground linestring->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE); linestring->set_coordinates(coordinates); StyleMapPtr styleMap = factory->CreateStyleMap(); // Add custom balloon style (gets rid of "Directions to here...") // https://groups.google.com/forum/?fromgroups#!topic/kml-support-getting-started/2CqF9oiynRY BalloonStylePtr balloonStyle = factory->CreateBalloonStyle(); balloonStyle->set_text("$[description]"); { double currentVelocity = (startPoint.groundspeed + endPoint.groundspeed)/2; // Set the linestyle. The color is a function of speed. LineStylePtr lineStyle = factory->CreateLineStyle(); lineStyle->set_color(mapVelocity2Color(currentVelocity)); PolyStylePtr polyStyle = factory->CreatePolyStyle(); polyStyle->set_color(mapVelocity2Color(currentVelocity, 100)); // Link the style to the icon StylePtr style = factory->CreateStyle(); style->set_balloonstyle(balloonStyle); style->set_linestyle(lineStyle); style->set_polystyle(polyStyle); PairPtr pair = factory->CreatePair(); pair->set_styleselector(style); pair->set_key(kmldom::STYLESTATE_NORMAL); styleMap->add_pair(pair); } { double currentVelocity = (startPoint.groundspeed + endPoint.groundspeed)/2; // Set the linestyle. The color is a function of speed. LineStylePtr lineStyle = factory->CreateLineStyle(); lineStyle->set_color(mapVelocity2Color(currentVelocity)); PolyStylePtr polyStyle = factory->CreatePolyStyle(); polyStyle->set_color(mapVelocity2Color(currentVelocity, 100)); polyStyle->set_fill(false); // Link the style to the icon StylePtr style = factory->CreateStyle(); style->set_balloonstyle(balloonStyle); style->set_linestyle(lineStyle); style->set_polystyle(polyStyle); PairPtr pair = factory->CreatePair(); pair->set_styleselector(style); pair->set_key(kmldom::STYLESTATE_HIGHLIGHT); styleMap->add_pair(pair); } PlacemarkPtr placemark = factory->CreatePlacemark(); placemark->set_geometry(linestring); placemark->set_styleselector(styleMap); placemark->set_visibility(true); // Create the timespan TimeSpanPtr timeSpan = factory->CreateTimeSpan(); QDateTime startTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); // FIXME: Make this a function of the true time, preferably gotten from the GPS QDateTime endTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); timeSpan->set_begin(startTime.toString(dateTimeFormat).toStdString()); timeSpan->set_end(endTime.toString(dateTimeFormat).toStdString()); // Set the name QDateTime trackTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); // FIXME: Make it a function of the realtime preferably gotten from the GPS placemark->set_name(trackTime.toString(dateTimeFormat).toStdString()); // Add a nice description to the track placemark placemark->set_description(informationString.toStdString()); // Set the timespan placemark->set_timeprimitive(timeSpan); return placemark; }
StyleMapPtr KmlExport::createWallAxesStyle() { StyleMapPtr styleMap = factory->CreateStyleMap(); { // Add custom balloon style (gets rid of "Directions to here...") // https://groups.google.com/forum/?fromgroups#!topic/kml-support-getting-started/2CqF9oiynRY BalloonStylePtr balloonStyle = factory->CreateBalloonStyle(); balloonStyle->set_text("$[id]"); // Create an icon style IconStylePtr iconStyle = factory->CreateIconStyle(); iconStyle->set_scale(0); // Create a label style LabelStylePtr labelStyle = factory->CreateLabelStyle(); labelStyle->set_color(kmlbase::Color32(255, 0, 255, 255)); labelStyle->set_scale(0); // Create a line style LineStylePtr lineStyle = factory->CreateLineStyle(); lineStyle->set_color(kmlbase::Color32(255, 0, 0, 0)); // Black lineStyle->set_width(.9); // Link the style to the icon StylePtr style = factory->CreateStyle(); style->set_balloonstyle(balloonStyle); style->set_iconstyle(iconStyle); style->set_linestyle(lineStyle); style->set_labelstyle(labelStyle); PairPtr pair = factory->CreatePair(); pair->set_styleselector(style); pair->set_key(kmldom::STYLESTATE_NORMAL); styleMap->add_pair(pair); } { // Add custom balloon style (gets rid of "Directions to here...") // https://groups.google.com/forum/?fromgroups#!topic/kml-support-getting-started/2CqF9oiynRY BalloonStylePtr balloonStyle = factory->CreateBalloonStyle(); balloonStyle->set_text("$[id]"); // Create an icon style IconStylePtr iconStyle = factory->CreateIconStyle(); iconStyle->set_scale(0); // Create a label style LabelStylePtr labelStyle = factory->CreateLabelStyle(); labelStyle->set_color(kmlbase::Color32(255, 0, 255, 255)); labelStyle->set_scale(0.75); // Create a line style LineStylePtr lineStyle = factory->CreateLineStyle(); lineStyle->set_color(kmlbase::Color32(255, 0, 0, 0)); // Black lineStyle->set_width(1.8); // Link the style to the icon StylePtr style = factory->CreateStyle(); style->set_balloonstyle(balloonStyle); style->set_iconstyle(iconStyle); style->set_linestyle(lineStyle); style->set_labelstyle(labelStyle); PairPtr pair = factory->CreatePair(); pair->set_styleselector(style); pair->set_key(kmldom::STYLESTATE_HIGHLIGHT); styleMap->add_pair(pair); } styleMap->set_id("ts_1_tb"); return styleMap; }
/** * @brief KmlExport::createCustomBalloonStyle Creates a custom balloon stye, using an arrow as an icon. * @return Returns the custom balloon style. */ StyleMapPtr KmlExport::createCustomBalloonStyle() { StyleMapPtr styleMap = factory->CreateStyleMap(); { // Add custom balloon style (gets rid of "Directions to here...") // https://groups.google.com/forum/?fromgroups#!topic/kml-support-getting-started/2CqF9oiynRY BalloonStylePtr balloonStyle = factory->CreateBalloonStyle(); balloonStyle->set_text("$[description]"); // Change the icon IconStyleIconPtr iconStyleIcon = factory->CreateIconStyleIcon(); iconStyleIcon->set_href("http://maps.google.com/mapfiles/kml/shapes/arrow.png"); // Create a label style LabelStylePtr labelStyle = factory->CreateLabelStyle(); labelStyle->set_color(kmlbase::Color32(255, 0, 255, 255)); labelStyle->set_scale(0.75); // Create an icon style IconStylePtr iconStyle = factory->CreateIconStyle(); iconStyle->set_icon(iconStyleIcon); iconStyle->set_scale(0.65); // Create a line style LineStylePtr lineStyle = factory->CreateLineStyle(); lineStyle->set_width(3.25); // Link the style to the icon StylePtr style = factory->CreateStyle(); style->set_balloonstyle(balloonStyle); style->set_iconstyle(iconStyle); style->set_linestyle(lineStyle); style->set_labelstyle(labelStyle); PairPtr pair = factory->CreatePair(); pair->set_styleselector(style); pair->set_key(kmldom::STYLESTATE_NORMAL); styleMap->add_pair(pair); } { // Add custom balloon style (gets rid of "Directions to here...") // https://groups.google.com/forum/?fromgroups#!topic/kml-support-getting-started/2CqF9oiynRY BalloonStylePtr balloonStyle = factory->CreateBalloonStyle(); balloonStyle->set_text("$[description]"); // Change the icon IconStyleIconPtr iconStyleIcon = factory->CreateIconStyleIcon(); iconStyleIcon->set_href("http://maps.google.com/mapfiles/kml/shapes/arrow.png"); // Create an icon style IconStylePtr iconStyle = factory->CreateIconStyle(); iconStyle->set_icon(iconStyleIcon); iconStyle->set_scale(0.65); // Create a label style LabelStylePtr labelStyle = factory->CreateLabelStyle(); labelStyle->set_color(kmlbase::Color32(255, 0, 255, 255)); labelStyle->set_scale(0.9); // Create a line style LineStylePtr lineStyle = factory->CreateLineStyle(); lineStyle->set_width(6.5); // Link the style to the icon StylePtr style = factory->CreateStyle(); style->set_balloonstyle(balloonStyle); style->set_iconstyle(iconStyle); style->set_linestyle(lineStyle); style->set_labelstyle(labelStyle); PairPtr pair = factory->CreatePair(); pair->set_styleselector(style); pair->set_key(kmldom::STYLESTATE_HIGHLIGHT); styleMap->add_pair(pair); } styleMap->set_id("directiveArrowStyle"); return styleMap; }