Example #1
0
static void OnMultiSelectListPaintListItem(WindowControl * Sender, LKSurface& Surface) {

    #define PICTO_WIDTH 50
    
    Surface.SetTextColor(RGB_BLACK);
    if ((DrawListIndex < iNO_ELEMENTS) &&(DrawListIndex >= 0)) {
        int j;
        static CAirspaceBase airspace_copy;
        int i = DrawListIndex;
        LKASSERT(i < MAX_LIST_ITEMS);
        PixelRect rc = {
            0, 
            0, 
            DLGSCALE(PICTO_WIDTH), 
            static_cast<PixelScalar>(Sender->GetHeight())
        };

        const CAirspace* pAS = NULL;
        int HorDist, Bearing, VertDist;
        double Distance;
        unsigned int idx = 0;
        TCHAR text1[180] = {TEXT("empty")};
        TCHAR text2[180] = {TEXT("empty")};
        TCHAR Comment[80] = {TEXT("")};
        TCHAR Comment1[80] = {TEXT("")};
        Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF));
        LKASSERT(i < MAX_LIST_ITEMS);

        switch (Elements[i].type) {
        case IM_AIRSPACE:
            pAS = (CAirspace*) Elements[i].ptr;
            if (pAS) {
                /***********************************************************************
                 * here we use a local copy of the airspace, only common property exists
                 ***********************************************************************/
                airspace_copy = CAirspaceManager::Instance().GetAirspaceCopy(pAS);

                // airspace type already in name?
                if (_tcsnicmp(airspace_copy.Name(), airspace_copy.TypeName(), _tcslen(airspace_copy.TypeName())) == 0) {
                    _stprintf(text1, TEXT("%s"), airspace_copy.Name()); // yes, take name only
                } else {
                    // fixed strings max. 20 NAME_SIZE 30 => max. 30 char
                    _stprintf(text1, TEXT("%s %s"), airspace_copy.TypeName(), airspace_copy.Name());
                }

                CAirspaceManager::Instance().GetSimpleAirspaceAltText(Comment, sizeof (Comment) / sizeof (Comment[0]), airspace_copy.Top());
                CAirspaceManager::Instance().GetSimpleAirspaceAltText(Comment1, sizeof (Comment1) / sizeof (Comment1[0]), airspace_copy.Base());

                CAirspaceManager::Instance().AirspaceCalculateDistance((CAirspace*) pAS, &HorDist, &Bearing, &VertDist);
                _stprintf(text2, TEXT("%3.1f%s (%s - %s)"), (double) HorDist*DISTANCEMODIFY, Units::GetDistanceName(), Comment1, Comment); //8 + 8+3   21

                /****************************************************************
                 * for drawing the airspace pictorial, we need the original data.
                 * copy contain only base class property, not geo data,
                 * original data are shared ressources !
                 * for that we need to grant all called methods are thread safe
                 ****************************************************************/
                pAS->DrawPicto(Surface, rc);
            }
            break;


        case IM_TASK_PT:
        case IM_WAYPOINT:
            idx = -1;
            LockTaskData(); // protect from external task changes

            if (Elements[i].type == IM_TASK_PT) {
                if(ValidTaskPointFast(Elements[i].iIdx)) {
                    idx = Task[Elements[i].iIdx].Index;
                }
            } else {
                if(ValidWayPointFast(Elements[i].iIdx)) {
                    idx = Elements[i].iIdx;
                }
            }

            // This is not a solution. It will avoid a crash but the solution is to understand
            // why we are getting a wrong idx, eventually. If ever we got a wrong idx!
            // And then this "fix" should be changed to something more useful, instead of 
            // adopting a totally wrong waypoint for task.
            assert(idx < WayPointList.size());
            if(idx < WayPointList.size()) {

                if (WayPointList[idx].Comment != NULL) {
                    LK_tcsncpy(Comment, WayPointList[idx].Comment, 30);
                } else {
                    _tcscpy(Comment, TEXT(""));
                }

                DistanceBearing(GPS_INFO.Latitude, GPS_INFO.Longitude, WayPointList[idx].Latitude,
                                WayPointList[idx].Longitude, &Distance, NULL);

                if (Elements[i].type != IM_TASK_PT) {
                    if (WayPointCalc[idx].IsLandable) {
                        MapWindow::DrawRunway(Surface, &WayPointList[idx], rc, nullptr, 1.5, true);

                        if (WayPointCalc[idx].IsAirport) {
                            // remove spaces from frequency
                            for (j = 1; j < (CUPSIZE_FREQ); j++)
                                if (WayPointList[idx].Freq[CUPSIZE_FREQ - j] == ' ')
                                    WayPointList[idx].Freq[CUPSIZE_FREQ - j] = '\0';

                            if (_tcslen(WayPointList[idx].Freq) > 2)
                                _stprintf(text1, TEXT("%s %s MHz"), WayPointList[idx].Name,
                                          WayPointList[idx].Freq);
                            else
                                _stprintf(text1, TEXT("%s"), WayPointList[idx].Name);
                        } else {
                            if (WayPointList[idx].Comment != NULL)
                                _stprintf(text1, TEXT("%s %s"), WayPointList[idx].Name, Comment);
                            else
                                _stprintf(text1, TEXT("%s"), WayPointList[idx].Name);
                        }

                        if ((WayPointList[idx].RunwayLen >= 10) ||
                            (WayPointList[idx].RunwayDir > 0)) {
                            _stprintf(text2, TEXT("%3.1f%s (%i%s  %02i/%02i  %i%s)"),
                                      Distance * DISTANCEMODIFY, Units::GetDistanceName(),
                                      (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY),
                                      Units::GetAltitudeName(),
                                      (int) (WayPointList[idx].RunwayDir / 10.0 + 0.5),
                                      (int) (AngleLimit360(WayPointList[idx].RunwayDir + 180.0) /
                                             10.0 + 0.5),
                                      (int) ((double) WayPointList[idx].RunwayLen * ALTITUDEMODIFY),
                                      Units::GetAltitudeName());
                        } else {
                            _stprintf(text2, TEXT("%3.1f%s (%i%s) "), Distance * DISTANCEMODIFY,
                                      Units::GetDistanceName(),
                                      (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY),
                                      Units::GetAltitudeName());
                        }

                    }// waypoint isLandable
                    else {
                        MapWindow::DrawWaypointPicto(Surface, rc, &WayPointList[idx]);
                        _stprintf(text1, TEXT("%s %s"), WayPointList[idx].Name, Comment);

                        _stprintf(text2, TEXT("%3.1f%s (%i%s)"), Distance * DISTANCEMODIFY,
                                  Units::GetDistanceName(),
                                  (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY),
                                  Units::GetAltitudeName());
                    }

                }// Elements IM_TASK
                else {
                    int iTaskIdx = Elements[i].iIdx;
                    MapWindow::DrawTaskPicto(Surface, iTaskIdx, rc, 3000);
                    int iLastTaskPoint = 0;

                    while (ValidTaskPoint(iLastTaskPoint))
                        iLastTaskPoint++;

                    iLastTaskPoint--;

                    if (iTaskIdx == 0) {
                        // _@M2301_  "S"    # S = Start Task point
                        _stprintf(text1, TEXT("%s: (%s)"), MsgToken(2301), WayPointList[idx].Name);
                        _stprintf(text2, TEXT("Radius %3.1f%s (%i%s)"),
                                  StartRadius * DISTANCEMODIFY, Units::GetDistanceName(),
                                  (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY),
                                  Units::GetAltitudeName());
                    } else {
                        if (iTaskIdx == iLastTaskPoint) {
                            //	_@M2303_  "F"                 // max 30         30 => max 60 char
                            _stprintf(text1, TEXT("%s: (%s) "), MsgToken(2303),
                                      WayPointList[idx].Name);
                            _stprintf(text2, TEXT("Radius %3.1f%s (%i%s)"),
                                      FinishRadius * DISTANCEMODIFY, Units::GetDistanceName(),
                                      (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY),
                                      Units::GetAltitudeName());
                        } else {
                            //   _@M2302_  "T"    # F = Finish point            // max 30         30 => max 60 char
                            _stprintf(text1, TEXT("%s%i: (%s) "), MsgToken(2302), iTaskIdx,
                                      WayPointList[idx].Name);
                            double SecRadius = 0;

                            SecRadius = SectorRadius;
                            if (AATEnabled) {
                                if (Task[iTaskIdx].AATType == SECTOR)
                                    SecRadius = Task[iTaskIdx].AATSectorRadius;
                                else
                                    SecRadius = Task[iTaskIdx].AATCircleRadius;
                            }

                            _stprintf(text2, TEXT("Radius %3.1f%s (%i%s)"),
                                      SecRadius * DISTANCEMODIFY, Units::GetDistanceName(),
                                      (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY),
                                      Units::GetAltitudeName());
                        }
                    }

                }
            }
            UnlockTaskData(); // protect from external task changes
            break;
        }

        /********************
         * show text
         ********************/
        Surface.SetBackgroundTransparent();
        Surface.SetTextColor(RGB_BLACK);
        Surface.DrawText(rc.right + DLGSCALE(2), DLGSCALE(2), text1);
        int ytext2 = Surface.GetTextHeight(text1);
        Surface.SetTextColor(RGB_DARKBLUE);
        Surface.DrawText(rc.right + DLGSCALE(2), ytext2, text2);

    }
}
Example #2
0
static BOOL FLYSEN(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *GPS_INFO)
{

  TCHAR ctemp[80];
  double vtas;

  // VOID GPS SIGNAL
  NMEAParser::ExtractParameter(String,ctemp,8);
  if (_tcscmp(ctemp,_T("V"))==0) {
	GPS_INFO->NAVWarning=true;
	GPSCONNECT=false;
	goto label_nogps;
  }
  // ------------------------

  double tmplat;
  double tmplon;

  NMEAParser::ExtractParameter(String,ctemp,1);
  tmplat = MixedFormatToDegrees(StrToDouble(ctemp, NULL));
  NMEAParser::ExtractParameter(String,ctemp,2);
  tmplat = NorthOrSouth(tmplat, ctemp[0]);

  NMEAParser::ExtractParameter(String,ctemp,3);
  tmplon = MixedFormatToDegrees(StrToDouble(ctemp, NULL));
  NMEAParser::ExtractParameter(String,ctemp,4);
  tmplon = EastOrWest(tmplon,ctemp[0]);

  if (!((tmplat == 0.0) && (tmplon == 0.0))) {
        GPS_INFO->Latitude = tmplat;
        GPS_INFO->Longitude = tmplon;
	GPS_INFO->NAVWarning=false;
	GPSCONNECT=true;
  }

  // GPS SPEED
  NMEAParser::ExtractParameter(String,ctemp,6);
  GPS_INFO->Speed = StrToDouble(ctemp,NULL)/10;

  // TRACK BEARING
  if (GPS_INFO->Speed>1.0) {
	NMEAParser::ExtractParameter(String,ctemp,5);
	GPS_INFO->TrackBearing = AngleLimit360(StrToDouble(ctemp, NULL));
  }

  // HGPS
  NMEAParser::ExtractParameter(String,ctemp,7);
  GPS_INFO->Altitude = StrToDouble(ctemp,NULL);

  // ------------------------
  label_nogps: 

  // SATS
  NMEAParser::ExtractParameter(String,ctemp,9);
  GPS_INFO->SatellitesUsed = (int) StrToDouble(ctemp,NULL);
  GPS_INFO->SatellitesUsed = 4;

  // TIME
  // ignoring 00:00.00 , but that's minor problem. We don't have the date.
  // And no UTC, since this is local time already.
  NMEAParser::ExtractParameter(String,ctemp,0);
  double fixTime = StrToDouble(ctemp,NULL);
  if (fixTime>0 && GPS_INFO->SatellitesUsed>0) {
	double hours, mins,secs;
	hours = fixTime / 10000;
	GPS_INFO->Hour = (int)hours;
	mins = fixTime / 100;
	mins = mins - (GPS_INFO->Hour*100);
	GPS_INFO->Minute = (int)mins;
	secs = fixTime - (GPS_INFO->Hour*10000) - (GPS_INFO->Minute*100);
	GPS_INFO->Second = (int)secs;
  }


  // HPA from the pressure sensor
  //   NMEAParser::ExtractParameter(String,ctemp,10);
  //   double ps = StrToDouble(ctemp,NULL)/100;
  //   GPS_INFO->BaroAltitude = (1 - pow(fabs(ps / QNH),  0.190284)) * 44307.69;

  // HBAR 1013.25
  NMEAParser::ExtractParameter(String,ctemp,11);
  GPS_INFO->BaroAltitude = AltitudeToQNHAltitude(StrToDouble(ctemp,NULL));

  // VARIO
  NMEAParser::ExtractParameter(String,ctemp,12);
  GPS_INFO->Vario = StrToDouble(ctemp,NULL)/100;

  // TAS
  NMEAParser::ExtractParameter(String,ctemp,13);
  vtas=StrToDouble(ctemp,NULL)/10;
  GPS_INFO->IndicatedAirspeed = vtas/AirDensityRatio(GPS_INFO->BaroAltitude);
  GPS_INFO->TrueAirspeed = vtas;
  if (GPS_INFO->IndicatedAirspeed >0) 
	GPS_INFO->AirspeedAvailable = TRUE;
  else 
	GPS_INFO->AirspeedAvailable = FALSE;

  // ignore n.14 airspeed source

  // OAT
  NMEAParser::ExtractParameter(String,ctemp,15);
  GPS_INFO->OutsideAirTemperature = StrToDouble(ctemp,NULL);
  GPS_INFO->TemperatureAvailable=TRUE;

  // ignore n.16 baloon temperature  

  // BATTERY PERCENTAGES
  NMEAParser::ExtractParameter(String,ctemp,17);
  GPS_INFO->ExtBatt1_Voltage = StrToDouble(ctemp,NULL)+1000;
  NMEAParser::ExtractParameter(String,ctemp,18);
  GPS_INFO->ExtBatt2_Voltage = StrToDouble(ctemp,NULL)+1000;



  GPS_INFO->BaroAltitudeAvailable = TRUE;
  GPS_INFO->VarioAvailable = TRUE;

  // currently unused in LK, but ready for next future
  TriggerVarioUpdate();
  TriggerGPSUpdate();

  return TRUE;
}
Example #3
0
int LKSurface::Segment(long x, long y, int radius, const RECT& rc, double start, double end, bool horizon) {
    POINT pt[66];
    int i;
    int istart;
    int iend;

    if ((x - radius) > rc.right) return false;
    if ((x + radius) < rc.left) return false;
    if ((y - radius) > rc.bottom) return false;
    if ((y + radius) < rc.top) return false;

    // JMW added faster checking...

    start = AngleLimit360(start);
    end = AngleLimit360(end);

    istart = iround(start / 360.0 * 64);
    iend = iround(end / 360.0 * 64);

    int npoly = 0;

    if (istart > iend) {
        iend += 64;
    }
    istart++;
    iend--;

    if (!horizon) {
        pt[0].x = x;
        pt[0].y = y;
        npoly = 1;
    }
    pt[npoly].x = x + (long) (radius * fastsine(start));
    pt[npoly].y = y - (long) (radius * fastcosine(start));
    npoly++;

    for (i = 0; i < 64; i++) {
        if (i <= iend - istart) {
            pt[npoly].x = x + (long) (radius * xcoords[(i + istart) % 64]);
            pt[npoly].y = y - (long) (radius * ycoords[(i + istart) % 64]);
            npoly++;
        }
    }
    pt[npoly].x = x + (long) (radius * fastsine(end));
    pt[npoly].y = y - (long) (radius * fastcosine(end));
    npoly++;

    if (!horizon) {
        pt[npoly].x = x;
        pt[npoly].y = y;
        npoly++;
    } else {
        pt[npoly].x = pt[0].x;
        pt[npoly].y = pt[0].y;
        npoly++;
    }
    if (npoly > 2) {
        Polygon(pt, npoly, rc);
    } else if (npoly > 1) {
        Polyline(pt, npoly, rc);
    }
    return true;
}
Example #4
0
int MapWindow::DrawCompassArc(HDC hdc, long x, long y, int radius, RECT rc,
	    double bearing)

