4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "MapWindow.hpp"
25 #include "Screen/Icon.hpp"
26 #include "Look/Fonts.hpp"
27 #include "Geo/Math.hpp"
28 #include "Task/ProtectedTaskManager.hpp"
29 #include "Engine/Task/Ordered/OrderedTask.hpp"
30 #include "Renderer/TaskRenderer.hpp"
31 #include "Renderer/TaskPointRenderer.hpp"
32 #include "Renderer/OZRenderer.hpp"
33 #include "Screen/Layout.hpp"
34 #include "Math/Screen.hpp"
35 #include "Look/MapLook.hpp"
41 MapWindow::DrawTask(Canvas
&canvas
)
46 /* RLD bearing is invalid if GPS not connected and in non-sim mode,
47 but we can still draw targets */
48 bool draw_bearing
= Basic().track_available
;
49 bool draw_route
= draw_bearing
;
52 if (Calculated().planned_route
.size()>2) {
59 ProtectedTaskManager::Lease
task_manager(*task
);
60 const AbstractTask
*task
= task_manager
->GetActiveTask();
61 if (task
&& task
->CheckTask()) {
62 TaskPointRenderer::TargetVisibility target_visibility
=
63 IsNearSelf() ? TaskPointRenderer::ACTIVE
: TaskPointRenderer::ALL
;
65 OZRenderer
ozv(look
.task
, airspace_renderer
.GetLook(),
66 GetMapSettings().airspace
);
67 TaskPointRenderer
tpv(canvas
, render_projection
, look
.task
,
68 /* we're accessing the OrderedTask here,
69 which may be invalid at this point, but it
70 will be used only if active, so it's ok */
71 task_manager
->GetOrderedTask().GetTaskProjection(),
72 ozv
, draw_bearing
, target_visibility
,
73 Basic().location_available
, Basic().location
);
74 TaskRenderer
dv(tpv
, render_projection
.GetScreenBounds());
83 MapWindow::DrawRoute(Canvas
&canvas
)
85 const auto &route
= Calculated().planned_route
;
87 const auto r_size
= route
.size();
88 RasterPoint p
[r_size
], *pp
= &p
[0];
89 for (auto i
= route
.begin(), end
= route
.end(); i
!= end
; ++i
, ++pp
)
90 *pp
= render_projection
.GeoToScreen(*i
);
92 ScreenClosestPoint(p
[r_size
-1], p
[r_size
-2], p
[r_size
-1], &p
[r_size
-1], Layout::Scale(20));
94 canvas
.Select(look
.task
.bearing_pen
);
95 canvas
.DrawPolyline(p
, r_size
);
99 MapWindow::DrawTaskOffTrackIndicator(Canvas
&canvas
)
101 if (Calculated().circling
102 || !Basic().location_available
103 || !Basic().track_available
104 || !GetMapSettings().detour_cost_markers_enabled
)
107 const TaskStats
&task_stats
= Calculated().task_stats
;
108 const ElementStat
¤t_leg
= task_stats
.current_leg
;
110 if (!task_stats
.task_valid
|| !current_leg
.location_remaining
.IsValid())
113 const GeoPoint target
= current_leg
.location_remaining
;
114 GeoVector
vec(Basic().location
, target
);
116 if ((Basic().track
- vec
.bearing
).AsDelta().AbsoluteDegrees() < fixed(10))
117 // insignificant error
121 std::min(vec
.distance
,
122 render_projection
.GetScreenDistanceMeters() * fixed(0.7));
124 // too short to bother
125 if (distance_max
< fixed(5000))
128 GeoPoint start
= Basic().location
;
130 canvas
.Select(Fonts::map_bold
);
131 canvas
.SetTextColor(COLOR_BLACK
);
132 canvas
.SetBackgroundTransparent();
136 for (fixed d
= fixed(1) / 4; d
<= fixed(1); d
+= fixed(1) / 4) {
137 dloc
= FindLatitudeLongitude(start
, Basic().track
, distance_max
* d
);
139 fixed distance0
= start
.Distance(dloc
);
140 fixed distance1
= target
.Distance(dloc
);
141 fixed distance
= fixed(distance0
+ distance1
) / vec
.distance
;
142 int idist
= iround((distance
- fixed(1)) * 100);
144 if ((idist
!= ilast
) && (idist
> 0) && (idist
< 1000)) {
146 _stprintf(Buffer
, _T("%d"), idist
);
147 RasterPoint sc
= render_projection
.GeoToScreen(dloc
);
148 PixelSize tsize
= canvas
.CalcTextSize(Buffer
);
149 canvas
.DrawText(sc
.x
- tsize
.cx
/ 2, sc
.y
- tsize
.cy
/ 2, Buffer
);