Skip to content

Commit

Permalink
Draw lines for sunrise and sunset
Browse files Browse the repository at this point in the history
Refs: #93
  • Loading branch information
orontee committed Jul 7, 2024
1 parent b59def7 commit 2751b2e
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 18 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Added

- Draw lines for sunrise and sunset
[#93](https://github.com/orontee/taranis/issues/93)

### Changed

### Removed
Expand Down
4 changes: 2 additions & 2 deletions src/app.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ int App::process_event(int event_type, int param_one, int param_two) {
if (event_type != EVT_MTSYNC) {
// No need to log multi touch synchronization events

BOOST_LOG_TRIVIAL(debug) << "Processing event of type "
<< format_event_type(event_type);
BOOST_LOG_TRIVIAL(debug)
<< "Processing event of type " << format_event_type(event_type);
}
if (event_type == EVT_INIT) {
this->setup();
Expand Down
1 change: 1 addition & 0 deletions src/compile_flags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
--language=c++
-I/home/matthias/Projets/taranis/SDK_6.3.0/SDK-B288/usr/arm-obreey-linux-gnueabi/lib/clang/7.0.0/include
-I/home/matthias/Projets/taranis/SDK_6.3.0/SDK-B288/usr/arm-obreey-linux-gnueabi/include/c++/6.3.0
-I/home/matthias/Projets/taranis/SDK_6.3.0/SDK-B288/usr/arm-obreey-linux-gnueabi/sysroot/include
-I/home/matthias/Projets/taranis/SDK_6.3.0/SDK-B288/usr/arm-obreey-linux-gnueabi/sysroot/usr/include
-I/home/matthias/Projets/taranis/SDK_6.3.0/SDK-B288/usr/arm-obreey-linux-gnueabi/sysroot/usr/local/include
55 changes: 44 additions & 11 deletions src/hourlyforecastbox.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void HourlyForecastBox::do_paint() {
this->draw_frame_and_values();
this->draw_precipitation_histogram();
this->draw_temperature_curve();
this->draw_sunrise_sunset_lines();
}

bool HourlyForecastBox::handle_key_press(int key) {
Expand Down Expand Up @@ -394,10 +395,52 @@ void HourlyForecastBox::draw_precipitation_histogram() const {
}
}

void HourlyForecastBox::draw_sunrise_sunset_lines() const {
BOOST_LOG_TRIVIAL(debug) << "Drawing sunrise and sunset lines";
const auto separator_start_y =
this->weather_icon_y + this->icon_size + this->vertical_padding;
const auto separator_stop_y = this->temperature_y - vertical_padding;

for (size_t bar_index = 0; bar_index < HourlyForecastBox::visible_bars;
++bar_index) {
const auto forecast_index = this->forecast_offset + bar_index;
if (forecast_index < this->model->hourly_forecast.size()) {
const auto forecast = this->model->hourly_forecast[forecast_index];

for (const auto daily_forecast : this->model->daily_forecast) {
if (not are_same_day(forecast.date, daily_forecast.date)) {
continue;
}

const auto minutes_before_sunrise =
get_duration_minutes(forecast.date, daily_forecast.sunrise);

const auto minutes_before_sunset =
get_duration_minutes(forecast.date, daily_forecast.sunset);

if (0 < minutes_before_sunrise and minutes_before_sunrise < 60) {
const int separator_x = bar_index * this->bar_width +
minutes_before_sunrise * this->bar_width / 60;
BOOST_LOG_TRIVIAL(debug) << "Drawing sunrise line";
DrawDashLine(separator_x, separator_start_y, separator_x,
separator_stop_y, LGRAY, 10, 10);
} else if (0 < minutes_before_sunset and minutes_before_sunset < 60) {
const int separator_x = bar_index * this->bar_width +
minutes_before_sunset * this->bar_width / 60;
BOOST_LOG_TRIVIAL(debug) << "Drawing sunset line";
DrawDashLine(separator_x, separator_start_y, separator_x,
separator_stop_y, LGRAY, 10, 10);
}
}
} else {
BOOST_LOG_TRIVIAL(debug) << "Out-of-range bar index";
}
}
}

std::map<int, std::vector<unsigned char>> rotated_icons;

const ibitmap *HourlyForecastBox::rotate_direction_icon(int degree) {
BOOST_LOG_TRIVIAL(debug) << "Rotating direction icon, " << degree;
const auto arrow_angle = (180 - degree);
// The parameter degree is an angle measure in degrees, interpreted
// as the direction where the wind is blowing FROM (0 means North,
Expand All @@ -419,29 +462,19 @@ const ibitmap *HourlyForecastBox::rotate_direction_icon(int degree) {
cv::warpAffine(image, rotated_image, rotation_matrix, image.size(),
cv::INTER_LINEAR, cv::BORDER_CONSTANT, 0xFF);

BOOST_LOG_TRIVIAL(debug) << "Rotated image has size " << rotated_image.cols
<< "×" << rotated_image.rows;

const auto header_size = offsetof(ibitmap, data);
const auto data_size = icon_to_rotate->scanline * icon_to_rotate->height;
auto &rotated_bitmap_data = rotated_icons[degree];
rotated_bitmap_data.resize(header_size + data_size);
BOOST_LOG_TRIVIAL(debug) << "Vector data for rotated icon added to cache";

BOOST_LOG_TRIVIAL(debug)
<< "Copying " << header_size << " bytes of header data";
std::memcpy(rotated_bitmap_data.data(), icon_to_rotate, header_size);
// headers are the same for both bitmap

BOOST_LOG_TRIVIAL(debug)
<< "Copying " << data_size << " bytes of image data";
std::memcpy(rotated_bitmap_data.data() + header_size, rotated_image.data,
data_size);

return reinterpret_cast<ibitmap *>(rotated_bitmap_data.data());
}
BOOST_LOG_TRIVIAL(debug) << "Rotated icon data found in cache";

return reinterpret_cast<ibitmap *>(found->second.data());
}
} // namespace taranis
2 changes: 2 additions & 0 deletions src/hourlyforecastbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class HourlyForecastBox : public Widget, public Paginated {

void draw_precipitation_histogram() const;

void draw_sunrise_sunset_lines() const;

const ibitmap *rotate_direction_icon(int degree);
};

Expand Down
33 changes: 28 additions & 5 deletions src/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,33 @@ std::string taranis::format_full_date(const TimePoint &time) {
std::string{formatted_time};
}

bool taranis::are_same_day(const TimePoint &first, const TimePoint &second) {
const time_t first_time_since_epoch{static_cast<long>(
std::chrono::duration_cast<std::chrono::seconds>(first - TimePoint{})
.count())};
auto first_calendar_time = std::localtime(&first_time_since_epoch);
const time_t second_time_since_epoch{static_cast<long>(
std::chrono::duration_cast<std::chrono::seconds>(second - TimePoint{})
.count())};
auto second_calendar_time = std::localtime(&second_time_since_epoch);
if (first_calendar_time and second_calendar_time) {
const auto first_time_year = first_calendar_time->tm_year;
const auto first_time_year_day = first_calendar_time->tm_yday;
const auto second_time_year = second_calendar_time->tm_year;
const auto second_time_year_day = second_calendar_time->tm_yday;
return first_time_year == second_time_year and
first_time_year_day == second_time_year_day;
}
return false;
}

int taranis::get_duration_minutes(const TimePoint &start,
const TimePoint &end) {
const auto duration =
std::chrono::duration_cast<std::chrono::minutes>((end - start));
return static_cast<float>(duration.count());
}

std::string taranis::format_duration(const TimePoint &start,
const TimePoint &end) {
const auto duration =
Expand All @@ -231,11 +258,7 @@ std::string taranis::format_duration(const TimePoint &start,
return "<1h";
}
std::stringstream duration_text;
duration_text << static_cast<int>(
std::chrono::duration_cast<std::chrono::hours>(
(end - start))
.count())
<< "h";
duration_text << static_cast<int>(duration.count()) << "h";
return duration_text.str();
}

Expand Down
5 changes: 5 additions & 0 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ std::string format_date(const TimePoint &time, bool shortcut = false);
// Saturday, 21st October 2023, 17:05
std::string format_full_date(const TimePoint &time);

bool are_same_day(const TimePoint &first, const TimePoint &second);

int get_duration_minutes(const TimePoint &start, const TimePoint &end);

// <1h, 1h, 2h, etc.
std::string format_duration(const TimePoint &start, const TimePoint &end);

int remaining_hours(const TimePoint &time);
Expand Down

0 comments on commit 2751b2e

Please sign in to comment.