{
		const int indicatorStep = 10;

		// For Oren: remember to always DeleteObject you create with Create, or in 1 hour any
		// device will run out of GDI space, including your PC...
		// Meanwhile, I have created LKObjects, so anytime we should use them . No need to delete them.
		//HPEN hPenBlack = ::CreatePen(PS_SOLID, (5), RGB(0x00,0x0,0x0));  
		//HPEN hPenWhite = (HPEN)CreatePen(PS_SOLID, (2), RGB(0xff,0xff,0xff));
		HPEN hPenBlack = LKPen_Black_N5;
		HPEN hPenWhite = LKPen_White_N2;
		HFONT oldfont;
		HPEN oldpen;

		oldpen=(HPEN) SelectObject(hdc, hPenBlack);
		DrawArc(hdc, x, y,radius, rc, 300, 60);

		int heading = (int)(bearing +0.5);

		// -----------Draw the detents around the circle-----------------------------

		double angleDiff = heading % indicatorStep;

		int screenAngle = (int)(300 - angleDiff);
		int curHeading = (int)(heading - 60 - angleDiff);
		TCHAR textBuffer[32];

		POINT pt[2];
		int i;

		oldfont=(HFONT)SelectObject(hdc, LK8MediumFont); // always remember to save object or we miss font 

		for(i = - 60; i<= 60;
				i+=indicatorStep,screenAngle += indicatorStep,curHeading += indicatorStep)
		{

			if ( (screenAngle < 300) && (screenAngle > 60) )
 			{
				continue;
			}

			screenAngle  = (int)AngleLimit360(screenAngle);

			pt[0].x = x + (long) (radius * fastsine(screenAngle) );
			pt[0].y = y - (long) (radius * fastcosine(screenAngle) );

			// The length of the tickmarks on the compass rose
			double tickLength;

			// Make sure the display heading is between 0 and 360
			int displayHeading = (int)AngleLimit360(curHeading);

			// If the heading is a multiple of ten, it gets a long tick
			if(displayHeading%30==0)
			{
				tickLength = 15;

				if(displayHeading%30==0)
				{

					int drawHdg = displayHeading/10;
					switch ( drawHdg )
					{
					case 0:
						wsprintf( textBuffer, _T("N"));
						break;
					case 9:
						wsprintf( textBuffer, _T("E"));
						break;
					case 18:
						wsprintf( textBuffer, _T("S"));
						break;
					case 27:
						wsprintf( textBuffer, _T("W"));
						break;
					default:
						wsprintf( textBuffer, _T("%d"), displayHeading/10 );
					}

					SIZE textSize;
					GetTextExtentPoint(hdc, textBuffer, _tcslen(textBuffer), &textSize);

					int textX = x + (long) ((radius - (textSize.cy/2)-2) * fastsine(screenAngle) ) - textSize.cx/2;
					int textY = y - (long) ((radius - (textSize.cy/2)-2) * fastcosine(screenAngle) );
					drawOutlineText(hdc,textX,textY ,textBuffer,RGB_WHITE);
				}
			}
			else // Otherwise it gets a short tick
				tickLength = 10;

			pt[1].x = x + (long) ((radius -tickLength) * fastsine(screenAngle) );
			pt[1].y = y - (long) ((radius -tickLength) * fastcosine(screenAngle) );
			SelectObject(hdc, hPenBlack);
			::Polyline(hdc,pt,2);
			SelectObject(hdc, hPenWhite);
			::Polyline(hdc,pt,2);
		}

		SelectObject(hdc, hPenWhite);
		DrawArc(hdc, x, y,radius, rc, 300, 60);
		SelectObject(hdc, oldfont);
		SelectObject(hdc, oldpen);
		return 0;
}
Example #5
0
int RenderFAISector (HDC hdc, const RECT rc , double lat1, double lon1, double lat2, double lon2, int iOpposite , COLORREF fillcolor)
{
float fFAI_Percentage = FAI_NORMAL_PERCENTAGE;

#define N_PLOYGON (3*FAI_SECTOR_STEPS)
double fDist_a, fDist_b, fDist_c, fAngle;
int i;

int iPolyPtr=0;
double lat_d,lon_d;
double alpha, fDistTri, cos_alpha=0;
POINT apSectorPolygon[N_PLOYGON];
POINT Pt1;
DistanceBearing(lat1, lon1, lat2, lon2, &fDist_c, &fAngle);

if(fabs(fDist_c) < 1000.0)  /* distance too short for a FAI sector */
	return -1;

LKASSERT(fFAI_Percentage>0);
double fDistMax = fDist_c/fFAI_Percentage;
LKASSERT(fFAI_Percentage!=0.5);
double fDistMin = fDist_c/(1.0-2.0*fFAI_Percentage);
double fDelta_Dist = 2.0* fDist_c*fFAI_Percentage / (double)(FAI_SECTOR_STEPS);

double dir = -1.0;

  if(fDistMax < FAI_BIG_THRESHOLD)
  {
    fDistMax = fDist_c/FAI_NORMAL_PERCENTAGE;
    fDistMin = fDist_c/(1.0-2.0*FAI_NORMAL_PERCENTAGE);
  }

  if (iOpposite >0)
  {
	dir = 1.0;
  }


  /********************************************************************
   * calc right leg
   ********************************************************************/
  fDelta_Dist =(fDistMax-fDistMin)/ (double)(FAI_SECTOR_STEPS);
  fDistTri = fDistMin;
  if(fDistTri < FAI_BIG_THRESHOLD)
  	fFAI_Percentage = FAI_NORMAL_PERCENTAGE;
  else
	fFAI_Percentage = FAI_NORMAL_PERCENTAGE;
  fDist_a = fDistMin * fFAI_Percentage;
  fDist_b = fDistMin * fFAI_Percentage;
  for(i =0 ;i < FAI_SECTOR_STEPS; i++)
  {
  	LKASSERT(fDist_c*fDist_b!=0);
	cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	alpha = acos(cos_alpha)*180/PI * dir;
	FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);


	MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
    apSectorPolygon[iPolyPtr++] = Pt1;

    fDistTri += fDelta_Dist;
    if(fDistTri < FAI_BIG_THRESHOLD)
      fFAI_Percentage = FAI_NORMAL_PERCENTAGE;
    else
      fFAI_Percentage = FAI_NORMAL_PERCENTAGE;
    fDist_a = fFAI_Percentage * fDistTri;
	fDist_b = fDistTri - fDist_a - fDist_c;
  }

  /********************************************************************
   * calc top leg
   ********************************************************************/
  if(fDistMax < FAI_BIG_THRESHOLD)
    fFAI_Percentage = FAI_NORMAL_PERCENTAGE;
  else
    fFAI_Percentage = FAI_NORMAL_PERCENTAGE;

  fDelta_Dist =  (fDistMax*(1.0-3.0*fFAI_Percentage)) / (double)(FAI_SECTOR_STEPS);
  fDist_a = fDist_c;
  fDist_b = fDistMax - fDist_a - fDist_c;
  for(i =0 ;i < FAI_SECTOR_STEPS; i++)
  {
	LKASSERT(fDist_c*fDist_b!=0);
	cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	alpha = acos(cos_alpha)*180/PI * dir;
	FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);

	MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
    apSectorPolygon[iPolyPtr++] = Pt1;

	fDist_a += fDelta_Dist;
	fDist_b = fDistMax - fDist_a - fDist_c;
  }

  /********************************************************************
   * calc left leg
   ********************************************************************/
  fDelta_Dist =(fDistMax-fDistMin)/ (double)(FAI_SECTOR_STEPS);
  fDistTri = fDistMax;

  fDist_b = fDistMax * fFAI_Percentage;
  fDist_a = fDistTri - fDist_b - fDist_c;
  for(i =0 ;i < FAI_SECTOR_STEPS; i++)
  {
    LKASSERT(fDist_c*fDist_b!=0);
	cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	alpha = acos(cos_alpha)*180/PI * dir;
	FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);

	MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
    apSectorPolygon[iPolyPtr++] = Pt1;

    fDistTri -= fDelta_Dist;
    if(fDistTri < FAI_BIG_THRESHOLD)
      fFAI_Percentage = FAI_NORMAL_PERCENTAGE;
    else
      fFAI_Percentage = FAI_NORMAL_PERCENTAGE;

    fDist_b = fFAI_Percentage * fDistTri;
	fDist_a = fDistTri - fDist_b - fDist_c;
  }

  /********************************************************************
   * draw polygon
   ********************************************************************/
  HPEN   hpSectorPen  = (HPEN)CreatePen(PS_SOLID, IBLSCALE(2),  fillcolor );
  HBRUSH hpSectorFill = NULL;

  HPEN hpOldPen     = (HPEN)  SelectObject(hdc, hpSectorPen);
  HBRUSH hpOldBrush;
/*  if (fillcolor != 0)
  {
	hpSectorFill = (HBRUSH)CreateSolidBrush(fillcolor);
    hpOldBrush = (HBRUSH)SelectObject(hdc, hpSectorFill);
  }
  else */
    hpOldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(HOLLOW_BRUSH));


  /********************************************/
 // Polygon(hdc, apSectorPolygon,iPolyPtr);
  if (ForcedClipping || DeviceNeedClipping)
    ClipPolygon(hdc,apSectorPolygon,iPolyPtr,rc, true);
  else
    Polygon(hdc,apSectorPolygon,iPolyPtr);
  /********************************************/

  SelectObject(hdc, (HPEN)hpOldPen);
  SelectObject(hdc, (HBRUSH)hpOldBrush);
  DeleteObject(hpSectorPen);
  if(hpSectorFill != NULL)
    DeleteObject(hpSectorFill);



  /********************************************************************
   * calc round leg grid
   ********************************************************************/
  hpSectorPen  = (HPEN)CreatePen(PS_SOLID, (2), RGB_DARKGREY );
  SelectObject(hdc, hpSectorPen);

  double fTic= 1/DISTANCEMODIFY;
  if(fDist_c > 5/DISTANCEMODIFY)   fTic = 10/DISTANCEMODIFY;
  if(fDist_c > 50/DISTANCEMODIFY)  fTic = 25/DISTANCEMODIFY;
  if(fDist_c > 100/DISTANCEMODIFY) fTic = 50/DISTANCEMODIFY;
  if(fDist_c > 200/DISTANCEMODIFY) fTic = 100/DISTANCEMODIFY;
  if(fDist_c > 500/DISTANCEMODIFY) fTic = 250/DISTANCEMODIFY;
  POINT line[2];
  fDistTri = ((int)(fDistMin/fTic)+1) * fTic ;
  HFONT hfOld = (HFONT)SelectObject(hdc, LK8PanelUnitFont);
  int iCnt =0;
  SetTextColor(hdc, RGB_DARKGREY);
  while(fDistTri < fDistMax)
  {
    fDelta_Dist =  (fDistTri-fDistMin)*(1.0-2.0*fFAI_Percentage) / (double)(FAI_SECTOR_STEPS-1);
    fDist_a = fDistTri*fFAI_Percentage;
    fDist_b = fDistTri - fDist_a - fDist_c;
    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
      LKASSERT(fDist_c*fDist_b!=0);
      cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);

	  MapWindow::LatLon2Screen(lon_d, lat_d,  line[0]);

      if(i> 0)
      {
  		ForcedClipping=true;
  		MapWindow::_DrawLine(hdc, PS_DASH, NIBLSCALE(1), line[0] , line[1] , RGB_BLACK, rc);
  		ForcedClipping=false;
      }
	  //  Polyline(hdc, line, 2);

      line[1] =  line[0];
	  fDist_a += fDelta_Dist;
	  fDist_b = fDistTri - fDist_a - fDist_c;

      TCHAR text[180]; SIZE tsize;
      if(iCnt==0)
        _stprintf(text, TEXT("%i%s"), (int)(fDistTri*DISTANCEMODIFY), Units::GetUnitName(Units::GetUserDistanceUnit()));
      else
        _stprintf(text, TEXT("%i"), (int)(fDistTri*DISTANCEMODIFY));
      GetTextExtentPoint(hdc, text, _tcslen(text), &tsize);
      if(i == 0)
        ExtTextOut(hdc, line[0].x, line[0].y, ETO_OPAQUE, NULL, text, _tcslen(text), NULL);

      if(iCnt > 1)
  	    if(i == FAI_SECTOR_STEPS-1)
  	      ExtTextOut(hdc, line[0].x, line[0].y, ETO_OPAQUE, NULL, text, _tcslen(text), NULL);

      if(iCnt > 2)
  	    if((i== (FAI_SECTOR_STEPS/2)))
  	      ExtTextOut(hdc, line[0].x, line[0].y, ETO_OPAQUE, NULL, text, _tcslen(text), NULL);
    }
    iCnt++;
    fDistTri+=fTic;
  }

