void WhereAmI(void) { TCHAR toracle[400]; TCHAR ttmp[100]; double dist,brg; wcscpy(toracle,_T("")); int j=FindNearestFarVisibleWayPoint(GPS_INFO.Longitude,GPS_INFO.Latitude,50000); if (!ValidNotResWayPoint(j)) goto _after_nearestwp; DistanceBearing( WayPointList[j].Latitude,WayPointList[j].Longitude, GPS_INFO.Latitude,GPS_INFO.Longitude,&dist,&brg); _tcscat(toracle,_T("The Oracle answered:\n\n")); _tcscat(toracle,_T("You are ")); // nn km south if (dist>2000) { if (ISPARAGLIDER) _stprintf(ttmp,_T("%.1f %s %s "), dist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); else _stprintf(ttmp,_T("%.0f %s %s "), dist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); _tcscat(toracle,ttmp); } // over/below _stprintf(ttmp,_T("%s "),AltDiffToText(GPS_INFO.Altitude, WayPointList[j].Altitude)); _tcscat(toracle,ttmp); // waypoint name _stprintf(ttmp,_T("<%s>"), WayPointList[j].Name); _tcscat(toracle,ttmp); _stprintf(toracle,_T("%s\n%s"),toracle,_T(".... and much more!")); goto _end; _after_nearestwp: wsprintf(toracle,_T("%s"), _T("NO WAYPOINT NEAR YOU")); _end: MessageBoxX(hWndMainWindow, toracle, _T("WHERE AM I ?"), MB_OK|MB_ICONQUESTION, true); }
void MarkLocation(const double lon, const double lat, const double altitude) #endif { #if USETOPOMARKS LockTerrainDataGraphics(); if (topo_marks) { topo_marks->addPoint(lon, lat); topo_marks->triggerUpdateCache = true; } UnlockTerrainDataGraphics(); #endif char message[160]; FILE *stream; TCHAR tstring[50]; bool dopreambol=false; TCHAR fname[MAX_PATH]; LocalPath(fname,TEXT(LKD_WAYPOINTS)); _tcscat(fname,_T("\\")); _stprintf(tstring,_T("LK%04d%02d%02d.cup"), GPS_INFO.Year,GPS_INFO.Month,GPS_INFO.Day); _tcscat(fname,tstring); stream = _tfopen(fname,TEXT("r")); if (stream == NULL) dopreambol=true; else fclose(stream); stream = _tfopen(fname,TEXT("a+")); if (stream != NULL){ if (dopreambol) { // file was created empty, we need to add preambol header for CUP strcpy(message,"name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc\r\n"); fwrite(message,strlen(message),1,stream); } char marktime[10], slat[20], slon[20], snear[50]; Units::TimeToTextSimple(tstring,TimeLocal((int)GPS_INFO.Time)); unicodetoascii(tstring,_tcslen(tstring),marktime); LatitudeToCUPString(lat,tstring); unicodetoascii(tstring,_tcslen(tstring),slat); LongitudeToCUPString(lon,tstring); unicodetoascii(tstring,_tcslen(tstring),slon); int j=FindNearestFarVisibleWayPoint(lon,lat,15000,WPT_UNKNOWN); if (j>0) { _tcscpy(tstring,WayPointList[j].Name); // Name is sized NAME_SIZE, 30, so ok with tstring[50] tstring[19]='\0'; // sized 20 chars unicodetoascii(tstring,_tcslen(tstring),snear); } else { strcpy(snear,"unknown"); } sprintf(message,"MK%s%02d,LK8000,,%s,%s,%d.0m,1,,,,Created on %02d-%02d-%04d at h%s near: %s\r\n", marktime,GPS_INFO.Second,slat,slon, iround((int)altitude), GPS_INFO.Day,GPS_INFO.Month,GPS_INFO.Year, marktime, snear ); fwrite(message,strlen(message),1,stream); fclose(stream); extern int GetVirtualWaypointMarkerSlot(void); j=GetVirtualWaypointMarkerSlot(); WayPointList[j].Latitude=lat; WayPointList[j].Longitude=lon; WayPointList[j].Altitude=altitude; WayPointList[j].Visible=TRUE; WayPointList[j].FarVisible=TRUE; wsprintf(WayPointList[j].Name,_T("MK%S%02d"),marktime,GPS_INFO.Second); #if BUGSTOP LKASSERT(WayPointList[j].Comment!=NULL); #endif if (WayPointList[j].Comment!=NULL) wsprintf(WayPointList[j].Comment,_T("Near: %hs"),snear); WayPointCalc[j].WpType=WPT_TURNPOINT; // Force updating DoRange otherwise it will pass up to 3 minutes // before this marker appears in the 2.3 tps page LastDoRangeWaypointListTime=0; } }
// This is called by the Draw thread // This is still a draft, to find out what's best to tell and how. // It should be recoded once the rules are clear. void WhereAmI(void) { TCHAR toracle[500]; TCHAR ttmp[100]; double dist,wpdist,brg; NearestTopoItem *item=NULL; bool found=false, over=false, saynear=false, needmorewp=false, secondwpdone=false; #if TESTBENCH if (NearestBigCity.Valid) StartupStore(_T("... NEAREST BIG CITY <%s> at %.0f km brg=%.0f\n"), NearestBigCity.Name,NearestBigCity.Distance/1000,NearestBigCity.Bearing); if (NearestCity.Valid) StartupStore(_T("... NEAREST CITY <%s> at %.0f km brg=%.0f\n"), NearestCity.Name,NearestCity.Distance/1000,NearestCity.Bearing); if (NearestSmallCity.Valid) StartupStore(_T("... NEAREST TOWN <%s> at %.0f km brg=%.0f\n"), NearestSmallCity.Name,NearestSmallCity.Distance/1000,NearestSmallCity.Bearing); if (NearestWaterArea.Valid) StartupStore(_T("... NEAREST WATER AREA <%s> at %.0f km brg=%.0f\n"), NearestWaterArea.Name,NearestWaterArea.Distance/1000,NearestWaterArea.Bearing); #endif _stprintf(toracle,_T("%s\n\n"), gettext(_T("_@M1724_"))); // YOUR POSITION: if (NearestBigCity.Valid) { _tcscat(toracle, OracleFormatDistance(NearestBigCity.Name,gettext(_T("_@M1714_")), NearestBigCity.Distance, NearestBigCity.Bearing,0)); // the city _tcscat(toracle, _T("\n")); } if (NearestCity.Valid && NearestSmallCity.Valid) { if ( (NearestCity.Distance - NearestSmallCity.Distance) <=3000) item=&NearestCity; else item=&NearestSmallCity; } else { if (NearestCity.Valid) item=&NearestCity; else if (NearestSmallCity.Valid) item=&NearestSmallCity; } if (item) { dist=item->Distance; brg=item->Bearing; if (dist>1500) { // // 2km South of city // _stprintf(ttmp,_T("%.0f %s %s %s "), dist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg), gettext(_T("_@M1715_"))); // of the city _tcscat(toracle,ttmp); } else { // // Over city // _stprintf(ttmp,_T("%s "),gettext(_T("_@M1716_"))); // Over the city _tcscat(toracle,ttmp); over=true; } _stprintf(ttmp,_T("<%s>"), item->Name); _tcscat(toracle,ttmp); found=true; } // Careful, some wide water areas have the center far away from us even if we are over them. // We can only check for 2-5km distances max. if (NearestWaterArea.Valid) { if (found) { if (NearestWaterArea.Distance<2000) { if (over) { // // Over city and lake // _stprintf(ttmp,_T(" %s %s"), gettext(_T("_@M1717_")),NearestWaterArea.Name); // and _tcscat(toracle,ttmp); saynear=true; } else { // // 2km South of city // over lake // _stprintf(ttmp,_T("\n%s %s"), gettext(_T("_@M1718_")),NearestWaterArea.Name); // over _tcscat(toracle,ttmp); saynear=true; } } else { if (NearestWaterArea.Distance<6000) { if (over) { // // Over city // near lake // _stprintf(ttmp,_T("\n%s %s"), gettext(_T("_@M1719_")),NearestWaterArea.Name); // near to _tcscat(toracle,ttmp); } else { // // 2km South of city // near lake // _stprintf(ttmp,_T("\n%s %s"), gettext(_T("_@M1718_")),NearestWaterArea.Name); // over _tcscat(toracle,ttmp); } } // else no mention to water area, even if it is the only item. Not accurate! } } else { if (NearestWaterArea.Distance>2000) { brg=NearestWaterArea.Bearing; // // 2km North of lake // _stprintf(ttmp,_T("%.0f %s %s "), NearestWaterArea.Distance*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); _tcscat(toracle,ttmp); _stprintf(ttmp,_T("%s <%s>"), gettext(_T("_@M1711_")),NearestWaterArea.Name); // of _tcscat(toracle,ttmp); } else { // // Over lake // _stprintf(ttmp,_T("%s <%s>"), gettext(_T("_@M1718_")),NearestWaterArea.Name); // over _tcscat(toracle,ttmp); over=true; } found=true; } } _tcscat(toracle,_T("\n")); int j=FindNearestFarVisibleWayPoint(GPS_INFO.Longitude,GPS_INFO.Latitude,70000,WPT_UNKNOWN); if (!ValidNotResWayPoint(j)) goto _end; found=true; _dowp: DistanceBearing( WayPointList[j].Latitude,WayPointList[j].Longitude, GPS_INFO.Latitude, GPS_INFO.Longitude, &wpdist,&brg); TCHAR wptype[100]; switch(WayPointList[j].Style) { case 2: case 4: _stprintf(wptype,_T("%s "), gettext(_T("_@M1720_"))); // the airfield of break; case 3: _stprintf(wptype,_T("%s "), gettext(_T("_@M1721_"))); // the field of needmorewp=true; break; case 5: _stprintf(wptype,_T("%s "), gettext(_T("_@M1722_"))); // the airport of break; default: _tcscpy(wptype,_T("")); needmorewp=true; break; } if ( (_tcslen(wptype)==0) && WayPointCalc[j].IsLandable) { if (WayPointCalc[j].IsAirport) { _stprintf(wptype,_T("%s "), gettext(_T("_@M1720_"))); // the airfield of needmorewp=false; } else { _stprintf(wptype,_T("%s "), gettext(_T("_@M1721_"))); // the field of needmorewp=true; } } else { if (_tcslen(wptype)==0 ) { _tcscpy(wptype,_T("")); needmorewp=true; } } // nn km south if (wpdist>2000) { // // 2km South of city // and/over lake // 4 km SW of waypoint _stprintf(ttmp,_T("\n%.0f %s %s "), wpdist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); _tcscat(toracle,ttmp); _stprintf(ttmp,_T("%s %s<%s>"), gettext(_T("_@M1711_")),wptype,WayPointList[j].Name); // of _tcscat(toracle,ttmp); } else { if (found) { if (over) { if (saynear) { // // 2km South of city // over lake // near waypoint // ---- // Over city and lake // near waypoint _stprintf(ttmp,_T("\n%s %s<%s>"), gettext(_T("_@M1719_")),wptype,WayPointList[j].Name); // near to _tcscat(toracle,ttmp); } else { // Over city // near lake and waypoint _stprintf(ttmp,_T(" %s %s<%s>"), gettext(_T("_@M1717_")),wptype,WayPointList[j].Name); // and _tcscat(toracle,ttmp); } } else { _stprintf(ttmp,_T("\n%s %s<%s>"), gettext(_T("_@M1719_")),wptype,WayPointList[j].Name); // near to _tcscat(toracle,ttmp); } } else { // // Near waypoint (because "over" could be wrong, we have altitudes in wp!) // _stprintf(ttmp,_T("%s %s<%s>"), gettext(_T("_@M1723_")),wptype,WayPointList[j].Name); // Near to _tcscat(toracle,ttmp); } } if (!needmorewp) goto _end; if (secondwpdone) goto _end; j=FindNearestFarVisibleWayPoint(GPS_INFO.Longitude,GPS_INFO.Latitude,70000,WPT_AIRPORT); if (!ValidNotResWayPoint(j)) goto _end; secondwpdone=true; goto _dowp; _end: // VERY SORRY - YOUR POSITION IS UNKNOWN! if (!found) wsprintf(toracle,_T("\n\n%s\n\n%s"), gettext(_T("_@M1725_")),gettext(_T("_@M1726_"))); ConvToUpper(toracle); MessageBoxX(hWndMainWindow, toracle, gettext(_T("_@M1690_")), MB_OK|MB_ICONQUESTION, true); }
// This function is called upon exiting a thermal, just before input event to cruise mode is issued // Functions using the ThermalHistory array should always check for Valid flag at each step, // and in any case never use the array while Circling. Because anytime we may change a value, in case // (very rare) the 100 limit is passed and we are reusing a value. // // When this function is called, the L> thermal is automatically selected as multitarget L // void InsertThermalHistory(double ThTime, double ThLat, double ThLon, double ThBase,double ThTop, double ThAvg) { int i; for (i=0; i<MAX_THERMAL_HISTORY; i++) { if (ThermalHistory[i].Valid == false) break; } if (i==MAX_THERMAL_HISTORY) { #if DEBUG_THISTORY StartupStore(_T("... no more space in thermal history\n")); #endif int oldest=0; // lets assume the 0 is the oldest, to begin for (i=1; i<MAX_THERMAL_HISTORY; i++) { if ( ThermalHistory[i].Time < ThermalHistory[oldest].Time ) { oldest=i; continue; } } #if DEBUG_THISTORY StartupStore(_T(".... oldest thermal in history is n.%d\n"),oldest); #endif i=oldest; } if (i<0 || i>=MAX_THERMAL_HISTORY) { #if DEBUG_THISTORY StartupStore(_T("..... Insert thermal history out of range: <%d>!\n"),i); #endif return; } ThermalHistory[i].Valid=false; TCHAR tstring[10]; Units::TimeToTextSimple(tstring,TimeLocal((int)ThTime)); _stprintf(ThermalHistory[i].Name,_T("th%s"),tstring); ThermalHistory[i].Time = ThTime; ThermalHistory[i].Latitude = ThLat; ThermalHistory[i].Longitude = ThLon; ThermalHistory[i].HBase = ThBase; ThermalHistory[i].HTop = ThTop; ThermalHistory[i].Lift = ThAvg; ThermalHistory[i].Valid=true; int j=FindNearestFarVisibleWayPoint(ThLon,ThLat,15000,WPT_UNKNOWN); if (j>0) { #if DEBUG_THISTORY StartupStore(_T("..... Thermal is near wp.%d <%s>\n"),j,WayPointList[j].Name); #endif TCHAR wpnear[NAME_SIZE+1]; _tcscpy(wpnear,WayPointList[j].Name); wpnear[19]='\0'; // sized 20 chars _tcscpy(ThermalHistory[i].Near,wpnear); } else { _tcscpy(ThermalHistory[i].Near,_T("")); } LockTaskData(); _tcscpy(WayPointList[RESWP_LASTTHERMAL].Name , ThermalHistory[i].Name); WayPointList[RESWP_LASTTHERMAL].Latitude = CALCULATED_INFO.ClimbStartLat; WayPointList[RESWP_LASTTHERMAL].Longitude = CALCULATED_INFO.ClimbStartLong; WayPointList[RESWP_LASTTHERMAL].Altitude = CALCULATED_INFO.ClimbStartAlt; LKASSERT(WayPointList[RESWP_LASTTHERMAL].Comment); if (j>0) _tcscpy(WayPointList[RESWP_LASTTHERMAL].Comment,ThermalHistory[i].Name); else _tcscpy(WayPointList[RESWP_LASTTHERMAL].Comment, MsgToken(1320)); // last good thermal UnlockTaskData(); // Update holder selected L> SetThermalMultitarget(i); #if DEBUG_THISTORY StartupStore(_T("... Insert new thermal in history[%d]: <%s> Base=%.0f Top=%.0f Lift=%.1f\n"), i, ThermalHistory[i].Name, ThBase, ThTop, ThAvg); #endif }