void MapWindow::DrawWaypointsNew(HDC hdc, const RECT rc) { unsigned int i; int bestwp=-1; TCHAR Buffer[LKSIZEBUFFER]; TCHAR Buffer2[LKSIZEBUFFER]; TCHAR sAltUnit[LKSIZEBUFFERUNIT]; TextInBoxMode_t TextDisplayMode = {0}; static int resizer[10]={ 20,20,20,3,5,8,10,12,0 }; // if pan mode, show full names int pDisplayTextType = DisplayTextType; if (!WayPointList) return; _tcscpy(sAltUnit, Units::GetAltitudeName()); MapWaypointLabelListCount = 0; int arrivalcutoff=0, foundairport=0; bool isairport; bool islandpoint; // setting decluttericons will not paint outlanding, and use minrunway to declutter even more bool decluttericons=false; // inrange : max scale allowed to print non-landable waypoints bool inrange=true; // minimal size of a runway to paint it while decluttering int minrunway=0; // // RealScale // // 2km 1.42 // 3.5km 2.5 // 5km 3.57 // 7.5km 5.35 // 10km 7.14 // 15km 10.71 // 20km 14.28 // 25km 17.85 // 40km 28.57 // 50km 35.71 // 75km 53.57 switch(DeclutterMode) { case dmDisabled: //inrange=(MapWindow::zoom.RealScale() <=18 ? true:false); // 17.85, 25km scale inrange=(MapWindow::zoom.RealScale() <=15 ? true:false); // 14.28, 20km scale decluttericons=false; break; case dmLow: inrange=(MapWindow::zoom.RealScale() <=11 ? true:false); // 10.71, 15km scale decluttericons=(MapWindow::zoom.RealScale() >=14 ? true : false); minrunway=200; break; case dmMedium: inrange=(MapWindow::zoom.RealScale() <=10 ? true:false); decluttericons=(MapWindow::zoom.RealScale() >=10 ? true : false); minrunway=400; break; case dmHigh: inrange=(MapWindow::zoom.RealScale() <=10 ? true:false); decluttericons=(MapWindow::zoom.RealScale() >=10 ? true : false); minrunway=800; break; case dmVeryHigh: inrange=(MapWindow::zoom.RealScale() <=10 ? true:false); decluttericons=(MapWindow::zoom.RealScale() >=10 ? true : false); minrunway=1600; break; default: LKASSERT(0); break; } if (MapWindow::zoom.RealScale() <=20) for(i=0;i<NumberOfWayPoints;i++) { if (WayPointList[i].Visible != TRUE ) continue; // false may not be FALSE? if (WayPointCalc[i].IsAirport) { if (WayPointList[i].Reachable == FALSE) { SelectObject(hDCTemp,hBmpAirportUnReachable); } else { SelectObject(hDCTemp,hBmpAirportReachable); if ( arrivalcutoff < (int)(WayPointList[i].AltArivalAGL)) { arrivalcutoff = (int)(WayPointList[i].AltArivalAGL); bestwp=i; foundairport++; } } } else { if ( WayPointCalc[i].IsOutlanding ) { // outlanding if (WayPointList[i].Reachable == FALSE) SelectObject(hDCTemp,hBmpFieldUnReachable); else { SelectObject(hDCTemp,hBmpFieldReachable); // get the outlanding as bestwp only if no other choice if (foundairport == 0) { // do not set arrivalcutoff: any next reachable airport is better than an outlanding if ( arrivalcutoff < (int)(WayPointList[i].AltArivalAGL)) bestwp=i; } } } else continue; // do not draw icons for normal turnpoints here } if(Appearance.IndLandable == wpLandableDefault) { double fScaleFact =MapWindow::zoom.RealScale(); if(fScaleFact < 0.1) fScaleFact = 0.1; // prevent division by zero fScaleFact = zoom.DrawScale(); if(fScaleFact > 20000.0) fScaleFact = 20000.0; // limit to prevent huge airfiel symbols if(fScaleFact < 1600) fScaleFact = 1600; // limit to prevent tiny airfiel symbols if (decluttericons) { if (WayPointCalc[i].IsAirport && (WayPointList[i].RunwayLen>minrunway || WayPointList[i].RunwayLen==0)) { DrawRunway(hdc,&WayPointList[i],rc, fScaleFact); } } else DrawRunway(hdc,&WayPointList[i],rc, fScaleFact); } else { DrawBitmapX(hdc, WayPointList[i].Screen.x-10, WayPointList[i].Screen.y-10, 20,20, hDCTemp,0,0,SRCPAINT,false); DrawBitmapX(hdc, WayPointList[i].Screen.x-10, WayPointList[i].Screen.y-10, 20,20, hDCTemp,20,0,SRCAND,false); } } // for all waypoints if (foundairport==0 && bestwp>=0) arrivalcutoff = (int)WayPointList[bestwp].AltArivalAGL; for(i=0;i<NumberOfWayPoints;i++) { if(WayPointList[i].Visible ) { bool irange = false; bool intask = false; bool islandable; // isairport+islandpoint bool excluded=false; bool dowrite; intask = WaypointInTask(i); dowrite = intask; // initially set only for intask memset((void*)&TextDisplayMode, 0, sizeof(TextDisplayMode)); // airports are also landpoints. should be better handled isairport=((WayPointList[i].Flags & AIRPORT) == AIRPORT); islandpoint=((WayPointList[i].Flags & LANDPOINT) == LANDPOINT); islandable=WayPointCalc[i].IsLandable; // always in range if MapScale <=10 irange = inrange; if(MapWindow::zoom.RealScale() > 20) { SelectObject(hDCTemp,hInvSmall); irange=false; goto NiklausWirth; // with compliments } if (decluttericons) { if (! (WayPointCalc[i].IsAirport && (WayPointList[i].RunwayLen>minrunway || WayPointList[i].RunwayLen==0))) { SelectObject(hDCTemp,hInvSmall); irange=false; goto NiklausWirth; } } if( islandable ) { if(WayPointList[i].Reachable){ TextDisplayMode.Reachable = 1; if ( isairport ) SelectObject(hDCTemp,hBmpAirportReachable); else SelectObject(hDCTemp,hBmpFieldReachable); if ((GetMultimap_Labels()<MAPLABELS_ALLOFF)||intask) { dowrite = true; // exclude outlandings worst than visible airports, only when there are visible reachable airports! if ( isairport==false && islandpoint==true ) { if ( (int)WayPointList[i].AltArivalAGL >=2000 ) { // more filter excluded=true; } else { if ( (bestwp>=0) && (i==(unsigned)bestwp) && (foundairport==0) ) { // this outlanding is the best option isairport=true; islandpoint=false; // make it an airport TODO paint it as best } else { if ( foundairport >0 ) { if ( (int)WayPointList[i].AltArivalAGL <= arrivalcutoff ) { excluded=true; } } } } } else // do not display airport arrival if close to the best so far. // ex: best arrival is 1200m, include onlye below 1200/4 (prevent division by zero) // This way we only display far points, and skip closer points // WE NEED MORE INFO ABOUT LANDING POINTS: THE .CUP FORMAT WILL LET US KNOW WHAT IS // BEST TO SHOW AND WHAT IS NOT. Winpilot format is useless here. { dowrite=true;// TEST FIX not necessary probably // it's an airport if ( (bestwp>=0) && (i != (unsigned)bestwp) && (arrivalcutoff>600) ) { if ( (arrivalcutoff / ((int)WayPointList[i].AltArivalAGL+1))<4 ) { excluded=true; } } } } } else // landable waypoint is unreachable { dowrite=true; if ( isairport ) { SelectObject(hDCTemp,hBmpAirportUnReachable); } else { SelectObject(hDCTemp,hBmpFieldUnReachable); } } } else { // waypoint is an ordinary turnpoint if(MapWindow::zoom.RealScale() > 4) { if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); } } // end landable-not landable NiklausWirth: if (intask || (OutlinedTp==(OutlinedTp_t)otAll) ) { TextDisplayMode.WhiteBold = 1; TextDisplayMode.Color=RGB_WHITE; } // No matter of how we thought to draw it, let it up to the user.. switch(NewMapDeclutter) { case 0: excluded=false; // no decluttering: show all airports and outlandings break; case 1: if ( isairport ) excluded=false; // show all airports, declutter outlandings break; default: break; // else work normally } // here come both turnpoints and landables.. if( intask || irange || dowrite) { // irange always set when MapScale <=10 bool draw_alt = TextDisplayMode.Reachable && ((GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask); // 100711 reachable landing point! if (excluded==true) draw_alt=false; // exclude close outlandings switch(pDisplayTextType) { case DISPLAYNAME: case DISPLAYFIRSTTHREE: case DISPLAYFIRSTFIVE: case DISPLAYFIRST8: case DISPLAYFIRST10: case DISPLAYFIRST12: dowrite = (GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask || islandable; // 100711 if ( (islandable && !isairport) && MapWindow::zoom.RealScale() >=10 ) dowrite=0; // FIX then no need to go further // 101215 if (DisplayTextType == DISPLAYNAME) { _tcscpy(Buffer2,WayPointList[i].Name); } else { LK_tcsncpy(Buffer2, WayPointList[i].Name, resizer[DisplayTextType]); } // ConvToUpper(Buffer2); if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%s:%d"), Buffer2, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%s:%d%s"), Buffer2, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%s:%d"), Buffer2, (int)WayPointCalc[i].GR); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { //wsprintf(Buffer, TEXT("%s"),Buffer2); _tcscpy(Buffer,Buffer2); if (islandable && isairport) { TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } } break; case DISPLAYNUMBER: dowrite = (GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask || islandable; if ( (islandable && !isairport) && MapWindow::zoom.RealScale() >=10 ) dowrite=0; // FIX then no need to go further if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%d:%d"), WayPointList[i].Number, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%d:%d%s"), WayPointList[i].Number, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%d:%d"), WayPointList[i].Number, (int)(WayPointCalc[i].GR)); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { wsprintf(Buffer, TEXT("%d"),WayPointList[i].Number); if (islandable && isairport) { TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } } break; case DISPLAYNAMEIFINTASK: dowrite = intask; if (intask) { if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%s:%d"), WayPointList[i].Name, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%s:%d%s"), WayPointList[i].Name, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%s:%d"), WayPointList[i].Name, (int)(WayPointCalc[i].GR)); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { wsprintf(Buffer, TEXT("%s"),WayPointList[i].Name); // TODO CHECK THIS, UNTESTED.. if (islandable && isairport) { TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } } } else { wsprintf(Buffer, TEXT(" ")); dowrite=true; } break; case DISPLAYNONE: dowrite = (GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask || islandable; if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%d"), (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%d%s"), (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%d"), (int)(WayPointCalc[i].GR) ); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { wsprintf(Buffer, TEXT(" ")); } break; default: #if (WINDOWSPC<1) //ASSERT(0); #endif break; } // end intask/irange/dowrite if (MapWindow::zoom.RealScale()<20 && islandable && dowrite) { TextInBox(hdc, &rc, Buffer, WayPointList[i].Screen.x+5, WayPointList[i].Screen.y, 0, &TextDisplayMode, true); dowrite=false; // do not pass it along } // Do not show takeoff for gliders, check TakeOffWayPoint if (i==RESWP_TAKEOFF) { if (TakeOffWayPoint) { intask=false; // 091031 let TAKEOFF be decluttered WayPointList[i].Visible=TRUE; } else { WayPointList[i].Visible=FALSE; dowrite=false; } } if(i==RESWP_OPTIMIZED) { dowrite = DoOptimizeRoute(); } if (dowrite) { MapWaypointLabelAdd( Buffer, WayPointList[i].Screen.x+5, WayPointList[i].Screen.y, &TextDisplayMode, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), intask,islandable,isairport,excluded,i,WayPointList[i].Style); } } // end if intask { ; } } // if visible } // for all waypoints qsort(&MapWaypointLabelList, MapWaypointLabelListCount, sizeof(MapWaypointLabel_t), MapWaypointLabelListCompare); int j; // now draw task/landable waypoints in order of range (closest last) // writing unconditionally for (j=MapWaypointLabelListCount-1; j>=0; j--){ MapWaypointLabel_t *E = &MapWaypointLabelList[j]; // draws if they are in task unconditionally, // otherwise, does comparison if ( E->inTask || (E->isLandable && !E->isExcluded) ) { TextInBox(hdc, &rc, E->Name, E->Pos.x, E->Pos.y, 0, &(E->Mode), false); // At low zoom, dont print the bitmap because drawn task would make it look offsetted if(MapWindow::zoom.RealScale() > 2) continue; // If we are at low zoom, use a dot for icons, so we dont clutter the screen if(MapWindow::zoom.RealScale() > 1) { if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); } DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,0,0,SRCPAINT,false); DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,20,0,SRCAND,false); } // wp in task } // for all waypoint, searching for those in task // now draw normal waypoints in order of range (furthest away last) // without writing over each other (or the task ones) for (j=0; j<MapWaypointLabelListCount; j++) { MapWaypointLabel_t *E = &MapWaypointLabelList[j]; if (!E->inTask && !E->isLandable ) { if ( TextInBox(hdc, &rc, E->Name, E->Pos.x, E->Pos.y, 0, &(E->Mode), true) == true) { // If we are at low zoom, use a dot for icons, so we dont clutter the screen if(MapWindow::zoom.RealScale() > 4) { if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { // We switch all styles in the correct order, to force a jump table by the compiler // It would be much better to use an array of bitmaps, but no time to do it for 3.0 switch(E->style) { case STYLE_NORMAL: goto turnpoint; break; // These are not used here in fact case STYLE_AIRFIELDGRASS: case STYLE_OUTLANDING: case STYLE_GLIDERSITE: case STYLE_AIRFIELDSOLID: goto turnpoint; break; case STYLE_MTPASS: SelectObject(hDCTemp,hMountpass); break; case STYLE_MTTOP: SelectObject(hDCTemp,hMountop); break; case STYLE_SENDER: SelectObject(hDCTemp,hSender); break; case STYLE_VOR: goto turnpoint; break; case STYLE_NDB: SelectObject(hDCTemp,hNdb); break; case STYLE_COOLTOWER: goto turnpoint; break; case STYLE_DAM: SelectObject(hDCTemp,hDam); break; case STYLE_TUNNEL: goto turnpoint; break; case STYLE_BRIDGE: SelectObject(hDCTemp,hBridge); break; case STYLE_POWERPLANT: case STYLE_CASTLE: goto turnpoint; break; case STYLE_INTERSECTION: SelectObject(hDCTemp,hIntersect); break; case STYLE_TRAFFIC: goto turnpoint; break; case STYLE_THERMAL: SelectObject(hDCTemp,hLKThermal); break; case STYLE_MARKER: SelectObject(hDCTemp,hBmpMarker); break; default: turnpoint: if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); break; } // switch estyle } // below zoom threshold // We dont do stretching here. We are using different bitmaps for hi res. // The 20x20 size is large enough to make much bigger icons than the old ones. DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,0,0,SRCPAINT,false); DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,20,0,SRCAND,false); } } } } // end DrawWaypoint
void MapWindow::DrawWaypoints(Canvas &canvas) { if (way_points == NULL) return; TCHAR Buffer[32]; TCHAR Buffer2[32]; TCHAR sAltUnit[4]; TextInBoxMode_t TextDisplayMode; // if pan mode, show full names int pDisplayTextType = SettingsMap().DisplayTextType; if (SettingsMap().EnablePan) { pDisplayTextType = DISPLAYNAME; } _tcscpy(sAltUnit, Units::GetAltitudeName()); MapWaypointLabelClear(); for (unsigned i = 0; way_points->verify_index(i); ++i) { const WAYPOINT &way_point = way_points->get(i); const WPCALC &wpcalc = way_points->get_calc(i); if (wpcalc.Visible) { bool irange = false; bool islandable = false; bool dowrite; dowrite = wpcalc.InTask; TextDisplayMode.AsInt = 0; irange = WaypointInScaleFilter(way_point); Bitmap *wp_bmp = &MapGfx.hSmall; if(GetMapScaleKM() > 20) { wp_bmp = &MapGfx.hSmall; } else if( ((way_point.Flags & AIRPORT) == AIRPORT) || ((way_point.Flags & LANDPOINT) == LANDPOINT) ) { islandable = true; // so we can always draw them if (wpcalc.Reachable) { TextDisplayMode.AsFlag.Reachable = 1; if ((SettingsMap().DeclutterLabels<2)||wpcalc.InTask) { if (wpcalc.InTask || (SettingsMap().DeclutterLabels<1)) { TextDisplayMode.AsFlag.Border = 1; } // show all reachable landing fields unless we want a decluttered // screen. dowrite = true; } if ((way_point.Flags & AIRPORT) == AIRPORT) wp_bmp = &MapGfx.hBmpAirportReachable; else wp_bmp = &MapGfx.hBmpFieldReachable; } else { if ((way_point.Flags & AIRPORT) == AIRPORT) wp_bmp = &MapGfx.hBmpAirportUnReachable; else wp_bmp = &MapGfx.hBmpFieldUnReachable; } } else { if (GetMapScaleKM()>4) { wp_bmp = &MapGfx.hTurnPoint; } else { wp_bmp = &MapGfx.hSmall; } } if (wpcalc.InTask) { // VNT TextDisplayMode.AsFlag.WhiteBold = 1; } if(irange || wpcalc.InTask || islandable || dowrite) { draw_masked_bitmap(canvas, *wp_bmp, wpcalc.Screen.x, wpcalc.Screen.y, 20, 20); } if(wpcalc.InTask || irange || dowrite) { bool draw_alt = TextDisplayMode.AsFlag.Reachable && ((SettingsMap().DeclutterLabels<1) || wpcalc.InTask); switch(pDisplayTextType) { case DISPLAYNAMEIFINTASK: dowrite = wpcalc.InTask; if (wpcalc.InTask) { if (draw_alt) _stprintf(Buffer, TEXT("%s:%d%s"), way_point.Name, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%s"),way_point.Name); } break; case DISPLAYNAME: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; if (draw_alt) _stprintf(Buffer, TEXT("%s:%d%s"), way_point.Name, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%s"),way_point.Name); break; case DISPLAYNUMBER: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; if (draw_alt) _stprintf(Buffer, TEXT("%d:%d%s"), way_point.Number, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%d"),way_point.Number); break; case DISPLAYFIRSTFIVE: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; _tcsncpy(Buffer2, way_point.Name, 5); Buffer2[5] = '\0'; if (draw_alt) _stprintf(Buffer, TEXT("%s:%d%s"), Buffer2, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%s"),Buffer2); break; case DISPLAYFIRSTTHREE: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; _tcsncpy(Buffer2, way_point.Name, 3); Buffer2[3] = '\0'; if (draw_alt) _stprintf(Buffer, TEXT("%s:%d%s"), Buffer2, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%s"),Buffer2); break; case DISPLAYNONE: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; if (draw_alt) _stprintf(Buffer, TEXT("%d%s"), (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else Buffer[0]= '\0'; break; default: assert(0); break; } if (dowrite) { MapWaypointLabelAdd( Buffer, wpcalc.Screen.x + 5, wpcalc.Screen.y, TextDisplayMode, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), wpcalc.InTask,false,false,false, MapRect); } } } } MapWaypointLabelSortAndRender(canvas); }
void MapWindow::DrawWaypointsNew(HDC hdc, const RECT rc) { unsigned int i; int bestwp=-1; TCHAR Buffer[LKSIZEBUFFER]; TCHAR Buffer2[LKSIZEBUFFER]; TCHAR sAltUnit[LKSIZEBUFFERUNIT]; TextInBoxMode_t TextDisplayMode; static int resizer[10]={ 20,20,20,3,5,8,10,12,0 }; // if pan mode, show full names int pDisplayTextType = DisplayTextType; if (!WayPointList) return; _tcscpy(sAltUnit, Units::GetAltitudeName()); MapWaypointLabelListCount = 0; int arrivalcutoff=0, foundairport=0; bool isairport; bool islandpoint; #ifndef MAP_ZOOM if (MapScale <=20) for(i=0;i<NumberOfWayPoints;i++) { #else /* MAP_ZOOM */ if (MapWindow::zoom.Scale() <=20) for(i=0;i<NumberOfWayPoints;i++) { #endif /* MAP_ZOOM */ if (WayPointList[i].Visible != TRUE ) continue; // false may not be FALSE? if (WayPointCalc[i].IsAirport) { if (WayPointList[i].Reachable == FALSE) { SelectObject(hDCTemp,hBmpAirportUnReachable); } else { SelectObject(hDCTemp,hBmpAirportReachable); if ( arrivalcutoff < (int)(WayPointList[i].AltArivalAGL)) { arrivalcutoff = (int)(WayPointList[i].AltArivalAGL); bestwp=i; foundairport++; } } } else { if ( WayPointCalc[i].IsOutlanding ) { // outlanding if (WayPointList[i].Reachable == FALSE) SelectObject(hDCTemp,hBmpFieldUnReachable); else { SelectObject(hDCTemp,hBmpFieldReachable); // get the outlanding as bestwp only if no other choice if (foundairport == 0) { // do not set arrivalcutoff: any next reachable airport is better than an outlanding if ( arrivalcutoff < (int)(WayPointList[i].AltArivalAGL)) bestwp=i; } } } else continue; // do not draw icons for normal turnpoints here } DrawBitmapX(hdc, WayPointList[i].Screen.x-NIBLSCALE(10), WayPointList[i].Screen.y-NIBLSCALE(10), 20,20, hDCTemp,0,0,SRCPAINT); DrawBitmapX(hdc, WayPointList[i].Screen.x-NIBLSCALE(10), WayPointList[i].Screen.y-NIBLSCALE(10), 20,20, hDCTemp,20,0,SRCAND); } // for all waypoints if (foundairport==0 && bestwp>=0) arrivalcutoff = (int)WayPointList[bestwp].AltArivalAGL; for(i=0;i<NumberOfWayPoints;i++) { if(WayPointList[i].Visible ) { #ifdef HAVEEXCEPTIONS __try{ #endif bool irange = false; bool intask = false; bool islandable; // isairport+islandpoint bool excluded=false; bool dowrite; intask = WaypointInTask(i); dowrite = intask; // initially set only for intask TextDisplayMode.AsInt = 0; // airports are also landpoints. should be better handled isairport=((WayPointList[i].Flags & AIRPORT) == AIRPORT); islandpoint=((WayPointList[i].Flags & LANDPOINT) == LANDPOINT); islandable=WayPointCalc[i].IsLandable; // always in range if MapScale <=10 since no zoom in waypoints is documented and .Zoom is always 0. irange = WaypointInRange(i); #ifndef MAP_ZOOM if(MapScale > 20) { #else /* MAP_ZOOM */ if(MapWindow::zoom.Scale() > 20) { #endif /* MAP_ZOOM */ SelectObject(hDCTemp,hInvSmall); irange=false; goto NiklausWirth; // with compliments } if( islandable ) { if(WayPointList[i].Reachable){ TextDisplayMode.AsFlag.Reachable = 1; if ( isairport ) SelectObject(hDCTemp,hBmpAirportReachable); else SelectObject(hDCTemp,hBmpFieldReachable); if ((DeclutterLabels<MAPLABELS_ALLOFF)||intask) { dowrite = true; // exclude outlandings worst than visible airports, only when there are visible reachable airports! if ( isairport==false && islandpoint==true ) { if ( (int)WayPointList[i].AltArivalAGL >=2000 ) { // more filter excluded=true; } else { if ( (bestwp>=0) && (i==(unsigned)bestwp) && (foundairport==0) ) { // this outlanding is the best option isairport=true; islandpoint=false; // make it an airport TODO paint it as best } else { if ( foundairport >0 ) { if ( (int)WayPointList[i].AltArivalAGL <= arrivalcutoff ) { excluded=true; } } } } } else // do not display airport arrival if close to the best so far. // ex: best arrival is 1200m, include onlye below 1200/4 (prevent division by zero) // This way we only display far points, and skip closer points // WE NEED MORE INFO ABOUT LANDING POINTS: THE .CUP FORMAT WILL LET US KNOW WHAT IS // BEST TO SHOW AND WHAT IS NOT. Winpilot format is useless here. { dowrite=true;// TEST FIX not necessary probably // it's an airport if ( (bestwp>=0) && (i != (unsigned)bestwp) && (arrivalcutoff>600) ) { if ( (arrivalcutoff / ((int)WayPointList[i].AltArivalAGL+1))<4 ) { excluded=true; } } } } } else // landable waypoint is unreachable { dowrite=true; if ( isairport ) { SelectObject(hDCTemp,hBmpAirportUnReachable); } else { SelectObject(hDCTemp,hBmpFieldUnReachable); } } } else { // waypoint is an ordinary turnpoint #ifndef MAP_ZOOM if(MapScale > 4) { #else /* MAP_ZOOM */ if(MapWindow::zoom.Scale() > 4) { #endif /* MAP_ZOOM */ if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); } } // end landable-not landable NiklausWirth: if (intask || (OutlinedTp==(OutlinedTp_t)otAll) ) { TextDisplayMode.AsFlag.WhiteBold = 1; TextDisplayMode.AsFlag.Color=TEXTWHITE; } // No matter of how we thought to draw it, let it up to the user.. switch(NewMapDeclutter) { case 0: excluded=false; // no decluttering: show all airports and outlandings break; case 1: if ( isairport ) excluded=false; // show all airports, declutter outlandings break; default: break; // else work normally } // here come both turnpoints and landables.. if( intask || irange || dowrite) { // irange almost always set when MapScale <=10 bool draw_alt = TextDisplayMode.AsFlag.Reachable && ((DeclutterLabels<MAPLABELS_ONLYTOPO) || intask); // 100711 reachable landing point! if (excluded==true) draw_alt=false; // exclude close outlandings switch(pDisplayTextType) { case DISPLAYNAME: case DISPLAYFIRSTTHREE: case DISPLAYFIRSTFIVE: case DISPLAYFIRST8: case DISPLAYFIRST10: case DISPLAYFIRST12: dowrite = (DeclutterLabels<MAPLABELS_ONLYTOPO) || intask || islandable; // 100711 #ifndef MAP_ZOOM if ( (islandable && !isairport) && MapScale >=10 ) dowrite=0; // FIX then no need to go further #else /* MAP_ZOOM */ if ( (islandable && !isairport) && MapWindow::zoom.Scale() >=10 ) dowrite=0; // FIX then no need to go further #endif /* MAP_ZOOM */ // 101215 if (DisplayTextType == DISPLAYNAME) { _tcscpy(Buffer2,WayPointList[i].Name); } else { _tcsncpy(Buffer2, WayPointList[i].Name, resizer[DisplayTextType]); Buffer2[resizer[DisplayTextType]] = '\0'; } // ConvToUpper(Buffer2); if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%s:%d"), Buffer2, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%s:%d%s"), Buffer2, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%s:%d"), Buffer2, (int)WayPointCalc[i].GR); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.AsFlag.Border = 1; TextDisplayMode.AsFlag.WhiteBold = 0; } else TextDisplayMode.AsFlag.WhiteBold = 1; // outlined TextDisplayMode.AsFlag.Color=TEXTWHITE; } else { //wsprintf(Buffer, TEXT("%s"),Buffer2); _tcscpy(Buffer,Buffer2); if (islandable && isairport) { TextDisplayMode.AsFlag.WhiteBold = 1; // outlined TextDisplayMode.AsFlag.Color=TEXTWHITE; } } break; case DISPLAYNUMBER: dowrite = (DeclutterLabels<MAPLABELS_ONLYTOPO) || intask || islandable; // 100620 #ifndef MAP_ZOOM if ( (islandable && !isairport) && MapScale >=10 ) dowrite=0; // FIX then no need to go further #else /* MAP_ZOOM */ if ( (islandable && !isairport) && MapWindow::zoom.Scale() >=10 ) dowrite=0; // FIX then no need to go further #endif /* MAP_ZOOM */ if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%d:%d"), WayPointList[i].Number, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%d:%d%s"), WayPointList[i].Number, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%d:%d"), WayPointList[i].Number, (int)(WayPointCalc[i].GR)); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.AsFlag.Border = 1; TextDisplayMode.AsFlag.WhiteBold = 0; } else TextDisplayMode.AsFlag.WhiteBold = 1; // outlined TextDisplayMode.AsFlag.Color=TEXTWHITE; } else { wsprintf(Buffer, TEXT("%d"),WayPointList[i].Number); if (islandable && isairport) { TextDisplayMode.AsFlag.WhiteBold = 1; // outlined TextDisplayMode.AsFlag.Color=TEXTWHITE; } } break; case DISPLAYNAMEIFINTASK: dowrite = intask; if (intask) { if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%s:%d"), WayPointList[i].Name, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%s:%d%s"), WayPointList[i].Name, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%s:%d"), WayPointList[i].Name, (int)(WayPointCalc[i].GR)); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.AsFlag.Border = 1; TextDisplayMode.AsFlag.WhiteBold = 0; } else TextDisplayMode.AsFlag.WhiteBold = 1; // outlined TextDisplayMode.AsFlag.Color=TEXTWHITE; } else { wsprintf(Buffer, TEXT("%s"),WayPointList[i].Name); // TODO CHECK THIS, UNTESTED.. if (islandable && isairport) { TextDisplayMode.AsFlag.WhiteBold = 1; // outlined TextDisplayMode.AsFlag.Color=TEXTWHITE; } } } else { wsprintf(Buffer, TEXT(" ")); dowrite=true; } break; case DISPLAYNONE: dowrite = (DeclutterLabels<MAPLABELS_ONLYTOPO) || intask || islandable; // 100711 if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%d"), (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%d%s"), (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%d"), (int)(WayPointCalc[i].GR) ); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.AsFlag.Border = 1; TextDisplayMode.AsFlag.WhiteBold = 0; } else TextDisplayMode.AsFlag.WhiteBold = 1; // outlined TextDisplayMode.AsFlag.Color=TEXTWHITE; } else { wsprintf(Buffer, TEXT(" ")); } break; default: #if (WINDOWSPC<1) ASSERT(0); #endif break; } // end intask/irange/dowrite #ifndef MAP_ZOOM if (MapScale<20 && islandable && dowrite) { #else /* MAP_ZOOM */ if (MapWindow::zoom.Scale()<20 && islandable && dowrite) { #endif /* MAP_ZOOM */ TextInBox(hdc, Buffer, WayPointList[i].Screen.x+5, WayPointList[i].Screen.y, 0, TextDisplayMode, true); dowrite=false; // do not pass it along } // Do not show takeoff for gliders, check TakeOffWayPoint if (i==RESWP_TAKEOFF) { if (TakeOffWayPoint) { intask=false; // 091031 let TAKEOFF be decluttered WayPointList[i].Visible=TRUE; } else { WayPointList[i].Visible=FALSE; dowrite=false; } } if (dowrite) { MapWaypointLabelAdd( Buffer, WayPointList[i].Screen.x+5, WayPointList[i].Screen.y, TextDisplayMode, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), intask,islandable,isairport,excluded,i); } } // end if intask #ifdef HAVEEXCEPTIONS }__finally #endif { ; } } // if visible } // for all waypoints qsort(&MapWaypointLabelList, MapWaypointLabelListCount, sizeof(MapWaypointLabel_t), MapWaypointLabelListCompare); int j; // now draw task/landable waypoints in order of range (closest last) // writing unconditionally for (j=MapWaypointLabelListCount-1; j>=0; j--){ MapWaypointLabel_t *E = &MapWaypointLabelList[j]; // draws if they are in task unconditionally, // otherwise, does comparison if ( E->inTask || (E->isLandable && !E->isExcluded) ) { TextInBox(hdc, E->Name, E->Pos.x, E->Pos.y, 0, E->Mode, false); } } // now draw normal waypoints in order of range (furthest away last) // without writing over each other (or the task ones) for (j=0; j<MapWaypointLabelListCount; j++) { MapWaypointLabel_t *E = &MapWaypointLabelList[j]; if (!E->inTask && !E->isLandable ) { if ( TextInBox(hdc, E->Name, E->Pos.x, E->Pos.y, 0, E->Mode, true) == true) { #ifndef MAP_ZOOM if(MapScale > 4) { #else /* MAP_ZOOM */ if(MapWindow::zoom.Scale() > 4) { #endif /* MAP_ZOOM */ if (BlackScreen) // 091109 SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { if (BlackScreen) // 091109 SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); } DrawBitmapX(hdc, E->Pos.x-NIBLSCALE(10), E->Pos.y-NIBLSCALE(10), 20,20, hDCTemp,0,0,SRCPAINT); DrawBitmapX(hdc, E->Pos.x-NIBLSCALE(10), E->Pos.y-NIBLSCALE(10), 20,20, hDCTemp,20,0,SRCAND); } } } } // end DrawWaypoint