SelectObject(hdc, hfOld);
SelectObject(hdc, (HPEN)hpOldPen);
DeleteObject( hpSectorPen);
return 0;
}
Example #6
0
double Reciprocal(double InBound)
{
  return AngleLimit360(InBound+180);
}
Example #7
0
                                            #else
					      const double cruise_efficiency)
                                            #endif
{

  int i;
  double BestSpeed, BestGlide, Glide;
  double BestSinkRate, TimeToDestCruise;
  static double HeadWind, CrossWind=0.0;
  static double CrossBearingLast= -1.0;
  static double WindSpeedLast= -1.0;
  double CrossBearing;
  double BestTime;
  static double HeadWindSqd, CrossWindSqd=0.0;

  CrossBearing = AngleLimit360(Bearing - WindBearing);
  if ((CrossBearing != CrossBearingLast)||(WindSpeed != WindSpeedLast)) {
    // saves a few floating point operations
    HeadWind = WindSpeed * fastcosine(CrossBearing);
    CrossWind = WindSpeed * fastsine(CrossBearing);
    HeadWindSqd = HeadWind*HeadWind;
    CrossWindSqd = CrossWind*CrossWind;

    // save old values
    CrossBearingLast = CrossBearing;
    WindSpeedLast = WindSpeed;
  }

  double sinkrate;
  double tc; // time spent in cruise
Example #8
0
static BOOL FLYSEN(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS)
{

    TCHAR ctemp[80];
    double vtas;
    static int offset=-1;

    GPSCONNECT=true;

    // firmware 3.31h no offset
    // firmware 3.32  1 offset
    // Determine firmware version, assuming it will not change in the session!
    if (offset<0) {
        NMEAParser::ExtractParameter(String,ctemp,8);
        if ( (_tcscmp(ctemp,_T("A"))==0) || (_tcscmp(ctemp,_T("V"))==0))
            offset=0;
        else {
            NMEAParser::ExtractParameter(String,ctemp,9);
            if ( (_tcscmp(ctemp,_T("A"))==0) || (_tcscmp(ctemp,_T("V"))==0))
                offset=1;
            else
                return TRUE;
        }
    }

    // VOID GPS SIGNAL
    NMEAParser::ExtractParameter(String,ctemp,8+offset);
    if (_tcscmp(ctemp,_T("V"))==0) {
        pGPS->NAVWarning=true;
        // GPSCONNECT=false; // 121127 NO!!
        goto label_nogps;
    }
    // ------------------------

    double tmplat;
    double tmplon;

    NMEAParser::ExtractParameter(String,ctemp,1+offset);
    tmplat = MixedFormatToDegrees(StrToDouble(ctemp, NULL));
    NMEAParser::ExtractParameter(String,ctemp,2+offset);
    tmplat = NorthOrSouth(tmplat, ctemp[0]);

    NMEAParser::ExtractParameter(String,ctemp,3+offset);
    tmplon = MixedFormatToDegrees(StrToDouble(ctemp, NULL));
    NMEAParser::ExtractParameter(String,ctemp,4+offset);
    tmplon = EastOrWest(tmplon,ctemp[0]);

    if (!((tmplat == 0.0) && (tmplon == 0.0))) {
        pGPS->Latitude = tmplat;
        pGPS->Longitude = tmplon;
        pGPS->NAVWarning=false;
    }

    // GPS SPEED
    NMEAParser::ExtractParameter(String,ctemp,6+offset);
    pGPS->Speed = StrToDouble(ctemp,NULL)/10;

    // TRACK BEARING
    if (pGPS->Speed>1.0) {
        NMEAParser::ExtractParameter(String,ctemp,5+offset);
        pGPS->TrackBearing = AngleLimit360(StrToDouble(ctemp, NULL));
    }

    // HGPS
    NMEAParser::ExtractParameter(String,ctemp,7+offset);
    pGPS->Altitude = StrToDouble(ctemp,NULL);

    // ------------------------
label_nogps:

    // SATS
    NMEAParser::ExtractParameter(String,ctemp,9+offset);
    pGPS->SatellitesUsed = (int) StrToDouble(ctemp,NULL);

    // DATE
    // Firmware 3.32 has got the date
    if (offset>0) {
        NMEAParser::ExtractParameter(String,ctemp,0);
        long gy, gm, gd;
        TCHAR *Stop;
        gy = _tcstol(&ctemp[4], &Stop, 10) + 2000;
        ctemp[4] = '\0';
        gm = _tcstol(&ctemp[2], &Stop, 10);
        ctemp[2] = '\0';
        gd = _tcstol(&ctemp[0], &Stop, 10);

        if ( ((gy > 1980) && (gy <2100) ) && (gm != 0) && (gd != 0) ) {
            pGPS->Year = gy;
            pGPS->Month = gm;
            pGPS->Day = gd;
        }
    }

    // TIME
    // ignoring 00:00.00
    // We need to manage UTC time
#ifndef OLD_TIME_MODIFY
    static int StartDay=-1;
    if (pGPS->SatellitesUsed>0) {
        NMEAParser::ExtractParameter(String,ctemp,0+offset);
        pGPS->Time = TimeModify(ctemp, pGPS, StartDay);
    }
    // TODO : check if TimeHasAdvanced check is needed (cf. Parser.cpp)
#else
    NMEAParser::ExtractParameter(String,ctemp,0+offset);
    double fixTime = StrToDouble(ctemp,NULL);

    static  int day_difference=0, previous_months_day_difference=0;
    static int startday=-1;

    if (fixTime>0 && pGPS->SatellitesUsed>0) {
        double hours, mins,secs;
        hours = fixTime / 10000;
        pGPS->Hour = (int)hours;
        mins = fixTime / 100;
        mins = mins - (pGPS->Hour*100);
        pGPS->Minute = (int)mins;
        secs = fixTime - (pGPS->Hour*10000) - (pGPS->Minute*100);
        pGPS->Second = (int)secs;

        fixTime = secs + (pGPS->Minute*60) + (pGPS->Hour*3600);

        if ((startday== -1) && (pGPS->Day != 0)) {
            if (offset)
                StartupStore(_T(". FLYSEN First GPS DATE: %d-%d-%d%s"), pGPS->Year, pGPS->Month, pGPS->Day,NEWLINE);
            else
                StartupStore(_T(". FLYSEN No Date, using PNA GPS DATE: %d-%d-%d%s"), pGPS->Year, pGPS->Month, pGPS->Day,NEWLINE);
            startday = pGPS->Day;
            day_difference=0;
            previous_months_day_difference=0;
        }
        if (startday != -1) {
            if (pGPS->Day < startday) {
                // detect change of month (e.g. day=1, startday=26)
                previous_months_day_difference=day_difference+1;
                day_difference=0;
                startday = pGPS->Day;
                StartupStore(_T(". FLYSEN Change GPS DATE to NEW MONTH: %d-%d-%d  (%d days running)%s"),
                             pGPS->Year, pGPS->Month, pGPS->Day,previous_months_day_difference,NEWLINE);
            }
            if ( (pGPS->Day-startday)!=day_difference) {
                StartupStore(_T(". FLYSEN Change GPS DATE: %d-%d-%d%s"), pGPS->Year, pGPS->Month, pGPS->Day,NEWLINE);
            }

            day_difference = pGPS->Day-startday;
            if ((day_difference+previous_months_day_difference)>0) {
                fixTime += (day_difference+previous_months_day_difference) * 86400;
            }
        }
        pGPS->Time = fixTime;
    }
#endif

    // HPA from the pressure sensor
    //   NMEAParser::ExtractParameter(String,ctemp,10+offset);
    //   double ps = StrToDouble(ctemp,NULL)/100;
    //   pGPS->BaroAltitude = (1 - pow(fabs(ps / QNH),  0.190284)) * 44307.69;

    // HBAR 1013.25
    NMEAParser::ExtractParameter(String,ctemp,11+offset);
    double palt=StrToDouble(ctemp,NULL);
    UpdateBaroSource( pGPS, 0,d, AltitudeToQNHAltitude(palt));

    // VARIO
    NMEAParser::ExtractParameter(String,ctemp,12+offset);
    pGPS->Vario = StrToDouble(ctemp,NULL)/100;

    // TAS
    NMEAParser::ExtractParameter(String,ctemp,13+offset);
    vtas=StrToDouble(ctemp,NULL)/10;
    pGPS->IndicatedAirspeed = vtas/AirDensityRatio(palt);
    pGPS->TrueAirspeed = vtas;
    if (pGPS->IndicatedAirspeed >0)
        pGPS->AirspeedAvailable = TRUE;
    else
        pGPS->AirspeedAvailable = FALSE;

    // ignore n.14 airspeed source

    // OAT
    NMEAParser::ExtractParameter(String,ctemp,15+offset);
    pGPS->OutsideAirTemperature = StrToDouble(ctemp,NULL);
    pGPS->TemperatureAvailable=TRUE;

    // ignore n.16 baloon temperature

    // BATTERY PERCENTAGES
    NMEAParser::ExtractParameter(String,ctemp,17+offset);
    pGPS->ExtBatt1_Voltage = StrToDouble(ctemp,NULL)+1000;
    NMEAParser::ExtractParameter(String,ctemp,18+offset);
    pGPS->ExtBatt2_Voltage = StrToDouble(ctemp,NULL)+1000;



    pGPS->VarioAvailable = TRUE;

    // currently unused in LK, but ready for next future
    TriggerVarioUpdate();
    TriggerGPSUpdate();

    return TRUE;
}
void CalculateAATTaskSectors()
{
  int i;
  int awp = ActiveTaskPoint;

  if(AATEnabled == FALSE || DoOptimizeRoute())
    return;

  double latitude = GPS_INFO.Latitude;
  double longitude = GPS_INFO.Longitude;
  double altitude = GPS_INFO.Altitude;

  LockTaskData();

  Task[0].AATTargetOffsetRadius = 0.0;
  Task[0].AATTargetOffsetRadial = 0.0;
  if (Task[0].Index>=0) {
    Task[0].AATTargetLat = WayPointList[Task[0].Index].Latitude;
    Task[0].AATTargetLon = WayPointList[Task[0].Index].Longitude;
  }

  for(i=1;i<MAXTASKPOINTS;i++) {
    if(ValidTaskPoint(i)) {
      if (!ValidTaskPoint(i+1)) {
        // This must be the final waypoint, so it's not an AAT OZ
        Task[i].AATTargetLat = WayPointList[Task[i].Index].Latitude;
        Task[i].AATTargetLon = WayPointList[Task[i].Index].Longitude;
        continue;
      }

      if(Task[i].AATType == SECTOR) {
        FindLatitudeLongitude (WayPointList[Task[i].Index].Latitude,
                                 WayPointList[Task[i].Index].Longitude, 
                               Task[i].AATStartRadial , 
                               Task[i].AATSectorRadius ,
                               &Task[i].AATStartLat,
                               &Task[i].AATStartLon);
        
        FindLatitudeLongitude (WayPointList[Task[i].Index].Latitude,
                               WayPointList[Task[i].Index].Longitude,
                               Task[i].AATFinishRadial , 
                               Task[i].AATSectorRadius,
                               &Task[i].AATFinishLat,
                               &Task[i].AATFinishLon);
      }

      // JMWAAT: if locked, don't move it
      if (i<awp) {
        // only update targets for current/later waypoints 
        continue;
      }

      Task[i].AATTargetOffsetRadius = 
        min(1.0, max(Task[i].AATTargetOffsetRadius,-1.0));

      Task[i].AATTargetOffsetRadial = 
        min(90.0, max(-90.0, Task[i].AATTargetOffsetRadial));

      double targetbearing;
      double targetrange;
      
      targetbearing = AngleLimit360(Task[i].Bisector+Task[i].AATTargetOffsetRadial);
      
      if(Task[i].AATType == SECTOR) {

        //AATStartRadial
        //AATFinishRadial

        targetrange = ((Task[i].AATTargetOffsetRadius+1.0)/2.0);

        double aatbisector = HalfAngle(Task[i].AATStartRadial, 
                                       Task[i].AATFinishRadial);

        if (fabs(AngleLimit180(aatbisector-targetbearing))>90) {
          // bisector is going away from sector 
          targetbearing = Reciprocal(targetbearing);
          targetrange = 1.0-targetrange;
        }
        if (!AngleInRange(Task[i].AATStartRadial,
                          Task[i].AATFinishRadial,
                          targetbearing,true)) {

          // Bisector is not within AAT sector, so
          // choose the closest radial as the target line

          if (fabs(AngleLimit180(Task[i].AATStartRadial-targetbearing))
              <fabs(AngleLimit180(Task[i].AATFinishRadial-targetbearing))) {
            targetbearing = Task[i].AATStartRadial;
          } else {
            targetbearing = Task[i].AATFinishRadial;
          }
        }

        targetrange*= Task[i].AATSectorRadius;

      } else {
        targetrange = Task[i].AATTargetOffsetRadius
          *Task[i].AATCircleRadius;
      }
      
      // TODO accuracy: if i=awp and in sector, range parameter needs to
      // go from current aircraft position to projection of target
      // out to the edge of the sector
      
      if (InAATTurnSector(longitude, latitude, i, altitude) && (awp==i) &&
          !Task[i].AATTargetLocked) {

        // special case, currently in AAT sector/cylinder
        
        double dist;
        double qdist;
        double bearing;
        
        // find bearing from last target through current aircraft position with offset
        DistanceBearing(Task[i-1].AATTargetLat,
                        Task[i-1].AATTargetLon,
                        latitude,
                        longitude,
                        &qdist, &bearing);

        bearing = AngleLimit360(bearing+Task[i].AATTargetOffsetRadial);

        dist = ((Task[i].AATTargetOffsetRadius+1)/2.0)*
          FindInsideAATSectorDistance(latitude, longitude, i, bearing);
        
        // if (dist+qdist>aatdistance.LegDistanceAchieved(awp)) {
        // JMW: don't prevent target from being closer to the aircraft
        // than the best achieved, so can properly plan arrival time        

        FindLatitudeLongitude (latitude,
                               longitude, 
                               bearing, 
                               dist,
                               &Task[i].AATTargetLat,
                               &Task[i].AATTargetLon);

        UpdateTargetAltitude(Task[i]);

        TargetModified = true;

        // }
        
      } else {
        
        FindLatitudeLongitude (WayPointList[Task[i].Index].Latitude,
                               WayPointList[Task[i].Index].Longitude, 
                               targetbearing, 
                               targetrange,
                               &Task[i].AATTargetLat,
                               &Task[i].AATTargetLon);
        
        UpdateTargetAltitude(Task[i]);
        TargetModified = true;
        
      }
    }
  }

  CalculateAATIsoLines();
  if (!TargetDialogOpen) {
    TargetModified = false;
    // allow target dialog to detect externally changed targets
  }

  UnlockTaskData();
}
Example #10
0
BOOL NMEAParser::ParseGPS_POSITION_internal(const GPS_POSITION& loc, NMEA_INFO& GPSData) {

    gpsValid = !(loc.dwFlags & GPS_DATA_FLAGS_HARDWARE_OFF);
    if (!gpsValid) {
        return TRUE;
    }
    GPSCONNECT=TRUE;

    switch (loc.FixType) {
        case GPS_FIX_UNKNOWN:
            gpsValid = false;
            break;
        case GPS_FIX_2D:
        case GPS_FIX_3D:
            gpsValid = true;
            break;
        default:
            break;
    }

    if (loc.dwValidFields & GPS_VALID_SATELLITE_COUNT) {
        nSatellites = loc.dwSatelliteCount;
    }

    if(!activeGPS) {
        return TRUE;
    }

    GPSData.SatellitesUsed = nSatellites;
    GPSData.NAVWarning = !gpsValid;
    
    if (loc.dwValidFields & GPS_VALID_UTC_TIME) {
        GPSData.Hour = loc.stUTCTime.wHour;
        GPSData.Minute = loc.stUTCTime.wMinute;
        GPSData.Second = loc.stUTCTime.wSecond;
        GPSData.Month = loc.stUTCTime.wMonth;
        GPSData.Day = loc.stUTCTime.wDay;
        GPSData.Year = loc.stUTCTime.wYear;
        if(!TimeHasAdvanced(TimeModify(&GPSData, StartDay), &GPSData)) {
            return FALSE;
        }
    }
    if (loc.dwValidFields & GPS_VALID_LATITUDE) {
        GPSData.Latitude = loc.dblLatitude;
    }
    if (loc.dwValidFields & GPS_VALID_LONGITUDE) {
        GPSData.Longitude = loc.dblLongitude;
    }
    if (loc.dwValidFields & GPS_VALID_SPEED) {
        GPSData.Speed = KNOTSTOMETRESSECONDS * loc.flSpeed;
    }
    if (loc.dwValidFields & GPS_VALID_HEADING) {
      	if (GPSData.Speed>trackbearingminspeed) {
            GPSData.TrackBearing = AngleLimit360(loc.flHeading);
        }
    }
    if (loc.dwValidFields & GPS_VALID_MAGNETIC_VARIATION) {

    }
    
    if (loc.dwValidFields & GPS_VALID_ALTITUDE_WRT_SEA_LEVEL) {
        GPSData.Altitude = loc.flAltitudeWRTSeaLevel;
        GPSData.Altitude += (GPSAltitudeOffset/1000); // BUGFIX 100429
    }
    
#if 0    
    if (loc.dwValidFields & GPS_VALID_ALTITUDE_WRT_ELLIPSOID) {
 
        /* MSDN says..
         * "flAltitudeWRTEllipsoid : Altitude, in meters, with respect to the WGS84 ellipsoid. "
         * "flAltitudeWRTSeaLevel : Altitude, in meters, with respect to sea level. "
         * 
         * But when I get this structure, flAltitudeWRTSeaLevel field has proper value. But,
         * flAltitudeWRTEllipsoid field has different meaning value.
         * 
         * But flAltitudeWRTEllipsoid field contains just geodial separation.
         */
    } 
#endif
    
    if (loc.dwValidFields & GPS_VALID_POSITION_DILUTION_OF_PRECISION) {

    }
    if (loc.dwValidFields & GPS_VALID_HORIZONTAL_DILUTION_OF_PRECISION) {

    }
    if (loc.dwValidFields & GPS_VALID_VERTICAL_DILUTION_OF_PRECISION) {

    }
    if (loc.dwValidFields & GPS_VALID_SATELLITES_USED_PRNS) {

    }
    if (loc.dwValidFields & GPS_VALID_SATELLITES_IN_VIEW) {
 
    }
    if (loc.dwValidFields & GPS_VALID_SATELLITES_IN_VIEW_PRNS) {

    }
    if (loc.dwValidFields & GPS_VALID_SATELLITES_IN_VIEW_ELEVATION) {

    }
    if (loc.dwValidFields & GPS_VALID_SATELLITES_IN_VIEW_AZIMUTH) {

    }
    if (loc.dwValidFields & GPS_VALID_SATELLITES_IN_VIEW_SIGNAL_TO_NOISE_RATIO) {

    }
    if(gpsValid && !GPSData.NAVWarning && GPSData.SatellitesUsed == 0) {
        GPSData.SatellitesUsed = -1;
    }
    
    TriggerGPSUpdate();
    
    return TRUE;
}
Example #11
0
BOOL NMEAParser::RMC(TCHAR *String, TCHAR **params, size_t nparams, NMEA_INFO *pGPS)
{
  TCHAR *Stop;
  static bool logbaddate=true;
  double speed=0;

  gpsValid = !NAVWarn(params[1][0]);

  GPSCONNECT = TRUE;    
  RMCAvailable=true; // 100409

  #ifdef PNA
  if (DeviceIsGM130) {

	double ps = GM130BarPressure();
	RMZAltitude = (1 - pow(fabs(ps / QNH),  0.190284)) * 44307.69;
	// StartupStore(_T("....... Pressure=%.0f QNH=%.2f Altitude=%.1f\n"),ps,QNH,RMZAltitude);

	RMZAvailable = TRUE;

	UpdateBaroSource(pGPS, BARO__GM130, NULL,   RMZAltitude);
  }
  if (DeviceIsRoyaltek3200) {
	if (Royaltek3200_ReadBarData()) {
		double ps = Royaltek3200_GetPressure();
		RMZAltitude = (1 - pow(fabs(ps / QNH),  0.190284)) * 44307.69;

		#if 0
		pGPS->TemperatureAvailable=true;
		pGPS->OutsideAirTemperature = Royaltek3200_GetTemperature();
		#endif
	}

	RMZAvailable = TRUE;

	UpdateBaroSource(pGPS, BARO__ROYALTEK3200,  NULL,  RMZAltitude);

  }
  #endif // PNA

  if (!activeGPS) {
	// Before ignoring anything else, commit RMZ altitude otherwise it will be ignored!
	if(RMZAvailable) {
		UpdateBaroSource(pGPS, isFlarm? BARO__RMZ_FLARM:BARO__RMZ, NULL, RMZAltitude);
	}
	return TRUE;
  }

  // if no valid fix, we dont get speed either!
  if (gpsValid)
  {
	// speed is in knots, 2 = 3.7kmh
	speed = StrToDouble(params[6], NULL);
  }
  
  pGPS->NAVWarning = !gpsValid;

  // say we are updated every time we get this,
  // so infoboxes get refreshed if GPS connected
  // the RMC sentence marks the start of a new fix, so we force the old data to be saved for calculations
        // note that Condor sends no date..
        if ((_tcslen(params[8]) <6) && !DevIsCondor) {
		#if TESTBENCH
		StartupStore(_T(".... RMC date field empty, skip sentence!\n"));
		#endif
		return TRUE;
	}

	// Even with no valid position, we let RMC set the time and date if valid
	long gy, gm, gd;
	gy = _tcstol(&params[8][4], &Stop, 10) + 2000;   
	params[8][4] = '\0';
	gm = _tcstol(&params[8][2], &Stop, 10); 
	params[8][2] = '\0';
	gd = _tcstol(&params[8][0], &Stop, 10); 

	// SeeYou PC is sending NMEA sentences with RMC date 2072-02-27
	if ( ((gy > 1980) && (gy <2100) ) && (gm != 0) && (gd != 0) ) { 
		pGPS->Year = gy;
		pGPS->Month = gm;
		pGPS->Day = gd;

force_advance:
		RMCtime = StrToDouble(params[0],NULL);
#ifndef OLD_TIME_MODIFY
		double ThisTime = TimeModify(params[0], pGPS, StartDay);
#else
		double ThisTime = TimeModify(RMCtime, pGPS);
#endif
		// RMC time has priority on GGA and GLL etc. so if we have it we use it at once
		if (!TimeHasAdvanced(ThisTime, pGPS)) {
			#if DEBUGSEQ
			StartupStore(_T("..... RMC time not advanced, skipping \n")); // 31C
			#endif
			return FALSE;
		}
			
	}  else {
		if (DevIsCondor) {
			#if DEBUGSEQ
			StartupStore(_T(".. Condor not sending valid date, using 1.1.2012%s"),NEWLINE);
			#endif
			gy=2012; gm=1; gd=1;
			goto force_advance;
		}

		if (gpsValid && logbaddate) { // 091115
			StartupStore(_T("------ NMEAParser:RMC Receiving an invalid or null DATE from GPS%s"),NEWLINE);
			StartupStore(_T("------ NMEAParser: Date received is y=%ld m=%ld d=%ld%s"),gy,gm,gd,NEWLINE); // 100422
			StartupStore(_T("------ This message will NOT be repeated. %s%s"),WhatTimeIsIt(),NEWLINE);
			DoStatusMessage(MsgToken(875));
			logbaddate=false;
		}
		gy=2012; gm=2; gd=30;	// an impossible date!
		goto force_advance;
		 
	}

  if (gpsValid) { 
	double tmplat;
	double tmplon;

	tmplat = MixedFormatToDegrees(StrToDouble(params[2], NULL));
	tmplat = NorthOrSouth(tmplat, params[3][0]);
	  
	tmplon = MixedFormatToDegrees(StrToDouble(params[4], NULL));
	tmplon = EastOrWest(tmplon,params[5][0]);
  
	if (!((tmplat == 0.0) && (tmplon == 0.0))) {
		pGPS->Latitude = tmplat;
		pGPS->Longitude = tmplon;
	}
  
	pGPS->Speed = KNOTSTOMETRESSECONDS * speed;
  
	if (pGPS->Speed>trackbearingminspeed) {
		pGPS->TrackBearing = AngleLimit360(StrToDouble(params[7], NULL));
	}
  } // gpsvalid 091108

#ifdef WIN32
  // As soon as we get a fix for the first time, set the
  // system clock to the GPS time.
  static bool sysTimeInitialised = false;
  
  if (!pGPS->NAVWarning && (gpsValid)) {
	if (SetSystemTimeFromGPS) {
		if (!sysTimeInitialised) {
			if ( ( pGPS->Year > 1980 && pGPS->Year<2100) && ( pGPS->Month > 0) && ( pGPS->Hour > 0)) {
        
				sysTimeInitialised =true; // Attempting only once
				SYSTEMTIME sysTime;
				// ::GetSystemTime(&sysTime);
				int hours = (int)pGPS->Hour;
				int mins = (int)pGPS->Minute;
				int secs = (int)pGPS->Second;
				sysTime.wYear = (unsigned short)pGPS->Year;
				sysTime.wMonth = (unsigned short)pGPS->Month;
				sysTime.wDay = (unsigned short)pGPS->Day;
				sysTime.wHour = (unsigned short)hours;
				sysTime.wMinute = (unsigned short)mins;
				sysTime.wSecond = (unsigned short)secs;
				sysTime.wMilliseconds = 0;
				::SetSystemTime(&sysTime);
			}
		}
	}
  }
#else
#warning "Set system clock to the GPS time not implemented."
#endif

  if(RMZAvailable) {
	UpdateBaroSource(pGPS, BARO__RMZ, NULL,  RMZAltitude);
  }
  if (!GGAAvailable) {
	// update SatInUse, some GPS receiver dont emmit GGA sentance
	if (!gpsValid) { 
		pGPS->SatellitesUsed = 0;
	} else {
		pGPS->SatellitesUsed = -1;
	}
  }
  
  if ( !GGAAvailable || (GGAtime == RMCtime)  )  {
	#if DEBUGSEQ
	StartupStore(_T("... RMC trigger gps, GGAtime==RMCtime\n")); // 31C
	#endif
	TriggerGPSUpdate(); 
  }

  return TRUE;

} // END RMC
Example #12
0
// draw aircraft
void RenderPlaneSideview(HDC hdc, double fDist, double fAltitude,double brg, DiagrammStruct* psDia )
{
//BOOL bInvCol = true ; //INVERTCOLORS
  #define NO_AP_PTS 17
  int deg = DEG_TO_INT(AngleLimit360(brg));
  double fCos = COSTABLE[deg];
  double fSin = SINETABLE[deg];

  int TAIL   = 6;
  int PROFIL = 1;
  int FINB   = 3;
  int BODY   = 2;
  int NOSE   = 7;
  int WING   = (int) (22.0 );
  int TUBE   = (int) (14.0  ) ;
  int FINH   = 6+BODY;

  POINT Start;
  int HEAD = TUBE / 2;
  TUBE =  3 * TUBE/ 2;
  POINT AircraftSide
  [8] = {
      {(int)(fSin * (HEAD+0   )    ), -BODY-1},  // 1
      {(int)(fSin * (HEAD+NOSE)    ),  0},       // 2
      {(int)(fSin * (HEAD+0   )    ),  BODY+1},  // 3
      {(int)(fSin * (-TUBE)        ),  BODY},    // 4   -1
      {(int)(fSin * -TUBE          ), -FINH},    // 5
      {(int)(fSin * (-TUBE+FINB)   ), -FINH},    // 6
      {(int)(fSin * (-TUBE+FINB+3) ), -BODY+1},  // 7  +1
      {(int)(fSin * (HEAD+0)       ), -BODY-1}     // 8
  };

  #define  FACT 2

  BODY = (int)((double)(BODY+1) * fCos * fCos);

  int DIA = (BODY + PROFIL);

  /* both wings */
  POINT AircraftWing
  [13] = {
      {(int)(fCos * BODY              ) ,  -DIA},    // 1
      {(int)(fCos * (int)( FACT*BODY) ), -PROFIL},    // 2
      {(int)(fCos * WING              ) ,  -PROFIL},    // 3
      {(int)(fCos * WING              ), 0* PROFIL},    // 4
      {(int)(fCos * (int)( FACT*BODY) ) , PROFIL},    // 5
      {(int)(fCos *  BODY             ), DIA},    // 6
      {(int)(fCos * -BODY             ) , DIA},    // 7
      {(int)(fCos * (int)( -FACT*BODY)), PROFIL},    // 8
      {(int)(fCos * -WING             ), 0* PROFIL  },    // 9
      {(int)(fCos * -WING             ) , -PROFIL}  ,    // 10
      {(int)(fCos * (int)( -FACT*BODY)), -PROFIL},    // 11
      {(int)(fCos * -BODY             ) , -DIA},    // 12
      {(int)(fCos *  BODY             ), -DIA}    // 13
  };


  POINT AircraftWingL
  [7] = {

      {(int)(0 * -BODY                ),  DIA       },    // 1
      {(int)(fCos * (int)( -FACT*BODY)),  PROFIL    },    // 2
      {(int)(fCos * -WING             ),  0* PROFIL },    // 3
      {(int)(fCos * -WING             ), -PROFIL    },    // 4
      {(int)(fCos * (int)( -FACT*BODY)), -PROFIL    },    // 5
      {(int)(0 * -BODY                ), -DIA       },    // 6
      {(int)(0 * -BODY                ),  DIA       }     // 7
  };


  POINT AircraftWingR
  [7] = {
      {(int)(0 * BODY                 ) ,  -DIA    },   // 1
      {(int)(fCos * (int)( FACT*BODY) ) , -PROFIL  },   // 2
      {(int)(fCos * WING              ) ,  -PROFIL },   // 3
      {(int)(fCos * WING              ) , 0* PROFIL},   // 4
      {(int)(fCos * (int)( FACT*BODY) ) , PROFIL   },   // 5
      {(int)(0 *  BODY                ) , DIA      },   // 6
      {(int)(0 *  BODY                ) , -DIA     }    // 7
  };



  POINT AircraftTail
  [5] = {
      {(int)(fCos *  TAIL - fSin*TUBE), -FINH},            // 1
      {(int)(fCos *  TAIL - fSin*TUBE), -FINH +PROFIL},    // 2
      {(int)(fCos * -TAIL - fSin*TUBE), -FINH +PROFIL},    // 3
      {(int)(fCos * -TAIL - fSin*TUBE), -FINH },           // 4
      {(int)(fCos *  TAIL - fSin*TUBE), -FINH},            // 5

  };

  Start.x = CalcDistanceCoordinat(fDist,  psDia);
  Start.y = CalcHeightCoordinat(fAltitude, psDia);
  HBRUSH oldBrush;
  HPEN   oldPen;
/*
  if(bInvCol)
  {
    oldPen   = (HPEN)SelectObject(hdc, GetStockObject(WHITE_PEN));
    oldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(BLACK_BRUSH));
  }
  else
*/
  {
    oldPen   = (HPEN) SelectObject(hdc, GetStockObject(BLACK_PEN));
    oldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(WHITE_BRUSH));
  }

  //SelectObject(hdc, GetStockObject(BLACK_PEN));
  PolygonRotateShift(AircraftWing, 13,  Start.x, Start.y,  0);
  PolygonRotateShift(AircraftSide, 8,   Start.x, Start.y,  0);
  PolygonRotateShift(AircraftTail, 5,   Start.x, Start.y,  0);
  PolygonRotateShift(AircraftWingL, 7,   Start.x, Start.y,  0);
  PolygonRotateShift(AircraftWingR, 7,   Start.x, Start.y,  0);

  HBRUSH GreenBrush = CreateSolidBrush(COLORREF RGB_GREEN);
  HBRUSH RedBrush = CreateSolidBrush(COLORREF RGB_RED);
  if((brg < 180))
  {
    SelectObject(hdc, RedBrush);
    Polygon(hdc,AircraftWingL ,7 );

    SelectObject(hdc, GetStockObject(WHITE_BRUSH));
    Polygon(hdc,AircraftSide  ,8 );

    SelectObject(hdc, GreenBrush);
    Polygon(hdc,AircraftWingR ,7 );

    SelectObject(hdc, oldBrush);
  }
  else
  {
    SelectObject(hdc, GreenBrush);
    Polygon(hdc,AircraftWingR ,7 );

    SelectObject(hdc, GetStockObject(WHITE_BRUSH));
    Polygon(hdc,AircraftSide  ,8 );

    SelectObject(hdc, RedBrush);
    Polygon(hdc,AircraftWingL ,7 );

    SelectObject(hdc, oldBrush);
   //Polygon(hdc,AircraftWing  ,13);
  }
  if((brg < 90)|| (brg > 270)) {
    Polygon(hdc,AircraftTail  ,5 );
  }

  SelectObject(hdc, oldPen);
  SelectObject(hdc, oldBrush);
  DeleteObject(RedBrush);
  DeleteObject(GreenBrush);

} //else !asp_heading_task
Example #13
0
BOOL NMEAParser::RMC(TCHAR *String, TCHAR **params, size_t nparams, NMEA_INFO *GPS_INFO)
{
  TCHAR *Stop;
  static bool logbaddate=true;
  double speed=0;

  gpsValid = !NAVWarn(params[1][0]);

  GPSCONNECT = TRUE;    
  RMCAvailable=true; // 100409

  if (!activeGPS) return TRUE; // 091205 BUGFIX true

  // if no valid fix, we dont get speed either!
  if (gpsValid)
  {
	speed = StrToDouble(params[6], NULL);
	// speed is in knots, 2 = 3.7kmh
	if (speed>2.0) {
		GPS_INFO->MovementDetected = TRUE;
		if (ReplayLogger::IsEnabled()) {
			// stop logger replay if aircraft is actually moving.
			ReplayLogger::Stop();
		}
	} else {
		GPS_INFO->MovementDetected = FALSE;
		if (ReplayLogger::IsEnabled()) {
			// block actual GPS signal if not moving and a log is being replayed
			return TRUE;
		}
	}
  }
  
  GPS_INFO->NAVWarning = !gpsValid;

  // say we are updated every time we get this,
  // so infoboxes get refreshed if GPS connected
  // the RMC sentence marks the start of a new fix, so we force the old data to be saved for calculations
#ifndef NEWTRIGGERGPS
  if (!GGAAvailable) { 
	TriggerGPSUpdate();
  }
#endif

	// Even with no valid position, we let RMC set the time and date if valid
	long gy, gm, gd;
	gy = _tcstol(&params[8][4], &Stop, 10) + 2000;   
	params[8][4] = '\0';
	gm = _tcstol(&params[8][2], &Stop, 10); 
	params[8][2] = '\0';
	gd = _tcstol(&params[8][0], &Stop, 10); 

	// SeeYou PC is sending NMEA sentences with RMC date 2072-02-27
	if ( ((gy > 1980) && (gy <2100) ) && (gm != 0) && (gd != 0) ) { 
		GPS_INFO->Year = gy;
		GPS_INFO->Month = gm;
		GPS_INFO->Day = gd;
#ifdef NEWTRIGGERGPS
		double ThisTime = TimeConvert(StrToDouble(params[0],NULL), GPS_INFO); // 091208
#else
		double ThisTime = TimeModify(StrToDouble(params[0],NULL), GPS_INFO);
#endif

#ifndef NEWTRIGGERGPS
		if (!TimeHasAdvanced(ThisTime, GPS_INFO))
			return FALSE;
#endif
#ifdef NEWTRIGGERGPS
		// is time advanced to a new quantum?
		if (ThisTime >NmeaTime) {
			// yes so lets trigger the gps event
			TriggerGPSUpdate();
			// and only then advance the time in the GPSINFO
			Sleep(50); // 091208
			NmeaTime=ThisTime;
			TimeSet(GPS_INFO); // 091208
			TimeHasAdvanced(ThisTime, GPS_INFO); // 091208
			StartupStore(_T(".............. trigger from RMC\n"));
		}
#endif
			
	}  else {
		if (gpsValid && logbaddate) { // 091115
			StartupStore(_T("------ NMEAParser:RMC Receiving an invalid or null DATE from GPS%s"),NEWLINE);
			StartupStore(_T("------ NMEAParser: Date received is y=%d m=%d d=%d%s"),gy,gm,gd,NEWLINE); // 100422
			StartupStore(_T("------ This message will NOT be repeated.%s"),NEWLINE);
			// DoStatusMessage(_T("WARNING: GPS IS SENDING INVALID DATE, AND PROBABLY WRONG TIME")); // REMOVE FIXV2
			// LKTOKEN 875  WARNING: GPS IS SENDING INVALID DATE, AND PROBABLY WRONG TIME")); 
			DoStatusMessage(gettext(TEXT("_@M875_")));
			logbaddate=false;
		}
	}
//  } // 091108

  if (gpsValid) {   // 091108 BUGFIX set latlon and speed ONLY if valid gpsdata, missing check!
	double tmplat;
	double tmplon;

	tmplat = MixedFormatToDegrees(StrToDouble(params[2], NULL));
	tmplat = NorthOrSouth(tmplat, params[3][0]);
	  
	tmplon = MixedFormatToDegrees(StrToDouble(params[4], NULL));
	tmplon = EastOrWest(tmplon,params[5][0]);
  
	if (!((tmplat == 0.0) && (tmplon == 0.0))) {
		GPS_INFO->Latitude = tmplat;
		GPS_INFO->Longitude = tmplon;
	}
  
	GPS_INFO->Speed = KNOTSTOMETRESSECONDS * speed;
  
	if (GPS_INFO->Speed>1.0) {
		// JMW don't update bearing unless we're moving
		GPS_INFO->TrackBearing = AngleLimit360(StrToDouble(params[7], NULL));
	}
  } // gpsvalid 091108
    
  // Altair doesn't have a battery-backed up realtime clock,
  // so as soon as we get a fix for the first time, set the
  // system clock to the GPS time.
  static bool sysTimeInitialised = false;
  
  if (!GPS_INFO->NAVWarning && (gpsValid)) {
	if (SetSystemTimeFromGPS) {
		if (!sysTimeInitialised) {
			if ( ( GPS_INFO->Year > 1980 && GPS_INFO->Year<2100) && ( GPS_INFO->Month > 0) && ( GPS_INFO->Hour > 0)) {
        
				sysTimeInitialised =true; // Attempting only once
				SYSTEMTIME sysTime;
				// ::GetSystemTime(&sysTime);
				int hours = (int)GPS_INFO->Hour;
				int mins = (int)GPS_INFO->Minute;
				int secs = (int)GPS_INFO->Second;
				sysTime.wYear = (unsigned short)GPS_INFO->Year;
				sysTime.wMonth = (unsigned short)GPS_INFO->Month;
				sysTime.wDay = (unsigned short)GPS_INFO->Day;
				sysTime.wHour = (unsigned short)hours;
				sysTime.wMinute = (unsigned short)mins;
				sysTime.wSecond = (unsigned short)secs;
				sysTime.wMilliseconds = 0;
				::SetSystemTime(&sysTime);
			}
		}
	}
  }

  if (!ReplayLogger::IsEnabled()) {      
	if(RMZAvailable) {
		// JMW changed from Altitude to BaroAltitude
		GPS_INFO->BaroAltitudeAvailable = true;
		GPS_INFO->BaroAltitude = RMZAltitude;
	}
	else if(RMAAvailable) {
	// JMW changed from Altitude to BaroAltitude
		GPS_INFO->BaroAltitudeAvailable = true;
		GPS_INFO->BaroAltitude = RMAAltitude;
	}
  }
  if (!GGAAvailable) {
	// update SatInUse, some GPS receiver dont emmit GGA sentance
	if (!gpsValid) { 
		GPS_INFO->SatellitesUsed = 0;
	} else {
		GPS_INFO->SatellitesUsed = -1;
	}
  }
  
  return TRUE;
}
Example #14
0
int MapWindow::SharedTopView(HDC hdc, DiagrammStruct* psDia , double fAS_Bearing, double fWP_Bearing)
{
  int iOldDisplayOrientation =  DisplayOrientation;
  DiagrammStruct m_Dia =	*psDia;
  RECT rct = m_Dia.rc;

  unsigned short getsideviewpage=GetSideviewPage();
  LKASSERT(getsideviewpage<NUMBER_OF_SHARED_MULTIMAPS);
  LKASSERT(Current_Multimap_SizeY!=SIZE0);

  DisplayOrientation = GetMMNorthUp(getsideviewpage);

  switch(GetMMNorthUp(getsideviewpage))
  {
   	case TRACKUP:
   		break;

   	case NORTHUP:
   	default:
		m_Dia.fXMin = -m_Dia.fXMax;
		break;
  }

  double fOldScale  =  zoom.Scale();
  HFONT hfOld = (HFONT)SelectObject(hdc, LK8PanelUnitFont);

  if(zoom.AutoZoom())
	zoom.AutoZoom(false);
  double fFact = 1.25 ;
#ifdef INIT_CASE


  switch(ScreenSize) {

	case ss896x672:	fFact=0.938; break;

	case ss800x480:	fFact=0.750; break;

	case ss640x480:	fFact=0.938; break;
	case ss480x272:	fFact=0.708; break;
	case ss400x240:	fFact=0.750; break;
	case ss320x240:	fFact=0.938; break;

	case ss480x800:	fFact=1.250; break;
	case ss480x640:	fFact=1.250; break;
	case ss272x480:	fFact=1.250; break;
	case ss240x400:	fFact=1.250; break;
	case ss240x320:	fFact=1.250; break;
	default:	fFact=1.000; break;
  }
#endif


  if((ScreenSizeX > 0) && (ScreenSizeY > 0))
  {
    if(ScreenSizeX > ScreenSizeY)
      fFact = (double)ScreenSizeY/(double)ScreenSizeX * 1.250;

  }
  PanLatitude  = DrawInfo.Latitude;
  PanLongitude = DrawInfo.Longitude;

  switch(GetMMNorthUp(getsideviewpage))
  {
      case TRACKUP:
	    	DisplayAngle = AngleLimit360(fAS_Bearing  +270.0);
	    	DisplayAircraftAngle = AngleLimit360(fWP_Bearing);
		break;

      case NORTHUP:
      default:
		DisplayAngle = 0;
		if( getsideviewpage == IM_HEADING || getsideviewpage==IM_VISUALGLIDE)
			DisplayAircraftAngle = AngleLimit360(fAS_Bearing);
		else
			DisplayAircraftAngle = AngleLimit360(DrawInfo.TrackBearing);
		break;
  }

  int iOldLocator = EnableThermalLocator;
  EnableThermalLocator =0;

  MapWindow::ChangeDrawRect(rct);       // set new area for terrain and topology

  zoom.ModifyMapScale();
  zoom.RequestedScale((m_Dia.fXMax -m_Dia.fXMin)  * fFact *  (DISTANCEMODIFY)/10.0f);

  POINT Orig           =  { CalcDistanceCoordinat(0.0,  (DiagrammStruct*) &m_Dia),(rct.bottom-rct.top)/2};
  POINT Orig_Aircraft= {0,0};

  zoom.ModifyMapScale();
  zoom.UpdateMapScale();

  CalculateScreenPositions( Orig,  rct, &Orig_Aircraft);
  CalculateScreenPositionsAirspace(rct);

  // 
  // Expose variables in use for topview drawing
  // 
  Current_Multimap_TopOrig=Orig_Aircraft;
  Current_Multimap_TopZoom=GetInvDrawScale();
  Current_Multimap_TopAngle=DisplayAngle;

  bool terrainpainted=false;

  if (IsMultimapTerrain() &&  DerivedDrawInfo.TerrainValid && RasterTerrain::isTerrainLoaded() ) {
        LKTextBlack=false;
        BlackScreen=false;
	LockTerrainDataGraphics();
	DrawTerrain(hdc, rct, GetAzimuth(), 40.0);
	UnlockTerrainDataGraphics();
	terrainpainted=true;
  } else {
	// We fill up the background wity chosen empty map color

	// display border and fill background..
        SelectObject(hdc, hInvBackgroundBrush[BgMapColor]);
        SelectObject(hdc, GetStockObject(WHITE_PEN));
        Rectangle(hdc,rct.left,rct.top,rct.right,rct.bottom);
        // We force LK painting black values on screen depending on the background color in use
        // blackscreen would force everything to be painted white, instead
        LKTextBlack=BgMapColorTextBlack[BgMapColor];
        if (BgMapColor>6 ) BlackScreen=true; else BlackScreen=false;
  } 

  ResetLabelDeclutter();

  // We reduce screen cluttering for some cases..
  short olddecluttermode=DeclutterMode;
  if (Current_Multimap_SizeY==SIZE4) goto _nomoredeclutter;
  if (Current_Multimap_SizeY<SIZE3) {
	DeclutterMode+=2;
  } else {
	if (Current_Multimap_SizeY==SIZE3)
		DeclutterMode++;
  }
  if (DeclutterMode>dmVeryHigh) DeclutterMode=dmVeryHigh;

_nomoredeclutter:

  if (IsMultimapTopology()) {
	// Do not print topology labels, to be used with another config later!
	// SaturateLabelDeclutter();
	RECT rc_red = rct;
	rc_red.bottom -= 3;
	DrawTopology  (hdc, rc_red);
  } else {
	// No topology is desired, but terrain requires water areas nevertheless
	if (terrainpainted) {
		RECT rc_red = rct;
		rc_red.bottom -= 3;
		DrawTopology  (hdc, rc_red,true); // water only!
	}
  }


  if (IsMultimapAirspace()) {
	if ( (GetAirSpaceFillType() == asp_fill_ablend_full) || (GetAirSpaceFillType() == asp_fill_ablend_borders) ) {
		DrawTptAirSpace(hdc, rct);
	} else {
		if ( GetAirSpaceFillType() == asp_fill_border_only)
			DrawAirSpaceBorders(hdc, rct); // full screen, to hide clipping effect on low border
		else
			DrawAirSpace(hdc, rct);   // full screen, to hide clipping effect on low border
	}
	// DrawAirspaceLabels( hdc,   rct, Orig_Aircraft);
  }

  if (Flags_DrawTask && MapSpaceMode!=MSM_MAPASP && ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) {
    DrawTaskAAT(hdc, DrawRect);
    DrawTask(hdc, DrawRect, Current_Multimap_TopOrig);
  }

  if (IsMultimapWaypoints()) {
	DrawWaypointsNew(hdc,DrawRect);
  }
  if (Flags_DrawFAI)
	DrawFAIOptimizer(hdc, DrawRect, Current_Multimap_TopOrig);

  DeclutterMode=olddecluttermode; // set it back correctly

 /* THIS STUFF DOES NOT WORK IN SHARED MAPS, YET
    NEED FIXING LatLon2Screen for shared maps using Sideview
    #ifdef GTL2
    if (((FinalGlideTerrain == 2) || (FinalGlideTerrain == 4)) &&
	DerivedDrawInfo.TerrainValid)
	DrawTerrainAbove(hdc, DrawRect);
    #endif
  */


  // 
  // Stuff for MAPTRK only (M1)
  if (MapSpaceMode==MSM_MAPTRK) {
	if(IsMultimapTerrain() || IsMultimapTopology() ) {
		if (FinalGlideTerrain && DerivedDrawInfo.TerrainValid)
			DrawGlideThroughTerrain(hdc, DrawRect); 
	}
	if (extGPSCONNECT)
		DrawBearing(hdc, DrawRect);
	// Wind arrow
	if (IsMultimapOverlaysGauges())
		DrawWindAtAircraft2(hdc, Current_Multimap_TopOrig, DrawRect);
  }

  if (MapSpaceMode==MSM_MAPWPT) {
	if (extGPSCONNECT)
		DrawBearing(hdc, DrawRect);
  }

  switch(GetMMNorthUp(getsideviewpage)) {
	case NORTHUP:
	default:
		DrawCompass( hdc,  rct, 0);
	break;
	case TRACKUP:
		if(getsideviewpage ==  IM_HEADING || getsideviewpage == IM_VISUALGLIDE)
		  DrawCompass( hdc,  rct, DrawInfo.TrackBearing-90.0);
		else
		  DrawCompass( hdc,  rct, DisplayAngle);
	break;
  }


  /****************************************************************************************************
   * draw vertical line
   ****************************************************************************************************/
  POINT line[2];
  line[0].x = rct.left;
  line[0].y = Orig_Aircraft.y-1;
  line[1].x = rct.right;
  line[1].y = line[0].y;

  switch(GetMMNorthUp(getsideviewpage))
  {
     case TRACKUP:
	// Are we are not topview fullscreen?
	if (Current_Multimap_SizeY<SIZE4 && !MapSpaceMode==MSM_VISUALGLIDE) {
		DrawDashLine(hdc,NIBLSCALE(1), line[0], line[1],  Sideview_TextColor, rct);
	} else {
    	 	if (TrackBar) DrawHeadUpLine(hdc, Orig, rct, psDia->fXMin ,psDia->fXMax);
	}
     break;

     case NORTHUP:
     default:
	if (TrackBar) {
		DrawHeadUpLine(hdc, Orig, rct, psDia->fXMin ,psDia->fXMax);
	}
	break;
  }
  DrawAircraft(hdc, Orig_Aircraft);

  // M3 has sideview always on, so wont apply here, and no need to check
  if (Current_Multimap_SizeY==SIZE4) {
	DrawMapScale(hdc,rct,0);
  }

  MapWindow::zoom.RequestedScale(fOldScale);
  EnableThermalLocator = iOldLocator;
  DisplayOrientation = iOldDisplayOrientation;
  SelectObject(hdc, hfOld);
  return 0;

}
Example #15
0
void Heading(NMEA_INFO *Basic, DERIVED_INFO *Calculated)
{
  double x0, y0, mag=0;
  static double LastTime = 0;
  static double lastHeading = 0;
  static double lastSpeed = 0;

  if (DoInit[MDI_HEADING]) {
	LastTime = 0;
	lastHeading = 0;
	DoInit[MDI_HEADING]=false;
  }

  if ((Basic->Speed>0)||(Calculated->WindSpeed>0)) {

    x0 = fastsine(Basic->TrackBearing)*Basic->Speed;
    y0 = fastcosine(Basic->TrackBearing)*Basic->Speed;
    x0 += fastsine(Calculated->WindBearing)*Calculated->WindSpeed;
    y0 += fastcosine(Calculated->WindBearing)*Calculated->WindSpeed;

    Calculated->Heading = AngleLimit360(atan2(x0,y0)*RAD_TO_DEG);

    if (!Calculated->Flying) {
      // don't take wind into account when on ground
      Calculated->Heading = Basic->TrackBearing;
    }

    // calculate turn rate in wind coordinates
    if(Basic->Time > LastTime) {
      double dT = Basic->Time - LastTime;

      LKASSERT(dT!=0);
      Calculated->TurnRateWind = AngleLimit180(Calculated->Heading
                                               - lastHeading)/dT;

      lastHeading = Calculated->Heading;
    }

    if (ISCAR) {
	// On ground, TAS is GS. Wind gradient irrilevant, normally.
	Calculated->TrueAirspeedEstimated = Basic->Speed;
	LKASSERT(AirDensityRatio(Calculated->NavAltitude)!=0);
	Calculated->IndicatedAirspeedEstimated = Basic->Speed/AirDensityRatio(Calculated->NavAltitude);
    } else {
	// calculate estimated true airspeed
	mag = isqrt4((unsigned long)(x0*x0*100+y0*y0*100))/10.0;
	Calculated->TrueAirspeedEstimated = mag;
	LKASSERT(AirDensityRatio(Calculated->NavAltitude)!=0);
	Calculated->IndicatedAirspeedEstimated = mag/AirDensityRatio(Calculated->NavAltitude);
    }
    // estimate bank angle (assuming balanced turn)
    double angle = atan(DEG_TO_RAD*Calculated->TurnRateWind*
			Calculated->TrueAirspeedEstimated/9.81);

    Calculated->BankAngle = RAD_TO_DEG*angle;

    if (ISCAR) {
	if(Basic->Time > LastTime) {
		Calculated->Gload = ((Basic->Speed - lastSpeed) / (Basic->Time-LastTime))/9.81;
		lastSpeed=Basic->Speed;
	} else {
		Calculated->Gload = 0;
	}
    } else {
	Calculated->Gload = 1.0/max(0.001,fabs(cos(angle)));
    }

    LastTime = Basic->Time;

    // estimate pitch angle (assuming balanced turn)
/*
    Calculated->PitchAngle = RAD_TO_DEG*
      atan2(Calculated->GPSVario-Calculated->Vario,
           Calculated->TrueAirspeedEstimated);
*/
	// should be used as here only when no real vario available
    Calculated->PitchAngle = RAD_TO_DEG*	
      atan2(Calculated->Vario,
           Calculated->TrueAirspeedEstimated);

    // update zigzag wind
    if (  ((AutoWindMode==D_AUTOWIND_ZIGZAG) || (AutoWindMode==D_AUTOWIND_BOTHCIRCZAG))
        && (!ReplayLogger::IsEnabled()) ) {
      double zz_wind_speed;
      double zz_wind_bearing;
      int quality=0;
      quality = WindKalmanUpdate(Basic, Calculated, &zz_wind_speed, &zz_wind_bearing);

      if (quality>0) {

        SetWindEstimate(zz_wind_speed, zz_wind_bearing);
	Calculated->WindSpeed   = zz_wind_speed;
	Calculated->WindBearing = zz_wind_bearing;

/* 100118 redundant!! removed. TOCHECK *
        Vector v_wind;
        v_wind.x = zz_wind_speed*cos(zz_wind_bearing*3.1415926/180.0);
        v_wind.y = zz_wind_speed*sin(zz_wind_bearing*3.1415926/180.0);
        LockFlightData();
        if (windanalyser) {
	  windanalyser->slot_newEstimate(Basic, Calculated, v_wind, quality);
        }
        UnlockFlightData();
*/
      }
    }
  // else basic speed is 0 and there is no wind.. 
  } else { 
    Calculated->Heading = Basic->TrackBearing;
    Calculated->TrueAirspeedEstimated = 0; // BUGFIX 100318
    Calculated->IndicatedAirspeedEstimated = 0; // BUGFIX 100318
  }

}
Example #16
0
void AATDistance::ShiftTargetFromBehind(double longitude, double latitude,
                              int taskwaypoint) {

  // JMWAAT if being externally updated e.g. from task dialog, don't move it
  if (TargetDialogOpen) return;
  if (taskwaypoint==0) return;

  // best is decreasing or first entry in sector, so project
  // target in direction of improvement or first entry into sector

  double course_bearing;
  double course_bearing_orig;
  double d_total_orig;
  double d_total_this;

  d_total_this = DoubleLegDistance(taskwaypoint,
                                   longitude,
                                   latitude);

  d_total_orig = DoubleLegDistance(taskwaypoint,
                                   Task[taskwaypoint].AATTargetLon,
                                   Task[taskwaypoint].AATTargetLat);

  if (d_total_this>d_total_orig-2.0*AATCloseDistance()) {
    // this is better than the previous best! (or very close)
    ShiftTargetFromInFront(longitude, latitude, taskwaypoint);
    return;
  }

  // JMWAAT if locked, don't move it
  if (Task[taskwaypoint].AATTargetLocked) {
    // 20080615 JMW don't do this; locked stays locked
    // Task[taskwaypoint].AATTargetLocked = false; // JMWAAT JB
    return;
  }

  /*
  // check to see if deviation is big enough to adjust target along track
  DistanceBearing(Task[taskwaypoint-1].AATTargetLat,
                  Task[taskwaypoint-1].AATTargetLon,
                  latitude,
                  longitude,
                  NULL, &course_bearing);

  DistanceBearing(Task[taskwaypoint-1].AATTargetLat,
                  Task[taskwaypoint-1].AATTargetLon,
                  Task[taskwaypoint].AATTargetLat,
                  Task[taskwaypoint].AATTargetLon,
                  NULL, &course_bearing_orig);

  if (fabs(AngleLimit180(course_bearing-course_bearing_orig))<5.0) {
    // don't update it if course deviation is less than 5 degrees,
    // otherwise we end up wasting a lot of CPU in recalculating, and also
    // the target ends up drifting.
    return;
  }

  course_bearing = AngleLimit360(course_bearing+
                                 Task[taskwaypoint].AATTargetOffsetRadial);
  //JMWAAT  Task[taskwaypoint].AATTargetOffsetRadial = course_bearing;
  */

  DistanceBearing(Task[taskwaypoint-1].AATTargetLat,
                  Task[taskwaypoint-1].AATTargetLon,
                  latitude,
                  longitude,
                  NULL, &course_bearing);
  course_bearing = AngleLimit360(course_bearing+
                                 Task[taskwaypoint].AATTargetOffsetRadial);

  DistanceBearing(latitude,
                  longitude,
                  Task[taskwaypoint].AATTargetLat,
                  Task[taskwaypoint].AATTargetLon,
                  NULL, &course_bearing_orig);

  if (fabs(AngleLimit180(course_bearing-course_bearing_orig))<5.0) {
    // don't update it if course deviation is less than 5 degrees,
    // otherwise we end up wasting a lot of CPU in recalculating, and also
    // the target ends up drifting.
    return;
  }

  double max_distance =
    FindInsideAATSectorDistance(latitude,
                                longitude,
                                taskwaypoint,
                                course_bearing,
                                0);

  // total distance of legs from previous through this to next target
  double delta = max_distance/2;

  // move target in line with previous target along track
  // at an offset to improve on max distance

  double t_distance_lower = 0;
  double t_distance = delta*2;

  int steps = 0;

  do {
    // find target position along projected line but
    // make sure it is in sector, and set at a distance
    // to preserve total task distance
    // we are aiming to make d_total_this = d_total_orig

    double t_lat, t_lon;
    FindLatitudeLongitude(latitude, longitude,
                          course_bearing, t_distance,
                          &t_lat,
                          &t_lon);

    if (InAATTurnSector(t_lon, t_lat, taskwaypoint, 0)) {
      d_total_this = DoubleLegDistance(taskwaypoint,
                                       t_lon,
                                       t_lat);
      if (d_total_orig - d_total_this>0.0) {
        t_distance_lower = t_distance;
        // ok, can go further
        t_distance += delta;
      } else {
        t_distance -= delta;
      }
    } else {
      t_distance -= delta;
    }
    delta /= 2.0;
  } while ((delta>5.0) && (steps++<20));

  // now scan to edge of sector to find approximate range %
  if (t_distance_lower>5.0) {
    FindLatitudeLongitude(latitude, longitude,
                          course_bearing, t_distance_lower,
                          &Task[taskwaypoint].AATTargetLat,
                          &Task[taskwaypoint].AATTargetLon);

    UpdateTargetAltitude(Task[taskwaypoint]);

    Task[taskwaypoint].AATTargetOffsetRadius =
      FindInsideAATSectorRange(latitude,
                               longitude,
                               taskwaypoint, course_bearing,
                               t_distance_lower);
    TargetModified = true;
    CalculateAATIsoLines();

  }

  //  if ((!t_in_sector) && (d_diff_total>1.0)) {
    // JMW TODO enhancement: this is too short now so need to lengthen the
    // next waypoint if possible
    // (re discussion with paul mander)
  //  }
}
void dlgWayPointDetailsShowModal(short mypage){

  TCHAR sTmp[128];
  double sunsettime;
  int sunsethours;
  int sunsetmins;
  WndProperty *wp;

  if (!ScreenLandscape) {
    TCHAR filename[MAX_PATH];
    LocalPathS(filename, TEXT("dlgWayPointDetails_L.xml"));
    wf = dlgLoadFromXML(CallBackTable, 
                        
                        filename, 
                        hWndMainWindow,
                        TEXT("IDR_XML_WAYPOINTDETAILS_L"));

  } else {
    TCHAR filename[MAX_PATH];
    LocalPathS(filename, TEXT("dlgWayPointDetails.xml"));
    wf = dlgLoadFromXML(CallBackTable, 
                        filename, 
                        hWndMainWindow,
                        TEXT("IDR_XML_WAYPOINTDETAILS"));
  }
  nTextLines = 0;

  if (!wf) return;

  wInfo    = ((WndFrame *)wf->FindByName(TEXT("frmInfos")));
  wCommand = ((WndFrame *)wf->FindByName(TEXT("frmCommands")));
  wSpecial = ((WndFrame *)wf->FindByName(TEXT("frmSpecial")));
  wDetails = (WndListFrame*)wf->FindByName(TEXT("frmDetails"));

  LKASSERT(wInfo!=NULL);
  LKASSERT(wCommand!=NULL);
  LKASSERT(wSpecial!=NULL);
  LKASSERT(wDetails!=NULL);

  // Resize Frames up to real screen size on the right.
  wInfo->SetBorderKind(BORDERLEFT);

  wCommand->SetBorderKind(BORDERLEFT);
  wSpecial->SetBorderKind(BORDERLEFT);
  wDetails->SetBorderKind(BORDERLEFT);

  wCommand->SetVisible(false);
  wSpecial->SetVisible(false);


  //
  // CAPTION: top line in black
  //

  // if SeeYou waypoint
  if (WPLSEL.Format == LKW_CUP) { 
	TCHAR ttmp[50];
	// and it is landable
	if ((WPLSEL.Style>1) && (WPLSEL.Style<6) ) {

		_stprintf(sTmp, TEXT("%s "), WPLSEL.Name);
		// ICAO name probably, let's print it
		if ( _tcslen(WPLSEL.Code)==4 ) {
			_stprintf(ttmp,_T("(%s) "),WPLSEL.Code);
			_tcscat(sTmp, ttmp);
		}

		if ( _tcslen(WPLSEL.Freq)>0 )  {
			_stprintf(ttmp,_T("%s "),WPLSEL.Freq);
			_tcscat(sTmp, ttmp);
		}

		if ( WPLSEL.RunwayDir>=0 )  {
			_stprintf(ttmp,_T("RW %d "),WPLSEL.RunwayDir);
			_tcscat(sTmp, ttmp);
		}
		if ( WPLSEL.RunwayLen>0 )  {
			// we use Altitude instead of distance, to keep meters and feet
			_stprintf(ttmp,_T("%.0f%s"),Units::ToUserAltitude((double)WPLSEL.RunwayLen), Units::GetAltitudeName());
			_tcscat(sTmp, ttmp);
		}

		wf->SetCaption(sTmp);
	} else {
		_stprintf(sTmp, TEXT("%s: "), wf->GetCaption());
		_tcscat(sTmp, WayPointList[SelectedWaypoint].Name);
		wf->SetCaption(sTmp);
	}
  } else {
	_stprintf(sTmp, TEXT("%s: "), wf->GetCaption());
	_tcscat(sTmp, WayPointList[SelectedWaypoint].Name);
	wf->SetCaption(sTmp);
  }

  //
  // Waypoint Comment
  //
  wp = ((WndProperty *)wf->FindByName(TEXT("prpWpComment")));
  LKASSERT(wp);
  if (WayPointList[SelectedWaypoint].Comment==NULL)
	wp->SetText(_T(""));
  else
	wp->SetText(WayPointList[SelectedWaypoint].Comment);

  wp->SetButtonSize(16);

  //
  // Lat and Lon
  //
  Units::CoordinateToString(
		  WayPointList[SelectedWaypoint].Longitude,
		  WayPointList[SelectedWaypoint].Latitude,
		  sTmp, sizeof(sTmp)-1);

  wp = ((WndProperty *)wf->FindByName(TEXT("prpCoordinate")));
  LKASSERT(wp);
  wp->SetText(sTmp);
	
  //
  // Waypoint Altitude 
  //
  Units::FormatUserAltitude(WayPointList[SelectedWaypoint].Altitude, sTmp, sizeof(sTmp)-1);
  wp = ((WndProperty *)wf->FindByName(TEXT("prpAltitude")));
  LKASSERT(wp);
  wp->SetText(sTmp);

  //
  // SUNSET at waypoint
  //
  sunsettime = DoSunEphemeris(WayPointList[SelectedWaypoint].Longitude,
                              WayPointList[SelectedWaypoint].Latitude);
  sunsethours = (int)sunsettime;
  sunsetmins = (int)((sunsettime-sunsethours)*60);

  _stprintf(sTmp, TEXT("%02d:%02d"), sunsethours, sunsetmins);
  ((WndProperty *)wf->FindByName(TEXT("prpSunset")))->SetText(sTmp);


  // 
  // Distance and bearing
  //
  double distance, bearing;
  DistanceBearing(GPS_INFO.Latitude,
                  GPS_INFO.Longitude,
                  WayPointList[SelectedWaypoint].Latitude,
                  WayPointList[SelectedWaypoint].Longitude, 
                  &distance, 
                  &bearing);

  TCHAR DistanceText[MAX_PATH];
  if (ScreenLandscape) {
      Units::FormatUserDistance(distance, DistanceText, 10);

      if ( Units::GetUserDistanceUnit() == unNauticalMiles ||
           Units::GetUserDistanceUnit() == unStatuteMiles ) {

          _stprintf(sTmp,_T("  (%.1fkm)"), distance*TOKILOMETER);
      } else {
	  _stprintf(sTmp,_T("  (%.1fnm)"), distance*TONAUTICALMILES);
      }
      _tcscat(DistanceText,sTmp);
  } else {
      Units::FormatUserDistance(distance, DistanceText, 10);
  }
  ((WndProperty *)wf->FindByName(TEXT("prpDistance")))->SetText(DistanceText);

  if (ScreenLandscape) {
      _stprintf(sTmp, TEXT("%d%s  (R:%d%s)"),iround(bearing), TEXT(DEG),
         iround(AngleLimit360(bearing+180)), TEXT(DEG));
  } else {
      _stprintf(sTmp, TEXT("%d")TEXT(DEG), iround(bearing));
  }
  ((WndProperty *)wf->FindByName(TEXT("prpBearing")))->SetText(sTmp);


  //
  // Altitude reqd at mc 0
  // 
  double alt=0;
  alt = CALCULATED_INFO.NavAltitude - 
    GlidePolar::MacCreadyAltitude(0.0,
				  distance,
				  bearing, 
				  CALCULATED_INFO.WindSpeed, 
				  CALCULATED_INFO.WindBearing, 
				  0, 0, true,
				  0)- WayPointList[SelectedWaypoint].Altitude;

  if (SafetyAltitudeMode==1 || WayPointCalc[SelectedWaypoint].IsLandable) 
	alt-=(SAFETYALTITUDEARRIVAL/10);

  _stprintf(sTmp, TEXT("%.0f %s"), alt*ALTITUDEMODIFY,
	    Units::GetAltitudeName());

  wp = ((WndProperty *)wf->FindByName(TEXT("prpMc0")));
  if (wp) wp->SetText(sTmp);



  // alt reqd at current mc
  alt = CALCULATED_INFO.NavAltitude - 
    GlidePolar::MacCreadyAltitude(MACCREADY,
				  distance,
				  bearing, 
				  CALCULATED_INFO.WindSpeed, 
				  CALCULATED_INFO.WindBearing, 
				  0, 0, true,
				  0)-
    WayPointList[SelectedWaypoint].Altitude;

  if (SafetyAltitudeMode==1 || WayPointCalc[SelectedWaypoint].IsLandable) 
	alt-=(SAFETYALTITUDEARRIVAL/10);

  _stprintf(sTmp, TEXT("%.0f %s"), alt*ALTITUDEMODIFY,
	    Units::GetAltitudeName());

  wp = ((WndProperty *)wf->FindByName(TEXT("prpMc2")));
  if (wp) {
	wp->SetText(sTmp);
  }


  wf->SetKeyDownNotify(FormKeyDown);

  ((WndButton *)wf->FindByName(TEXT("cmdClose")))->SetOnClickNotify(OnCloseClicked);

  // We DONT use PREV  anymore
  ((WndButton *)wf->FindByName(TEXT("cmdPrev")))->SetVisible(false);


  //
  // Details (WAYNOTES) page
  //
  wDetailsEntry = (WndOwnerDrawFrame*)wf->FindByName(TEXT("frmDetailsEntry"));
  LKASSERT(wDetailsEntry!=NULL);
  wDetailsEntry->SetCanFocus(true);

  nTextLines = TextToLineOffsets(WayPointList[SelectedWaypoint].Details,
				 LineOffsets,
				 MAXLINES);

  // ScrollbarWidth is initialised from DrawScrollBar in WindowControls, so it might not be ready here
  if ( wDetails->ScrollbarWidth == -1) {
   #if defined (PNA)
   #define SHRINKSBFACTOR 1.0 // shrink width factor.  Range .1 to 1 where 1 is very "fat"
   #else
   #define SHRINKSBFACTOR 0.75  // shrink width factor.  Range .1 to 1 where 1 is very "fat"
   #endif
   wDetails->ScrollbarWidth = (int) (SCROLLBARWIDTH_INITIAL * ScreenDScale * SHRINKSBFACTOR);

  }
  wDetailsEntry->SetWidth(wDetails->GetWidth() - wDetails->ScrollbarWidth - 5);

  WndButton *wb;

  TCHAR captmp[200];

  // Resize also buttons
  wb = ((WndButton *)wf->FindByName(TEXT("cmdInserInTask")));
  if (wb) {
    wb->SetOnClickNotify(OnInserInTaskClicked);
    wb->SetWidth(wCommand->GetWidth()-wb->GetLeft()*2);

    if ((ActiveWayPoint<0) || !ValidTaskPoint(0)) {
	// this is going to be the first tp (ActiveWayPoint 0)
	_stprintf(captmp,_T("%s"),MsgToken(1824)); // insert as START
    } else {
	LKASSERT(ActiveWayPoint>=0 && ValidTaskPoint(0));
	int indexInsert = max(ActiveWayPoint,0); // safe check
	if (indexInsert==0) {
		_stprintf(captmp,_T("%s"),MsgToken(1824)); // insert as START
	} else {
		LKASSERT(ValidWayPoint(Task[indexInsert].Index));
		_stprintf(captmp,_T("%s <%s>"),MsgToken(1825),WayPointList[ Task[indexInsert].Index ].Name); // insert before xx
	}
    }
    wb->SetCaption(captmp);
  }

  wb = ((WndButton *)wf->FindByName(TEXT("cmdAppendInTask1")));
  if (wb) {
    wb->SetOnClickNotify(OnAppendInTask1Clicked);
    wb->SetWidth(wCommand->GetWidth()-wb->GetLeft()*2);
  }

  wb = ((WndButton *)wf->FindByName(TEXT("cmdAppendInTask2")));
  if (wb) {
    wb->SetOnClickNotify(OnAppendInTask2Clicked);
    wb->SetWidth(wCommand->GetWidth()-wb->GetLeft()*2);
  }

  wb = ((WndButton *)wf->FindByName(TEXT("cmdRemoveFromTask")));
  if (wb) {
    wb->SetOnClickNotify(OnRemoveFromTaskClicked);
    wb->SetWidth(wCommand->GetWidth()-wb->GetLeft()*2);
  }

  wb = ((WndButton *)wf->FindByName(TEXT("cmdReplace")));
  if (wb) {
    wb->SetWidth(wCommand->GetWidth()-wb->GetLeft()*2);

    int tmpIdx =  -1;
    if (ValidTaskPoint(ActiveWayPoint))
      tmpIdx = Task[ActiveWayPoint].Index;
    if(  ValidTaskPoint(PanTaskEdit))
     tmpIdx = RealActiveWaypoint;
    if(tmpIdx != -1)
    {
    	wb->SetOnClickNotify(OnReplaceClicked);
	_stprintf(captmp,_T("%s <%s>"),MsgToken(1826),WayPointList[tmpIdx ].Name); // replace  xx
    } else {
	_stprintf(captmp,_T("( %s )"),MsgToken(555));
    }
    wb->SetCaption(captmp);
  }


  wb = ((WndButton *)wf->FindByName(TEXT("cmdNewHome")));
  if (wb)  {
    wb->SetOnClickNotify(OnNewHomeClicked);
    wb->SetWidth(wSpecial->GetWidth()-wb->GetLeft()*2);
  }

  wb = ((WndButton *)wf->FindByName(TEXT("cmdTeamCode")));
  if (wb) {
    wb->SetOnClickNotify(OnTeamCodeClicked);
    wb->SetWidth(wSpecial->GetWidth()-wb->GetLeft()*2);
  }

  page = mypage;

  NextPage(0);

  wf->ShowModal();

  delete wf;

  wf = NULL;

}
Example #18
0
int RenderFAISector (LKSurface& Surface, const RECT& rc , double lat1, double lon1, double lat2, double lon2, int iOpposite , const LKColor& fillcolor)
{

POINT Pt1;
float fFAI_Percentage = FAI_NORMAL_PERCENTAGE;
double fDist_a, fDist_b, fDist_c, fAngle;
int i;

int iPolyPtr=0;
double lat_d,lon_d;
double alpha, fDistTri, cos_alpha=0;
POINT apSectorPolygon[MAX_FAI_SECTOR_PTS+1];
DistanceBearing(lat1, lon1, lat2, lon2, &fDist_c, &fAngle);

if(fabs(fDist_c) < 1000.0)  /* distance too short for a FAI sector */
	return -1;


double fDistMax = fDist_c/FAI_NORMAL_PERCENTAGE;
double fDistMin = fDist_c/(1.0-2.0*FAI28_45Threshold);
double fDelta_Dist = 2.0* fDist_c*fFAI_Percentage / (double)(FAI_SECTOR_STEPS-1);
double fA, fB;
double fMinLeg, fMaxLeg,fDiff=0;
double dir = -1.0;
BOOL bBigFAISector = false;

if(fDistMax > FAI28_45Threshold)
{
  bBigFAISector = true;
  fDistMax = fDist_c/FAI_BIG_PERCENTAGE;
}

if(fDistMin < FAI28_45Threshold)
{
  fDistMin = fDist_c/(1.0-2.0*FAI_NORMAL_PERCENTAGE);
}


if (iOpposite >0)
{
  dir = 1.0;
}

//#define  HELP_LINES
#ifdef HELP_LINES
  int x2,y2, style;
  FindLatitudeLongitude(lat1, lon1, AngleLimit360 (fAngle), fDist_c/2, &lat_d, &lon_d);
  x1 = (lon_d - lon_c)*fastcosine(lat_d);
  y1 = (lat_d - lat_c);
  FindLatitudeLongitude(lat_d, lon_d, AngleLimit360 (fAngle-90.0), fDist_c, &lat_d, &lon_d);
  x2 = (lon_d - lon_c)*fastcosine(lat_d);
  y2 = (lat_d - lat_c);
  Surface.DrawLine(rc, x1, y1, x2, y2, style);
#endif

  /********************************************************************
   * right below threshold 1
   ********************************************************************/
  fA = 	fDistMin;
  if(fDistMax > FAI28_45Threshold)
    fB = FAI28_45Threshold;
  else
	fB = fDistMax ;


  if(fA<fB)
  {
	fDelta_Dist =(fB-fA)/ (double)(FAI_SECTOR_STEPS-1);
	fDistTri = fA;
    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  fDist_a = FAI_NORMAL_PERCENTAGE * fDistTri;
	  fDist_b = fDistTri - fDist_a - fDist_c;

	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);

	  MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	  LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	  apSectorPolygon[iPolyPtr++] = Pt1;


      fDistTri += fDelta_Dist;
    }
  }

  /********************************************************************
   * right  threshold extender 2
   ********************************************************************/
