More natural grouping.
Make groups no shorter than 8 and no longer than 16 photos. Also, make time and not only number of images a factor when deciding which group to split next.
This commit is contained in:
parent
3071431452
commit
858f873f98
@ -48,31 +48,36 @@ pub struct PhotoLink {
|
||||
|
||||
impl PhotoLink {
|
||||
fn for_group(g: &[Photo], base_url: &str) -> PhotoLink {
|
||||
PhotoLink {
|
||||
href: format!(
|
||||
"{}?from={}&to={}",
|
||||
base_url,
|
||||
g.last().map(|p| p.id).unwrap_or(0),
|
||||
g.first().map(|p| p.id).unwrap_or(0),
|
||||
),
|
||||
id: g.iter()
|
||||
.max_by_key(|p| {
|
||||
p.grade.unwrap_or(27) + if p.is_public { 38 } else { 0 }
|
||||
})
|
||||
.map(|p| p.id)
|
||||
.unwrap_or(0),
|
||||
lable: Some(format!(
|
||||
"{} - {} ({})",
|
||||
g.last()
|
||||
.and_then(|p| p.date)
|
||||
.map(|d| format!("{}", d.format("%F %T")))
|
||||
.unwrap_or_else(|| "-".to_string()),
|
||||
g.first()
|
||||
.and_then(|p| p.date)
|
||||
.map(|d| format!("{}", d.format("%F %T")))
|
||||
.unwrap_or_else(|| "-".to_string()),
|
||||
g.len(),
|
||||
)),
|
||||
if g.len() == 1 {
|
||||
PhotoLink::from(&g[0])
|
||||
} else {
|
||||
fn imgscore(p: &Photo) -> i16 {
|
||||
p.grade.unwrap_or(27) + if p.is_public { 38 } else { 0 }
|
||||
}
|
||||
PhotoLink {
|
||||
href: format!(
|
||||
"{}?from={}&to={}",
|
||||
base_url,
|
||||
g.last().map(|p| p.id).unwrap_or(0),
|
||||
g.first().map(|p| p.id).unwrap_or(0),
|
||||
),
|
||||
id: g.iter()
|
||||
.max_by_key(|ref p| imgscore(p))
|
||||
.map(|ref p| p.id)
|
||||
.unwrap_or(0),
|
||||
lable: Some(format!(
|
||||
"{} - {} ({})",
|
||||
g.last()
|
||||
.and_then(|p| p.date)
|
||||
.map(|d| format!("{}", d.format("%F %T")))
|
||||
.unwrap_or_else(|| "-".to_string()),
|
||||
g.first()
|
||||
.and_then(|p| p.date)
|
||||
.map(|d| format!("{}", d.format("%F %T")))
|
||||
.unwrap_or_else(|| "-".to_string()),
|
||||
g.len(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,10 +36,12 @@ pub fn links_by_time<'a>(
|
||||
}
|
||||
|
||||
pub fn split_to_groups(photos: &[Photo]) -> Option<Vec<&[Photo]>> {
|
||||
if photos.len() < 42 {
|
||||
return None;
|
||||
}
|
||||
let wanted_groups = (photos.len() as f64).sqrt() as usize;
|
||||
let wanted_groups = match photos.len() {
|
||||
l if l <= 16 => return None,
|
||||
l if l < 81 => 8,
|
||||
l if l >= 225 => 15,
|
||||
l => (l as f64).sqrt() as usize,
|
||||
};
|
||||
let mut groups = vec![&photos[..]];
|
||||
while groups.len() < wanted_groups {
|
||||
let i = find_largest(&groups);
|
||||
@ -52,10 +54,13 @@ pub fn split_to_groups(photos: &[Photo]) -> Option<Vec<&[Photo]>> {
|
||||
|
||||
fn find_largest(groups: &[&[Photo]]) -> usize {
|
||||
let mut found = 0;
|
||||
let mut largest = 0;
|
||||
let mut largest = 0.0;
|
||||
for (i, g) in groups.iter().enumerate() {
|
||||
if g.len() > largest {
|
||||
largest = g.len();
|
||||
let time = 1 + g.first().map(|p| timestamp(p)).unwrap_or(0)
|
||||
- g.last().map(|p| timestamp(p)).unwrap_or(0);
|
||||
let score = (g.len() as f64).powi(3) * (time as f64);
|
||||
if score > largest {
|
||||
largest = score;
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
@ -64,9 +69,10 @@ fn find_largest(groups: &[&[Photo]]) -> usize {
|
||||
|
||||
fn split(group: &[Photo]) -> (&[Photo], &[Photo]) {
|
||||
let l = group.len();
|
||||
let edge = l / 16;
|
||||
let mut pos = 0;
|
||||
let mut dist = 0;
|
||||
for i in l / 8..l - l / 8 - 1 {
|
||||
for i in edge..l - 1 - edge {
|
||||
let tttt = timestamp(&group[i]) - timestamp(&group[i + 1]);
|
||||
if tttt > dist {
|
||||
dist = tttt;
|
||||
|
Loading…
Reference in New Issue
Block a user