void GEUIDialog::SetCursorLatLon(double lat, double lon) { LogDebugMessage(wxString::Format(_T("Following the cursor to %f, %f requested"), lat, lon)); DetachIfNeeded(m_camera_azimuth, m_camera_range, m_camera_tilt); if (!m_cbConnected->GetValue()) { LogDebugMessage(_T("Not following as the checkbox is not checked")); return; } m_hotspot_lon = lon; m_hotspot_lat = lat; GEMoveCamera(); }
int RunSystemCommand(const gxString &input_command, const gxString &user, const gxString &group) { gxString superuser = "******"; gxString command; if(servercfg->cluster_user == superuser) { #ifdef __HAS_SU_DASH_G__ command << clear << "su -g " << group << " -c \'" << input_command << "\' - " << user << " >/dev/null 2>&1"; #else command << clear << "su -c \'" << input_command << "\' - " << user << " >/dev/null 2>&1"; #endif } else { #ifdef __HAS_SU_DASH_G__ command << clear << servercfg->sudo_command << " \"su -g " << group << " -c \'" << input_command << "\' - " << user << "\""; #else command << clear << servercfg->sudo_command << " \"su -c \'" << input_command << "\' - " << user << "\""; #endif } if(servercfg->debug && servercfg->debug_level >= 5) { LogDebugMessage(command.c_str()); } return system(command.c_str()); }
// Discover the components that should be explicitly included. // These are any included top components. void GoogleVssClient::DiscoverExplicitelyIncludedComponents() { LogDebugMessage(L"Discover explicitly included components ..."); // Enumerate all writers. for (unsigned idx = 0; idx < writers_.size(); idx++) { VssWriter* writer = &writers_[idx]; if (writer->isExcluded) { continue; } // Compute the roots of included components. for (unsigned i = 0; i < writer->components.size(); i++) { VssComponent* component = &(writer->components[i]); if (!component->CanBeExplicitlyIncluded()) { continue; } // Test if our component has a parent that is also included. component->isExplicitlyIncluded = true; for (unsigned j = 0; j < writer->components.size(); j++) { VssComponent* ancestor = &(writer->components[j]); if (ancestor->IsAncestorOf(*component) && ancestor->CanBeExplicitlyIncluded()) { // This cannot be explicitely included since we have another // ancestor that that must be implictely or explicitely included. component->isExplicitlyIncluded = false; break; } } } } }
bool gecomapi_pi::LoadConfig(void) { wxFileConfig *pConf = (wxFileConfig *)m_pconfig; if(pConf) { pConf->SetPath( _T("/PlugIns/GoogleEarth") ); wxString config; pConf->Read( _T( "WindowWidth" ), &m_iWindowWidth, DEFAULT_WIDTH ); pConf->Read( _T( "WindowHeight" ), &m_iWindowHeight, DEFAULT_HEIGHT ); pConf->Read( _T( "WindowFloating" ), &m_bWindowFloating, DEFAULT_FLOATING ); pConf->Read( _T( "AlwaysStartHidden" ), &m_bstartHidden, true ); pConf->Read( _T( "DisconnectOnGEAction" ), &m_bdisconnectOnGEAction, true ); pConf->Read( _T( "UpdateSettingsFromGE" ), &m_bupdateSettingsFromGE, true ); pConf->Read( _T( "ShowBoatInGE" ), &m_bShowBoatInGE, true ); pConf->Read( _T( "WhatToFollow" ), &m_iWhatToFollow, GECOMAPI_FOLLOW_VIEW ); //1-Cursor, 2-boat, 3-View, 0-Nothing pConf->Read( _T( "CameraAzimuth" ), &m_iCameraAzimuth, 0 ); pConf->Read( _T( "CameraTilt" ), &m_iCameraTilt, 0 ); pConf->Read( _T( "CameraRange" ), &m_iCameraRange, 0 ); pConf->Read( _T( "WindowOpacity" ), &m_iOpacity, 255 ); LogDebugMessage(wxString::Format(_T("Config params loaded: WW=%d, ASH=%d, DGA=%d, USG=%d, SB=%d, WF=%d, Az=%d, Ti=%d, Ra=%d, Opa=%d"), m_iWindowWidth, m_bstartHidden, m_bdisconnectOnGEAction, m_bupdateSettingsFromGE, m_bShowBoatInGE, m_iWhatToFollow, m_iCameraAzimuth, m_iCameraTilt, m_iCameraRange, m_iOpacity)); return true; } else return false; }
bool gecomapi_pi::SaveConfig(void) { wxFileConfig *pConf = (wxFileConfig *)m_pconfig; if(pConf) { pConf->SetPath( _T( "/PlugIns/GoogleEarth" ) ); pConf->Write( _T( "WindowWidth" ), m_iWindowWidth ); pConf->Write( _T( "WindowHeight" ), m_iWindowHeight ); pConf->Write( _T( "WindowFloating" ), m_bWindowFloating ); pConf->Write( _T( "AlwaysStartHidden" ), m_bstartHidden ); pConf->Write( _T( "DisconnectOnGEAction" ), m_bdisconnectOnGEAction ); pConf->Write( _T( "UpdateSettingsFromGE" ), m_bupdateSettingsFromGE ); pConf->Write( _T( "ShowBoatInGE" ), m_bShowBoatInGE ); pConf->Write( _T( "WhatToFollow" ), m_iWhatToFollow ); pConf->Write( _T( "CameraAzimuth" ), m_iCameraAzimuth ); pConf->Write( _T( "CameraTilt" ), m_iCameraTilt ); pConf->Write( _T( "CameraRange" ), m_iCameraRange ); pConf->Write( _T( "WindowOpacity" ), m_iOpacity ); LogDebugMessage(wxString::Format(_T("Config params saved: WW=%d, ASH=%d, DGA=%d, USG=%d, SB=%d, WF=%d, Az=%d, Ti=%d, Ra=%d, Opa=%d"), m_iWindowWidth, m_bstartHidden, m_bdisconnectOnGEAction, m_bupdateSettingsFromGE, m_bShowBoatInGE, m_iWhatToFollow, m_iCameraAzimuth, m_iCameraTilt, m_iCameraRange, m_iOpacity)); return true; } else return false; }
GEUIDialog::GEUIDialog(wxWindow *pparent, wxWindowID id, wxAuiManager *auimgr, int tbitem, gecomapi_pi *ppi) :wxPanel(pparent, id, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE, _T("GoogleEarth")) { pPlugIn = ppi; LogDebugMessage(_T("Constructing the GE plugin window")); m_pauimgr = auimgr; m_toolbar_item_id = tbitem; m_ballowStart = false; m_bshouldcatchup = true; m_bbusy = false; m_pfocusedwindow = FindFocus(); GEParentHwnd = NULL; this->SetSizeHints( wxDefaultSize, wxDefaultSize ); itemBoxSizer = new wxBoxSizer(wxVERTICAL); SetSizerAndFit(itemBoxSizer); m_panel1 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); itemBoxSizer->Add( m_panel1, 1, wxEXPAND | wxALL, 5 ); itemBoxSizer1 = new wxBoxSizer(wxHORIZONTAL); itemBoxSizer->Add(itemBoxSizer1, 0, wxEXPAND); m_cbConnected = new wxCheckBox( this, wxID_ANY, _("Connected to chart viewport"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer1->Add( m_cbConnected, 0, wxALIGN_RIGHT|wxALL, 10 ); m_buttonSave = new wxButton( this, wxID_ANY, _("Save view..."), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer1->Add( m_buttonSave, 0, wxALIGN_RIGHT|wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 5 ); this->Layout(); this->Centre( wxBOTH ); Connect(this->GetId(), wxEVT_SIZE, wxSizeEventHandler(GEUIDialog::OnSize)); Connect(this->GetId(), wxEVT_SHOW, wxShowEventHandler(GEUIDialog::OnShow)); app = NULL; m_bgeisuseable = false; m_binitializing = false; m_bclosed = false; m_bisfollowingboat = false; //LogDebugMessage(_T("GE plugin window created, going to start GE")); //GEInitialize(); m_buttonSave->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GEUIDialog::SaveView ), NULL, this ); m_cbConnected->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( GEUIDialog::ConnectedClicked ), NULL, this ); ConnectToGE(); m_stopwatch.Start(); m_stopwatch_boat.Start(); m_pPositions = new PositionsList(); m_sEnvelopeKmlFilename = wxStandardPaths::Get().GetTempDir() + _T("\\gecomapi.kml"); m_sLiveKmlFilename = wxStandardPaths::Get().GetTempDir() + _T("\\gecomapilive.kml"); m_pdialog = new GESaveViewDlgImpl(this, wxID_ANY, _("Save view"), wxDefaultPosition, wxSize( -1,-1 ), wxDEFAULT_DIALOG_STYLE ); }
void GEUIDialog::OnShow(wxShowEvent& event) { LogDebugMessage(_T("GE plugin - OnShow event")); if(m_ballowStart) GEInitialize(); SetToolbarItemState(m_toolbar_item_id, IsShown()); event.Skip(); }
// Discover excluded writers. These are writers that: // - either have a top-level nonselectable excluded component, // - do not have any included components while all its components are excluded. void GoogleVssClient::DiscoverExcludedWriters() { LogDebugMessage(L"Discover excluded writers ..."); // Enumerate writers. for (unsigned idx = 0; idx < writers_.size(); idx++) { VssWriter* writer = &writers_[idx]; if (writer->isExcluded) { continue; } // Discover if we have any: // - non-excluded selectable components, // - non-excluded top-level non-selectable components. // If we have none, then the whole writer must be excluded from the backup. writer->isExcluded = true; for (unsigned i = 0; i < writer->components.size(); i++) { VssComponent* component = &(writer->components[i]); if (component->CanBeExplicitlyIncluded()) { writer->isExcluded = false; break; } } // No included components were found. if (writer->isExcluded) { LogDebugMessage( L"The writer '%s' is now excluded from the backup (it does not " L"contain any components that should be included in the backup).", writer->name.c_str()); continue; } // Now, discover if we have any top-level excluded non-selectable component. // If this is true, then the whole writer must be excluded from the backup. for (unsigned i = 0; i < writer->components.size(); i++) { VssComponent* component = &(writer->components[i]); if (component->isTopLevel && !component->isSelectable && component->isExcluded) { LogDebugMessage( L"The writer '%s' is now excluded from the backup (the top-level " L"non-selectable component '%s' is an excluded component).", writer->name.c_str(), component->fullPath.c_str()); writer->isExcluded = true; break; } } } }
void GEUIDialog::OnSize ( wxSizeEvent& event ) { LogDebugMessage(_T("GE plugin - OnSize event")); GEResize(); if (m_pfocusedwindow) m_pfocusedwindow->SetFocus(); //returns focus - don't know why, but seems needed pPlugIn->m_iWindowWidth = this->GetSize().GetWidth(); pPlugIn->m_iWindowHeight = this->GetSize().GetHeight(); event.Skip(); }
bool GEUIDialog::GEReadViewParameters(double& lat, double& lon, double& alt, double& azimuth, double& range, double& tilt) { LogDebugMessage(_T("GE View parameters requested")); while ( m_bbusy ) ; m_bbusy = true; int interval = m_stopwatch.Time(); if (interval > CAMERA_MOVE_INTERVAL * 10) m_stopwatch.Start(); //Things got crazy, it's time to let it settle down... if(NULL != app && m_bgeisuseable) { LogDebugMessage(_T("Getting GE view parameters")); try { ICameraInfoGE* camera; app->raw_GetCamera(false, &camera); if (NULL != camera) { lat = camera->FocusPointLatitude; lon = camera->FocusPointLongitude; alt = camera->FocusPointAltitude; azimuth = camera->Azimuth; range = camera->Range; tilt = camera->Tilt; } else { m_bgeisuseable = false; app = NULL; } } catch(...) { LogDebugMessage(_T("Error geting GE view parameters")); } LogDebugMessage(wxString::Format(_T("GE view parameters obtained: lat=%f, lon=%f, alt=%f, azimuth=%f, range=%f, tilt=%f"), lat, lon, alt, azimuth, range, tilt)); m_bbusy = false; return true; } m_bbusy = false; return false; }
void gecomapi_pi::SetCurrentViewPort(PlugIn_ViewPort &vp) { if (vp.clat == m_pastVp.clat && vp.clon == m_pastVp.clon && vp.pix_height == m_pastVp.pix_height && vp.pix_width == m_pastVp.pix_width && vp.rotation == m_pastVp.rotation && vp.chart_scale == m_pastVp.chart_scale && vp.lat_max == m_pastVp.lat_max && vp.lat_min == m_pastVp.lat_min && vp.lon_max == m_pastVp.lon_max && vp.lon_min == m_pastVp.lon_min && vp.view_scale_ppm == m_pastVp.view_scale_ppm) { return; //Prevents event storm killing the responsiveness. At least in course-up it looks needed. } m_pastVp = vp; if (m_bshuttingDown) return; LogDebugMessage(_T("SetCurrentViewPort called by OpenCPN")); if(m_iWhatToFollow == GECOMAPI_FOLLOW_VIEW && m_pgecomapi_window) { m_pgecomapi_window->SetViewPort(vp.clat, vp.clon, vp.lat_max - vp.lat_min, vp.lon_max - vp.lon_min, vp.rotation); } }
// Removes entries from the system registry. STDAPI DllUnregisterServer(void) { CComPtr<IVssAdmin> vssAdmin; HRESULT hr = CoCreateInstance( CLSID_VSSCoordinator, NULL, CLSCTX_ALL, IID_IVssAdmin, reinterpret_cast<void**>(&vssAdmin)); if (SUCCEEDED(hr)) { hr = vssAdmin->UnregisterProvider(kGooglsVssProviderId); if (FAILED(hr)) { LogDebugMessage(L"Error(%x) was returned calling UnregisterProvider.", hr); } } hr = _AtlModule.DllUnregisterServer(); vssAdmin.Release(); return hr; }
int RunSystemCommand(const gxString &input_command) { gxString superuser = "******"; gxString command; if(servercfg->cluster_user == superuser) { command = input_command; } else { command << clear << servercfg->sudo_command << " \'" << input_command << "\'"; } if(servercfg->debug && servercfg->debug_level >= 5) { LogDebugMessage(command.c_str()); } return system(command.c_str()); }
BOOL RTT4TCPAccessor::SetConnectingSocket(const SOCKET& socketHandler, const struct sockaddr_in* pAddress) { BOOL bUse = TRUE; setsockopt(socketHandler, SOL_SOCKET, SO_REUSEADDR, (const char*)&bUse, sizeof(bUse)); int nResult = 0; TCHAR szError[BUFFER_SIZE] = {0}; nResult = connect(socketHandler, (const sockaddr*)pAddress, sizeof(*pAddress)); if (nResult == SOCKET_ERROR) { _stprintf_s(szError, _countof(szError), _T("[ERROR] connect() : %d"), WSAGetLastError()); ReportError(szError); LogDebugMessage(Log_Error, szError); closesocket(socketHandler); return FALSE; } return TRUE; }
bool GEUIDialog::GEMoveCamera() { LogDebugMessage(wxString::Format(_T("GE camera move to %f, %f requested"), m_hotspot_lat, m_hotspot_lon, m_camera_range, m_camera_tilt, m_camera_azimuth)); int interval = m_stopwatch.Time(); m_prev_camera_azimuth = m_camera_azimuth; m_prev_camera_range = m_camera_range; m_prev_camera_tilt = m_camera_tilt; if (m_bbusy) { LogDebugMessage(_T("GE camera move request discarded, GE busy")); m_bshouldcatchup = true; return false; } if (interval < CAMERA_MOVE_INTERVAL) // If it is less than CAMERA_MOVE_INTERVAL since last request, don't move the camera { LogDebugMessage(_T("GE camera move request discarded, too soon after a previous action")); m_bshouldcatchup = true; return false; } m_stopwatch.Start(); if(NULL != app && m_bgeisuseable) { LogDebugMessage(_T("Moving GE camera")); //app->raw_GetCamera(false, &camera); //camera->PutFocusPointLatitude(m_hotspot_lat); //camera->PutFocusPointLongitude(m_hotspot_lon); //camera->PutAzimuth(m_camera_azimuth); //north up //camera->PutFocusPointAltitude(0.0); //focus point on sea level //camera->PutRange(m_camera_range); //camera 1000 meters high //camera->PutTilt(0.0); //camera directly over a focus point //app->raw_SetCamera(camera, 1.0); //1.0 - how fast the camera gets there try { app->SetCameraParams(m_hotspot_lat, m_hotspot_lon, 0.0, AbsoluteAltitudeGE, m_camera_range, m_camera_tilt, m_camera_azimuth, 5.0); LogDebugMessage(_T("GE camera moved")); } catch(...) { LogDebugMessage(_T("Error moving GE camera")); return false; } return true; } LogDebugMessage(_T("Not moving the camera, GE looks unusable")); return false; }
SOCKET RTT4TCPAccessor::InitializeTCPSocket(struct sockaddr_in* pAddress, LPCSTR szAddress, BOOL bSend, USHORT uPort) { SOCKET socketHandler; TCHAR szError[BUFFER_SIZE]; socketHandler = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (socketHandler == INVALID_SOCKET) { _stprintf_s(szError, _countof(szError), _T("[ERROR] socket() : %d"), WSAGetLastError()); ReportError(szError); LogDebugMessage(Log_Error, szError); return socketHandler; } pAddress->sin_family = AF_INET; pAddress->sin_port = htons(uPort); if (bSend) { pAddress->sin_addr.S_un.S_addr = inet_addr(szAddress); } else { pAddress->sin_addr.S_un.S_addr = INADDR_ANY; } return socketHandler; }
// Check the status for all selected writers. HRESULT GoogleVssClient::CheckSelectedWriterStatus() { // Gather writer status to detect potential errors. HRESULT hr = GatherWriterStatus(); if (SUCCEEDED(hr)) { // Gets the number of writers in the gathered status info // (WARNING: GatherWriterStatus must be called before). unsigned writers = 0; hr = vss_object_->GetWriterStatusCount(&writers); if (FAILED(hr)) { LogDebugMessage(L"GetWriterStatusCount failed with error %x ", hr); } else { // Enumerate each writer. HRESULT hrWriterFailure = S_OK; for (unsigned writer = 0; writer < writers; writer++) { VSS_ID idInstance = GUID_NULL; VSS_ID idWriter = GUID_NULL; VSS_WRITER_STATE writerStatus = VSS_WS_UNKNOWN; CComBSTR bstrWriterName; // Get writer status. hr = vss_object_->GetWriterStatus(writer, &idInstance, &idWriter, &bstrWriterName, &writerStatus, &hrWriterFailure); // If the writer is not selected, just continue. if (!IsWriterSelected(idInstance)) { continue; } // If the writer is in non-stable state, break. switch (writerStatus) { case VSS_WS_FAILED_AT_IDENTIFY: case VSS_WS_FAILED_AT_PREPARE_BACKUP: case VSS_WS_FAILED_AT_PREPARE_SNAPSHOT: case VSS_WS_FAILED_AT_FREEZE: case VSS_WS_FAILED_AT_THAW: case VSS_WS_FAILED_AT_POST_SNAPSHOT: case VSS_WS_FAILED_AT_BACKUP_COMPLETE: case VSS_WS_FAILED_AT_PRE_RESTORE: case VSS_WS_FAILED_AT_POST_RESTORE: // Print writer status. LogDebugMessage( L"ERROR: Selected writer '%s' is in failed state." L" Status: %d (%s), Writer Failure code: 0x%08lx," L" Writer ID: " WSTR_GUID_FMT L" Instance ID: " WSTR_GUID_FMT, BstrToWString(bstrWriterName).c_str(), writerStatus, GetStringFromWriterStatus(writerStatus).c_str(), hrWriterFailure, GUID_PRINTF_ARG(idWriter), GUID_PRINTF_ARG(idInstance)); // Stop here. hr = E_UNEXPECTED; break; default: break; } if (FAILED(hr)) { break; } } } } LogDebugMessage(L"CheckSelectedWriterStatus returned with %x", hr); return hr; }
void GEUIDialog::GEInitialize() { LogDebugMessage(_T("GE initialization requested")); if (NULL == app && !m_bgeisuseable & !m_binitializing & !m_bclosed) { m_binitializing = true; LogDebugMessage(_T("Initializing GE")); if (pPlugIn->IsProcessRunningByName(_T("googleearth.exe"))) { LogDebugMessage(_T("GE found running, killing it")); if (pPlugIn->KillProcessByName(_T("googleearth.exe"))) LogDebugMessage(_T("GE killed")); else LogDebugMessage(_T("GE kill attempt failed")); } try { CoInitialize(NULL); HRESULT hr; hr = CoCreateInstance( CLSID_ApplicationGE, NULL, //0, CLSCTX_LOCAL_SERVER, IID_IApplicationGE, (void**) &app); //reinterpret_cast<LPVOID *>( &app )); if ( FAILED( hr )) { LogDebugMessage(_T("Error %i while initializing GE")); return; } LogDebugMessage(_T("We survived CoCreateInstance")); Sleep(500); long is_initialized; do { is_initialized = app->IsInitialized(); } while ( is_initialized == 0 ); LogDebugMessage(_T("We survived waiting for IsInitialized")); Sleep(500); m_bgeisuseable = true; m_binitializing = false; } catch(...) { LogDebugMessage(_T("Error initializing GE, we caught an exception")); return; } LogDebugMessage(_T("GE Initialized, attaching to the window")); GEAttachWindow(); } else { LogDebugMessage(_T("Not even trying to initialize GE")); } }
void GEUIDialog::GEShowBoat(double lat, double lon) { LogDebugMessage(wxString::Format(_T("Show boat at %f, %f requested"), lat, lon)); if ( m_bbusy ) { LogDebugMessage(_T("Not showing, busy")); return; } int interval = m_stopwatch_boat.Time(); if (interval < CAMERA_MOVE_INTERVAL * 5) // If it is less than CAMERA_MOVE_INTERVAL * 5 since last request, don't move the boat { LogDebugMessage(_T("Boat display request discarded, too soon after a previous action")); return; } m_stopwatch_boat.Start(); if (m_pPositions->GetCount() > BOAT_POSITIONS_STORED) m_pPositions->Erase(m_pPositions->GetFirst()); m_pPositions->Append(new PositionReport(lat, lon, wxDateTime::Now())); wxTextFile kml(m_sLiveKmlFilename); if(wxFile::Exists(m_sLiveKmlFilename)) { kml.Open(); kml.Clear(); } else { kml.Create(); } wxString coords; wxPositionsListNode *posn = m_pPositions->GetFirst(); do { coords += wxString::Format(_T("%f,%f,0.000000\n"), posn->GetData()->longitude, posn->GetData()->latitude); } while (posn = posn->GetNext()); if (pPlugIn->ShouldShowBoat()) kml.AddLine(wxString::Format(LiveKml, 1, lon, lat, 1, coords)); else kml.AddLine(wxString::Format(LiveKml, 0, lon, lat, 0, coords)); kml.Write(); kml.Close(); if(NULL != app && m_bgeisuseable) { if (!m_bisfollowingboat && pPlugIn->ShouldShowBoat()) { if(wxFile::Exists(m_sEnvelopeKmlFilename)) wxRemoveFile(m_sEnvelopeKmlFilename); wxTextFile kml(m_sEnvelopeKmlFilename); kml.Create(); kml.AddLine(wxString::Format(EnvelopeKml, m_sLiveKmlFilename)); kml.Write(); kml.Close(); BSTR pdata = wxConvertStringToOle(m_sEnvelopeKmlFilename); m_bbusy = true; app->OpenKmlFile(pdata, 1); m_bisfollowingboat = true; } else if (m_bisfollowingboat && !pPlugIn->ShouldShowBoat()) { if(wxFile::Exists(m_sEnvelopeKmlFilename)) wxRemoveFile(m_sEnvelopeKmlFilename); wxTextFile kml(m_sEnvelopeKmlFilename); kml.Create(); kml.AddLine(EmptyKml); kml.Write(); kml.Close(); BSTR pdata = wxConvertStringToOle(m_sEnvelopeKmlFilename); m_bbusy = true; app->OpenKmlFile(pdata, 1); m_bisfollowingboat = false; } /* IFeatureGE* tp; app->raw_GetTemporaryPlaces(&tp); if ( tp ) { IFeatureCollectionGE* tps; tp->raw_GetChildren(&tps); if ( tps && tps->GetCount() > 0 ) { //for (int i = 0; i < tps->Count; i++) //{ // tps->Item[i]->PutVisibility(0); //} try { //FIXME: This works, BUT GE consumes enormous amounts of memory - really there is no way to change the properties of existing waypoint? //Looks like ther isn't, so some trick like from http://groups.google.com/group/kml-support-com-api/browse_thread/thread/76c9f9f3ab5ff28f/4244ff5df01c5c25?lnk=gst&q=temporary+places# and http://bbs.keyhole.com/ubb/ubbthreads.php?ubb=showflat&Number=816832&site_id=1#import will be necessary //Tutorial: http://code.google.com/intl/cs/apis/kml/documentation/kml_21tutorial.html#updates tps->GetItem(tps->GetCount() - 1)->PutVisibility(false); } catch (...) {} } } wxString kml = wxString::Format(_T("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://earth.google.com/kml/2.0\">\n<Placemark>\n <name>BOAT</name>\n <visibility>1</visibility>\n <Style>\n <IconStyle>\n <Icon>\n <href>root://icons/palette-4.png</href>\n <x>32</x>\n <y>0</y>\n <w>32</w>\n <h>32</h>\n </Icon>\n </IconStyle>\n </Style>\n <Point>\n <extrude>1</extrude>\n <altitudeMode>relativeToGround</altitudeMode>\n <coordinates>%f,%f,0</coordinates>\n </Point>\n</Placemark>\n</kml>"), lon, lat); BSTR pdata = wxConvertStringToOle(kml); try { app->LoadKmlData(&pdata); LogDebugMessage(_T("Shown")); } catch (...) { LogDebugMessage(_T("There was an error showing the boat")); } */ } m_bbusy = false; }