if(fDistMin < FAI28_45Threshold)
  if(bBigFAISector && (fDistMin < FAI28_45Threshold))
  {
	fMaxLeg = FAI28_45Threshold*FAI_BIG_MAX_PERCENTAGE;
	fMinLeg = FAI28_45Threshold*FAI_BIG_PERCENTAGE;
	fA = FAI28_45Threshold*FAI_NORMAL_PERCENTAGE;
	fB = FAI28_45Threshold-fMaxLeg-fDist_c;

	if(fB < fMinLeg)
	  fB = fMinLeg;

	fDist_a = fA;
	fDelta_Dist =  (fB-fA) / (double)(FAI_SECTOR_STEPS-1);
    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  fDist_b = FAI28_45Threshold - fDist_a - fDist_c;
  	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
	  MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	  LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	  apSectorPolygon[iPolyPtr++] = Pt1;

	  fDist_a += fDelta_Dist;
    }
  }
  /********************************************************************
   * right  above threshold  3
   ********************************************************************/
  if(bBigFAISector)
  {
    fA = 	FAI28_45Threshold;
    if(fDistMin > fA)
	  fA= fDistMin;
    fB =fDist_c/(1- FAI_BIG_PERCENTAGE-FAI_BIG_MAX_PERCENTAGE);

    if(fA < fB)
    {
      fDelta_Dist =(fB-fA)/ (double)(FAI_SECTOR_STEPS-1);
      fDistTri = fA;
      for(i =0 ;i < FAI_SECTOR_STEPS; i++)
      {
  	    fMaxLeg = fDistTri*FAI_BIG_MAX_PERCENTAGE;
	    fMinLeg = fDistTri*FAI_BIG_PERCENTAGE;
	    fDist_a = fDistTri-fMinLeg-fDist_c;;
	    fDist_b = fMinLeg;

	    if(fDist_a > fMaxLeg)
	    {
	      fDiff =  fDist_a - fMaxLeg;
	      fDist_b+=fDiff;
	      fDist_a-=fDiff;
	    }

	    LKASSERT(fDist_c*fDist_b!=0);
	    cos_alpha = ( fDist_a*fDist_a + fDist_c*fDist_c - fDist_b*fDist_b )/(2.0*fDist_c*fDist_a);
	    alpha = acos(cos_alpha)*180/PI * dir;
	    FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_a, &lat_d, &lon_d);
		MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
		LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	    apSectorPolygon[iPolyPtr++] = Pt1;


	    fDistTri += fDelta_Dist;
      }
    }
  }
