wind direction -> wind degree
This commit is contained in:
parent
025cc8ce86
commit
bd6678da08
8 changed files with 59 additions and 56 deletions
|
|
@ -1,5 +1,6 @@
|
|||
const std = @import("std");
|
||||
const types = @import("../weather/types.zig");
|
||||
const utils = @import("utils.zig");
|
||||
|
||||
pub const Format = enum {
|
||||
plain_text,
|
||||
|
|
@ -55,7 +56,7 @@ fn renderCurrent(w: *std.Io.Writer, current: types.CurrentCondition, options: Re
|
|||
if (options.format == .plain_text) {
|
||||
try w.print("{s} {s}\n", .{ art[0], current.condition });
|
||||
try w.print("{s} {c}{d:.0}({c}{d:.0}) {s}\n", .{ art[1], sign, abs_temp, fl_sign, abs_fl, temp_unit });
|
||||
try w.print("{s} {s} {d:.0} {s}\n", .{ art[2], current.wind_dir, wind_speed, wind_unit });
|
||||
try w.print("{s} {s} {d:.0} {s}\n", .{ art[2], utils.degreeToDirection(current.wind_deg), wind_speed, wind_unit });
|
||||
try w.print("{s} {s}\n", .{ art[3], visibility });
|
||||
try w.print("{s} {d:.1} {s}\n", .{ art[4], precip, precip_unit });
|
||||
} else {
|
||||
|
|
@ -66,7 +67,7 @@ fn renderCurrent(w: *std.Io.Writer, current: types.CurrentCondition, options: Re
|
|||
|
||||
try w.print("{s}{s}{s} {s}\n", .{ cloud_color, art[0], reset, current.condition });
|
||||
try w.print("{s}{s}{s} \x1b[38;5;{d}m{c}{d:.0}({c}{d:.0}){s} {s}\n", .{ cloud_color, art[1], reset, temp_color_code, sign, abs_temp, fl_sign, abs_fl, reset, temp_unit });
|
||||
try w.print("{s}{s}{s} {s} \x1b[38;5;{d}m{d:.0}{s} {s}\n", .{ cloud_color, art[2], reset, current.wind_dir, wind_color_code, wind_speed, reset, wind_unit });
|
||||
try w.print("{s}{s}{s} {s} \x1b[38;5;{d}m{d:.0}{s} {s}\n", .{ cloud_color, art[2], reset, utils.degreeToDirection(current.wind_deg), wind_color_code, wind_speed, reset, wind_unit });
|
||||
try w.print("{s}{s}{s} {s}\n", .{ cloud_color, art[3], reset, visibility });
|
||||
try w.print("{s}{s}{s} {d:.1} {s}\n", .{ cloud_color, art[4], reset, precip, precip_unit });
|
||||
}
|
||||
|
|
@ -327,7 +328,7 @@ test "render with imperial units" {
|
|||
.weather_code = .clear,
|
||||
.humidity = 60,
|
||||
.wind_kph = 16.0,
|
||||
.wind_dir = "N",
|
||||
.wind_deg = 0.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -354,7 +355,7 @@ test "clear weather art" {
|
|||
.weather_code = .clear,
|
||||
.humidity = 50,
|
||||
.wind_kph = 10.0,
|
||||
.wind_dir = "N",
|
||||
.wind_deg = 0.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -379,7 +380,7 @@ test "partly cloudy weather art" {
|
|||
.weather_code = .clouds_few,
|
||||
.humidity = 55,
|
||||
.wind_kph = 12.0,
|
||||
.wind_dir = "NE",
|
||||
.wind_deg = 45.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -404,7 +405,7 @@ test "cloudy weather art" {
|
|||
.weather_code = .clouds_overcast,
|
||||
.humidity = 70,
|
||||
.wind_kph = 15.0,
|
||||
.wind_dir = "E",
|
||||
.wind_deg = 90.0,
|
||||
.pressure_mb = 1010.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -429,7 +430,7 @@ test "rain weather art" {
|
|||
.weather_code = .rain_moderate,
|
||||
.humidity = 85,
|
||||
.wind_kph = 20.0,
|
||||
.wind_dir = "SE",
|
||||
.wind_deg = 135.0,
|
||||
.pressure_mb = 1005.0,
|
||||
.precip_mm = 5.0,
|
||||
},
|
||||
|
|
@ -453,7 +454,7 @@ test "thunderstorm weather art" {
|
|||
.weather_code = .thunderstorm,
|
||||
.humidity = 90,
|
||||
.wind_kph = 30.0,
|
||||
.wind_dir = "S",
|
||||
.wind_deg = 180.0,
|
||||
.pressure_mb = 1000.0,
|
||||
.precip_mm = 10.0,
|
||||
},
|
||||
|
|
@ -477,7 +478,7 @@ test "snow weather art" {
|
|||
.weather_code = .snow,
|
||||
.humidity = 80,
|
||||
.wind_kph = 18.0,
|
||||
.wind_dir = "SW",
|
||||
.wind_deg = 225.0,
|
||||
.pressure_mb = 1008.0,
|
||||
.precip_mm = 3.0,
|
||||
},
|
||||
|
|
@ -501,7 +502,7 @@ test "sleet weather art" {
|
|||
.weather_code = .sleet,
|
||||
.humidity = 75,
|
||||
.wind_kph = 22.0,
|
||||
.wind_dir = "W",
|
||||
.wind_deg = 270.0,
|
||||
.pressure_mb = 1007.0,
|
||||
.precip_mm = 2.0,
|
||||
},
|
||||
|
|
@ -525,7 +526,7 @@ test "fog weather art" {
|
|||
.weather_code = .fog,
|
||||
.humidity = 95,
|
||||
.wind_kph = 5.0,
|
||||
.wind_dir = "NW",
|
||||
.wind_deg = 315.0,
|
||||
.pressure_mb = 1012.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -549,7 +550,7 @@ test "unknown weather code art" {
|
|||
.weather_code = .unknown,
|
||||
.humidity = 60,
|
||||
.wind_kph = 10.0,
|
||||
.wind_dir = "N",
|
||||
.wind_deg = 0.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -576,7 +577,7 @@ test "temperature matches between ansi and custom format" {
|
|||
.weather_code = .clear,
|
||||
.humidity = 60,
|
||||
.wind_kph = 10.0,
|
||||
.wind_dir = "N",
|
||||
.wind_deg = 0.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const std = @import("std");
|
||||
const types = @import("../weather/types.zig");
|
||||
const emoji = @import("emoji.zig");
|
||||
const utils = @import("utils.zig");
|
||||
|
||||
pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format: []const u8, use_imperial: bool) ![]const u8 {
|
||||
var output: std.ArrayList(u8) = .empty;
|
||||
|
|
@ -38,7 +39,7 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, format:
|
|||
'w' => {
|
||||
const wind = if (use_imperial) weather.current.wind_kph * 0.621371 else weather.current.wind_kph;
|
||||
const unit = if (use_imperial) "mph" else "km/h";
|
||||
try writer.print("{d:.0} {s} {s}", .{ wind, unit, weather.current.wind_dir });
|
||||
try writer.print("{d:.0} {s} {s}", .{ wind, unit, utils.degreeToDirection(weather.current.wind_deg) });
|
||||
},
|
||||
'l' => try writer.print("{s}", .{weather.location}),
|
||||
'p' => {
|
||||
|
|
@ -87,7 +88,7 @@ test "render custom format with location and temp" {
|
|||
.weather_code = .clouds_overcast,
|
||||
.humidity = 76,
|
||||
.wind_kph = 11.0,
|
||||
.wind_dir = "NNE",
|
||||
.wind_deg = 22.5,
|
||||
.pressure_mb = 1019.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -114,7 +115,7 @@ test "render custom format with newline" {
|
|||
.weather_code = .clear,
|
||||
.humidity = 65,
|
||||
.wind_kph = 8.0,
|
||||
.wind_dir = "E",
|
||||
.wind_deg = 90.0,
|
||||
.pressure_mb = 1020.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -140,7 +141,7 @@ test "render custom format with humidity and pressure" {
|
|||
.weather_code = .clouds_overcast,
|
||||
.humidity = 85,
|
||||
.wind_kph = 12.0,
|
||||
.wind_dir = "W",
|
||||
.wind_deg = 270.0,
|
||||
.pressure_mb = 1012.0,
|
||||
.precip_mm = 0.2,
|
||||
},
|
||||
|
|
@ -167,7 +168,7 @@ test "render custom format with imperial units" {
|
|||
.weather_code = .clear,
|
||||
.humidity = 60,
|
||||
.wind_kph = 16.0,
|
||||
.wind_dir = "N",
|
||||
.wind_deg = 0.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 2.5,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData) ![]const
|
|||
.weatherDesc = .{.{ .value = weather.current.condition }},
|
||||
.humidity = weather.current.humidity,
|
||||
.windspeedKmph = weather.current.wind_kph,
|
||||
.winddirDegree = weather.current.wind_dir,
|
||||
.winddirDegree = weather.current.wind_deg,
|
||||
.pressure = weather.current.pressure_mb,
|
||||
.precipMM = weather.current.precip_mm,
|
||||
},
|
||||
|
|
@ -31,7 +31,7 @@ test "render json format" {
|
|||
.weather_code = .clouds_few,
|
||||
.humidity = 72,
|
||||
.wind_kph = 13.0,
|
||||
.wind_dir = "SW",
|
||||
.wind_deg = 225.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const std = @import("std");
|
||||
const types = @import("../weather/types.zig");
|
||||
const emoji = @import("emoji.zig");
|
||||
const utils = @import("utils.zig");
|
||||
|
||||
pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []const u8, use_imperial: bool) ![]const u8 {
|
||||
if (std.mem.eql(u8, format, "1")) {
|
||||
|
|
@ -23,7 +24,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c
|
|||
temp,
|
||||
unit,
|
||||
"🌬️",
|
||||
data.current.wind_dir,
|
||||
utils.degreeToDirection(data.current.wind_deg),
|
||||
wind,
|
||||
wind_unit,
|
||||
});
|
||||
|
|
@ -38,7 +39,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c
|
|||
temp,
|
||||
unit,
|
||||
"🌬️",
|
||||
data.current.wind_dir,
|
||||
utils.degreeToDirection(data.current.wind_deg),
|
||||
wind,
|
||||
wind_unit,
|
||||
"💧",
|
||||
|
|
@ -55,7 +56,7 @@ pub fn render(allocator: std.mem.Allocator, data: types.WeatherData, format: []c
|
|||
temp,
|
||||
unit,
|
||||
"🌬️",
|
||||
data.current.wind_dir,
|
||||
utils.degreeToDirection(data.current.wind_deg),
|
||||
wind,
|
||||
wind_unit,
|
||||
"💧",
|
||||
|
|
@ -90,7 +91,7 @@ fn renderCustom(allocator: std.mem.Allocator, data: types.WeatherData, format: [
|
|||
'w' => {
|
||||
const wind = if (use_imperial) data.current.wind_kph * 0.621371 else data.current.wind_kph;
|
||||
const wind_unit = if (use_imperial) "mph" else "km/h";
|
||||
try output.writer(allocator).print("{s}{d:.0}{s}", .{ data.current.wind_dir, wind, wind_unit });
|
||||
try output.writer(allocator).print("{s}{d:.0}{s}", .{ utils.degreeToDirection(data.current.wind_deg), wind, wind_unit });
|
||||
},
|
||||
'l' => try output.appendSlice(allocator, data.location),
|
||||
'p' => {
|
||||
|
|
@ -127,7 +128,7 @@ test "format 1" {
|
|||
.weather_code = .clear,
|
||||
.humidity = 65,
|
||||
.wind_kph = 10.0,
|
||||
.wind_dir = "N",
|
||||
.wind_deg = 0.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -151,7 +152,7 @@ test "custom format" {
|
|||
.weather_code = .clear,
|
||||
.humidity = 65,
|
||||
.wind_kph = 10.0,
|
||||
.wind_dir = "N",
|
||||
.wind_deg = 0.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -175,7 +176,7 @@ test "format 2 with imperial units" {
|
|||
.weather_code = .clouds_overcast,
|
||||
.humidity = 70,
|
||||
.wind_kph = 20.0,
|
||||
.wind_dir = "SE",
|
||||
.wind_deg = 135.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
|
|||
19
src/render/utils.zig
Normal file
19
src/render/utils.zig
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn degreeToDirection(deg: f32) []const u8 {
|
||||
const normalized = @mod(deg + 22.5, 360.0);
|
||||
const idx: usize = @intFromFloat(normalized / 45.0);
|
||||
const directions = [_][]const u8{ "N", "NE", "E", "SE", "S", "SW", "W", "NW" };
|
||||
return directions[@min(idx, 7)];
|
||||
}
|
||||
|
||||
test "degreeToDirection" {
|
||||
try std.testing.expectEqualStrings("N", degreeToDirection(0));
|
||||
try std.testing.expectEqualStrings("NE", degreeToDirection(45));
|
||||
try std.testing.expectEqualStrings("E", degreeToDirection(90));
|
||||
try std.testing.expectEqualStrings("SE", degreeToDirection(135));
|
||||
try std.testing.expectEqualStrings("S", degreeToDirection(180));
|
||||
try std.testing.expectEqualStrings("SW", degreeToDirection(225));
|
||||
try std.testing.expectEqualStrings("W", degreeToDirection(270));
|
||||
try std.testing.expectEqualStrings("NW", degreeToDirection(315));
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
const std = @import("std");
|
||||
const types = @import("../weather/types.zig");
|
||||
const utils = @import("utils.zig");
|
||||
|
||||
pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, use_imperial: bool) ![]const u8 {
|
||||
var output: std.ArrayList(u8) = .empty;
|
||||
|
|
@ -23,9 +24,9 @@ pub fn render(allocator: std.mem.Allocator, weather: types.WeatherData, use_impe
|
|||
try writer.writeAll(" 🌬️ ");
|
||||
if (use_imperial) {
|
||||
const wind_mph = weather.current.wind_kph * 0.621371;
|
||||
try writer.print("{d:.1} mph {s}\n", .{ wind_mph, weather.current.wind_dir });
|
||||
try writer.print("{d:.1} mph {s}\n", .{ wind_mph, utils.degreeToDirection(weather.current.wind_deg) });
|
||||
} else {
|
||||
try writer.print("{d:.1} km/h {s}\n", .{ weather.current.wind_kph, weather.current.wind_dir });
|
||||
try writer.print("{d:.1} km/h {s}\n", .{ weather.current.wind_kph, utils.degreeToDirection(weather.current.wind_deg) });
|
||||
}
|
||||
try writer.writeAll(" 🔽 ");
|
||||
if (use_imperial) {
|
||||
|
|
@ -77,7 +78,7 @@ test "render v2 format" {
|
|||
.weather_code = .clouds_overcast,
|
||||
.humidity = 80,
|
||||
.wind_kph = 15.0,
|
||||
.wind_dir = "NW",
|
||||
.wind_deg = 315.0,
|
||||
.pressure_mb = 1015.0,
|
||||
.precip_mm = 0.5,
|
||||
},
|
||||
|
|
@ -106,7 +107,7 @@ test "render v2 format with imperial units" {
|
|||
.weather_code = .clear,
|
||||
.humidity = 65,
|
||||
.wind_kph = 16.0,
|
||||
.wind_dir = "N",
|
||||
.wind_deg = 0.0,
|
||||
.pressure_mb = 1013.0,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -172,11 +172,10 @@ fn parseMetNoResponse(allocator: std.mem.Allocator, coords: Coordinates, json: s
|
|||
"clearsky_day";
|
||||
|
||||
// Get wind direction
|
||||
const wind_from_deg = details.object.get("wind_from_direction");
|
||||
const wind_dir = if (wind_from_deg) |deg|
|
||||
degreeToDirection(@as(f32, @floatCast(deg.float)))
|
||||
const wind_deg = if (details.object.get("wind_from_direction")) |deg|
|
||||
@as(f32, @floatCast(deg.float))
|
||||
else
|
||||
"N";
|
||||
0.0;
|
||||
|
||||
// Parse forecast days from timeseries
|
||||
const forecast = try parseForecastDays(allocator, timeseries.array.items);
|
||||
|
|
@ -192,7 +191,7 @@ fn parseMetNoResponse(allocator: std.mem.Allocator, coords: Coordinates, json: s
|
|||
.weather_code = symbolCodeToWeatherCode(symbol_code),
|
||||
.humidity = humidity,
|
||||
.wind_kph = wind_kph,
|
||||
.wind_dir = try allocator.dupe(u8, wind_dir),
|
||||
.wind_deg = wind_deg,
|
||||
.pressure_mb = pressure_mb,
|
||||
.precip_mm = 0.0,
|
||||
},
|
||||
|
|
@ -430,24 +429,6 @@ fn symbolCodeToCondition(symbol: []const u8) []const u8 {
|
|||
return "Unknown";
|
||||
}
|
||||
|
||||
fn degreeToDirection(deg: f32) []const u8 {
|
||||
const normalized = @mod(deg + 22.5, 360.0);
|
||||
const idx: usize = @intFromFloat(normalized / 45.0);
|
||||
const directions = [_][]const u8{ "N", "NE", "E", "SE", "S", "SW", "W", "NW" };
|
||||
return directions[@min(idx, 7)];
|
||||
}
|
||||
|
||||
test "degreeToDirection" {
|
||||
try std.testing.expectEqualStrings("N", degreeToDirection(0));
|
||||
try std.testing.expectEqualStrings("NE", degreeToDirection(45));
|
||||
try std.testing.expectEqualStrings("E", degreeToDirection(90));
|
||||
try std.testing.expectEqualStrings("SE", degreeToDirection(135));
|
||||
try std.testing.expectEqualStrings("S", degreeToDirection(180));
|
||||
try std.testing.expectEqualStrings("SW", degreeToDirection(225));
|
||||
try std.testing.expectEqualStrings("W", degreeToDirection(270));
|
||||
try std.testing.expectEqualStrings("NW", degreeToDirection(315));
|
||||
}
|
||||
|
||||
test "symbolCodeToWeatherCode" {
|
||||
try std.testing.expectEqual(types.WeatherCode.clear, symbolCodeToWeatherCode("clearsky_day"));
|
||||
try std.testing.expectEqual(types.WeatherCode.clouds_few, symbolCodeToWeatherCode("fair_night"));
|
||||
|
|
|
|||
|
|
@ -90,7 +90,6 @@ pub const WeatherData = struct {
|
|||
pub fn deinit(self: WeatherData) void {
|
||||
self.allocator.free(self.location);
|
||||
self.allocator.free(self.current.condition);
|
||||
self.allocator.free(self.current.wind_dir);
|
||||
for (self.forecast) |day| {
|
||||
self.allocator.free(day.date);
|
||||
self.allocator.free(day.condition);
|
||||
|
|
@ -114,7 +113,7 @@ pub const CurrentCondition = struct {
|
|||
weather_code: WeatherCode,
|
||||
humidity: u8,
|
||||
wind_kph: f32,
|
||||
wind_dir: []const u8,
|
||||
wind_deg: f32,
|
||||
pressure_mb: f32,
|
||||
precip_mm: f32,
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue