From 079cc93864b14beaa16304a68e06e3636dbb04d1 Mon Sep 17 00:00:00 2001 From: Sylvain Carlioz Date: Mon, 11 Jun 2018 10:20:42 +0200 Subject: [PATCH] ADD comfort status in the WeatherRouting panel and ReportDialog This allows to: * Display directly in the table what will be the worst sailing comfort conditions found on the way. * Display in the ReportDialog the most comfortable route and date to start. --- src/ReportDialog.cpp | 29 +++++++++++++++++++++++++++-- src/RouteMapOverlay.cpp | 25 +++++++++++++++++++++++-- src/RouteMapOverlay.h | 7 ++++++- src/SettingsDialog.cpp | 5 +++-- src/WeatherRouting.cpp | 15 +++++++++++++-- src/WeatherRouting.h | 4 ++-- 6 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/ReportDialog.cpp b/src/ReportDialog.cpp index 1403a1fb..6be34184 100644 --- a/src/ReportDialog.cpp +++ b/src/ReportDialog.cpp @@ -110,8 +110,14 @@ void ReportDialog::SetRouteMapOverlays(std::list routemapoverl (_T("%d/%d"), (int)port_starboard, 100-(int)port_starboard)) + _T("
"); if (d) { - page += _("Number of tacks") + wxString::Format(_T(": %d "), d->tacks) + _T("
\n"); + page += _("Number of tacks") + wxString::Format(_T(": %d "), d->tacks) + _T("
"); } + + // CUSTOMIZATION + // Display sailing comfort in the report + page += ("Sailing comfort") + wxString(_T(": ")) \ + + (*it)->sailingConditionText((*it)->RouteInfo(RouteMapOverlay::COMFORT)) \ + + _T("
\n"); /* determine if currents significantly improve this (boat over ground speed average is 10% or more faster than boat over water) then attempt to determine which current based on lat/lon @@ -249,7 +255,26 @@ void ReportDialog::GenerateRoutesReport() page += s.Format(_T("%d %B ")) + _("to") + e.Format(_T(" %d %B")); } } - + + // CUSTOMIZATION + // Display the best option to travel in order + // to get the most comfortable sailing + page += _T("
"); + page += _("Best Sailing Comfort") + wxString(_T(": ")); + wxDateTime best_comfort_date; + int best_sailing_comfort = 6; + for(std::multimap< wxDateTime, RouteMapOverlay * >::iterator it3 = sort_by_start.begin(); it3 != sort_by_start.end(); it3++) { + RouteMapOverlay *r = it3->second; + if (best_comfort_date < r->StartTime() && best_sailing_comfort > r->RouteInfo(RouteMapOverlay::COMFORT)) + { + best_comfort_date = r->StartTime(); + best_sailing_comfort = r->RouteInfo(RouteMapOverlay::COMFORT); + } + } + page += RouteMapOverlay::sailingConditionText(best_sailing_comfort); + page += _T(" on "); + page += best_comfort_date.Format(_T("%x %X")) + _T(" UTC"); + page += _T("
"); page += _("Cyclones") + wxString(_T(": ")); diff --git a/src/RouteMapOverlay.cpp b/src/RouteMapOverlay.cpp index 1a0895fb..9a17a11f 100644 --- a/src/RouteMapOverlay.cpp +++ b/src/RouteMapOverlay.cpp @@ -565,7 +565,7 @@ int RouteMapOverlay::sailingConditionLevel(const PlotData &plot) const if (level_calc <= 0.5) // Light conditions, enjoy ;-) return 1; - if (level_calc > 0.5 && level_calc < 1) + if (level_calc > 0.5 && level_calc < 1) // Can be tough return 2; if (level_calc >= 1) @@ -574,7 +574,7 @@ int RouteMapOverlay::sailingConditionLevel(const PlotData &plot) const return 0; } -static wxColour sailingConditionColor(int level) +wxColour RouteMapOverlay::sailingConditionColor(int level) { switch (level) { case 1: @@ -587,6 +587,17 @@ static wxColour sailingConditionColor(int level) return *wxBLACK; } +wxString RouteMapOverlay::sailingConditionText(int level) +{ + if (level == 1) + return _T("Good"); + if (level == 2) + return _T("Bumpy"); + if (level == 3) + return _T("Difficult"); + return _T("N/A"); +} + // ----------------------------------------------------- @@ -1267,6 +1278,7 @@ double RouteMapOverlay::RouteInfo(enum RouteInfoType type, bool cursor_route) std::list &plotdata = GetPlotData(cursor_route); double total = 0, count = 0, lat0 = 0, lon0 = 0; + int comfort = 0, current_comfort = 0; for(std::list::iterator it=plotdata.begin(); it!=plotdata.end(); it++) { switch(type) { @@ -1325,6 +1337,13 @@ double RouteMapOverlay::RouteInfo(enum RouteInfoType type, bool cursor_route) if(heading_resolve(it->B - it->W) > 0) total++; break; + // CUSTOMIZATION + // Comfort on route + case COMFORT: + current_comfort = sailingConditionLevel(*it); + if (current_comfort > comfort) + comfort = current_comfort; + break; default: break; } @@ -1343,6 +1362,8 @@ double RouteMapOverlay::RouteInfo(enum RouteInfoType type, bool cursor_route) total += DistGreatCircle_Plugin(lat0, lon0, configuration.EndLat, configuration.EndLon); } return total; + case COMFORT: + return comfort; case PERCENTAGE_UPWIND: case PORT_STARBOARD: total *= 100.0; diff --git a/src/RouteMapOverlay.h b/src/RouteMapOverlay.h index 706ada32..112b9625 100644 --- a/src/RouteMapOverlay.h +++ b/src/RouteMapOverlay.h @@ -48,7 +48,7 @@ class RouteMapOverlay : public RouteMap public: enum RouteInfoType {DISTANCE, AVGSPEED, MAXSPEED, AVGSPEEDGROUND, MAXSPEEDGROUND, AVGWIND, MAXWIND, MAXWINDGUST, AVGCURRENT, MAXCURRENT, AVGSWELL, MAXSWELL, - PERCENTAGE_UPWIND, PORT_STARBOARD, TACKS}; + PERCENTAGE_UPWIND, PORT_STARBOARD, TACKS, COMFORT}; RouteMapOverlay(); ~RouteMapOverlay(); @@ -65,6 +65,8 @@ class RouteMapOverlay : public RouteMap // Customization ComfortDisplay void RenderCourse(bool cursor_route, wrDC &dc, PlugIn_ViewPort &vp, bool comfortRoute = false); int sailingConditionLevel(const PlotData &plot) const; + static wxColour sailingConditionColor(int level); + static wxString sailingConditionText(int level); // Customization WindBarbsOnRoute void RenderWindBarbsOnRoute(wrDC &dc, PlugIn_ViewPort &vp); @@ -130,6 +132,9 @@ class RouteMapOverlay : public RouteMap // Customization WindBarbsOnRoute LineBuffer wind_barb_route_cache; + + // Customization Sailing Comfort + int m_sailingComfort; LineBuffer current_cache; double current_cache_scale; diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 41b3c289..7a3988b2 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -44,8 +44,9 @@ const wxString SettingsDialog::column_names[] = {"", "Boat", "Start", "Start Tim "Avg Wind", "Max Wind", "Max Wind Gust", "Avg Current", "Max Current", "Avg Swell", "Max Swell", - "Upwind Percentage", - "Port Starboard", "Tacks", "State"}; + "Upwind Percentage", "Port Starboard", + "Tacks", "Sailing Comfort", + "State"}; SettingsDialog::SettingsDialog( wxWindow *parent ) #ifndef __WXOSX__ diff --git a/src/WeatherRouting.cpp b/src/WeatherRouting.cpp index 3740e874..acd93668 100644 --- a/src/WeatherRouting.cpp +++ b/src/WeatherRouting.cpp @@ -88,7 +88,8 @@ const wxString WeatherRouting::column_names[NUM_COLS] = {"Visible", "Boat", "Sta "Avg Current", "Max Current", "Avg Swell", "Max Swell", "Upwind Percentage", - "Port Starboard", "Tacks", "State"}; + "Port Starboard", "Tacks", "Comfort", + "State"}; static int sortcol, sortorder = 1; // sort callback. Sort by body. @@ -1733,6 +1734,11 @@ void WeatherRoute::Update(WeatherRouting *wr, bool stateonly) PortStarboard = wxString::Format(_T("%.0f/%.0f"), ps, 100-ps); Tacks = wxString::Format(_T("%.0f"), routemapoverlay->RouteInfo(RouteMapOverlay::TACKS)); + + // CUSTOMIZATION + // Display sailing comfort + int comfort_level = routemapoverlay->RouteInfo(RouteMapOverlay::COMFORT); + Comfort = RouteMapOverlay::sailingConditionText(comfort_level); } if(!routemapoverlay->Valid()) @@ -1893,11 +1899,16 @@ void WeatherRouting::UpdateItem(long index, bool stateonly) m_panel->m_lWeatherRoutes->SetItem(index, columns[PORT_STARBOARD], weatherroute->PortStarboard); m_panel->m_lWeatherRoutes->SetColumnWidth(columns[PORT_STARBOARD], wxLIST_AUTOSIZE); } - + if(columns[TACKS] >= 0) { m_panel->m_lWeatherRoutes->SetItem(index, columns[TACKS], weatherroute->Tacks); m_panel->m_lWeatherRoutes->SetColumnWidth(columns[TACKS], wxLIST_AUTOSIZE); } + + if(columns[COMFORT] >= 0) { + m_panel->m_lWeatherRoutes->SetItem(index, columns[COMFORT], weatherroute->Comfort); + m_panel->m_lWeatherRoutes->SetColumnWidth(columns[COMFORT], wxLIST_AUTOSIZE); + } } if(columns[STATE] >= 0) { diff --git a/src/WeatherRouting.h b/src/WeatherRouting.h index 095a1442..adcd55ba 100644 --- a/src/WeatherRouting.h +++ b/src/WeatherRouting.h @@ -56,7 +56,7 @@ class WeatherRoute AvgSpeed, MaxSpeed, AvgSpeedGround, MaxSpeedGround, AvgWind, MaxWind, MaxWindGust, AvgCurrent, MaxCurrent, AvgSwell, MaxSwell, UpwindPercentage, PortStarboard, - Tacks, State; + Tacks, State, Comfort; RouteMapOverlay *routemapoverlay; }; @@ -74,7 +74,7 @@ class WeatherRouting : public WeatherRoutingBase enum {VISIBLE=0, BOAT, START, STARTTIME, END, ENDTIME, TIME, DISTANCE, AVGSPEED, MAXSPEED, AVGSPEEDGROUND, MAXSPEEDGROUND, AVGWIND, MAXWIND, MAXWINDGUST, AVGCURRENT, MAXCURRENT, AVGSWELL, MAXSWELL, - UPWIND_PERCENTAGE, PORT_STARBOARD, TACKS, STATE, NUM_COLS}; + UPWIND_PERCENTAGE, PORT_STARBOARD, TACKS, COMFORT, STATE, NUM_COLS}; long columns[NUM_COLS]; static const wxString column_names[NUM_COLS]; int sashpos;