/********************************************************************
 * TOP limited round 4
 ********************************************************************/
  if(fDistMax <= FAI28_45Threshold)
	fDist_b = fDistMax*(1.0-2*FAI_NORMAL_PERCENTAGE);
  else
	fDist_b = fDistMax*FAI_BIG_MAX_PERCENTAGE;

  fDist_a = fDistMax-fDist_b-fDist_c;
  fDelta_Dist =  (fDist_a-fDist_b) / (double)(FAI_SECTOR_STEPS-1);
  for(i =0 ;i < FAI_SECTOR_STEPS; i++)
  {
	LKASSERT(fDist_c*fDist_b!=0);
	cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	alpha = acos(cos_alpha)*180/PI * dir;
	FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);

	MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
    apSectorPolygon[iPolyPtr++] = Pt1;


    fDist_a -= fDelta_Dist;
    fDist_b += fDelta_Dist;
  }

/********************************************************************
 * calc left leg
 ********************************************************************/

/********************************************************************
 * LEFT above threshold 5
 ********************************************************************/
  if(bBigFAISector)
  {
    fB = FAI28_45Threshold;
    if( fB < fDistMin)
	  fB = fDistMin;

    fA =fDist_c/(1- FAI_BIG_PERCENTAGE-FAI_BIG_MAX_PERCENTAGE);

    if(fA >= fB)
    {
      fDelta_Dist =(fA-fB)/ (double)(FAI_SECTOR_STEPS-1);
      fDistTri = fA;
      for(i =0 ;i < FAI_SECTOR_STEPS; i++)
      {
	    fMaxLeg = fDistTri*FAI_BIG_MAX_PERCENTAGE;
	    fMinLeg = fDistTri*FAI_BIG_PERCENTAGE;
	    fDist_a = fDistTri-fMinLeg-fDist_c;
	    fDist_b = fMinLeg;

	    if(fDist_a > fMaxLeg)
	    {
	      fDiff =  fDist_a - fMaxLeg;
	      fDist_b+=fDiff;
	      fDist_a-=fDiff;
  	    }

	    LKASSERT(fDist_c*fDist_b!=0);
	    cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	    alpha = acos(cos_alpha)*180/PI * dir;
	    FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
		MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
		LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	    apSectorPolygon[iPolyPtr++] = Pt1;


	    fDistTri -= fDelta_Dist;
     }
    }
  }

  /********************************************************************
   * LEFT threshold extender 6
   ********************************************************************/
