// Is this route equal to another, meaning, // Do all routepoint positions and names match? bool Route::IsEqualTo( Route *ptargetroute ) { wxRoutePointListNode *pthisnode = ( this->pRoutePointList )->GetFirst(); wxRoutePointListNode *pthatnode = ( ptargetroute->pRoutePointList )->GetFirst(); if( NULL == pthisnode ) return false; if( this->m_bIsInLayer || ptargetroute->m_bIsInLayer ) return false; if( this->GetnPoints() != ptargetroute->GetnPoints() ) return false; while( pthisnode ) { if( NULL == pthatnode ) return false; RoutePoint *pthisrp = pthisnode->GetData(); RoutePoint *pthatrp = pthatnode->GetData(); if( ( fabs( pthisrp->m_lat - pthatrp->m_lat ) > 1.0e-6 ) || ( fabs( pthisrp->m_lon - pthatrp->m_lon ) > 1.0e-6 ) ) return false; if( !pthisrp->GetName().IsSameAs( pthatrp->GetName() ) ) return false; pthisnode = pthisnode->GetNext(); pthatnode = pthatnode->GetNext(); } return true; // success, they are the same }
bool NavObjectCollection::LoadAllGPXObjects() { //FIXME: unite with MyConfig::ImportGPX TiXmlNode *root = RootElement(); wxString RootName = wxString::FromUTF8( root->Value() ); if( RootName == _T ( "gpx" ) ) { TiXmlNode *child; for( child = root->FirstChild(); child != 0; child = child->NextSibling() ) { wxString ChildName = wxString::FromUTF8( child->Value() ); if( ChildName == _T ( "trk" ) ) ::GPXLoadTrack( (GpxTrkElement *) child ); else if( ChildName == _T ( "rte" ) ) { int m_NextRouteNum = 0; //FIXME: we do not need it for GPX ::GPXLoadRoute( (GpxRteElement *) child, m_NextRouteNum ); } else if( ChildName == _T ( "wpt" ) ) { int m_NextWPNum = 0; //FIXME: we do not need it for GPX RoutePoint *pWp = ::LoadGPXWaypoint( (GpxWptElement *) child, _T("circle") ); RoutePoint *pExisting = WaypointExists( pWp->GetName(), pWp->m_lat, pWp->m_lon ); if( !pExisting ) { if( NULL != pWayPointMan ) pWayPointMan->m_pWayPointList->Append( pWp ); pWp->m_bIsolatedMark = true; // This is an isolated mark pSelect->AddSelectableRoutePoint( pWp->m_lat, pWp->m_lon, pWp ); pWp->m_ConfigWPNum = m_NextWPNum; m_NextWPNum++; } } } } return true; }
// The following is used only for route splitting, assumes just created, empty route // void Route::CloneRoute( Route *psourceroute, int start_nPoint, int end_nPoint, const wxString & suffix) { m_bIsTrack = psourceroute->m_bIsTrack; m_RouteNameString = psourceroute->m_RouteNameString + suffix; m_RouteStartString = psourceroute->m_RouteStartString; m_RouteEndString = psourceroute->m_RouteEndString; int i; for( i = start_nPoint; i <= end_nPoint; i++ ) { if( !psourceroute->m_bIsInLayer ) AddPoint( psourceroute->GetPoint( i ), false ); else { RoutePoint *psourcepoint = psourceroute->GetPoint( i ); RoutePoint *ptargetpoint = new RoutePoint( psourcepoint->m_lat, psourcepoint->m_lon, psourcepoint->m_IconName, psourcepoint->GetName(), GPX_EMPTY_STRING, false ); AddPoint( ptargetpoint, false ); CloneAddedRoutePoint( m_pLastAddedPoint, psourcepoint ); } } CalculateBBox(); }
void Route::CloneTrack( Route *psourceroute, int start_nPoint, int end_nPoint, const wxString & suffix) { if( psourceroute->m_bIsInLayer ) return; m_bIsTrack = psourceroute->m_bIsTrack; m_RouteNameString = psourceroute->m_RouteNameString + suffix; m_RouteStartString = psourceroute->m_RouteStartString; m_RouteEndString = psourceroute->m_RouteEndString; bool b_splitting = GetnPoints() == 0; int startTrkSegNo; if( b_splitting ) startTrkSegNo = psourceroute->GetPoint( start_nPoint )->m_GPXTrkSegNo; else startTrkSegNo = this->GetLastPoint()->m_GPXTrkSegNo; int i; for( i = start_nPoint; i <= end_nPoint; i++ ) { RoutePoint *psourcepoint = psourceroute->GetPoint( i ); RoutePoint *ptargetpoint = new RoutePoint( psourcepoint->m_lat, psourcepoint->m_lon, psourcepoint->GetIconName(), psourcepoint->GetName(), GPX_EMPTY_STRING, false ); AddPoint( ptargetpoint, false ); // This is a hack, need to undo the action of Route::AddPoint ptargetpoint->m_bIsInRoute = false; ptargetpoint->m_bIsInTrack = true; CloneAddedTrackPoint( m_pLastAddedPoint, psourcepoint ); int segment_shift = psourcepoint->m_GPXTrkSegNo; if( start_nPoint == 2 ) segment_shift = psourcepoint->m_GPXTrkSegNo - 1; // continue first segment if tracks share the first point if( b_splitting ) m_pLastAddedPoint->m_GPXTrkSegNo = ( psourcepoint->m_GPXTrkSegNo - startTrkSegNo ) + 1; else m_pLastAddedPoint->m_GPXTrkSegNo = startTrkSegNo + segment_shift; } FinalizeForRendering(); }
// The following is used only for route splitting, assumes just created, empty route // void Route::CloneRoute( Route *psourceroute, int start_nPoint, int end_nPoint, const wxString & suffix) { m_RouteNameString = psourceroute->m_RouteNameString + suffix; m_RouteStartString = psourceroute->m_RouteStartString; m_RouteEndString = psourceroute->m_RouteEndString; int i; for( i = start_nPoint; i <= end_nPoint; i++ ) { if( !psourceroute->m_bIsInLayer ) AddPoint( psourceroute->GetPoint( i ), false ); else { RoutePoint *psourcepoint = psourceroute->GetPoint( i ); RoutePoint *ptargetpoint = new RoutePoint( psourcepoint->m_lat, psourcepoint->m_lon, psourcepoint->GetIconName(), psourcepoint->GetName(), GPX_EMPTY_STRING, false ); AddPoint( ptargetpoint, false ); } } FinalizeForRendering(); }
bool Multiplexer::SendRouteToGPS(Route *pr, wxString &com_name, bool bsend_waypoints, wxGauge *pProgress) { bool ret_bool = false; DataStream *old_stream = FindStream( com_name ); if( old_stream ) { SaveStreamProperties( old_stream ); StopAndRemoveStream( old_stream ); } #ifdef USE_GARMINHOST #ifdef __WXMSW__ if(com_name.Upper().Matches(_T("*GARMIN*"))) // Garmin USB Mode { // if(m_pdevmon) // m_pdevmon->StopIOThread(true); int v_init = Garmin_GPS_Init(wxString(_T("usb:"))); if(v_init < 0) { wxString msg(_T(" Garmin USB GPS could not be initialized")); wxLogMessage(msg); msg.Printf(_T(" Error Code is %d"), v_init); wxLogMessage(msg); msg = _T(" LastGarminError is: "); msg += GetLastGarminError(); wxLogMessage(msg); ret_bool = false; } else { wxLogMessage(_T("Garmin USB Initialized")); wxString msg = _T("USB Unit identifies as: "); wxString GPS_Unit = Garmin_GPS_GetSaveString(); msg += GPS_Unit; wxLogMessage(msg); wxLogMessage(_T("Sending Routes...")); int ret1 = Garmin_GPS_SendRoute(wxString(_T("usb:")), pr, pProgress); if(ret1 != 1) { wxLogMessage(_T(" Error Sending Routes")); wxString msg; msg = _T(" LastGarminError is: "); msg += GetLastGarminError(); wxLogMessage(msg); ret_bool = false; } else ret_bool = true; } // if(m_pdevmon) // m_pdevmon->RestartIOThread(); goto ret_point_1; } #endif if(g_bGarminHostUpload) { int ret_val; if ( pProgress ) { pProgress->SetValue ( 20 ); pProgress->Refresh(); pProgress->Update(); } wxString short_com = com_name.Mid(7); // Initialize the Garmin receiver, build required Jeeps internal data structures int v_init = Garmin_GPS_Init(short_com); if(v_init < 0) { wxString msg(_T("Garmin GPS could not be initialized on port: ")); msg +=short_com; wxString err; err.Printf(_T(" Error Code is %d"), v_init); msg += err; msg += _T("\n LastGarminError is: "); msg += GetLastGarminError(); wxLogMessage(msg); ret_bool = false; goto ret_point; } else { wxString msg(_T("Sent Route to Garmin GPS on port: ")); msg +=short_com; msg += _T("\n Unit identifies as: "); wxString GPS_Unit = Garmin_GPS_GetSaveString(); msg += GPS_Unit; wxLogMessage(msg); } if ( pProgress ) { pProgress->SetValue ( 40 ); pProgress->Refresh(); pProgress->Update(); } ret_val = Garmin_GPS_SendRoute(short_com, pr, pProgress); if(ret_val != 1) { wxString msg(_T("Error Sending Route to Garmin GPS on port: ")); msg +=short_com; wxString err; err.Printf(_T(" Error Code is %d"), ret_val); msg += _T("\n LastGarminError is: "); msg += GetLastGarminError(); msg += err; wxLogMessage(msg); ret_bool = false; goto ret_point; } else ret_bool = true; ret_point: if ( pProgress ) { pProgress->SetValue ( 100 ); pProgress->Refresh(); pProgress->Update(); } wxMilliSleep ( 500 ); goto ret_point_1; } else #endif //USE_GARMINHOST { { // Standard NMEA mode // If the port was temporarily closed, reopen as I/O type // Otherwise, open another port using default properties wxString baud; if( old_stream ) { baud = baud_rate_save; } else { baud = _T("4800"); } DataStream *dstr = new DataStream( this, com_name, baud, DS_TYPE_INPUT_OUTPUT, 0 ); SENTENCE snt; NMEA0183 oNMEA0183; oNMEA0183.TalkerID = _T ( "EC" ); int nProg = pr->pRoutePointList->GetCount() + 1; if ( pProgress ) pProgress->SetRange ( 100 ); int progress_stall = 500; if(pr->pRoutePointList->GetCount() > 10) progress_stall = 500; // Send out the waypoints, in order if ( bsend_waypoints ) { wxRoutePointListNode *node = pr->pRoutePointList->GetFirst(); int ip = 1; while ( node ) { RoutePoint *prp = node->GetData(); if(g_GPS_Ident == _T("Generic")) { if ( prp->m_lat < 0. ) oNMEA0183.Wpl.Position.Latitude.Set ( -prp->m_lat, _T ( "S" ) ); else oNMEA0183.Wpl.Position.Latitude.Set ( prp->m_lat, _T ( "N" ) ); if ( prp->m_lon < 0. ) oNMEA0183.Wpl.Position.Longitude.Set ( -prp->m_lon, _T ( "W" ) ); else oNMEA0183.Wpl.Position.Longitude.Set ( prp->m_lon, _T ( "E" ) ); oNMEA0183.Wpl.To = prp->GetName().Truncate ( 6 ); oNMEA0183.Wpl.Write ( snt ); } else if(g_GPS_Ident == _T("FurunoGP3X")) { oNMEA0183.TalkerID = _T ( "PFEC," ); if ( prp->m_lat < 0. ) oNMEA0183.GPwpl.Position.Latitude.Set ( -prp->m_lat, _T ( "S" ) ); else oNMEA0183.GPwpl.Position.Latitude.Set ( prp->m_lat, _T ( "N" ) ); if ( prp->m_lon < 0. ) oNMEA0183.GPwpl.Position.Longitude.Set ( -prp->m_lon, _T ( "W" ) ); else oNMEA0183.GPwpl.Position.Longitude.Set ( prp->m_lon, _T ( "E" ) ); oNMEA0183.GPwpl.To = prp->GetName().Truncate ( 8 ); oNMEA0183.GPwpl.Write ( snt ); } if( dstr->SendSentence( snt.Sentence ) ) LogOutputMessage( snt.Sentence, dstr->GetPort(), false ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += snt.Sentence; msg.Trim(); wxLogMessage(msg); if ( pProgress ) { pProgress->SetValue ( ( ip * 100 ) / nProg ); pProgress->Refresh(); pProgress->Update(); } wxMilliSleep ( progress_stall ); node = node->GetNext(); ip++; } } // Create the NMEA Rte sentence oNMEA0183.Rte.Empty(); oNMEA0183.Rte.TypeOfRoute = CompleteRoute; if ( pr->m_RouteNameString.IsEmpty() ) oNMEA0183.Rte.RouteName = _T ( "1" ); else oNMEA0183.Rte.RouteName = pr->m_RouteNameString; if(g_GPS_Ident == _T("FurunoGP3X")) { oNMEA0183.Rte.RouteName = _T ( "1" ); oNMEA0183.TalkerID = _T ( "GP" ); } oNMEA0183.Rte.total_number_of_messages = 1; oNMEA0183.Rte.message_number = 1; // add the waypoints wxRoutePointListNode *node = pr->pRoutePointList->GetFirst(); while ( node ) { RoutePoint *prp = node->GetData(); wxString name = prp->GetName().Truncate ( 6 ); if(g_GPS_Ident == _T("FurunoGP3X")) { name = prp->GetName().Truncate ( 7 ); name.Prepend(_T(" ")); } oNMEA0183.Rte.AddWaypoint ( name ); node = node->GetNext(); } oNMEA0183.Rte.Write ( snt ); unsigned int max_length = 70; if(snt.Sentence.Len() > max_length) { // Make a route with one waypoint to get tare load. NMEA0183 tNMEA0183; SENTENCE tsnt; tNMEA0183.TalkerID = _T ( "EC" ); tNMEA0183.Rte.Empty(); tNMEA0183.Rte.TypeOfRoute = CompleteRoute; if(g_GPS_Ident != _T("FurunoGP3X")) { if ( pr->m_RouteNameString.IsEmpty() ) tNMEA0183.Rte.RouteName = _T ( "1" ); else tNMEA0183.Rte.RouteName = pr->m_RouteNameString; tNMEA0183.Rte.AddWaypoint ( _T("123456") ); } else { if (( pr->m_RouteNameString.IsNumber() ) && ( pr->m_RouteNameString.Len() <= 2 ) ) { if( pr->m_RouteNameString.Len() == 2) { tNMEA0183.Rte.RouteName = pr->m_RouteNameString; } else { tNMEA0183.Rte.RouteName = _T("0"); tNMEA0183.Rte.RouteName += pr->m_RouteNameString; } } else { tNMEA0183.Rte.RouteName = _T ( "01" ); } tNMEA0183.Rte.AddWaypoint ( _T(" 1234567") ); } tNMEA0183.Rte.Write ( tsnt ); unsigned int tare_length = tsnt.Sentence.Len(); wxArrayString sentence_array; // Trial balloon: add the waypoints, with length checking int n_total = 1; bool bnew_sentence = true; int sent_len=0; wxRoutePointListNode *node = pr->pRoutePointList->GetFirst(); while ( node ) { RoutePoint *prp = node->GetData(); unsigned int name_len = prp->GetName().Truncate ( 6 ).Len(); if(g_GPS_Ident == _T("FurunoGP3X")) name_len = 1 + prp->GetName().Truncate ( 7 ).Len(); if(bnew_sentence) { sent_len = tare_length; sent_len += name_len; bnew_sentence = false; node = node->GetNext(); } else { if(sent_len + name_len > max_length) { n_total ++; bnew_sentence = true; } else { sent_len += name_len; node = node->GetNext(); } } } // Now we have the sentence count, so make the real sentences using the same counting logic int final_total = n_total; int n_run = 1; bnew_sentence = true; node = pr->pRoutePointList->GetFirst(); while ( node ) { RoutePoint *prp = node->GetData(); wxString name = prp->GetName().Truncate ( 6 ); if(g_GPS_Ident == _T("FurunoGP3X")) { name = prp->GetName().Truncate ( 7 ); name.Prepend(_T(" ")); } unsigned int name_len = name.Len(); if(bnew_sentence) { sent_len = tare_length; sent_len += name_len; bnew_sentence = false; oNMEA0183.Rte.Empty(); oNMEA0183.Rte.TypeOfRoute = CompleteRoute; if(g_GPS_Ident != _T("FurunoGP3X")) { if ( pr->m_RouteNameString.IsEmpty() ) oNMEA0183.Rte.RouteName = _T ( "1" ); else oNMEA0183.Rte.RouteName = pr->m_RouteNameString; } else { if (( pr->m_RouteNameString.IsNumber() ) && ( pr->m_RouteNameString.Len() <= 2 ) ) { if( pr->m_RouteNameString.Len() == 2) { oNMEA0183.Rte.RouteName = pr->m_RouteNameString; } else { oNMEA0183.Rte.RouteName = _T("0"); oNMEA0183.Rte.RouteName += pr->m_RouteNameString; } } else { oNMEA0183.Rte.RouteName = _T ( "01" ); } } oNMEA0183.Rte.total_number_of_messages = final_total; oNMEA0183.Rte.message_number = n_run; snt.Sentence.Clear(); oNMEA0183.Rte.AddWaypoint ( name ); node = node->GetNext(); } else { if(sent_len + name_len > max_length) { n_run ++; bnew_sentence = true; oNMEA0183.Rte.Write ( snt ); // printf("%s", snt.Sentence.mb_str()); sentence_array.Add(snt.Sentence); } else { sent_len += name_len; oNMEA0183.Rte.AddWaypoint ( name ); node = node->GetNext(); } } } oNMEA0183.Rte.Write ( snt ); //last one... if(snt.Sentence.Len() > tare_length) sentence_array.Add(snt.Sentence); for(unsigned int ii=0 ; ii < sentence_array.GetCount(); ii++) { if(dstr->SendSentence( sentence_array.Item(ii) ) ) LogOutputMessage( sentence_array.Item(ii), dstr->GetPort(), false ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += sentence_array.Item(ii); msg.Trim(); wxLogMessage(msg); wxMilliSleep ( 500 ); } } else { if( dstr->SendSentence( snt.Sentence ) ) LogOutputMessage( snt.Sentence, dstr->GetPort(), false ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += snt.Sentence; msg.Trim(); wxLogMessage(msg); } if(g_GPS_Ident == _T("FurunoGP3X")) { wxString term; term.Printf(_T("$PFEC,GPxfr,CTL,E%c%c"), 0x0d, 0x0a); if( dstr->SendSentence( term ) ) LogOutputMessage( term, dstr->GetPort(), false ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += term; msg.Trim(); wxLogMessage(msg); } if ( pProgress ) { pProgress->SetValue ( 100 ); pProgress->Refresh(); pProgress->Update(); } wxMilliSleep ( 500 ); ret_bool = true; // All finished with the temp port dstr->Close(); } } ret_point_1: if( old_stream ) CreateAndRestoreSavedStreamProperties(); return ret_bool; }
MyRoutePrintout::MyRoutePrintout( std::vector<bool> _toPrintOut, Route* route, const wxChar* title ) : MyPrintout( title ), myRoute( route ), toPrintOut( _toPrintOut ) { // Let's have at least some device units margin marginX = 5; marginY = 5; // Offset text from the edge of the cell (Needed on Linux) textOffsetX = 5; textOffsetY = 8; table.StartFillHeader(); // setup widths for columns if ( toPrintOut[ PRINT_WP_NAME ] ) { table << (const char *)wxString(_("Name")).mb_str(); } if ( toPrintOut[ PRINT_WP_POSITION ] ) { table << (const char *)wxString(_("Position")).mb_str(); } if ( toPrintOut[ PRINT_WP_COURSE ] ) { table << (const char *)wxString(_("Course")).mb_str(); } if ( toPrintOut[ PRINT_WP_DISTANCE ] ) { table << (const char *)wxString(_("Distance")).mb_str(); } if ( toPrintOut[ PRINT_WP_DESCRIPTION ] ) { table << (const char *)wxString(_("Description")).mb_str(); } table.StartFillWidths(); // setup widths for columns if ( toPrintOut[ PRINT_WP_NAME ] ) { table << 23; } if ( toPrintOut[ PRINT_WP_POSITION ] ) { table << 40; } if ( toPrintOut[ PRINT_WP_COURSE ] ) { table << 30; } if ( toPrintOut[ PRINT_WP_DISTANCE ] ) { table << 38; } if ( toPrintOut[ PRINT_WP_DESCRIPTION ] ) { table << 100; } table.StartFillData(); for ( int n = 1; n <= myRoute->GetnPoints(); n++ ) { RoutePoint* point = myRoute->GetPoint( n ); if ( toPrintOut[ PRINT_WP_NAME ] ) { string cell( point->GetName().mb_str() ); table << cell; } if ( toPrintOut[ PRINT_WP_POSITION ] ) { wxString point_position = toSDMM( 1, point->m_lat, point->m_bIsInTrack ) + _T( "\n" ) + toSDMM( 2, point->m_lon, point->m_bIsInTrack ); string cell( point_position.mb_str() ); table << cell; } if ( toPrintOut[ PRINT_WP_COURSE ] ) { wxString point_course; point_course.Printf( _T( "%03.0f Deg" ), point->GetCourse() ); string cell( point_course.mb_str() ); table << cell; } if ( toPrintOut[ PRINT_WP_DISTANCE ] ) { wxString point_distance; point_distance.Printf( _T( "%6.2f" + getUsrDistanceUnit() ), toUsrDistance( point->GetDistance() ) ); string cell( point_distance.mb_str() ); table << cell; } if ( toPrintOut[ PRINT_WP_DESCRIPTION ] ) { string cell( point->GetDescription().mb_str() ); table << cell; } table << "\n"; } }
bool Multiplexer::SendRouteToGPS(Route *pr, wxString &com_name, bool bsend_waypoints, wxGauge *pProgress) { bool ret_bool = false; /*TODO: RE-enable use of Garmin host #ifdef USE_GARMINHOST #ifdef __WXMSW__ if(com_name.Upper().Matches(_T("*GARMIN*"))) // Garmin USB Mode { if(m_pdevmon) m_pdevmon->StopIOThread(true); int v_init = Garmin_GPS_Init(NULL, wxString(_T("usb:"))); if(v_init < 0) { wxString msg(_T(" Garmin USB GPS could not be initialized")); wxLogMessage(msg); msg.Printf(_T(" Error Code is %d"), v_init); wxLogMessage(msg); msg = _T(" LastGarminError is: "); msg += GetLastGarminError(); wxLogMessage(msg); ret_bool = false; } else { wxLogMessage(_T("Garmin USB Initialized")); wxString msg = _T("USB Unit identifies as: "); wxString GPS_Unit = Garmin_GPS_GetSaveString(); msg += GPS_Unit; wxLogMessage(msg); wxLogMessage(_T("Sending Routes...")); int ret1 = Garmin_GPS_SendRoute(NULL, wxString(_T("usb:")), pr, pProgress); if(ret1 != 1) { wxLogMessage(_T(" Error Sending Routes")); wxString msg; msg = _T(" LastGarminError is: "); msg += GetLastGarminError(); wxLogMessage(msg); ret_bool = false; } else ret_bool = true; } if(m_pdevmon) m_pdevmon->RestartIOThread(); return ret_bool; } #endif if(m_bGarmin_host) { int ret_val; // Request that the thread should pause m_brequest_thread_pause = true; ::wxSleep(1); bool b_gotPort = false; // Poll, waiting for the Mutex. Abort after 5 seconds long time = ::wxGetLocalTime(); while(::wxGetLocalTime() < time + 5) { if(wxMUTEX_BUSY != m_pPortMutex->TryLock()) { b_gotPort = true; break; } } if(!b_gotPort) { wxString msg(_T("Error Sending Route...could not lock Mutex on port: ")); msg +=com_name; wxLogMessage(msg); return false; } if ( pProgress ) { pProgress->SetValue ( 20 ); pProgress->Refresh(); pProgress->Update(); } // Initialize the Garmin receiver, build required Jeeps internal data structures int v_init = Garmin_GPS_Init(g_pCommMan, com_name); if(v_init < 0) { wxString msg(_T("Garmin GPS could not be initialized on port: ")); msg +=com_name; wxString err; err.Printf(_T(" Error Code is %d"), v_init); msg += err; msg += _T("\n LastGarminError is: "); msg += GetLastGarminError(); wxLogMessage(msg); ret_bool = false; goto ret_point; } else { wxString msg(_T("Sent Route to Garmin GPS on port: ")); msg +=com_name; msg += _T("\n Unit identifies as: "); wxString GPS_Unit = Garmin_GPS_GetSaveString(); msg += GPS_Unit; wxLogMessage(msg); } if ( pProgress ) { pProgress->SetValue ( 40 ); pProgress->Refresh(); pProgress->Update(); } ret_val = Garmin_GPS_SendRoute(g_pCommMan, com_name, pr, pProgress); if(ret_val != 1) { wxString msg(_T("Error Sending Route to Garmin GPS on port: ")); msg +=com_name; wxString err; err.Printf(_T(" Error Code is %d"), ret_val); msg += _T("\n LastGarminError is: "); msg += GetLastGarminError(); msg += err; wxLogMessage(msg); ret_bool = false; goto ret_point; } else ret_bool = true; ret_point: // Release the Mutex m_brequest_thread_pause = false; m_pPortMutex->Unlock(); if ( pProgress ) { pProgress->SetValue ( 100 ); pProgress->Refresh(); pProgress->Update(); } wxMilliSleep ( 500 ); return ret_bool; } else #endif //USE_GARMINHOST */ { { // Standard NMEA mode SENTENCE snt; NMEA0183 oNMEA0183; oNMEA0183.TalkerID = _T ( "EC" ); int nProg = pr->pRoutePointList->GetCount() + 1; if ( pProgress ) pProgress->SetRange ( 100 ); int progress_stall = 500; if(pr->pRoutePointList->GetCount() > 10) progress_stall = 500; // Send out the waypoints, in order if ( bsend_waypoints ) { wxRoutePointListNode *node = pr->pRoutePointList->GetFirst(); int ip = 1; while ( node ) { RoutePoint *prp = node->GetData(); if(g_GPS_Ident == _T("Generic")) { if ( prp->m_lat < 0. ) oNMEA0183.Wpl.Position.Latitude.Set ( -prp->m_lat, _T ( "S" ) ); else oNMEA0183.Wpl.Position.Latitude.Set ( prp->m_lat, _T ( "N" ) ); if ( prp->m_lon < 0. ) oNMEA0183.Wpl.Position.Longitude.Set ( -prp->m_lon, _T ( "W" ) ); else oNMEA0183.Wpl.Position.Longitude.Set ( prp->m_lon, _T ( "E" ) ); oNMEA0183.Wpl.To = prp->GetName().Truncate ( 6 ); oNMEA0183.Wpl.Write ( snt ); } else if(g_GPS_Ident == _T("FurunoGP3X")) { oNMEA0183.TalkerID = _T ( "PFEC," ); if ( prp->m_lat < 0. ) oNMEA0183.GPwpl.Position.Latitude.Set ( -prp->m_lat, _T ( "S" ) ); else oNMEA0183.GPwpl.Position.Latitude.Set ( prp->m_lat, _T ( "N" ) ); if ( prp->m_lon < 0. ) oNMEA0183.GPwpl.Position.Longitude.Set ( -prp->m_lon, _T ( "W" ) ); else oNMEA0183.GPwpl.Position.Longitude.Set ( prp->m_lon, _T ( "E" ) ); oNMEA0183.GPwpl.To = prp->GetName().Truncate ( 8 ); oNMEA0183.GPwpl.Write ( snt ); } SendNMEAMessage( snt.Sentence ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += snt.Sentence; msg.Trim(); wxLogMessage(msg); if ( pProgress ) { pProgress->SetValue ( ( ip * 100 ) / nProg ); pProgress->Refresh(); pProgress->Update(); } wxMilliSleep ( progress_stall ); node = node->GetNext(); ip++; } } // Create the NMEA Rte sentence oNMEA0183.Rte.Empty(); oNMEA0183.Rte.TypeOfRoute = CompleteRoute; if ( pr->m_RouteNameString.IsEmpty() ) oNMEA0183.Rte.RouteName = _T ( "1" ); else oNMEA0183.Rte.RouteName = pr->m_RouteNameString; if(g_GPS_Ident == _T("FurunoGP3X")) { oNMEA0183.Rte.RouteName = _T ( "1" ); oNMEA0183.TalkerID = _T ( "GP" ); } oNMEA0183.Rte.total_number_of_messages = 1; oNMEA0183.Rte.message_number = 1; // add the waypoints wxRoutePointListNode *node = pr->pRoutePointList->GetFirst(); while ( node ) { RoutePoint *prp = node->GetData(); wxString name = prp->GetName().Truncate ( 6 ); if(g_GPS_Ident == _T("FurunoGP3X")) { name = prp->GetName().Truncate ( 7 ); name.Prepend(_T(" ")); } oNMEA0183.Rte.AddWaypoint ( name ); node = node->GetNext(); } oNMEA0183.Rte.Write ( snt ); unsigned int max_length = 70; if(snt.Sentence.Len() > max_length) { // Make a route with one waypoint to get tare load. NMEA0183 tNMEA0183; SENTENCE tsnt; tNMEA0183.TalkerID = _T ( "EC" ); tNMEA0183.Rte.Empty(); tNMEA0183.Rte.TypeOfRoute = CompleteRoute; if(g_GPS_Ident != _T("FurunoGP3X")) { if ( pr->m_RouteNameString.IsEmpty() ) tNMEA0183.Rte.RouteName = _T ( "1" ); else tNMEA0183.Rte.RouteName = pr->m_RouteNameString; tNMEA0183.Rte.AddWaypoint ( _T("123456") ); } else { if (( pr->m_RouteNameString.IsNumber() ) && ( pr->m_RouteNameString.Len() <= 2 ) ) { if( pr->m_RouteNameString.Len() == 2) { tNMEA0183.Rte.RouteName = pr->m_RouteNameString; } else { tNMEA0183.Rte.RouteName = _T("0"); tNMEA0183.Rte.RouteName += pr->m_RouteNameString; } } else { tNMEA0183.Rte.RouteName = _T ( "01" ); } tNMEA0183.Rte.AddWaypoint ( _T(" 1234567") ); } tNMEA0183.Rte.Write ( tsnt ); unsigned int tare_length = tsnt.Sentence.Len(); wxArrayString sentence_array; // Trial balloon: add the waypoints, with length checking int n_total = 1; bool bnew_sentence = true; int sent_len=0; wxRoutePointListNode *node = pr->pRoutePointList->GetFirst(); while ( node ) { RoutePoint *prp = node->GetData(); unsigned int name_len = prp->GetName().Truncate ( 6 ).Len(); if(g_GPS_Ident == _T("FurunoGP3X")) name_len = 1 + prp->GetName().Truncate ( 7 ).Len(); if(bnew_sentence) { sent_len = tare_length; sent_len += name_len; bnew_sentence = false; node = node->GetNext(); } else { if(sent_len + name_len > max_length) { n_total ++; bnew_sentence = true; } else { sent_len += name_len; node = node->GetNext(); } } } // Now we have the sentence count, so make the real sentences using the same counting logic int final_total = n_total; int n_run = 1; bnew_sentence = true; node = pr->pRoutePointList->GetFirst(); while ( node ) { RoutePoint *prp = node->GetData(); wxString name = prp->GetName().Truncate ( 6 ); if(g_GPS_Ident == _T("FurunoGP3X")) { name = prp->GetName().Truncate ( 7 ); name.Prepend(_T(" ")); } unsigned int name_len = name.Len(); if(bnew_sentence) { sent_len = tare_length; sent_len += name_len; bnew_sentence = false; oNMEA0183.Rte.Empty(); oNMEA0183.Rte.TypeOfRoute = CompleteRoute; if(g_GPS_Ident != _T("FurunoGP3X")) { if ( pr->m_RouteNameString.IsEmpty() ) oNMEA0183.Rte.RouteName = _T ( "1" ); else oNMEA0183.Rte.RouteName = pr->m_RouteNameString; } else { if (( pr->m_RouteNameString.IsNumber() ) && ( pr->m_RouteNameString.Len() <= 2 ) ) { if( pr->m_RouteNameString.Len() == 2) { oNMEA0183.Rte.RouteName = pr->m_RouteNameString; } else { oNMEA0183.Rte.RouteName = _T("0"); oNMEA0183.Rte.RouteName += pr->m_RouteNameString; } } else { oNMEA0183.Rte.RouteName = _T ( "01" ); } } oNMEA0183.Rte.total_number_of_messages = final_total; oNMEA0183.Rte.message_number = n_run; snt.Sentence.Clear(); oNMEA0183.Rte.AddWaypoint ( name ); node = node->GetNext(); } else { if(sent_len + name_len > max_length) { n_run ++; bnew_sentence = true; oNMEA0183.Rte.Write ( snt ); // printf("%s", snt.Sentence.mb_str()); sentence_array.Add(snt.Sentence); } else { sent_len += name_len; oNMEA0183.Rte.AddWaypoint ( name ); node = node->GetNext(); } } } oNMEA0183.Rte.Write ( snt ); //last one... if(snt.Sentence.Len() > tare_length) sentence_array.Add(snt.Sentence); for(unsigned int ii=0 ; ii < sentence_array.GetCount(); ii++) { SendNMEAMessage( sentence_array.Item(ii) ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += sentence_array.Item(ii); msg.Trim(); wxLogMessage(msg); wxMilliSleep ( 500 ); } } else { SendNMEAMessage( snt.Sentence ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += snt.Sentence; msg.Trim(); wxLogMessage(msg); } if(g_GPS_Ident == _T("FurunoGP3X")) { wxString term; term.Printf(_T("$PFEC,GPxfr,CTL,E%c%c"), 0x0d, 0x0a); SendNMEAMessage( term ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += term; msg.Trim(); wxLogMessage(msg); } if ( pProgress ) { pProgress->SetValue ( 100 ); pProgress->Refresh(); pProgress->Update(); } wxMilliSleep ( 500 ); ret_bool = true; return ret_bool; } } return ret_bool; }
int Multiplexer::SendRouteToGPS(Route *pr, const wxString &com_name, bool bsend_waypoints, wxGauge *pProgress) { int ret_val = 0; DataStream *old_stream = FindStream( com_name ); if( old_stream ) { SaveStreamProperties( old_stream ); StopAndRemoveStream( old_stream ); } #ifdef USE_GARMINHOST #ifdef __WXMSW__ if(com_name.Upper().Matches(_T("*GARMIN*"))) // Garmin USB Mode { // if(m_pdevmon) // m_pdevmon->StopIOThread(true); int v_init = Garmin_GPS_Init(wxString(_T("usb:"))); if(v_init < 0) { wxString msg(_T(" Garmin USB GPS could not be initialized")); wxLogMessage(msg); msg.Printf(_T(" Error Code is %d"), v_init); wxLogMessage(msg); msg = _T(" LastGarminError is: "); msg += GetLastGarminError(); wxLogMessage(msg); ret_val = ERR_GARMIN_INITIALIZE; } else { wxLogMessage(_T("Garmin USB Initialized")); wxString msg = _T("USB Unit identifies as: "); wxString GPS_Unit = Garmin_GPS_GetSaveString(); msg += GPS_Unit; wxLogMessage(msg); wxLogMessage(_T("Sending Routes...")); int ret1 = Garmin_GPS_SendRoute(wxString(_T("usb:")), pr, pProgress); if(ret1 != 1) { wxLogMessage(_T(" Error Sending Routes")); wxString msg; msg = _T(" LastGarminError is: "); msg += GetLastGarminError(); wxLogMessage(msg); ret_val = ERR_GARMIN_GENERAL; } else ret_val = 0; } // if(m_pdevmon) // m_pdevmon->RestartIOThread(); goto ret_point_1; } #endif if(g_bGarminHostUpload) { int lret_val; if ( pProgress ) { pProgress->SetValue ( 20 ); pProgress->Refresh(); pProgress->Update(); } wxString short_com = com_name.Mid(7); // Initialize the Garmin receiver, build required Jeeps internal data structures int v_init = Garmin_GPS_Init(short_com); if(v_init < 0) { wxString msg(_T("Garmin GPS could not be initialized on port: ")); msg +=short_com; wxString err; err.Printf(_T(" Error Code is %d"), v_init); msg += err; msg += _T("\n LastGarminError is: "); msg += GetLastGarminError(); wxLogMessage(msg); ret_val = ERR_GARMIN_INITIALIZE; goto ret_point; } else { wxString msg(_T("Sent Route to Garmin GPS on port: ")); msg +=short_com; msg += _T("\n Unit identifies as: "); wxString GPS_Unit = Garmin_GPS_GetSaveString(); msg += GPS_Unit; wxLogMessage(msg); } if ( pProgress ) { pProgress->SetValue ( 40 ); pProgress->Refresh(); pProgress->Update(); } lret_val = Garmin_GPS_SendRoute(short_com, pr, pProgress); if(lret_val != 1) { wxString msg(_T("Error Sending Route to Garmin GPS on port: ")); msg +=short_com; wxString err; err.Printf(_T(" Error Code is %d"), ret_val); msg += _T("\n LastGarminError is: "); msg += GetLastGarminError(); msg += err; wxLogMessage(msg); ret_val = ERR_GARMIN_GENERAL; goto ret_point; } else ret_val = 0; ret_point: if ( pProgress ) { pProgress->SetValue ( 100 ); pProgress->Refresh(); pProgress->Update(); } wxMilliSleep ( 500 ); goto ret_point_1; } else #endif //USE_GARMINHOST { { // Standard NMEA mode // If the port was temporarily closed, reopen as I/O type // Otherwise, open another port using default properties wxString baud; if( old_stream ) { baud = baud_rate_save; } else { baud = _T("4800"); } DataStream *dstr = new DataStream( this, SERIAL, com_name, baud, DS_TYPE_INPUT_OUTPUT, 0 ); // Wait up to 5 seconds for Datastream secondary thread to come up int timeout = 0; while( !dstr-> IsSecThreadActive() && (timeout < 50)) { wxMilliSleep(100); timeout++; } if( !dstr-> IsSecThreadActive() ){ wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" ...Could not be opened for writing"); wxLogMessage(msg); dstr->Close(); goto ret_point_1; } SENTENCE snt; NMEA0183 oNMEA0183; oNMEA0183.TalkerID = _T ( "EC" ); int nProg = pr->pRoutePointList->GetCount() + 1; if ( pProgress ) pProgress->SetRange ( 100 ); int progress_stall = 500; if(pr->pRoutePointList->GetCount() > 10) progress_stall = 200; if(!pProgress) progress_stall = 200; // 80 chars at 4800 baud is ~160 msec // Send out the waypoints, in order if ( bsend_waypoints ) { wxRoutePointListNode *node = pr->pRoutePointList->GetFirst(); int ip = 1; while ( node ) { RoutePoint *prp = node->GetData(); if(g_GPS_Ident == _T("Generic")) { if ( prp->m_lat < 0. ) oNMEA0183.Wpl.Position.Latitude.Set ( -prp->m_lat, _T ( "S" ) ); else oNMEA0183.Wpl.Position.Latitude.Set ( prp->m_lat, _T ( "N" ) ); if ( prp->m_lon < 0. ) oNMEA0183.Wpl.Position.Longitude.Set ( -prp->m_lon, _T ( "W" ) ); else oNMEA0183.Wpl.Position.Longitude.Set ( prp->m_lon, _T ( "E" ) ); oNMEA0183.Wpl.To = prp->GetName().Truncate ( 6 ); oNMEA0183.Wpl.Write ( snt ); } else if(g_GPS_Ident == _T("FurunoGP3X")) { oNMEA0183.TalkerID = _T ( "PFEC," ); if ( prp->m_lat < 0. ) oNMEA0183.GPwpl.Position.Latitude.Set ( -prp->m_lat, _T ( "S" ) ); else oNMEA0183.GPwpl.Position.Latitude.Set ( prp->m_lat, _T ( "N" ) ); if ( prp->m_lon < 0. ) oNMEA0183.GPwpl.Position.Longitude.Set ( -prp->m_lon, _T ( "W" ) ); else oNMEA0183.GPwpl.Position.Longitude.Set ( prp->m_lon, _T ( "E" ) ); wxString name = prp->GetName(); name += _T("000000"); name.Truncate( 6 ); oNMEA0183.GPwpl.To = name; oNMEA0183.GPwpl.Write ( snt ); } wxString payload = snt.Sentence; // for some gps, like some garmin models, they assume the first waypoint // in the route is the boat location, therefore it is dropped. // These gps also can only accept a maximum of up to 20 waypoints at a time before // a delay is needed and a new string of waypoints may be sent. // To ensure all waypoints will arrive, we can simply send each one twice. // This ensures that the gps will get the waypoint and also allows us to send as many as we like payload += _T("\r\n") + payload; if( dstr->SendSentence( payload ) ) LogOutputMessage( snt.Sentence, dstr->GetPort(), false ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += snt.Sentence; msg.Trim(); wxLogMessage(msg); if ( pProgress ) { pProgress->SetValue ( ( ip * 100 ) / nProg ); pProgress->Refresh(); pProgress->Update(); } wxMilliSleep ( progress_stall ); node = node->GetNext(); ip++; } } // Create the NMEA Rte sentence // Try to create a single sentence, and then check the length to see if too long unsigned int max_length = 76; unsigned int max_wp = 2; // seems to be required for garmin... // Furuno GPS can only accept 5 (five) waypoint linkage sentences.... // So, we need to compact a few more points into each link sentence. if(g_GPS_Ident == _T("FurunoGP3X")){ max_wp = 6; } oNMEA0183.Rte.Empty(); oNMEA0183.Rte.TypeOfRoute = CompleteRoute; if ( pr->m_RouteNameString.IsEmpty() ) oNMEA0183.Rte.RouteName = _T ( "1" ); else oNMEA0183.Rte.RouteName = pr->m_RouteNameString; if(g_GPS_Ident == _T("FurunoGP3X")) { oNMEA0183.Rte.RouteName = _T ( "01" ); oNMEA0183.TalkerID = _T ( "GP" ); oNMEA0183.Rte.m_complete_char = 'C'; // override the default "c" oNMEA0183.Rte.m_skip_checksum = 1; // no checksum needed } oNMEA0183.Rte.total_number_of_messages = 1; oNMEA0183.Rte.message_number = 1; // add the waypoints wxRoutePointListNode *node = pr->pRoutePointList->GetFirst(); while ( node ) { RoutePoint *prp = node->GetData(); wxString name = prp->GetName().Truncate ( 6 ); if(g_GPS_Ident == _T("FurunoGP3X")) { name = prp->GetName(); name += _T("000000"); name.Truncate( 6 ); name .Prepend( _T(" ")); // What Furuno calls "Skip Code", space means use the WP } oNMEA0183.Rte.AddWaypoint ( name ); node = node->GetNext(); } oNMEA0183.Rte.Write ( snt ); if( (snt.Sentence.Len() > max_length) || (pr->pRoutePointList->GetCount() > max_wp) ) // Do we need split sentences? { // Make a route with zero waypoints to get tare load. NMEA0183 tNMEA0183; SENTENCE tsnt; tNMEA0183.TalkerID = _T ( "EC" ); tNMEA0183.Rte.Empty(); tNMEA0183.Rte.TypeOfRoute = CompleteRoute; if(g_GPS_Ident != _T("FurunoGP3X")) { if ( pr->m_RouteNameString.IsEmpty() ) tNMEA0183.Rte.RouteName = _T ( "1" ); else tNMEA0183.Rte.RouteName = pr->m_RouteNameString; } else { tNMEA0183.Rte.RouteName = _T ( "01" ); } tNMEA0183.Rte.Write ( tsnt ); unsigned int tare_length = tsnt.Sentence.Len(); wxArrayString sentence_array; // Trial balloon: add the waypoints, with length checking int n_total = 1; bool bnew_sentence = true; int sent_len=0; unsigned int wp_count = 0; wxRoutePointListNode *node = pr->pRoutePointList->GetFirst(); while ( node ) { RoutePoint *prp = node->GetData(); unsigned int name_len = prp->GetName().Truncate ( 6 ).Len(); if(g_GPS_Ident == _T("FurunoGP3X")) name_len = 7; // six chars, with leading space for "Skip Code" if(bnew_sentence) { sent_len = tare_length; sent_len += name_len + 1; // with comma bnew_sentence = false; node = node->GetNext(); wp_count = 1; } else { if( (sent_len + name_len > max_length) || (wp_count >= max_wp) ) { n_total ++; bnew_sentence = true; } else { sent_len += name_len + 1; // with comma wp_count++; node = node->GetNext(); } } } // Now we have the sentence count, so make the real sentences using the same counting logic int final_total = n_total; int n_run = 1; bnew_sentence = true; node = pr->pRoutePointList->GetFirst(); while ( node ) { RoutePoint *prp = node->GetData(); wxString name = prp->GetName().Truncate ( 6 ); if(g_GPS_Ident == _T("FurunoGP3X")) { name = prp->GetName(); name += _T("000000"); name.Truncate( 6 ); name .Prepend( _T(" ")); // What Furuno calls "Skip Code", space means use the WP } unsigned int name_len = name.Len(); if(bnew_sentence) { sent_len = tare_length; sent_len += name_len + 1; // comma bnew_sentence = false; oNMEA0183.Rte.Empty(); oNMEA0183.Rte.TypeOfRoute = CompleteRoute; if(g_GPS_Ident != _T("FurunoGP3X")) { if ( pr->m_RouteNameString.IsEmpty() ) oNMEA0183.Rte.RouteName = _T ( "1" ); else oNMEA0183.Rte.RouteName = pr->m_RouteNameString; } else { oNMEA0183.Rte.RouteName = _T ( "01" ); } oNMEA0183.Rte.total_number_of_messages = final_total; oNMEA0183.Rte.message_number = n_run; snt.Sentence.Clear(); wp_count = 1; oNMEA0183.Rte.AddWaypoint ( name ); node = node->GetNext(); } else { if( (sent_len + name_len > max_length) || (wp_count >= max_wp) ) { n_run ++; bnew_sentence = true; oNMEA0183.Rte.Write ( snt ); sentence_array.Add(snt.Sentence); } else { sent_len += name_len + 1; // comma oNMEA0183.Rte.AddWaypoint ( name ); wp_count ++; node = node->GetNext(); } } } oNMEA0183.Rte.Write ( snt ); //last one... if(snt.Sentence.Len() > tare_length) sentence_array.Add(snt.Sentence); for(unsigned int ii=0 ; ii < sentence_array.GetCount(); ii++) { wxString sentence = sentence_array.Item(ii); if(dstr->SendSentence( sentence ) ) LogOutputMessage( sentence, dstr->GetPort(), false ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += sentence; msg.Trim(); wxLogMessage(msg); wxMilliSleep ( progress_stall ); } } else { if( dstr->SendSentence( snt.Sentence ) ) LogOutputMessage( snt.Sentence, dstr->GetPort(), false ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += snt.Sentence; msg.Trim(); wxLogMessage(msg); } if(g_GPS_Ident == _T("FurunoGP3X")) { wxString term; term.Printf(_T("$PFEC,GPxfr,CTL,E%c%c"), 0x0d, 0x0a); if( dstr->SendSentence( term ) ) LogOutputMessage( term, dstr->GetPort(), false ); wxString msg(_T("-->GPS Port:")); msg += com_name; msg += _T(" Sentence: "); msg += term; msg.Trim(); wxLogMessage(msg); } if ( pProgress ) { pProgress->SetValue ( 100 ); pProgress->Refresh(); pProgress->Update(); } wxMilliSleep ( progress_stall ); ret_val = 0; // All finished with the temp port dstr->Close(); } } ret_point_1: if( old_stream ) CreateAndRestoreSavedStreamProperties(); return ret_val; }