Пример #1
0
/*
 * Used by Alternates and BestAlternate
 * Colors VGR are used by DrawNearest &c.
 */
void DoAlternates(NMEA_INFO *Basic, DERIVED_INFO *Calculated, int AltWaypoint) {
   CScopeLock(LockTaskData, UnlockTaskData);
   
  #ifdef GTL2
  // If flying an AAT and working on the RESWP_OPTIMIZED waypoint, then use
  // this "optimized" waypoint to store data for the AAT virtual waypoint.

  if ((AltWaypoint == RESWP_OPTIMIZED) && (!ISPARAGLIDER || (AATEnabled && !DoOptimizeRoute()))) {
    WayPointList[RESWP_OPTIMIZED].Latitude  = Task[ActiveWayPoint].AATTargetLat;
    WayPointList[RESWP_OPTIMIZED].Longitude = Task[ActiveWayPoint].AATTargetLon;
    WayPointList[RESWP_OPTIMIZED].Altitude = WayPointList[Task[ActiveWayPoint].Index].Altitude;
	WaypointAltitudeFromTerrain(&WayPointList[RESWP_OPTIMIZED]);
	_stprintf(WayPointList[RESWP_OPTIMIZED].Name, _T("!%s"),WayPointList[Task[ActiveWayPoint].Index].Name);
  }
  #endif

  // handle virtual wps as alternates
  if (AltWaypoint<=RESWP_END) {
	if (!ValidResWayPoint(AltWaypoint)) return;
  } else {
	if (!ValidWayPoint(AltWaypoint)) return;
  }

  double *altwp_dist	= &WayPointCalc[AltWaypoint].Distance;
  double *altwp_gr	= &WayPointCalc[AltWaypoint].GR;
  double *altwp_arrival	= &WayPointCalc[AltWaypoint].AltArriv[AltArrivMode];

  DistanceBearing(WayPointList[AltWaypoint].Latitude, WayPointList[AltWaypoint].Longitude,
                  Basic->Latitude, Basic->Longitude,
                  altwp_dist, NULL);

  *altwp_gr = CalculateGlideRatio( *altwp_dist,
	Calculated->NavAltitude - WayPointList[AltWaypoint].Altitude - GetSafetyAltitude(AltWaypoint));

  // We need to calculate arrival also for BestAlternate, since the last "reachable" could be
  // even 60 seconds old and things may have changed drastically
  *altwp_arrival = CalculateWaypointArrivalAltitude(Basic, Calculated, AltWaypoint);
  
  WayPointCalc[AltWaypoint].VGR = GetVisualGlideRatio(*altwp_arrival, *altwp_gr);
} 
Пример #2
0
// This is converting DAT Winpilot
int ParseDAT(TCHAR *String,WAYPOINT *Temp)
{
  TCHAR ctemp[(COMMENT_SIZE*2)+1]; // 101102 BUGFIX, we let +1 for safety
  TCHAR *Number;
  TCHAR *pWClast = NULL;
  TCHAR *pToken;
  TCHAR TempString[READLINE_LENGTH];

  _tcscpy(TempString, String);  
  // 20060513:sgi added wor on a copy of the string, do not modify the
  // source string, needed on error messages

  Temp->Visible = true; // default all waypoints visible at start
  Temp->FarVisible = true;
  Temp->Format = LKW_DAT;

  Temp->FileNum = globalFileNum;

  // ExtractParameter(TempString,ctemp,0);
  if ((pToken = _tcstok_r(TempString, TEXT(","), &pWClast)) == NULL)
    return FALSE;
  Temp->Number = _tcstol(pToken, &Number, 10);
        
  //ExtractParameter(TempString,ctemp,1); //Latitude
  if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL)
    return FALSE;
  Temp->Latitude = CalculateAngle(pToken);

  if((Temp->Latitude > 90) || (Temp->Latitude < -90))
    {
      return FALSE;
    }

  //ExtractParameter(TempString,ctemp,2); //Longitude
  if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL)
    return FALSE;
  Temp->Longitude  = CalculateAngle(pToken);
  if((Temp->Longitude  > 180) || (Temp->Longitude  < -180))
    {
      return FALSE;
    }

  //ExtractParameter(TempString,ctemp,3); //Altitude
  if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL)
    return FALSE;
  Temp->Altitude = ReadAltitude(pToken);
  if (Temp->Altitude == -9999){
    return FALSE;
  }

  //ExtractParameter(TempString,ctemp,4); //Flags
  if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL)
    return FALSE;
  Temp->Flags = CheckFlags(pToken);

  //ExtractParameter(TempString,ctemp,5); // Name
  if ((pToken = _tcstok_r(NULL, TEXT(",\n\r"), &pWClast)) == NULL)
    return FALSE;

  // guard against overrun
  if (_tcslen(pToken)>NAME_SIZE) {
    pToken[NAME_SIZE-1]= _T('\0');
  }

  _tcscpy(Temp->Name, pToken);
  int i;
  for (i=_tcslen(Temp->Name)-1; i>1; i--) {
    if (Temp->Name[i]==' ') {
      Temp->Name[i]=0;
    } else {
      break;
    }
  }

  //ExtractParameter(TempString,ctemp,6); // Comment
  // DAT Comment
  if ((pToken = _tcstok_r(NULL, TEXT("\n\r"), &pWClast)) != NULL){
    LK_tcsncpy(ctemp, pToken, COMMENT_SIZE); //@ 101102 BUGFIX bad. ctemp was not sized correctly!

    if (_tcslen(ctemp) >0 ) {
	if (Temp->Comment) {
		free(Temp->Comment);
	}
	Temp->Comment = (TCHAR*)malloc((_tcslen(ctemp)+1)*sizeof(TCHAR));
	if (Temp->Comment) _tcscpy(Temp->Comment, ctemp);
    }

  } else {
    Temp->Comment = NULL; // useless
  }

  if(Temp->Altitude <= 0) {
    WaypointAltitudeFromTerrain(Temp);
  } 

  if (Temp->Details) {
    free(Temp->Details);
  }

  return TRUE;
}
Пример #3
0
static bool
ParseWayPointString(WAYPOINT *Temp, const TCHAR *input,
                    RasterTerrain &terrain)
{
  TCHAR *endptr;
  size_t length;

  Temp->FileNum = globalFileNum;

  Temp->Number = _tcstol(input, &endptr, 10);
  if (endptr == input || *endptr != _T(','))
    return false;

  input = endptr + 1;

  if (!ParseAngle(input, &Temp->Location.Latitude, &endptr) ||
      Temp->Location.Latitude > 90 || Temp->Location.Latitude < -90 ||
      *endptr != _T(','))
    return false;

  input = endptr + 1;

  ParseAngle(input, &Temp->Location.Longitude, &endptr);
  if (!ParseAngle(input, &Temp->Location.Longitude, &endptr) ||
      Temp->Location.Longitude > 180 || Temp->Location.Longitude < -180 ||
      *endptr != _T(','))
    return false;

  input = endptr + 1;

  if (!ParseAltitude(input, &Temp->Altitude, &endptr) ||
      *endptr != _T(','))
    return false;

  input = endptr + 1;

  Temp->Flags = ParseFlags(input, &input);
  if (*input != _T(','))
    return false;

  ++input;

  endptr = _tcschr(input, _T(','));
  if (endptr != NULL)
    length = endptr - input;
  else
    length = _tcslen(input);

  if (length >= sizeof(Temp->Name))
    length = sizeof(Temp->Name) - 1;

  while (length > 0 && input[length - 1] == 0)
    --length;

  memcpy(Temp->Name, input, length * sizeof(input[0]));
  Temp->Name[length] = 0;

  if (endptr != NULL) {
    input = endptr + 1;

    endptr = _tcschr(input, '*');
    if (endptr != NULL) {
      length = endptr - input;

      // if it is a home waypoint raise zoom level
      Temp->Zoom = _tcstol(endptr + 2, NULL, 10);
    } else {
      length = _tcslen(input);
      Temp->Zoom = 0;
    }

    if (length >= sizeof(Temp->Comment))
      length = sizeof(Temp->Comment) - 1;

    while (length > 0 && input[length - 1] == 0)
      --length;

    memcpy(Temp->Comment, input, length * sizeof(input[0]));
    Temp->Comment[length] = 0;
  } else {
    Temp->Comment[0] = 0;
    Temp->Zoom = 0;
  }

  if(Temp->Altitude <= 0) {
    WaypointAltitudeFromTerrain(Temp, terrain);
  }

  if (Temp->Details) {
    free(Temp->Details);
  }

  return true;
}
Пример #4
0
//#define CUPDEBUG
bool ParseCUPWayPointString(TCHAR *String,WAYPOINT *Temp)
{
  TCHAR ctemp[(COMMENT_SIZE*2)+1]; // must be bigger than COMMENT_SIZE!
  TCHAR *pToken;
  TCHAR TempString[READLINE_LENGTH+1];
  TCHAR OrigString[READLINE_LENGTH+1];
  TCHAR Tname[NAME_SIZE+1];
  int flags=0;

  unsigned int i, j;
  bool ishome=false; // 100310

  // strtok does not return empty fields. we create them here with special char
  #define DUMCHAR	'|'

  Temp->Visible = true; // default all waypoints visible at start
  Temp->FarVisible = true;
  Temp->Format = LKW_CUP;
  Temp->Number = WayPointList.size();

  Temp->FileNum = globalFileNum;

  #if BUGSTOP
  // This should never happen
  LKASSERT(_tcslen(String) < sizeof(OrigString));
  #endif
  LK_tcsncpy(OrigString, String,READLINE_LENGTH);
  // if string is too short do nothing
  if (_tcslen(OrigString)<11) return false;

  #ifdef CUPDEBUG
  StartupStore(_T("OLD:<%s>%s"),OrigString,NEWLINE);
  #endif

  for (i=0,j=0; i<_tcslen(OrigString); i++) {

	// skip last comma, and avoid overruning the end
	if (  (i+1)>= _tcslen(OrigString)) break;
	if ( (OrigString[i] == _T(',')) && (OrigString[i+1] == _T(',')) ) {
		TempString[j++] = _T(',');
		TempString[j++] = _T(DUMCHAR);
		continue;
	}
	/* we need terminations for comments
	if ( OrigString[i] == _T('\r') ) continue;
	if ( OrigString[i] == _T('\n') ) continue;
	*/

	TempString[j++] = OrigString[i];
  }
  TempString[j] = _T('\0');

  #ifdef CUPDEBUG
  StartupStore(_T("NEW:<%s>%s"),TempString,NEWLINE);
  #endif
  // ---------------- NAME ----------------
  pToken = _tcstok(TempString, TEXT(","));
  if (pToken == NULL) return false;

  if (_tcslen(pToken)>NAME_SIZE) {
	pToken[NAME_SIZE-1]= _T('\0');
  }

  _tcscpy(Temp->Name, pToken);
  CleanCupCode(Temp->Name);

  #ifdef CUPDEBUG
  StartupStore(_T("   CUP NAME=<%s>%s"),Temp->Name,NEWLINE);
  #endif


  // ---------------- CODE ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;

  if (_tcslen(pToken)>CUPSIZE_CODE) {
      pToken[CUPSIZE_CODE-1]= _T('\0');
  }
  _tcscpy(Temp->Code, pToken);
  for (i=_tcslen(Temp->Code)-1; i>1; i--) { 
      if (Temp->Code[i]==' ') {
          Temp->Code[i]=0;  
      } else {
          break;
      }
  }
  _tcscpy(Tname,Temp->Code);
  for (j=0, i=0; i<_tcslen(Tname); i++) {
	//if (Tname[i]!='\"') Temp->Code[j++]=Tname[i];
	if ( (Tname[i]!='\"') && (Tname[i]!=DUMCHAR) ){
       Temp->Code[j++]=Tname[i];
    } 
  }
  Temp->Code[j]= _T('\0');

  if (_tcslen(Temp->Code)>5) { // 100310
	if (  _tcscmp(Temp->Code,_T("LKHOME")) == 0 ) {
		StartupStore(_T(". Found LKHOME inside CUP waypoint <%s>%s"),Temp->Name,NEWLINE);
		ishome=true;
	}
  }
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP CODE=<%s>%s"),Temp->Code,NEWLINE);
  #endif


  // ---------------- COUNTRY ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  LK_tcsncpy(Temp->Country,pToken,CUPSIZE_COUNTRY);
  if (_tcslen(Temp->Country)>3) {
	Temp->Country[3]= _T('\0');
  }
  if ((_tcslen(Temp->Country) == 1) && Temp->Country[0]==DUMCHAR) Temp->Country[0]=_T('\0');

  #ifdef CUPDEBUG
  StartupStore(_T("   CUP COUNTRY=<%s>%s"),Temp->Country,NEWLINE);
  #endif


  // ---------------- LATITUDE  ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;

  Temp->Latitude = CUPToLat(pToken);

  if((Temp->Latitude > 90) || (Temp->Latitude < -90)) {
	return false;
  }
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP LATITUDE=<%f>%s"),Temp->Latitude,NEWLINE);
  #endif


  // ---------------- LONGITUDE  ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  Temp->Longitude  = CUPToLon(pToken);
  if((Temp->Longitude  > 180) || (Temp->Longitude  < -180)) {
	return false;
  }
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP LONGITUDE=<%f>%s"),Temp->Longitude,NEWLINE);
  #endif



  // ---------------- ELEVATION  ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  Temp->Altitude = ReadAltitude(pToken);
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP ELEVATION=<%f>%s"),Temp->Altitude,NEWLINE);
  #endif
  if (Temp->Altitude == -9999){
	  Temp->Altitude=0;
  }


  // ---------------- STYLE  ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;

  Temp->Style = (int)_tcstol(pToken,NULL,10);
  switch(Temp->Style) {
	case STYLE_AIRFIELDGRASS:	// airfield grass
	case STYLE_GLIDERSITE:		// glider site
	case STYLE_AIRFIELDSOLID:	// airfield solid
		flags = AIRPORT;
		flags += LANDPOINT;
		break;
	case STYLE_OUTLANDING:		// outlanding
		flags = LANDPOINT;
		break;
	default:
		flags = TURNPOINT;
		break;
  }
  if (ishome) flags += HOME;
  Temp->Flags = flags;

  #ifdef CUPDEBUG
  StartupStore(_T("   CUP STYLE=<%d> flags=%d %s"),Temp->Style,Temp->Flags,NEWLINE);
  #endif

  // ---------------- RWY DIRECTION   ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  if ((_tcslen(pToken) == 1) && (pToken[0]==DUMCHAR))
	Temp->RunwayDir=-1;
  else
	Temp->RunwayDir = (int)AngleLimit360(_tcstol(pToken, NULL, 10));
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP RUNWAY DIRECTION=<%d>%s"),Temp->RunwayDir,NEWLINE);
  #endif


  // ---------------- RWY LENGTH   ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  if ((_tcslen(pToken) == 1) && (pToken[0]==DUMCHAR))
	Temp->RunwayLen = -1;
  else
	Temp->RunwayLen = (int)ReadLength(pToken);
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP RUNWAY LEN=<%d>%s"),Temp->RunwayLen,NEWLINE);
  #endif



  // ---------------- AIRPORT FREQ   ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  if (_tcslen(pToken)>CUPSIZE_FREQ) pToken[CUPSIZE_FREQ-1]= _T('\0');
  _tcscpy(Temp->Freq, pToken);
  TrimRight(Temp->Freq);
  _tcscpy(Tname,Temp->Freq);
  for (j=0, i=0; i<_tcslen(Tname); i++)
	if ( (Tname[i]!='\"') && (Tname[i]!=DUMCHAR) ) Temp->Freq[j++]=Tname[i];
  Temp->Freq[j]= _T('\0');

  #ifdef CUPDEBUG
  StartupStore(_T("   CUP FREQ=<%s>%s"),Temp->Freq,NEWLINE);
  #endif


  // ---------------- COMMENT   ------------------
  pToken = _tcstok(NULL, TEXT("\n\r"));
  if (pToken != NULL) {

	if (_tcslen(pToken)>=COMMENT_SIZE) pToken[COMMENT_SIZE-1]= _T('\0');

	// remove trailing spaces and CR LF
	_tcscpy(ctemp, pToken);
	for (i=_tcslen(ctemp)-1; i>1; i--) {
		if ( (ctemp[i]==' ') || (ctemp[i]=='\r') || (ctemp[i]=='\n') ) ctemp[i]=0;
		else
			break;
	}

	// now remove " " (if there)
	for (j=0, i=0; i<_tcslen(ctemp); i++)
		if (ctemp[i]!='\"') ctemp[j++]=ctemp[i];
	ctemp[j]= _T('\0');
	if (_tcslen(ctemp) >0 ) {
		if (Temp->Comment) {
			free(Temp->Comment);
		}
		Temp->Comment = (TCHAR*)malloc((_tcslen(ctemp)+1)*sizeof(TCHAR));
		if (Temp->Comment) _tcscpy(Temp->Comment, ctemp);
	}

	#ifdef CUPDEBUG
	StartupStore(_T("   CUP COMMENT=<%s>%s"),Temp->Comment,NEWLINE);
	#endif
  } else {
	Temp->Comment=NULL; // useless
  }

  if(Temp->Altitude <= 0) {
	WaypointAltitudeFromTerrain(Temp);
  }

  if (Temp->Details) {
	free(Temp->Details);
  }

  return true;
}
Пример #5
0
static void GetValues(void) {
  WndProperty* wp;
  bool sign = false;
  int dd = 0;
  double num=0, mm = 0, ss = 0; // mm,ss are numerators (division) so don't want to lose decimals

  wp = (WndProperty*)wf->FindByName(TEXT("prpLongitudeSign"));
  if (wp) {
    sign = (wp->GetDataField()->GetAsInteger()==1);
  }
  wp = (WndProperty*)wf->FindByName(TEXT("prpLongitudeD"));
  if (wp) {
    dd = wp->GetDataField()->GetAsInteger();
  }

  switch (Units::CoordinateFormat) {
  case 0: // ("DDMMSS");
  case 1: // ("DDMMSS.ss");
    wp = (WndProperty*)wf->FindByName(TEXT("prpLongitudeM"));
    if (wp) {
      mm = wp->GetDataField()->GetAsInteger();
    }
    wp = (WndProperty*)wf->FindByName(TEXT("prpLongitudeS"));
    if (wp) {
      ss = wp->GetDataField()->GetAsInteger();
    }
    num = dd+mm/60.0+ss/3600.0;
    break;
  case 2: // ("DDMM.mmm");
    wp = (WndProperty*)wf->FindByName(TEXT("prpLongitudeM"));
    if (wp) {
      mm = wp->GetDataField()->GetAsInteger();
    }
    wp = (WndProperty*)wf->FindByName(TEXT("prpLongitudemmm"));
    if (wp) {
      ss = wp->GetDataField()->GetAsInteger();
    }
    num = dd+(mm+ss/1000.0)/60.0;
    break;
  case 3: // ("DD.dddd");
    wp = (WndProperty*)wf->FindByName(TEXT("prpLongitudeDDDD"));
    if (wp) {
      mm = wp->GetDataField()->GetAsInteger();
    }
    num = dd+mm/10000;
    break;
  }
  if (!sign) {
    num = -num;
  }
  
  global_wpt->Longitude = num;
  
  wp = (WndProperty*)wf->FindByName(TEXT("prpLatitudeSign"));
  if (wp) {
    sign = (wp->GetDataField()->GetAsInteger()==1);
  }
  wp = (WndProperty*)wf->FindByName(TEXT("prpLatitudeD"));
  if (wp) {
    dd = wp->GetDataField()->GetAsInteger();
  }

  switch (Units::CoordinateFormat) {
  case 0: // ("DDMMSS");
  case 1: // ("DDMMSS.ss");
    wp = (WndProperty*)wf->FindByName(TEXT("prpLatitudeM"));
    if (wp) {
      mm = wp->GetDataField()->GetAsInteger();
    }
    wp = (WndProperty*)wf->FindByName(TEXT("prpLatitudeS"));
    if (wp) {
      ss = wp->GetDataField()->GetAsInteger();
    }
    num = dd+mm/60.0+ss/3600.0;
    break;
  case 2: // ("DDMM.mmm");
    wp = (WndProperty*)wf->FindByName(TEXT("prpLatitudeM"));
    if (wp) {
      mm = wp->GetDataField()->GetAsInteger();
    }
    wp = (WndProperty*)wf->FindByName(TEXT("prpLatitudemmm"));
    if (wp) {
      ss = wp->GetDataField()->GetAsInteger();
    }
    num = dd+(mm+ss/1000.0)/60.0;
    break;
  case 3: // ("DD.dddd");
    wp = (WndProperty*)wf->FindByName(TEXT("prpLatitudeDDDD"));
    if (wp) {
      mm = wp->GetDataField()->GetAsInteger();
    }
    num = dd+mm/10000;
    break;
  }
  if (!sign) {
    num = -num;
  }
  
  global_wpt->Latitude = num;
  
  wp = (WndProperty*)wf->FindByName(TEXT("prpAltitude"));
  if (wp) {
    ss = wp->GetDataField()->GetAsInteger();
    if (ss==0) {
      WaypointAltitudeFromTerrain(global_wpt);
    } else {
      global_wpt->Altitude = ss/ALTITUDEMODIFY;
    }
  }
  
  wp = (WndProperty*)wf->FindByName(TEXT("prpFlags"));
  if (wp) {
    int myflag = wp->GetDataField()->GetAsInteger();
    switch(myflag) {
    case 0:
      global_wpt->Flags = TURNPOINT;
	#if 100825
	if ( global_wpt->Format == LKW_CUP) {
		// set normal turnpoint style
		global_wpt->Style = 1;
	}
	#endif
      break;
    case 1:
      global_wpt->Flags = AIRPORT | TURNPOINT;
	#if 100825
	if ( global_wpt->Format == LKW_CUP) {
		// set airfield style
		global_wpt->Style = 5;
	}
	#endif
      break;
    case 2:
      global_wpt->Flags = LANDPOINT;
	#if 100825
	if ( global_wpt->Format == LKW_CUP) {
		// set outlanding style
		global_wpt->Style = 3;
	}
	#endif
      break;
    default:
      global_wpt->Flags = 0;
    };
  }
}
Пример #6
0
bool ParseOZIWayPointString(TCHAR *String,WAYPOINT *Temp) {

    Temp->Visible = true; // default all waypoints visible at start
    Temp->FarVisible = true;
    Temp->Format = LKW_OZI;
    Temp->Number = NumberOfWayPoints;
    Temp->FileNum = globalFileNum;
    Temp->Flags = TURNPOINT;

    memset(Temp->Name, 0, sizeof(Temp->Name)); // clear Name

    TCHAR TempString[READLINE_LENGTH];
    memset(TempString, 0, sizeof(TempString)); // clear TempString

    _tcscpy(TempString, String);

    // strtok_r skip empty field, It's not compatible with OziExplorer Waypoint File Version 1.1
    // use strsep_r instead of ( cf. Utils.h )

    TCHAR *pToken = NULL;
    TCHAR *Stop= NULL;

    TCHAR *pWClast = TempString;


    //	Field 1 : Number - this is the location in the array (max 1000), must be unique, usually start at 1 and increment. Can be set to -1 (minus 1) and the number will be auto generated.
    if ((pToken = strsep_r(TempString, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 2 : Name - the waypoint name, use the correct length name to suit the GPS type.
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    // guard against overrun
    if (_tcslen(pToken)>NAME_SIZE) {
        pToken[NAME_SIZE-1]= _T('\0');
    }

    // remove trailing spaces
    for (int i=_tcslen(pToken)-1; i>1; i--) if (pToken[i]==' ') pToken[i]=0;
        else break;

    _tcscpy(Temp->Name, pToken);

    //	Field 3 : Latitude - decimal degrees.
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    Temp->Latitude = (double)StrToDouble(pToken, &Stop);

    if((Temp->Latitude > 90) || (Temp->Latitude < -90)) {
        return false;
    }

    //	Field 4 : Longitude - decimal degrees.
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    Temp->Longitude  = (double)StrToDouble(pToken, &Stop);
    if((Temp->Longitude  > 180) || (Temp->Longitude  < -180)) {
        return false;
    }
    //	Field 5 : Date - see Date Format below, if blank a preset date will be used
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 6 : Symbol - 0 to number of symbols in GPS
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 7 : Status - always set to 1
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 8 : Map Display Format
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 9 : Foreground Color (RGB value)
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 10 : Background Color (RGB value)
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 11 : Description (max 40), no commas
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    if (_tcslen(pToken) >0 ) {
        // remove trailing spaces
        for (int i=_tcslen(pToken)-1; i>1; i--) if (pToken[i]==' ') pToken[i]=0;
            else break;

        if (Temp->Comment) {
            free(Temp->Comment);
        }
        Temp->Comment = (TCHAR*)malloc((_tcslen(pToken)+1)*sizeof(TCHAR));
        if (Temp->Comment) _tcscpy(Temp->Comment, pToken);
    }
    else {
        Temp->Comment = NULL; // useless
    }

    //	Field 12 : Pointer Direction
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 13 : Garmin Display Format
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 14 : Proximity Distance - 0 is off any other number is valid
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    //	Field 15 : Altitude - in feet (-777 if not valid)
    if ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) == NULL)
        return false;

    Temp->Altitude = (double)StrToDouble(pToken, &Stop)/TOFEET;
    if(Temp->Altitude <= 0) {
        WaypointAltitudeFromTerrain(Temp);
    }

    //	Field 16 : Font Size - in points
    //	Field 17 : Font Style - 0 is normal, 1 is bold.
    //	Field 18 : Symbol Size - 17 is normal size
    //	Field 19 : Proximity Symbol Position
    //	Field 20 : Proximity Time
    //	Field 21 : Proximity or Route or Both
    //	Field 22 : File Attachment Name
    //	Field 23 : Proximity File Attachment Name
    //	Field 24 : Proximity Symbol Name

    return true;
}