if(fDistMin < FAI28_45Threshold)
  if((fDistMin < FAI28_45Threshold) && (FAI28_45Threshold < fDistMax))
  {
	fMaxLeg = FAI28_45Threshold*FAI_BIG_MAX_PERCENTAGE;
	fMinLeg = FAI28_45Threshold*FAI_BIG_PERCENTAGE;
	fA = FAI28_45Threshold*FAI_NORMAL_PERCENTAGE;
	fB = FAI28_45Threshold-fMaxLeg-fDist_c;

	if(fB < fMinLeg)
	  fB = fMinLeg;

	fDist_b = fB;
	fDelta_Dist =  (fA-fB) / (double)(FAI_SECTOR_STEPS-1);

    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  fDist_a = FAI28_45Threshold - fDist_b - fDist_c;
	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
	  MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	  LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	  apSectorPolygon[iPolyPtr++] = Pt1;

	  fDist_b += fDelta_Dist;
    }
  }


  /********************************************************************
   * LEFT below threshold 7
   ********************************************************************/
  fA = 	fDistMin;
  if(fDistMax > FAI28_45Threshold)
    fB = FAI28_45Threshold;
  else
	fB = fDistMax ;

  if(fA<fB)
  {
	fDelta_Dist =(fB-fA)/ (double)(FAI_SECTOR_STEPS-1);
	fDistTri = fB;
    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  fDist_b = FAI_NORMAL_PERCENTAGE * fDistTri;
	  fDist_a = fDistTri - fDist_b - fDist_c;

	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
	  MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
	  LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	  apSectorPolygon[iPolyPtr++] = Pt1;
      fDistTri -= fDelta_Dist;
    }
  }

  /********************************************************************
   * low open PEAK round 8
   ********************************************************************/
  if(fDistMin >FAI28_45Threshold)
  {
	fDist_b = fDistMin*FAI_BIG_PERCENTAGE;
	fDist_a = fDistMin-fDist_b-fDist_c;
	fDelta_Dist =  (fDist_b-fDist_a) / (double)(FAI_SECTOR_STEPS-1);

	for(i =0 ;i < FAI_SECTOR_STEPS; i++)
	{
		LKASSERT(fDist_c*fDist_b!=0);
		cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
		alpha = acos(cos_alpha)*180/PI * dir;
		FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
		MapWindow::LatLon2Screen(lon_d, lat_d,  Pt1);
		LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS);
	    apSectorPolygon[iPolyPtr++] = Pt1;

	    fDist_a += fDelta_Dist;
	    fDist_b -= fDelta_Dist;
	}
  }

  /********************************************************************
   * draw polygon
   ********************************************************************/
  LKPen   hpSectorPen(PEN_SOLID, IBLSCALE(2),  fillcolor );

  LKPen hpOldPen = Surface.SelectObject(hpSectorPen);
  LKBrush hpOldBrush = Surface.SelectObject(LKBrush_Hollow);

  Surface.Polygon(apSectorPolygon,iPolyPtr,rc);

  Surface.SelectObject(hpOldPen);
  Surface.SelectObject(hpOldBrush);
  hpSectorPen.Release();

  /********************************************************************
   * calc round leg grid
   ********************************************************************/
  hpSectorPen.Create(PEN_SOLID, (1), RGB_BLACK );
  Surface.SelectObject(hpSectorPen);
  Surface.SetTextColor(RGB_BLACK);
  double fTic= 1/DISTANCEMODIFY;
  if(fDist_c > 5/DISTANCEMODIFY)   fTic = 10/DISTANCEMODIFY;
  if(fDist_c > 50/DISTANCEMODIFY)  fTic = 25/DISTANCEMODIFY;
  if(fDist_c > 100/DISTANCEMODIFY) fTic = 50/DISTANCEMODIFY;
//  if(fDist_c > 200/DISTANCEMODIFY) fTic = 100/DISTANCEMODIFY;
  if(fDist_c > 500/DISTANCEMODIFY) fTic = 250/DISTANCEMODIFY;
  POINT line[2];
  BOOL bFirstUnit = true;
  LKASSERT(fTic!=0);
  fDistTri = ((int)(fDistMin/fTic)+1) * fTic ;
  LKFont hfOld = Surface.SelectObject(LK8PanelUnitFont);

int iCnt = 0;

  while(fDistTri <= fDistMax)
  {
    TCHAR text[180]; SIZE tsize;
	if(bFirstUnit)
	  _stprintf(text, TEXT("%i%s"), (int)(fDistTri*DISTANCEMODIFY), Units::GetUnitName(Units::GetUserDistanceUnit()));
	else
	  _stprintf(text, TEXT("%i"), (int)(fDistTri*DISTANCEMODIFY));
	bFirstUnit = false;
	Surface.GetTextSize(text, _tcslen(text), &tsize);

    int j=0;

	if(fDistTri < FAI28_45Threshold)
	{
	  fDist_b = fDistTri*FAI_NORMAL_PERCENTAGE;
	  fDist_a = fDistTri-fDist_b-fDist_c;
	  fDelta_Dist =  (fDist_a-fDist_b) / (double)(FAI_SECTOR_STEPS-1);
	}
	else
	{
      fMaxLeg = fDistTri*FAI_BIG_MAX_PERCENTAGE;
      fMinLeg = fDistTri*FAI_BIG_PERCENTAGE;
	  fA = fMaxLeg;
	  fB = fDistTri-fA-fDist_c;
	  fDist_a = fA;
	  fDist_b = fB;
	  if(fB < fMinLeg)
	  {
		  fDiff = fMinLeg-fB;
		  fB+=2*fDiff;
		  fDist_b += fDiff;
		  fDist_a -= fDiff;
	  }
	  if(fB > fMaxLeg)
	  {
		  fDiff =  fB - fMaxLeg;
		  fB+=2*fDiff;
		  fDist_b-=fDiff;
		  fDist_a+=fDiff;
	  }
	  fFAI_Percentage =  FAI_BIG_PERCENTAGE;
	  fDelta_Dist =  (fA-fB) / (double)(FAI_SECTOR_STEPS-1);
	}


    for(i =0 ;i < FAI_SECTOR_STEPS; i++)
    {
	  LKASSERT(fDist_c*fDist_b!=0);
	  cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b);
	  alpha = acos(cos_alpha)*180/PI * dir;
	  FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d);
	  MapWindow::LatLon2Screen(lon_d, lat_d,  line[0]);

      if(j> 0)
      {
  		ForcedClipping=true;
  		Surface.DrawLine(PEN_DASH, NIBLSCALE(1), line[0] , line[1] , RGB_BLACK, rc);
  		ForcedClipping=false;
      }


      if(j==0)
      {
    	Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text));
    	j=1;

      }

//      TCHAR text[180]; SIZE tsize;
      if(iCnt==0)
        _stprintf(text, TEXT("%i%s"), (int)(fDistTri*DISTANCEMODIFY), Units::GetUnitName(Units::GetUserDistanceUnit()));
      else
        _stprintf(text, TEXT("%i"), (int)(fDistTri*DISTANCEMODIFY));
      Surface.GetTextSize(text, _tcslen(text), &tsize);
      if(i == 0)
        Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text));

      if(iCnt > 1)
  	    if(i == FAI_SECTOR_STEPS-1)
  	      Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text));

      if(iCnt > 2)
  	    if((i== (FAI_SECTOR_STEPS/2)))
  	      Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text));

      line[1] =  line[0];



	  fDist_a -= fDelta_Dist;
	  fDist_b += fDelta_Dist;
    }
    fDistTri+=fTic;iCnt++;
 //   if((iCnt %2) ==0)
  //    DrawText(hdc, line[0].x, line[0].y, ETO_OPAQUE, NULL, text, _tcslen(text), NULL);
  }

Surface.SelectObject(hfOld);
Surface.SelectObject(hpOldPen);

