#[derive(Debug, Clone, Copy)]
pub struct MollweideLayout {
pub width: f64,
pub height: f64,
pub map_pad: f64,
pub map_x: f64,
pub map_y: f64,
pub map_w: f64,
pub map_h: f64,
pub cbar_x: f64,
pub cbar_y: f64,
pub cbar_w: f64,
pub cbar_h: f64,
pub cbar_pad: f64,
pub border_width_px: f64,
}
#[derive(Debug, Clone)]
pub struct ColorbarLayout {
pub x: f64,
pub y: f64,
pub w: f64,
pub h: f64,
pub tick_bottom: f64,
pub major_tick_height: f64,
pub minor_tick_height: f64,
pub major_tick_width: f64,
pub minor_tick_width: f64,
pub tick_font_size: f64,
pub tick_label_pad: f64,
pub tick_direction: crate::cli::TickDirection,
}
pub fn compute_mollweide_layout(
width: f64,
show_colorbar: bool,
tick_direction: crate::cli::TickDirection,
) -> (MollweideLayout, ColorbarLayout) {
compute_mollweide_layout_with_fonts(width, show_colorbar, tick_direction, None)
}
pub fn compute_mollweide_layout_with_fonts(
width: f64,
show_colorbar: bool,
tick_direction: crate::cli::TickDirection,
custom_tick_font_size: Option<f32>,
) -> (MollweideLayout, ColorbarLayout) {
let scale = width / 1200.0;
let outer_pad = 24.0 * scale; let cbar_pad = 16.0 * scale; let label_pad = 14.0 * scale; let units_pad = if show_colorbar { -4.0 * scale } else { 0.0 };
let border_width_px = (width * 0.0025).max(2.0 * scale);
let map_pad = border_width_px.ceil() + 2.0 * scale;
let map_w = width - 2.0 * outer_pad;
let map_h = map_w / 2.0;
let cbar_h = if show_colorbar {
let base_h = map_h / 20.0;
let rounded = base_h.round();
((rounded / 3.0).round() * 3.0).max(12.0)
} else {
0.0
};
let label_h = if show_colorbar { 70.0 * scale } else { 0.0 };
let tick_overflow = match &tick_direction {
crate::cli::TickDirection::Outward => (cbar_h * 0.5).max(6.0 * scale),
crate::cli::TickDirection::Inward => 0.0,
};
let height = outer_pad
+ map_h
+ map_pad
+ cbar_pad
+ cbar_h
+ label_h
+ tick_overflow
+ units_pad
+ outer_pad;
let map_x = outer_pad;
let map_y = outer_pad;
let cbar_y = map_y + map_h + map_pad + cbar_pad;
(
MollweideLayout {
width,
height,
map_pad,
map_x,
map_y,
map_w: width - 2.0 * outer_pad,
map_h,
cbar_x: outer_pad,
cbar_y,
cbar_w: width - 2.0 * outer_pad,
cbar_h,
cbar_pad,
border_width_px,
},
compute_cbar_layout(
crate::params::GeometryRect {
x: outer_pad,
y: cbar_y,
w: width - 2.0 * outer_pad,
h: cbar_h,
},
crate::params::ColorbarLayoutConfig {
label_pad,
image_width: width,
tick_direction,
custom_tick_font_size,
width_scale: 1.0,
},
),
)
}
fn compute_cbar_layout(
geom: crate::params::GeometryRect,
config: crate::params::ColorbarLayoutConfig,
) -> ColorbarLayout {
let tick_font_size = if let Some(custom) = config.custom_tick_font_size {
custom as f64
} else {
(12.0 * (config.image_width / 800.0)).clamp(7.0, 24.0)
};
ColorbarLayout {
x: geom.x,
y: geom.y,
w: geom.w,
h: geom.h,
tick_bottom: geom.y + geom.h,
major_tick_height: (geom.h * 0.5).round().max(1.0),
minor_tick_height: (geom.h * 0.3).round().max(1.0),
major_tick_width: ((geom.w * 0.002) * config.width_scale).round().max(1.0),
minor_tick_width: ((geom.w * 0.001) * config.width_scale).round().max(1.0),
tick_font_size,
tick_label_pad: geom.h + geom.y + config.label_pad,
tick_direction: config.tick_direction,
}
}
pub fn compute_gnomonic_layout(
map_size: f64,
show_colorbar: bool,
tick_direction: crate::cli::TickDirection,
show_text: bool,
show_title: bool,
) -> (MollweideLayout, ColorbarLayout) {
compute_gnomonic_layout_with_fonts(
map_size,
show_colorbar,
tick_direction,
show_text,
show_title,
None,
)
}
pub fn compute_gnomonic_layout_with_fonts(
map_size: f64,
show_colorbar: bool,
tick_direction: crate::cli::TickDirection,
show_text: bool,
show_title: bool,
custom_tick_font_size: Option<f32>,
) -> (MollweideLayout, ColorbarLayout) {
let scale = map_size / 1200.0;
let outer_pad = 24.0 * scale; let title_pad = if show_title {
32.0 * scale } else {
0.0
};
let left_text_pad = if show_text {
50.0 * scale } else {
0.0
};
let cbar_pad = 8.0 * scale; let label_pad = 4.0 * scale; let units_pad = if show_colorbar { -4.0 * scale } else { 0.0 };
let border_width_px = (map_size * 0.0025).max(2.0 * scale);
let map_pad = border_width_px.ceil() + 2.0 * scale;
let map_w = map_size;
let map_h = map_size;
let cbar_h = if show_colorbar {
let base_h = map_h / 25.0;
let rounded = base_h.round();
((rounded / 3.0).round() * 3.0).max(12.0)
} else {
0.0
};
let label_h = if show_colorbar { 120.0 * scale } else { 0.0 };
let tick_overflow = match &tick_direction {
crate::cli::TickDirection::Outward => (cbar_h * 0.5).max(6.0 * scale),
crate::cli::TickDirection::Inward => 0.0,
};
let height = outer_pad
+ title_pad
+ map_h
+ cbar_pad
+ cbar_h
+ label_h
+ tick_overflow
+ units_pad
+ outer_pad;
let map_x = outer_pad + (if show_text { left_text_pad } else { 0.0 });
let map_y = outer_pad + title_pad;
let cbar_y = map_y + map_h + cbar_pad;
let width = map_w + outer_pad + (if show_text { left_text_pad } else { 0.0 }) + outer_pad;
let width_scale = map_size / 1200.0;
(
MollweideLayout {
width,
height,
map_pad,
map_x,
map_y,
map_w,
map_h,
cbar_x: map_x, cbar_y,
cbar_w: map_w,
cbar_h,
cbar_pad,
border_width_px,
},
compute_cbar_layout(
crate::params::GeometryRect {
x: map_x,
y: cbar_y,
w: map_w,
h: cbar_h,
},
crate::params::ColorbarLayoutConfig {
label_pad,
image_width: width,
tick_direction,
custom_tick_font_size,
width_scale,
},
),
)
}