return 0;
}
Example #19
0
double AngleDifference(double angle1, double angle0) {
	angle0 = AngleLimit360(angle0);
	angle1 = AngleLimit360(angle1);
	return fmod(angle1-angle0+180,360)-180;
}
Example #20
0
// draw aircraft
void RenderPlaneSideview(LKSurface& Surface, double fDist, double fAltitude,double brg, DiagrammStruct* psDia )
{
//BOOL bInvCol = true ; //INVERTCOLORS
  #define NO_AP_PTS 17
  int deg = DEG_TO_INT(AngleLimit360(brg));
  double fCos = COSTABLE[deg];
  double fSin = SINETABLE[deg];

  int TAIL   = 6;
  int PROFIL = 1;
  int FINB   = 3;
  int BODY   = 2;
  int NOSE   = 7;
  int WING   = (int) (22.0 );
  int TUBE   = (int) (14.0  ) ;
  int FINH   = 6+BODY;

  POINT Start;
  int HEAD = TUBE / 2;
  TUBE =  3 * TUBE/ 2;
  POINT AircraftSide
  [8] = {
      {(int)(fSin * (HEAD+0   )    ), -BODY-1},  // 1
      {(int)(fSin * (HEAD+NOSE)    ),  0},       // 2
      {(int)(fSin * (HEAD+0   )    ),  BODY+1},  // 3
      {(int)(fSin * (-TUBE)        ),  BODY},    // 4   -1
      {(int)(fSin * -TUBE          ), -FINH},    // 5
      {(int)(fSin * (-TUBE+FINB)   ), -FINH},    // 6
      {(int)(fSin * (-TUBE+FINB+3) ), -BODY+1},  // 7  +1
      {(int)(fSin * (HEAD+0)       ), -BODY-1}     // 8
  };

  #define  FACT 2

  BODY = (int)((double)(BODY+1) * fCos * fCos);

  int DIA = (BODY + PROFIL);

  /* both wings */
  POINT AircraftWing
  [13] = {
      {(int)(fCos * BODY              ) ,  -DIA},    // 1
      {(int)(fCos * (int)( FACT*BODY) ), -PROFIL},    // 2
      {(int)(fCos * WING              ) ,  -PROFIL},    // 3
      {(int)(fCos * WING              ), 0* PROFIL},    // 4
      {(int)(fCos * (int)( FACT*BODY) ) , PROFIL},    // 5
      {(int)(fCos *  BODY             ), DIA},    // 6
      {(int)(fCos * -BODY             ) , DIA},    // 7
      {(int)(fCos * (int)( -FACT*BODY)), PROFIL},    // 8
      {(int)(fCos * -WING             ), 0* PROFIL  },    // 9
      {(int)(fCos * -WING             ) , -PROFIL}  ,    // 10
      {(int)(fCos * (int)( -FACT*BODY)), -PROFIL},    // 11
      {(int)(fCos * -BODY             ) , -DIA},    // 12
      {(int)(fCos *  BODY             ), -DIA}    // 13
  };


  POINT AircraftWingL
  [7] = {

      {(int)(0 * -BODY                ),  DIA       },    // 1
      {(int)(fCos * (int)( -FACT*BODY)),  PROFIL    },    // 2
      {(int)(fCos * -WING             ),  0* PROFIL },    // 3
      {(int)(fCos * -WING             ), -PROFIL    },    // 4
      {(int)(fCos * (int)( -FACT*BODY)), -PROFIL    },    // 5
      {(int)(0 * -BODY                ), -DIA       },    // 6
      {(int)(0 * -BODY                ),  DIA       }     // 7
  };


  POINT AircraftWingR
  [7] = {
      {(int)(0 * BODY                 ) ,  -DIA    },   // 1
      {(int)(fCos * (int)( FACT*BODY) ) , -PROFIL  },   // 2
      {(int)(fCos * WING              ) ,  -PROFIL },   // 3
      {(int)(fCos * WING              ) , 0* PROFIL},   // 4
      {(int)(fCos * (int)( FACT*BODY) ) , PROFIL   },   // 5
      {(int)(0 *  BODY                ) , DIA      },   // 6
      {(int)(0 *  BODY                ) , -DIA     }    // 7
  };



  POINT AircraftTail
  [5] = {
      {(int)(fCos *  TAIL - fSin*TUBE), -FINH},            // 1
      {(int)(fCos *  TAIL - fSin*TUBE), -FINH +PROFIL},    // 2
      {(int)(fCos * -TAIL - fSin*TUBE), -FINH +PROFIL},    // 3
      {(int)(fCos * -TAIL - fSin*TUBE), -FINH },           // 4
      {(int)(fCos *  TAIL - fSin*TUBE), -FINH},            // 5

  };

  Start.x = CalcDistanceCoordinat(fDist,  psDia);
  Start.y = CalcHeightCoordinat(fAltitude, psDia);

  const auto oldPen = Surface.SelectObject(LK_BLACK_PEN);
  const auto oldBrush = Surface.SelectObject(LKBrush_White);

  PolygonRotateShift(AircraftWing, 13,  Start.x, Start.y,  0);
  PolygonRotateShift(AircraftSide, 8,   Start.x, Start.y,  0);
  PolygonRotateShift(AircraftTail, 5,   Start.x, Start.y,  0);
  PolygonRotateShift(AircraftWingL, 7,   Start.x, Start.y,  0);
  PolygonRotateShift(AircraftWingR, 7,   Start.x, Start.y,  0);

  #ifndef UNDITHER
  LKBrush GreenBrush(RGB_GREEN);
  LKBrush RedBrush(RGB_RED);
  #else
  LKBrush GreenBrush(RGB_WHITE);
  LKBrush RedBrush(RGB_BLACK);
  #endif
  if((brg < 180))
  {
    Surface.SelectObject(RedBrush);
    Surface.Polygon(AircraftWingL ,7 );

    Surface.SelectObject(LKBrush_White);
    Surface.Polygon(AircraftSide  ,8 );

    Surface.SelectObject(GreenBrush);
    Surface.Polygon(AircraftWingR ,7 );

    Surface.SelectObject(oldBrush);
  }
  else
  {
    Surface.SelectObject(GreenBrush);
    Surface.Polygon(AircraftWingR ,7 );

    Surface.SelectObject(LKBrush_White);
    Surface.Polygon(AircraftSide  ,8 );

    Surface.SelectObject(RedBrush);
    Surface.Polygon(AircraftWingL ,7 );

    Surface.SelectObject(oldBrush);
  }
  if((brg < 90)|| (brg > 270)) {
    Surface.Polygon(AircraftTail  ,5 );
  }

  Surface.SelectObject(oldPen);
  Surface.SelectObject(oldBrush);
} //else !asp_heading_task
Example #21
0
void LKSurface::Segment(long x, long y, int radius, const RECT& rc, double start, double end) {

    // JMW added faster checking...
    if ((x - radius) > rc.right) return;
    if ((x + radius) < rc.left) return;
    if ((y - radius) > rc.bottom) return;
    if ((y + radius) < rc.top) return;

    
    bool EmptySector = end == start;
    if(EmptySector) {
      RasterPoint pt[2];
      
      start = AngleLimit360(start);

      pt[0].x = x;
      pt[0].y = y;
      
      pt[1].x = x + (long) (radius * fastsine(start));
      pt[1].y = y - (long) (radius * fastcosine(start));
      
      Polyline(pt, array_size(pt), rc);
      
    } else {
      RasterPoint pt[68];

      start = AngleLimit360(start);
      end = AngleLimit360(end);

      const int istart = std::ceil(start / 360.0 * 64);
      const int iend = std::floor(((end > start) ? end : end + 360) / 360 * 64);

      int npoly = 0;

      // Center point
      pt[npoly].x = x;
      pt[npoly].y = y;
      npoly++;

      // first Segment point
      pt[npoly].x = x + (long) (radius * fastsine(start));
      pt[npoly].y = y - (long) (radius * fastcosine(start));
      npoly++;

      for (int i = 0; i < 64; i++) {
          if (i <= iend - istart) {
              pt[npoly].x = x + (long) (radius * xcoords[(i + istart) % 64]);
              pt[npoly].y = y - (long) (radius * ycoords[(i + istart) % 64]);
              npoly++;
          }
      }

      // Last Segment Point
      pt[npoly].x = x + (long) (radius * fastsine(end));
      pt[npoly].y = y - (long) (radius * fastcosine(end));
      npoly++;

      // Close Polygon ( center point )
      pt[npoly].x = x;
      pt[npoly].y = y;
      npoly++;
      
      assert(npoly <= (int)array_size(pt));
      
      Polygon(pt, npoly, rc);
    }
}
Example #22
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 2:				// airfield grass
	case 4:				// glider site
	case 5:				// airfield solid
		flags = AIRPORT;
		flags += LANDPOINT;
		break;
	case 3:				// 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;
}
Example #23
0
static BOOL FLYSEN(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *GPS_INFO)
{

  TCHAR ctemp[80];
  double vtas;
  static int offset=-1;


  // firmware 3.31h no offset
  // firmware 3.32  1 offset
  // Determine firmware version, assuming it will not change in the session!
  if (offset<0) {
	NMEAParser::ExtractParameter(String,ctemp,8);
	if ( (_tcscmp(ctemp,_T("A"))==0) || (_tcscmp(ctemp,_T("V"))==0))
		offset=0;
	else {
		NMEAParser::ExtractParameter(String,ctemp,9);
		if ( (_tcscmp(ctemp,_T("A"))==0) || (_tcscmp(ctemp,_T("V"))==0))
			offset=1;
		else 
			return TRUE;
	}
  }

  // VOID GPS SIGNAL
  NMEAParser::ExtractParameter(String,ctemp,8+offset);
  if (_tcscmp(ctemp,_T("V"))==0) {
	GPS_INFO->NAVWarning=true;
	GPSCONNECT=false;
	goto label_nogps;
  }
  // ------------------------

  double tmplat;
  double tmplon;

  NMEAParser::ExtractParameter(String,ctemp,1+offset);
  tmplat = MixedFormatToDegrees(StrToDouble(ctemp, NULL));
  NMEAParser::ExtractParameter(String,ctemp,2+offset);
  tmplat = NorthOrSouth(tmplat, ctemp[0]);

  NMEAParser::ExtractParameter(String,ctemp,3+offset);
  tmplon = MixedFormatToDegrees(StrToDouble(ctemp, NULL));
  NMEAParser::ExtractParameter(String,ctemp,4+offset);
  tmplon = EastOrWest(tmplon,ctemp[0]);

  if (!((tmplat == 0.0) && (tmplon == 0.0))) {
        GPS_INFO->Latitude = tmplat;
        GPS_INFO->Longitude = tmplon;
	GPS_INFO->NAVWarning=false;
	GPSCONNECT=true;
  }

  // GPS SPEED
  NMEAParser::ExtractParameter(String,ctemp,6+offset);
  GPS_INFO->Speed = StrToDouble(ctemp,NULL)/10;

  // TRACK BEARING
  if (GPS_INFO->Speed>1.0) {
	NMEAParser::ExtractParameter(String,ctemp,5+offset);
	GPS_INFO->TrackBearing = AngleLimit360(StrToDouble(ctemp, NULL));
  }

  // HGPS
  NMEAParser::ExtractParameter(String,ctemp,7+offset);
  GPS_INFO->Altitude = StrToDouble(ctemp,NULL);

  // ------------------------
  label_nogps: 

  // SATS
  NMEAParser::ExtractParameter(String,ctemp,9+offset);
  GPS_INFO->SatellitesUsed = (int) StrToDouble(ctemp,NULL);

  // DATE
  // Firmware 3.32 has got the date 
  if (offset>0) {
	NMEAParser::ExtractParameter(String,ctemp,0);
	long gy, gm, gd;
	TCHAR *Stop;
        gy = _tcstol(&ctemp[4], &Stop, 10) + 2000;
        ctemp[4] = '\0';
        gm = _tcstol(&ctemp[2], &Stop, 10);
        ctemp[2] = '\0';
        gd = _tcstol(&ctemp[0], &Stop, 10);

	if ( ((gy > 1980) && (gy <2100) ) && (gm != 0) && (gd != 0) ) {
		GPS_INFO->Year = gy;
		GPS_INFO->Month = gm;
		GPS_INFO->Day = gd;
	}
  }

  // TIME
  // ignoring 00:00.00
  // And no UTC, since this is local time already.
  NMEAParser::ExtractParameter(String,ctemp,0+offset);
  double fixTime = StrToDouble(ctemp,NULL);
  if (fixTime>0 && GPS_INFO->SatellitesUsed>0) {
	double hours, mins,secs;
	hours = fixTime / 10000;
	GPS_INFO->Hour = (int)hours;
	mins = fixTime / 100;
	mins = mins - (GPS_INFO->Hour*100);
	GPS_INFO->Minute = (int)mins;
	secs = fixTime - (GPS_INFO->Hour*10000) - (GPS_INFO->Minute*100);
	GPS_INFO->Second = (int)secs;
  }


  // HPA from the pressure sensor
  //   NMEAParser::ExtractParameter(String,ctemp,10+offset);
  //   double ps = StrToDouble(ctemp,NULL)/100;
  //   GPS_INFO->BaroAltitude = (1 - pow(fabs(ps / QNH),  0.190284)) * 44307.69;

  // HBAR 1013.25
  NMEAParser::ExtractParameter(String,ctemp,11+offset);
  if (d == pDevPrimaryBaroSource) {
	GPS_INFO->BaroAltitude = AltitudeToQNHAltitude(StrToDouble(ctemp,NULL));
	GPS_INFO->BaroAltitudeAvailable = TRUE;
  }

  // VARIO
  NMEAParser::ExtractParameter(String,ctemp,12+offset);
  GPS_INFO->Vario = StrToDouble(ctemp,NULL)/100;

  // TAS
  NMEAParser::ExtractParameter(String,ctemp,13+offset);
  vtas=StrToDouble(ctemp,NULL)/10;
  GPS_INFO->IndicatedAirspeed = vtas/AirDensityRatio(GPS_INFO->BaroAltitude);
  GPS_INFO->TrueAirspeed = vtas;
  if (GPS_INFO->IndicatedAirspeed >0) 
	GPS_INFO->AirspeedAvailable = TRUE;
  else 
	GPS_INFO->AirspeedAvailable = FALSE;

  // ignore n.14 airspeed source

  // OAT
  NMEAParser::ExtractParameter(String,ctemp,15+offset);
  GPS_INFO->OutsideAirTemperature = StrToDouble(ctemp,NULL);
  GPS_INFO->TemperatureAvailable=TRUE;

  // ignore n.16 baloon temperature  

  // BATTERY PERCENTAGES
  NMEAParser::ExtractParameter(String,ctemp,17+offset);
  GPS_INFO->ExtBatt1_Voltage = StrToDouble(ctemp,NULL)+1000;
  NMEAParser::ExtractParameter(String,ctemp,18+offset);
  GPS_INFO->ExtBatt2_Voltage = StrToDouble(ctemp,NULL)+1000;



  GPS_INFO->VarioAvailable = TRUE;

  // currently unused in LK, but ready for next future
  TriggerVarioUpdate();
  TriggerGPSUpdate();

  return TRUE;
}
Example #24
0
void  MapWindow::RenderNearAirspace(LKSurface& Surface, const RECT rci)
{
RECT rc  = rci; /* rectangle for sideview */
RECT rct = rc; /* rectangle for topview */

rc.top     = (int)((double)(rci.bottom-rci.top  )*fSplitFact);
rct.bottom = rc.top ;
// Expose the topview rect size in use..
Current_Multimap_TopRect=rct;

LKFont	 hfOldFnt = Surface.SelectObject(LK8PanelUnitFont/* Sender->GetFont()*/);

int *iSplit = &Multimap_SizeY[Get_Current_Multimap_Type()];

int  k;
static double fHeigtScaleFact = 1.0;


  double GPSlat, GPSlon, GPSalt, GPSbrg;
  double calc_terrainalt;
  double calc_altitudeagl;

 // double alt;
  TCHAR text[TBSIZE+1];
  TCHAR buffer[TBSIZE+1];

  CAirspaceBase near_airspace;
  CAirspace *found = NULL;
//  bool bFound = false;
  DiagrammStruct sDia;
  bool bAS_Inside=false;
  int iAS_Bearing=0;
  int iAS_HorDistance=15000;
  int iABS_AS_HorDistance=0;
  int iAS_VertDistance=0;
  bool   bValid;
static  bool bHeightScale = false;
  long wpt_brg = 0;
  POINT line[2];
  POINT TxYPt;
  POINT TxXPt;
  SIZE tsize;
  LKColor GREEN_COL     = RGB_GREEN;
  LKColor BLUE_COL      = RGB_BLUE;
  LKColor LIGHTBLUE_COL = RGB_LIGHTBLUE;
  BOOL bInvCol = true; //INVERTCOLORS

  unsigned short getsideviewpage=GetSideviewPage();
  LKASSERT(getsideviewpage<3);

  if(bInvCol)
    Sideview_TextColor = INV_GROUND_TEXT_COLOUR;
  else
    Sideview_TextColor = RGB_WHITE;

	  switch(LKevent) {
		case LKEVENT_NEWRUN:
			// CALLED ON ENTRY: when we select this page coming from another mapspace
			bHeightScale = false;
			// fZOOMScale[getsideviewpage] = 1.0;
			fHeigtScaleFact = 1.0;
			if (IsMultimapTopology()) ForceVisibilityScan=true;
		break;
		case LKEVENT_UP:
			// click on upper part of screen, excluding center
			if(bHeightScale)
			  fHeigtScaleFact /= ZOOMFACTOR;
			else
			  fZOOMScale[getsideviewpage] /= ZOOMFACTOR;

			if (IsMultimapTopology()) ForceVisibilityScan=true;
			break;

		case LKEVENT_DOWN:
			// click on lower part of screen,  excluding center
			if(bHeightScale)
			  fHeigtScaleFact *= ZOOMFACTOR;
			else
		  	  fZOOMScale[getsideviewpage] *= ZOOMFACTOR;
			if (IsMultimapTopology()) ForceVisibilityScan=true;
			break;

		case LKEVENT_LONGCLICK:
		     for (k=0 ; k <= Sideview_iNoHandeldSpaces; k++)
			 {
			   if( Sideview_pHandeled[k].psAS != NULL)
			   {
				 if (PtInRect(&(Sideview_pHandeled[k].rc), startScreen))
				 {	
				   #if 1 // MULTISELECT
				     dlgAddMultiSelectListItem((long*) Sideview_pHandeled[k].psAS, 0, IM_AIRSPACE, 0);
				   #else 	
				     if (EnableSoundModes)PlayResource(TEXT("IDR_WAV_BTONE4"));
				     dlgAirspaceDetails(Sideview_pHandeled[k].psAS);       // dlgA
                   #endif
				   LKevent=LKEVENT_NONE;
				 }
			   }
			 }
			 dlgMultiSelectListShowModal();

		     if ( LKevent != LKEVENT_NONE ) {
			 if (PtInRect(&rc, startScreen))
			   bHeightScale = !bHeightScale;
			 if (PtInRect(&rct, startScreen))
			   bHeightScale = false;
		     }
	     break;

		case LKEVENT_PAGEUP:
#ifdef OFFSET_SETP
			if(bHeightScale)
			  fOffset -= OFFSET_SETP;
			else
#endif
			{
			  if(*iSplit == SIZE1) *iSplit = SIZE0;
			  if(*iSplit == SIZE2) *iSplit = SIZE1;
			  if(*iSplit == SIZE3) *iSplit = SIZE2;
			}
		break;
		case LKEVENT_PAGEDOWN:
#ifdef OFFSET_SETP
			if(bHeightScale)
			  fOffset += OFFSET_SETP;
			else
#endif
			{
			  if(*iSplit == SIZE2) *iSplit = SIZE3;
			  if(*iSplit == SIZE1) *iSplit = SIZE2;
			  if(*iSplit == SIZE0) *iSplit = SIZE1;
			}
		break;

	  }

	  LKASSERT(((*iSplit==SIZE0)||(*iSplit==SIZE1)||(*iSplit==SIZE2)||(*iSplit==SIZE3)||(*iSplit==SIZE4)));

	  LKevent=LKEVENT_NONE;

	  // Current_Multimap_SizeY is global, and must be used by all multimaps!
	  // It is defined in Multimap.cpp and as an external in Multimap.h
	  // It is important that it is updated, because we should resize terrain
	  // only if needed! Resizing terrain takes some cpu and some time.
	  // So we need to know when this is not necessary, having the same size of previous
	  // multimap, if we are switching.
	  // The current implementation is terribly wrong by managing resizing of sideview in
	  // each multimap: it should be done by a common layer.
	  // CAREFUL:
	  // If for any reason DrawTerrain() is called after resizing to 0 (full sideview)
	  // LK WILL CRASH with no hope to recover.
	  if(Current_Multimap_SizeY != *iSplit)
	  {
		Current_Multimap_SizeY=*iSplit;
		SetSplitScreenSize(*iSplit);
		rc.top     = (long)((double)(rci.bottom-rci.top  )*fSplitFact);
		rct.bottom = rc.top ;
	  }


  if(bInvCol)
  {
    GREEN_COL     = GREEN_COL.ChangeBrightness(0.6);
    BLUE_COL      = BLUE_COL.ChangeBrightness(0.6);;
    LIGHTBLUE_COL = LIGHTBLUE_COL.ChangeBrightness(0.4);;
  }

    GPSlat = DrawInfo.Latitude;
    GPSlon = DrawInfo.Longitude;
    GPSalt = DrawInfo.Altitude;
    GPSbrg = DrawInfo.TrackBearing;
    calc_terrainalt  = DerivedDrawInfo.TerrainAlt;
    calc_altitudeagl = DerivedDrawInfo.AltitudeAGL;
    GPSalt =  DerivedDrawInfo.NavAltitude;

  bValid = false;
  iAS_HorDistance = 5000;
  iAS_Bearing     = (int)GPSbrg;
  iAS_VertDistance= 0;
  found = CAirspaceManager::Instance().GetNearestAirspaceForSideview();
  if(found != NULL) {
    near_airspace = CAirspaceManager::Instance().GetAirspaceCopy(found);
    bValid = near_airspace.GetDistanceInfo(bAS_Inside, iAS_HorDistance, iAS_Bearing, iAS_VertDistance);
  }
  iABS_AS_HorDistance = abs( iAS_HorDistance);
  wpt_brg = (long)AngleLimit360(GPSbrg - iAS_Bearing + 90.0);


  // Variables from ASP system here contain the following informations:
  // fAS_HorDistance - always contains horizontal distance from the asp, negative if horizontally inside (This does not mean that we're inside vertically as well!)
  // fAS_Bearing - always contains bearing to the nearest horizontal point
  // bValid - true if bAS_Inside, iAS_HorDistance, iAS_Bearing, iAS_VertDistance contains valid informations
  //          this will be true if the asp border is close enough to be tracked by the warning system
  // bAS_Inside - current position is inside in the asp, calculated by the warning system
  // iAS_HorDistance - horizontal distance to the nearest horizontal border, negative if horizontally inside, calculated by the warning system
  // iAS_Bearing - bearing to the nearest horizontal border, calculated by the warning system
  // iAS_VertDistance - vertical distance to the nearest asp border, negative if the border is above us, positive if the border below us, calculated by the warning system
  // near_airspace.WarningLevel():
  //           awNone - no warning condition exists
  //           awYellow - current position is near to a warning position
  //           awRed - current posisiton is forbidden by asp system, we are in a warning position


  /*********************************************************************
   * calc the horizontal zoom
   *********************************************************************/
  sDia.fXMin = -5000.0;
  sDia.fXMax =  5000.0;
  /* even when invalid the horizontal distance is calculated correctly */


  if(bValid)
  {
	double fScaleDist = iABS_AS_HorDistance;

	sDia.fXMin = min(-2500.0 , fScaleDist * 1.5 );
	sDia.fXMax = max( 2500.0 , fScaleDist * 1.5 );

	#ifdef NEAR_AS_ZOOM_1000M
	if(((iABS_AS_HorDistance) < 900) && (bValid)) // 1km zoom
	{
	  sDia.fXMin = min(-900.0, fScaleDist * 1.5 );
	  sDia.fXMax = max( 900.0, fScaleDist * 1.5 );

	}
	#endif
	#ifdef NEAR_AS_ZOOM_1000FT
	  if((abs(iABS_AS_HorDistance) < 333)) // 1000ft zoom
	  {
		sDia.fXMin = min(-333.0, fScaleDist * 1.5 );
		sDia.fXMax = max( 333.0, fScaleDist * 1.5 );
	  }
	#endif

  }


#define RND_FACT 10.0


   if( ( sDia.fXMax  *fZOOMScale[getsideviewpage]) > 100000)
	  fZOOMScale[getsideviewpage] /= ZOOMFACTOR;

   if(( sDia.fXMax *fZOOMScale[getsideviewpage]) < 500)
   {
	  fZOOMScale[getsideviewpage] *= ZOOMFACTOR;
   }

  double fOldZoomScale=-1;
  if(fZOOMScale[getsideviewpage] != fOldZoomScale)
  {
   fOldZoomScale =  fZOOMScale[getsideviewpage];
   sDia.fXMax = sDia.fXMax *fZOOMScale[getsideviewpage];
   sDia.fXMin = -sDia.fXMax /5;
  }


  /*********************************************************************
   * calc the vertical zoom
   *********************************************************************/
sDia.fYMin = max(0.0, GPSalt-2300);
sDia.fYMax = max(MAXALTTODAY, GPSalt+1000);

if(bValid)
{
  double fBottom = near_airspace.Base()->Altitude;
  sDia.fYMin = min(fBottom*0.8, sDia.fYMin );
  sDia.fYMin = max(0.0, sDia.fYMin );
  if(sDia.fYMin < 300) sDia.fYMin =0;
  sDia.fYMax = max((fBottom*1.2f), sDia.fYMax );

  if(abs(iAS_VertDistance) < 250)
  {
    sDia.fYMax =  ((int)((GPSalt+abs(iAS_VertDistance))/400) + 2) *400 ;
    sDia.fYMin =  ((int)((GPSalt-abs(iAS_VertDistance))/400) - 1) *400 ;
    if(sDia.fYMin-MIN_ALTITUDE < 0) sDia.fYMin = 0;
  }

#ifdef VERTICAL_ZOOM_50
  if(abs(iAS_VertDistance) < 50)
  {
    sDia.fYMax =  ((int)((GPSalt+abs(iAS_VertDistance))/100) + 2) *100 ;
    sDia.fYMin =  ((int)((GPSalt-abs(iAS_VertDistance))/100) - 1) *100 ;
    if(sDia.fYMin-MIN_ALTITUDE < 0) sDia.fYMin = 0;
  }
#endif
  sDia.fYMin = max((double)0.0f,(double) sDia.fYMin);

#ifdef OFFSET_SETP
	  if(( sDia.fYMax + fOffset) > MAX_ALTITUDE)
		fOffset -= OFFSET_SETP;
	  if(( sDia.fYMin + fOffset) < 0.0)
		fOffset += OFFSET_SETP;

	  sDia.fYMin +=  fOffset;
	  sDia.fYMax +=  fOffset;
#endif
//  if(fHeigtScaleFact * sDia.fYMax > MAX_ALTITUDE )
//    fHeigtScaleFact /=ZOOMFACTOR;

  if(fHeigtScaleFact * sDia.fYMax < MIN_ALTITUDE )
	  fHeigtScaleFact *=ZOOMFACTOR;
  sDia.fYMax *= fHeigtScaleFact;
}


/****************************************************************************************************
 * draw topview first
 ****************************************************************************************************/

  if(fSplitFact > 0.0)
  {
    sDia.rc = rct;
    sDia.rc.bottom-=1;
    SharedTopView(Surface, &sDia, (double) iAS_Bearing, (double) wpt_brg);

  }

  /****************************************************************************************************
   * draw airspace and terrain elements
   ****************************************************************************************************/
  RECT rcc = rc;          /* rc corrected      */
  if(sDia.fYMin < GC_SEA_LEVEL_TOLERANCE)
    rcc.bottom -= SV_BORDER_Y; /* scale witout sea  */
  sDia.rc = rcc;

  RenderAirspaceTerrain(Surface, GPSlat, GPSlon, iAS_Bearing, &sDia );

  LKFont hfOld = Surface.SelectObject(LK8InfoNormalFont);
  if(bValid) {
    LKASSERT(_tcslen(near_airspace.Name())<TBSIZE); // Diagnostic only in 3.1j, to be REMOVED
    LK_tcsncpy(Sideview_szNearAS, near_airspace.Name(), TBSIZE );
  } else
  {
	_stprintf(text,TEXT("%s"), MsgToken(1259)); 	 // LKTOKEN _@M1259_ "Too far, not calculated"
	Surface.GetTextSize(text, _tcslen(text), &tsize);
	TxYPt.x = (rc.right-rc.left-tsize.cx)/2;
	TxYPt.y = (rc.bottom-rc.top)/2;

	Surface.SetBkMode(TRANSPARENT);
	Surface.DrawText(TxYPt.x, TxYPt.y-20, text, _tcslen(text));

	_stprintf(Sideview_szNearAS,TEXT("%s"), text);

  }
  Surface.SelectObject(hfOld);
  /****************************************************************************************************
   * draw airspace and terrain elements
   ****************************************************************************************************/

  /****************************************************************************************************
   * draw diagram
   ****************************************************************************************************/
  double xtick = 1.0;
  double fRange =fabs(sDia.fXMax - sDia.fXMin) ;
  if (fRange>3.0*1000.0) xtick = 2.0;
  if (fRange>15*1000.0) xtick = 5.0;
  if (fRange>50.0*1000.0) xtick = 10.0;
  if (fRange>100.0*1000.0) xtick = 20.0;
  if (fRange>200.0*1000.0) xtick = 25.0;
  if (fRange>250.0*1000.0) xtick = 50.0;
  if (fRange>500.0*1000.0) xtick = 100.0;
  if (fRange>1000.0*1000.0) xtick = 1000.0;

  if(bInvCol)
  {
    Surface.SelectObject(LK_BLACK_PEN);
    Surface.SelectObject(LKBrush_Black);
  }
  else
  {
    Surface.SelectObject(LK_WHITE_PEN);
    Surface.SelectObject(LKBrush_White);
  }

  LKColor txtCol = GROUND_TEXT_COLOUR;
  if(bInvCol)
    if(sDia.fYMin > GC_SEA_LEVEL_TOLERANCE)
    	txtCol = INV_GROUND_TEXT_COLOUR;
  Surface.SetBkMode(TRANSPARENT);
  Surface.SetTextColor(txtCol);
  _stprintf(text, TEXT("%s"),Units::GetUnitName(Units::GetUserDistanceUnit()));

  switch(GetMMNorthUp(getsideviewpage))
  {
	 case NORTHUP:
	 default:
	   DrawXGrid(Surface, rc , xtick/DISTANCEMODIFY, xtick, 0,TEXT_ABOVE_LEFT, RGB_BLACK,  &sDia,text);
     break;

	 case TRACKUP:
	   DrawXGrid(Surface, rci, xtick/DISTANCEMODIFY, xtick, 0,TEXT_ABOVE_LEFT, RGB_BLACK,  &sDia,text);
     break;
  }

  Surface.SetTextColor(Sideview_TextColor);

  double  fHeight = (sDia.fYMax-sDia.fYMin);
  double  ytick = 100.0;
  if (fHeight >500.0) ytick = 200.0;
  if (fHeight >1000.0) ytick = 500.0;
  if (fHeight >2000.0) ytick = 1000.0;
  if (fHeight >4000.0) ytick = 2000.0;
  if (fHeight >8000.0) ytick = 4000.0;

  if(Units::GetUserAltitudeUnit() == unFeet)
	 ytick = ytick * FEET_FACTOR;

  _stprintf(text, TEXT("%s"),Units::GetUnitName(Units::GetUserAltitudeUnit()));
  if(sDia.fYMin < GC_SEA_LEVEL_TOLERANCE)
	  rc.bottom -= SV_BORDER_Y; /* scale witout sea  */
  DrawYGrid(Surface, rc, ytick/ALTITUDEMODIFY,ytick, 0,TEXT_UNDER_RIGHT ,Sideview_TextColor,  &sDia, text);


  if(!bInvCol)
    Surface.SetBkMode(OPAQUE);
  /****************************************************************************************************
   * draw AGL
   ****************************************************************************************************/
  if(calc_altitudeagl - sDia.fYMin  > 500)
  {
    Surface.SetTextColor(LIGHTBLUE_COL);
    Units::FormatUserAltitude(calc_altitudeagl, buffer, 7);
    LK_tcsncpy(text, MsgToken(1742), TBSIZE-_tcslen(buffer)); // AGL:
    _tcscat(text,buffer);
    Surface.GetTextSize(text, _tcslen(text), &tsize);
    TxYPt.x = CalcDistanceCoordinat(0,  &sDia)- tsize.cx/2;
    TxYPt.y  = CalcHeightCoordinat(  (calc_terrainalt + calc_altitudeagl )*0.8,  &sDia );
    if((tsize.cy) < ( CalcHeightCoordinat(  calc_terrainalt, &sDia )- TxYPt.y )) {
      Surface.DrawText(TxYPt.x+IBLSCALE(1),  TxYPt.y , text, _tcslen(text));
    }
  }

  Surface.SetBkMode(TRANSPARENT);

  /****************************************************************************************************
   * Print current Elevation
   ****************************************************************************************************/
  Surface.SetTextColor(RGB_BLACK);
  int x,y;
  if((calc_terrainalt-  sDia.fYMin)  > 0)
  {
	Units::FormatUserAltitude(calc_terrainalt, buffer, 7);
    LK_tcsncpy(text, MsgToken(1743), TBSIZE-_tcslen(buffer));   // ELV:
    _tcscat(text,buffer);
    Surface.GetTextSize(text, _tcslen(text), &tsize);
    x = CalcDistanceCoordinat(0, &sDia) - tsize.cx/2;
    y = CalcHeightCoordinat( calc_terrainalt,  &sDia  );
    if ((ELV_FACT*tsize.cy) < abs(rc.bottom - y)) {
      Surface.DrawText(x, rc.bottom -(int)(ELV_FACT * tsize.cy), text, _tcslen(text));
    }
  }


  /****************************************************************************************************
   * draw side elements
   ****************************************************************************************************/
  Surface.SetTextColor(Sideview_TextColor);
  Surface.SetBkMode(OPAQUE);
  LKFont hfOld2 = Surface.SelectObject(LK8InfoNormalFont);

  //  DrawTelescope      ( hdc, iAS_Bearing-90.0, rc.right  - NIBLSCALE(13),  rc.top   + NIBLSCALE(58));

  Surface.SelectObject(hfOld2);
  Surface.SetBkMode(TRANSPARENT);

  Surface.SelectObject(hfOld);
  Surface.SetTextColor(GROUND_TEXT_COLOUR);
  if(bInvCol)
    if(sDia.fYMin > GC_SEA_LEVEL_TOLERANCE)
	  Surface.SetTextColor(INV_GROUND_TEXT_COLOUR);



  /****************************************************************************************************/
  /****************************************************************************************************/
  /****************************************************************************************************
   * draw distances to next airspace
   ****************************************************************************************************/
  /****************************************************************************************************/
  /****************************************************************************************************/
  if (bValid)
  {

	/****************************************************************************************************
	 * draw horizontal distance to next airspace
	 ****************************************************************************************************/
	Surface.SetTextColor(Sideview_TextColor);
	Surface.SetBkMode(OPAQUE);
	LKFont hfOldU = Surface.SelectObject(LK8InfoNormalFont);
    // horizontal distance
    line[0].x = CalcDistanceCoordinat(0, &sDia);
    line[0].y = CalcHeightCoordinat(  GPSalt,  &sDia );
    line[1].x = CalcDistanceCoordinat(iABS_AS_HorDistance, &sDia);
    line[1].y = line[0].y;
    Surface.DrawDashLine(THICK_LINE, line[0], line[1],  Sideview_TextColor, rc);
    if(iAS_HorDistance < 0)
    {
      line[0].y = CalcHeightCoordinat(  GPSalt - (double)iAS_VertDistance, &sDia );
      line[1].y = line[0].y;

      Surface.DrawDashLine(THICK_LINE, line[0], line[1],  Sideview_TextColor, rc);
    }

    bool bLeft = false;
    if( line[0].x < line[1].x)
      bLeft = false;
    else
      bLeft = true;

    Units::FormatUserDistance(iABS_AS_HorDistance, buffer, 7);
    _stprintf(text,_T(" %s"),buffer);
    Surface.GetTextSize(text, _tcslen(text), &tsize);

    if((GPSalt- sDia.fYMin /*-calc_terrainalt */) < 300)
      TxXPt.y = CalcHeightCoordinat(  GPSalt, &sDia ) -  tsize.cy;
    else
      TxXPt.y = CalcHeightCoordinat(  GPSalt, &sDia ) +  NIBLSCALE(3);


    if(tsize.cx > (line[1].x - line[0].x) )
      TxXPt.x = CalcDistanceCoordinat( iABS_AS_HorDistance ,&sDia) -tsize.cx-  NIBLSCALE(3);
    else
      TxXPt.x = CalcDistanceCoordinat( iABS_AS_HorDistance / 2.0, &sDia) -tsize.cx/2;
    Surface.DrawText(TxXPt.x,  TxXPt.y, text, _tcslen(text));



	/****************************************************************************************************
	 * draw vertical distance to next airspace
	 ****************************************************************************************************/
    line[0].x = CalcDistanceCoordinat( iABS_AS_HorDistance , &sDia);
    line[0].y = CalcHeightCoordinat( GPSalt, &sDia );
    line[1].x = line[0].x;
    line[1].y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance, &sDia );

    Surface.DrawDashLine(THICK_LINE, line[0], line[1],  Sideview_TextColor, rc);
    Units::FormatUserAltitude( (double)abs(iAS_VertDistance), buffer, 7);
    _stprintf(text,_T(" %s"),buffer);
    Surface.GetTextSize(text, _tcslen(text), &tsize);

    if ( bLeft )
      TxYPt.x = CalcDistanceCoordinat(iABS_AS_HorDistance,  &sDia)- tsize.cx - NIBLSCALE(3);
    else
      TxYPt.x = CalcDistanceCoordinat(iABS_AS_HorDistance,  &sDia)+ NIBLSCALE(5);
    if( abs( line[0].y -  line[1].y) > tsize.cy)
      TxYPt.y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance/2.0, &sDia) -tsize.cy/2 ;
    else
      TxYPt.y = min( line[0].y ,  line[1].y) - tsize.cy ;
    Surface.DrawText(TxYPt.x,  TxYPt.y , text, _tcslen(text));
	Surface.SelectObject(hfOldU);
  }

 /****************************************************************************************************
  * draw plane sideview at least
  ****************************************************************************************************/
  RenderPlaneSideview(Surface, 0.0 , GPSalt,wpt_brg, &sDia );

  hfOldFnt = Surface.SelectObject(LK8InfoNormalFont/* Sender->GetFont()*/);

  DrawMultimap_SideTopSeparator(Surface,rct);

  /****************************************************************************************************
   * draw selection frame
   ****************************************************************************************************/
  if(bHeightScale)
	DrawSelectionFrame(Surface,  rc);
#ifdef TOP_SELECTION_FRAME
  else
	DrawSelectionFrame(hdc,  rci);
#endif
  Surface.SelectObject(hfOldFnt/* Sender->GetFont()*/);
  Surface.SetBkMode(TRANSPARENT);
  Surface.SelectObject(hfOldFnt/* Sender->GetFont()*/);
}
Example #25
0
void DistanceBearing(double lat1, double lon1, double lat2, double lon2,
                     double *Distance, double *Bearing) {

// incomplete, test does not show benefits, low hits
#if (LK_CACHECALC && LK_CACHECALC_DBE)
  #define CASIZE_DBE 50
  static bool doinit=true;
  static int  cacheIndex;
  static double cur_checksum;
  static double cur_lat1, cur_lat2, cur_lon1, cur_lon2;
  bool cacheFound;
  int i;

  static double cache_checksum[CASIZE_DBE];
  static double cache_lat1[CASIZE_DBE];
  static double cache_lat2[CASIZE_DBE];
  static double cache_lon1[CASIZE_DBE];
  static double cache_lon2[CASIZE_DBE];
  static double cache_Distance[CASIZE_DBE];
  static double cache_Bearing[CASIZE_DBE];

  if (doinit) {
	cacheIndex=0;
	for (i=0; i<CASIZE_DBE; i++) {
		cache_checksum[i]=0;
		cache_lat1[i]=0;
		cache_lat2[i]=0;
		cache_lon1[i]=0;
		cache_lon2[i]=0;
		cache_Distance[i]=0;
		cache_Bearing[i]=0;
	}
	doinit=false;
  }

  Cache_Calls_DBE++;
  cur_checksum=lat1+lat2+lon1+lon2;
  cacheFound=false;

  for (i=0; i<CASIZE_DBE; i++) {
	if ( cache_checksum[i] != cur_checksum ) continue;
	if ( cache_lat1[i] != lat1 ) {
		Cache_False_DBE++;
		continue;
	}
	if ( cache_lat2[i] != lat2 ) {
		Cache_False_DBE++;
		continue;
	}
	if ( cache_lon1[i] != lon1 ) {
		Cache_False_DBE++;
		continue;
	}
	if ( cache_lon2[i] != lon2 ) {
		Cache_False_DBE++;
		continue;
	}
	cacheFound=true;
	break;
  }

  if (cacheFound) {
	Cache_Hits_DBE++;
  }  else {
	cur_lat1=lat1;
	cur_lat2=lat2;
	cur_lon1=lon1;
	cur_lon2=lon2;
  }
#endif
   

  lat1 *= DEG_TO_RAD;
  lat2 *= DEG_TO_RAD;
  lon1 *= DEG_TO_RAD;
  lon2 *= DEG_TO_RAD;

  double clat1 = cos(lat1);
  double clat2 = cos(lat2);
  double dlon = lon2-lon1;

  if (Distance) {
    double s1 = sin((lat2-lat1)/2);
    double s2 = sin(dlon/2);
    double a= max(0.0,min(1.0,s1*s1+clat1*clat2*s2*s2));
    *Distance = 6371000.0*2.0*atan2(sqrt(a),sqrt(1.0-a));
  }
  if (Bearing) {
    double y = sin(dlon)*clat2;
    double x = clat1*sin(lat2)-sin(lat1)*clat2*cos(dlon);
    *Bearing = (x==0 && y==0) ? 0:AngleLimit360(atan2(y,x)*RAD_TO_DEG);
  }

#if (LK_CACHECALC && LK_CACHECALC_DBE)
  if (!cacheFound) {
	if (++cacheIndex==CASIZE_DBE) cacheIndex=0;
	cache_checksum[cacheIndex]=cur_checksum;
	cache_lat1[cacheIndex]=cur_lat1;
	cache_lat2[cacheIndex]=cur_lat2;
	cache_lon1[cacheIndex]=cur_lon1;
	cache_lon2[cacheIndex]=cur_lon2;
  }
#endif

}
Example #26
0
void MapWindow::DrawWindAtAircraft2(LKSurface& Surface, const POINT& Orig, const RECT& rc) {
  int i;
  POINT Start;
  TCHAR sTmp[12];
  static SIZE tsize = {0,0};
  
  if (DerivedDrawInfo.WindSpeed<1) {
    return; // JMW don't bother drawing it if not significant
  }
  
  if (tsize.cx == 0){

    const auto oldFont = Surface.SelectObject(MapWindowBoldFont);
    Surface.GetTextSize(TEXT("99"), 2, &tsize);
    Surface.SelectObject(oldFont);
    tsize.cx = tsize.cx/2;
  }

  int wmag = iround(4.0*DerivedDrawInfo.WindSpeed);
  
  Start.y = Orig.y;
  Start.x = Orig.x;

  int kx = tsize.cx/ScreenScale/2;

  POINT Arrow[7] = { {0,-20}, {-6,-26}, {0,-20}, 
                     {6,-26}, {0,-20}, 
                     {8+kx, -24}, 
                     {-8-kx, -24}};

  for (i=1;i<4;i++)
    Arrow[i].y -= wmag;

  PolygonRotateShift(Arrow, 7, Start.x, Start.y, 
		     DerivedDrawInfo.WindBearing-DisplayAngle);

  //
  // Draw Wind Arrow
  //
  POINT Tail[2] = {{0,-20}, {0,-26-min(20,wmag)*3}};
  double angle = AngleLimit360(DerivedDrawInfo.WindBearing-DisplayAngle);
  for(i=0; i<2; i++) {
    if (ScreenScale>1) {
      Tail[i].x *= ScreenScale;
      Tail[i].y *= ScreenScale;
    }
    protateshift(Tail[i], angle, Start.x, Start.y);
  }
  // optionally draw dashed line for wind arrow
  Surface.DrawLine(PEN_DASH, 1, Tail[0], Tail[1], LKColor(0,0,0), rc);

  // Paint wind value only while circling
  if ( (mode.Is(Mode::MODE_CIRCLING)) ) {

    _stprintf(sTmp, _T("%d"), iround(DerivedDrawInfo.WindSpeed * SPEEDMODIFY));

    TextInBoxMode_t TextInBoxMode = {0};
    TextInBoxMode.AlligneCenter = true;   // { 16 | 32 }; // JMW test {2 | 16};
    TextInBoxMode.WhiteBorder = true;
    if (Arrow[5].y>=Arrow[6].y) {
      TextInBox(Surface, &rc, sTmp, Arrow[5].x-kx, Arrow[5].y, 0, &TextInBoxMode);
    } else {
      TextInBox(Surface, &rc, sTmp, Arrow[6].x-kx, Arrow[6].y, 0, &TextInBoxMode);
    }
  }
  const auto hpOld = Surface.SelectObject(LKPen_Black_N2);
  const auto hbOld = Surface.SelectObject(LKBrush_Grey);
  Surface.Polygon(Arrow,5);

  Surface.SelectObject(hbOld);
  Surface.SelectObject(hpOld);
}