diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 8bef9c4..7484aa5 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -689,25 +689,25 @@ public class DlibDotNet private void MapLogic(string argZero, Container[] containers, long ticks, string dResultsFullGroupDirectory, string zResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, MapLogic mapLogic, string outputResolution) { - string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, $"({ticks})"); + string zPropertyHolderContentDirectory = Path.Combine(zResultsFullGroupDirectory, $"({ticks})"); mapLogic.UseKeyValuePairsSaveFaceEncoding(containers); foreach (Container container in containers) { mapLogic.AddToMapping(container.Items); if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution)) - mapLogic.SaveShortcuts(_Configuration.JuliePhares, dFacesContentDirectory, container.Items); + mapLogic.SaveShortcuts(_Configuration.JuliePhares, zPropertyHolderContentDirectory, container.Items); } mapLogic.SaveAllCollection(); if (_Configuration.SaveResizedSubfiles) { - string zPropertyHolderContentDirectory; + string dFacesContentDirectory; string zPropertyHolderSingletonDirectory; string zPropertyHolderCollectionDirectory; + dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()"); zPropertyHolderSingletonDirectory = Path.Combine(zResultsFullGroupDirectory, "{}"); - zPropertyHolderContentDirectory = Path.Combine(zResultsFullGroupDirectory, $"({ticks})"); zPropertyHolderCollectionDirectory = Path.Combine(zResultsFullGroupDirectory, $"[{ticks}]"); - mapLogic.SaveNotMappedPersonKeys(zPropertyHolderContentDirectory); - _ = LogDeltaInMinutes(ticks, nameof(mapLogic.SaveNotMappedPersonKeys)); + mapLogic.SaveNotMappedTicks(zPropertyHolderContentDirectory); + _ = LogDeltaInMinutes(ticks, nameof(mapLogic.SaveNotMappedTicks)); Dictionary> keyValuePairs = _Distance.ParallelWork(_AppSettings.MaxDegreeOfParallelism, _Configuration.IgnoreRelativePaths, argZero, ticks, mapLogic, containers); _ = LogDeltaInSeconds(ticks, nameof(E_Distance.ParallelWork)); Dictionary> strippedKeyValuePairs = Strip(keyValuePairs); diff --git a/Instance/Models/_E_Distance.cs b/Instance/Models/_E_Distance.cs index 7ef6f3a..b5e31a9 100644 --- a/Instance/Models/_E_Distance.cs +++ b/Instance/Models/_E_Distance.cs @@ -665,12 +665,8 @@ internal class E_Distance internal Dictionary> ParallelWork(int maxDegreeOfParallelism, string[] ignoreRelativePaths, string argZero, long ticks, Map.Models.MapLogic mapLogic, Container[] containers) { Dictionary> results; + mapLogic.ForceSingleImage(ignoreRelativePaths, argZero, containers); Dictionary> keyValuePairs = Map.Models.Stateless.IMapLogic.GetKeyValuePairs(ignoreRelativePaths, argZero, containers); - if (!keyValuePairs.Any()) - { - mapLogic.SetSingleImage(ignoreRelativePaths, argZero, containers); - keyValuePairs = Map.Models.Stateless.IMapLogic.GetKeyValuePairs(ignoreRelativePaths, argZero, containers); - } results = GetThreeSigmaFaceEncodings(maxDegreeOfParallelism, ticks, keyValuePairs); return results; } diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index e56e67c..ed860a3 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -10,8 +10,8 @@ namespace View_by_Distance.Map.Models; public class MapLogic { + protected readonly List _NotMappedTicks; protected readonly List _SkipCollection; - protected readonly List _NotMappedPersonKeys; protected readonly List<(int, string[])> _AllCollection; protected readonly Dictionary _KeyValuePairs; protected readonly Dictionary _IndicesFromNew; @@ -49,7 +49,7 @@ public class MapLogic string fullPath; List skipCollection = new(); Dictionary? keyValuePairs; - List notMappedPersonKeys = new(); + List notMappedTicks = new(); List>? collection; string deterministicHashCodeContentDirectory; Dictionary indicesFromNew = new(); @@ -72,7 +72,7 @@ public class MapLogic if (!Directory.Exists(deterministicHashCodeRootDirectory)) _ = Directory.CreateDirectory(deterministicHashCodeRootDirectory); deterministicHashCodeContentDirectory = Path.Combine(deterministicHashCodeRootDirectory, "()"); - Stateless.ByDeterministicHashCode.SetByRef(_ResizeFilenameExtension, people, skipCollection, peopleKeyValuePairs, notMappedPersonKeys, deterministicHashCodeUnknownFaceKeyValuePairs, deterministicHashCodeKeyValuePairs, incorrectDeterministicHashCodeKeyValuePairs, deterministicHashCodeRootDirectory, deterministicHashCodeContentDirectory); + Stateless.ByDeterministicHashCode.SetByRef(_ResizeFilenameExtension, people, skipCollection, peopleKeyValuePairs, notMappedTicks, deterministicHashCodeUnknownFaceKeyValuePairs, deterministicHashCodeKeyValuePairs, incorrectDeterministicHashCodeKeyValuePairs, deterministicHashCodeRootDirectory, deterministicHashCodeContentDirectory); if (!deterministicHashCodeUnknownFaceKeyValuePairs.Any()) sixCharacterNamedFaceInfo = new(); else @@ -119,7 +119,7 @@ public class MapLogic _KeyValuePairs = keyValuePairs; _IndicesFromNew = indicesFromNew; _SkipCollection = skipCollection; - _NotMappedPersonKeys = notMappedPersonKeys; + _NotMappedTicks = notMappedTicks; _PeopleKeyValuePairs = peopleKeyValuePairs; _SixCharacterNamedFaceInfo = sixCharacterNamedFaceInfo; _DeterministicHashCodeKeyValuePairs = deterministicHashCodeKeyValuePairs; @@ -158,16 +158,16 @@ public class MapLogic return results; } - public void SaveShortcuts(string[] juliePhares, string dFacesContentDirectory, List items) + public void SaveShortcuts(string[] juliePhares, string zPropertyHolderContentDirectory, List items) { string fileName; string fullName; string personKey; - DateTime? minimumDateTime; + DateTime minimumDateTime; PersonBirthday personBirthday; WindowsShortcut windowsShortcut; (string DisplayDirectoryName, int? ApproximateYears, PersonBirthday[] _, long Ticks) person; - List<(Item, (long?, Face?, (string, string, string, string))[])> collections = GetCollection(items, dFacesContentDirectory); + List<(Item, (long?, Face?, (string, string, string, string))[])> collections = GetCollection(items, zPropertyHolderContentDirectory); foreach ((Item item, (long? ticks, Face? _, (string, string, string, string))[] collection) in collections) { if (collection.Length != 1) @@ -179,8 +179,6 @@ public class MapLogic if (item.Property?.Id is null || item.ImageFileHolder is null || item.ResizedFileHolder is null) continue; minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); - if (minimumDateTime is null) - continue; if (!Directory.Exists(directory)) { _ = Directory.CreateDirectory(directory); @@ -206,12 +204,12 @@ public class MapLogic fileName = Path.Combine(directory, $"{item.Property.Id.Value}.lnk"); if (File.Exists(fileName)) continue; - windowsShortcut = new() { Path = item.ImageFileHolder.FullName }; + windowsShortcut = new() { Path = item.ResizedFileHolder.FullName }; windowsShortcut.Save(fileName); windowsShortcut.Dispose(); if (!File.Exists(fileName)) continue; - File.SetLastWriteTime(fileName, minimumDateTime.Value); + File.SetLastWriteTime(fileName, minimumDateTime); } } } @@ -314,6 +312,7 @@ public class MapLogic { long ticks; Mapping mapping; + bool forced = false; int? approximateYears; string displayDirectoryName; PersonBirthday personBirthday; @@ -344,7 +343,7 @@ public class MapLogic personBirthday = person.PersonBirthdays[0]; approximateYears = person.ApproximateYears; displayDirectoryName = person.DisplayDirectoryName; - mapping = new(approximateYears, displayDirectoryName, face.Location.NormalizedPixelPercentage, personBirthday); + mapping = new(approximateYears, displayDirectoryName, forced, face.Location.NormalizedPixelPercentage, personBirthday); item.Mapping.Add(mapping); } } @@ -362,7 +361,7 @@ public class MapLogic personBirthday = person.PersonBirthdays[0]; approximateYears = person.ApproximateYears; displayDirectoryName = person.DisplayDirectoryName; - mapping = new(approximateYears, displayDirectoryName, personBirthday); + mapping = new(approximateYears, displayDirectoryName, forced, personBirthday); item.Mapping.Add(mapping); } } @@ -420,7 +419,7 @@ public class MapLogic } } - public void SaveNotMappedPersonKeys(string zPropertyHolderContentDirectory) + public void SaveNotMappedTicks(string zPropertyHolderContentDirectory) { string directory; string personKey; @@ -428,7 +427,7 @@ public class MapLogic PersonBirthday personBirthday; List saveContainers = new(); const string facePopulatedKey = nameof(Closest); - foreach (long ticks in _NotMappedPersonKeys) + foreach (long ticks in _NotMappedTicks) { personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(ticks); personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); @@ -439,7 +438,7 @@ public class MapLogic SaveContainers(saveContainers); } - public List<(Item, (long?, Face?, (string, string, string, string))[])> GetCollection(List items, string dFacesContentDirectory) + public List<(Item, (long?, Face?, (string, string, string, string))[])> GetCollection(List items, string zPropertyHolderContentDirectory) { List<(Item, (long?, Face?, (string, string, string, string))[])> results = new(); int years; @@ -457,8 +456,8 @@ public class MapLogic string isWrongYearFlag; string shortcutFileName; string subDirectoryName; + DateTime minimumDateTime; List indices = new(); - DateTime? minimumDateTime; List faceCollection; PersonBirthday personBirthday; PersonBirthday[] personBirthdays; @@ -482,39 +481,37 @@ public class MapLogic { faceCollection = new(); ticks = null; - directory = Path.Combine(dFacesContentDirectory, $"Unnamed{relativePath[2..]}"); + directory = Path.Combine(zPropertyHolderContentDirectory, $"Unnamed{relativePath[2..]}"); } else { faceCollection = item.Faces; personBirthdays = _DeterministicHashCodeUnknownFaceKeyValuePairs[item.Property.Id.Value]; minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); - if (minimumDateTime is null) - continue; - (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime.Value); + (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime); isWrongYearFlag = Shared.Models.Stateless.Methods.IItem.GetWrongYearFlag(isWrongYear); - subDirectoryName = $"{isWrongYearFlag}{minimumDateTime.Value:yyyy}"; + subDirectoryName = $"{isWrongYearFlag}{minimumDateTime:yyyy}"; if (!faceCollection.Any()) { ticks = null; - directory = Path.Combine(dFacesContentDirectory, $"None{relativePath[2..]}", subDirectoryName); + directory = Path.Combine(zPropertyHolderContentDirectory, $"None{relativePath[2..]}", subDirectoryName); } else if (personBirthdays.Length != 1) { ticks = null; - directory = Path.Combine(dFacesContentDirectory, $"Not Supported{relativePath[2..]}", subDirectoryName); + directory = Path.Combine(zPropertyHolderContentDirectory, $"Not Supported{relativePath[2..]}", subDirectoryName); } else if (faceCollection.Count != 1) { ticks = null; - directory = Path.Combine(dFacesContentDirectory, $"Many{relativePath[2..]}", subDirectoryName); + directory = Path.Combine(zPropertyHolderContentDirectory, $"Many{relativePath[2..]}", subDirectoryName); } else { indices.Add(zero); personBirthday = personBirthdays[zero]; ticks = personBirthday.Value.Ticks; - timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime.Value, isWrongYear, personBirthday); + timeSpan = Shared.Models.Stateless.Methods.IPersonBirthday.GetTimeSpan(minimumDateTime, isWrongYear, personBirthday); if (timeSpan.HasValue) { if (timeSpan.Value.Ticks < 0) @@ -527,11 +524,11 @@ public class MapLogic } face = faceCollection[zero]; personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); - directory = Path.Combine(dFacesContentDirectory, "Shortcuts", personKey, subDirectoryName); + directory = Path.Combine(zPropertyHolderContentDirectory, "Shortcuts", personKey, subDirectoryName); if (face.FaceEncoding is not null && face.Location?.NormalizedPixelPercentage is not null) - copyDirectory = Path.Combine(dFacesContentDirectory, "Images", personKey, subDirectoryName); + copyDirectory = Path.Combine(zPropertyHolderContentDirectory, "Images", personKey, subDirectoryName); else - copyDirectory = Path.Combine(dFacesContentDirectory, "ImagesBut", personKey, subDirectoryName); + copyDirectory = Path.Combine(zPropertyHolderContentDirectory, "ImagesBut", personKey, subDirectoryName); copyFileName = Path.Combine(copyDirectory, $"{item.Property.Id.Value}{item.ResizedFileHolder.ExtensionLowered}"); } } @@ -550,27 +547,21 @@ public class MapLogic public void AddToClosest(int maxDegreeOfParallelism, string argZero, Container[] containers) { - long ticks; string key; string dateKey; Closest closest; string personKey; - const int zero = 0; DateTime minimumDateTime; Closest[] closestCollection; - PersonBirthday personBirthday; double deterministicHashCodeKey; DateTime dateTime = DateTime.Now; Dictionary keyValuePairs = new(); foreach (Container container in containers) { - if (!_NotMappedPersonKeys.Any()) - break; if (!container.Items.Any()) continue; if (!container.SourceDirectory.StartsWith(argZero)) continue; - ticks = _NotMappedPersonKeys[zero]; foreach (Item item in container.Items) { if (item.ImageFileHolder is null || item.Property is null) @@ -581,15 +572,14 @@ public class MapLogic continue; deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item, face); if (_DeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey)) - continue; - personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(ticks); + continue; minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); - closestCollection = Shared.Models.Stateless.Methods.IClosest.GetCollection(personBirthday, face, minimumDateTime, face.FaceDistances); + closestCollection = Shared.Models.Stateless.Methods.IClosest.GetCollection(face, minimumDateTime, face.FaceDistances); face.FaceDistances.Clear(); for (int j = 0; j < closestCollection.Length; j++) { closest = closestCollection[j]; - if (_IncorrectDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey) && _IncorrectDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey].Contains(personBirthday)) + if (_IncorrectDeterministicHashCodeKeyValuePairs.ContainsKey(deterministicHashCodeKey) && _IncorrectDeterministicHashCodeKeyValuePairs[deterministicHashCodeKey].Contains(closest.Mapping.PersonBirthday)) continue; personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(closest.Mapping.PersonBirthday); dateKey = Stateless.MapLogic.GetDateKey(dateTime, closest.Mapping, closest.MinimumDateTime, closest.IsWrongYear); @@ -663,6 +653,8 @@ public class MapLogic continue; foreach (Closest closest in item.Closest) { + if (closest.Mapping.Forced) + continue; if (closest.NormalizedPixelPercentage != face.Location.NormalizedPixelPercentage.Value) continue; throw new Exception(); @@ -728,6 +720,8 @@ public class MapLogic continue; foreach (Closest closest in item.Closest) { + if (closest.Mapping.Forced) + continue; if (closest.NormalizedPixelPercentage != face.Location.NormalizedPixelPercentage.Value) continue; throw new Exception(); @@ -792,6 +786,7 @@ public class MapLogic FileHolder faceFileHolder; string facePartsDirectory; SaveContainer saveContainer; + PersonBirthday personBirthday; FileHolder facePartsFileHolder; FileHolder hiddenFaceFileHolder; double deterministicHashCodeKey; @@ -829,11 +824,28 @@ public class MapLogic continue; foreach (Mapping mapping in item.Mapping) { + if (mapping.Forced) + continue; if (mapping.NormalizedPixelPercentage is null || mapping.NormalizedPixelPercentage.Value != face.Location.NormalizedPixelPercentage.Value) continue; throw new Exception(); } - personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(match.Mapping.PersonBirthday); + if (!match.AboveTolerance) + personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(match.Mapping.PersonBirthday); + else + { + personKey = string.Empty; + foreach (long ticks in _NotMappedTicks) + { + if (ticks == match.Mapping.PersonBirthday.Value.Ticks) + continue; + personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(ticks); + personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(personBirthday); + break; + } + if (string.IsNullOrEmpty(personKey)) + personKey = Shared.Models.Stateless.Methods.IPersonBirthday.GetFormatted(match.Mapping.PersonBirthday); + } dateKey = Stateless.MapLogic.GetDateKey(dateTime, match.Mapping, match.MinimumDateTime, match.IsWrongYear); directory = Path.Combine(zPropertyHolderContentDirectory, facePopulatedKey, personKey, dateKey); personDirectory = Path.Combine(directory, match.Mapping.DisplayDirectoryName[..1], "lnk"); @@ -902,17 +914,22 @@ public class MapLogic SaveContainers(saveContainers); } - public void SetSingleImage(string[] ignoreRelativePaths, string argZero, Container[] containers) + public void ForceSingleImage(string[] ignoreRelativePaths, string argZero, Container[] containers) { + Closest closest; Mapping mapping; + bool? isWrongYear; long? ticks = null; const int zero = 0; + bool forced = true; + DateTime minimumDateTime; + bool aboveTolerance = false; int? approximateYears = null; PersonBirthday personBirthday; const string displayDirectoryName = Property.Models.Stateless.IResult.AllInOne; foreach (Container container in containers) { - if (!_NotMappedPersonKeys.Any()) + if (!_NotMappedTicks.Any()) break; if (!container.Items.Any()) continue; @@ -922,15 +939,19 @@ public class MapLogic continue; foreach (Item item in container.Items) { - if (item.ImageFileHolder is null || item.Property?.Id is null) + if (item.ImageFileHolder is null || item.Property?.Id is null || item.Mapping.Any()) continue; foreach (Face face in item.Faces) { if (face.FaceEncoding is null || face.Location?.NormalizedPixelPercentage is null) continue; - ticks = _NotMappedPersonKeys[zero]; + ticks = _NotMappedTicks[zero]; + minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); + (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder.FullName, minimumDateTime); personBirthday = Shared.Models.Stateless.Methods.IPersonBirthday.GetPersonBirthday(ticks.Value); - mapping = new(approximateYears, displayDirectoryName, face.Location.NormalizedPixelPercentage, personBirthday); + mapping = new(approximateYears, displayDirectoryName, forced, face.Location.NormalizedPixelPercentage, personBirthday); + closest = new(aboveTolerance, zero, face.Location.NormalizedPixelPercentage.Value, isWrongYear, mapping, zero, minimumDateTime, null); + item.Closest.Add(closest); item.Mapping.Add(mapping); if (ticks is not null) break; diff --git a/Map/Models/Stateless/SetByDeterministicHashCode.cs b/Map/Models/Stateless/SetByDeterministicHashCode.cs index ec57238..971627d 100644 --- a/Map/Models/Stateless/SetByDeterministicHashCode.cs +++ b/Map/Models/Stateless/SetByDeterministicHashCode.cs @@ -231,7 +231,7 @@ public class ByDeterministicHashCode } } - internal static void SetByRef(string resizeFilenameExtension, Person[] people, List skipCollection, Dictionary peopleKeyValuePairs, List notMappedPersonKeys, Dictionary deterministicHashCodeUnknownFaceKeyValuePairs, Dictionary deterministicHashCodeKeyValuePairs, Dictionary incorrectDeterministicHashCodeKeyValuePairs, string deterministicHashCodeRootDirectory, string deterministicHashCodeContentDirectory) + internal static void SetByRef(string resizeFilenameExtension, Person[] people, List skipCollection, Dictionary peopleKeyValuePairs, List notMappedTicks, Dictionary deterministicHashCodeUnknownFaceKeyValuePairs, Dictionary deterministicHashCodeKeyValuePairs, Dictionary incorrectDeterministicHashCodeKeyValuePairs, string deterministicHashCodeRootDirectory, string deterministicHashCodeContentDirectory) { Dictionary> keyValuePairs = new(); List deterministicHashCodePersonKeys = new(); @@ -271,7 +271,7 @@ public class ByDeterministicHashCode if (deterministicHashCodeUnknownFacePersonKeys.Contains(ticks) || deterministicHashCodePersonKeys.Contains(ticks)) peopleKeyValuePairs.Add(ticks, new(displayDirectoryName, approximateYears, personBirthdays, ticks)); else - notMappedPersonKeys.Add(ticks); + notMappedTicks.Add(ticks); } } if (deterministicHashCodeUnknownFacePersonKeys.Any() || deterministicHashCodePersonKeys.Any()) diff --git a/Shared/Models/Closest.cs b/Shared/Models/Closest.cs index 0d64e2f..7869288 100644 --- a/Shared/Models/Closest.cs +++ b/Shared/Models/Closest.cs @@ -6,6 +6,7 @@ namespace View_by_Distance.Shared.Models; public class Closest : Properties.IClosest { + protected readonly bool _AboveTolerance; protected readonly int _Average; protected readonly bool? _IsWrongYear; protected Mapping _Mapping; @@ -13,6 +14,7 @@ public class Closest : Properties.IClosest protected readonly DateTime _MinimumDateTime; protected readonly int _NormalizedPixelPercentage; protected readonly long? _TicksDelta; + public bool AboveTolerance => _AboveTolerance; public double Average => _Average; public bool? IsWrongYear => _IsWrongYear; public Mapping Mapping => _Mapping; @@ -22,8 +24,9 @@ public class Closest : Properties.IClosest public long? TicksDelta => _TicksDelta; [JsonConstructor] - public Closest(int average, int normalizedPixelPercentage, bool? isWrongYear, Mapping mapping, double minimum, DateTime minimumDateTime, long? ticksDelta) + public Closest(bool aboveTolerance, int average, int normalizedPixelPercentage, bool? isWrongYear, Mapping mapping, double minimum, DateTime minimumDateTime, long? ticksDelta) { + _AboveTolerance = aboveTolerance; _Average = average; _NormalizedPixelPercentage = normalizedPixelPercentage; _IsWrongYear = isWrongYear; diff --git a/Shared/Models/Mapping.cs b/Shared/Models/Mapping.cs index fd09112..8ed36fa 100644 --- a/Shared/Models/Mapping.cs +++ b/Shared/Models/Mapping.cs @@ -6,33 +6,36 @@ namespace View_by_Distance.Shared.Models; public class Mapping : Properties.IMapping { - protected readonly int? _ApproximateYears; + protected int? _ApproximateYears; protected readonly string _DisplayDirectoryName; protected bool? _Filtered; + protected bool _Forced; protected readonly int? _NormalizedPixelPercentage; protected PersonBirthday _PersonBirthday; public int? ApproximateYears => _ApproximateYears; public string DisplayDirectoryName => _DisplayDirectoryName; public bool? Filtered => _Filtered; + public bool Forced => _Forced; public int? NormalizedPixelPercentage => _NormalizedPixelPercentage; public PersonBirthday PersonBirthday => _PersonBirthday; [JsonConstructor] - public Mapping(int? approximateYears, string displayDirectoryName, bool? filtered, int? normalizedPixelPercentage, PersonBirthday personBirthday) + public Mapping(int? approximateYears, string displayDirectoryName, bool? filtered, bool forced, int? normalizedPixelPercentage, PersonBirthday personBirthday) { _ApproximateYears = approximateYears; _DisplayDirectoryName = displayDirectoryName; _Filtered = filtered; + _Forced = forced; _NormalizedPixelPercentage = normalizedPixelPercentage; _PersonBirthday = personBirthday; } - public Mapping(int? approximateYears, string displayDirectoryName, int? normalizedPixelPercentage, PersonBirthday personBirthday) : - this(approximateYears, displayDirectoryName, null, normalizedPixelPercentage, personBirthday) + public Mapping(int? approximateYears, string displayDirectoryName, bool forced, int? normalizedPixelPercentage, PersonBirthday personBirthday) : + this(approximateYears, displayDirectoryName, null, forced, normalizedPixelPercentage, personBirthday) { } - public Mapping(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday) : - this(approximateYears, displayDirectoryName, null, null, personBirthday) + public Mapping(int? approximateYears, string displayDirectoryName, bool forced, PersonBirthday personBirthday) : + this(approximateYears, displayDirectoryName, null, forced, null, personBirthday) { } public override string ToString() @@ -45,6 +48,4 @@ public class Mapping : Properties.IMapping public void SetFiltered(bool value) => _Filtered = value; - public void SetPersonBirthday(PersonBirthday personBirthday) => _PersonBirthday = personBirthday; - } \ No newline at end of file diff --git a/Shared/Models/Properties/IMapping.cs b/Shared/Models/Properties/IMapping.cs index 15a6ad4..1eff0a4 100644 --- a/Shared/Models/Properties/IMapping.cs +++ b/Shared/Models/Properties/IMapping.cs @@ -6,6 +6,7 @@ public interface IMapping public int? ApproximateYears { get; } public string DisplayDirectoryName { get; } public bool? Filtered { get; } + public bool Forced { get; } public int? NormalizedPixelPercentage { get; } public PersonBirthday PersonBirthday { get; } diff --git a/Shared/Models/Stateless/Methods/Closest.cs b/Shared/Models/Stateless/Methods/Closest.cs index e769336..b79e311 100644 --- a/Shared/Models/Stateless/Methods/Closest.cs +++ b/Shared/Models/Stateless/Methods/Closest.cs @@ -3,14 +3,15 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class Closest { - private static int Get(List faceDistances) => (int)(Math.Round(faceDistances.Average(), Stateless.IClosest.Digits) * Stateless.ILocation.Factor); + private static int Get(double rawAverage) => (int)(Math.Round(rawAverage, Stateless.IClosest.Digits) * Stateless.ILocation.Factor); - private static Models.Closest Get(Models.PersonBirthday personBirthday, Models.Face face, DateTime minimumDateTime, FaceDistance faceDistance) + private static Models.Closest Get(Models.Face face, DateTime minimumDateTime, FaceDistance faceDistance) { Models.Closest result; - int average = Get(faceDistance.Distances); - double minimum = faceDistance.Distances.Min(); long? ticksDelta; + double minimum = faceDistance.Distances.Min(); + double rawAverage = faceDistance.Distances.Average(); + bool aboveTolerance = minimum >= Stateless.IClosest.Tolerance || rawAverage >= Stateless.IClosest.Tolerance; if (faceDistance.IsWrongYear is null || faceDistance.IsWrongYear.Value) ticksDelta = null; else @@ -18,19 +19,20 @@ internal abstract class Closest ticksDelta = Math.Abs(faceDistance.MinimumDateTime.Ticks - minimumDateTime.Ticks); if (faceDistance.MinimumDateTime < faceDistance.Mapping.PersonBirthday.Value) ticksDelta *= 2; + else if (faceDistance.Mapping.ApproximateYears.HasValue && faceDistance.MinimumDateTime < DateTime.Now.AddYears(-faceDistance.Mapping.ApproximateYears.Value)) + ticksDelta *= 2; } - if (minimum > Stateless.IClosest.Tolerance) - faceDistance.Mapping.SetPersonBirthday(personBirthday); if (face.Location?.NormalizedPixelPercentage is null) throw new NullReferenceException(nameof(face.Location.NormalizedPixelPercentage)); - result = new(average, face.Location.NormalizedPixelPercentage.Value, faceDistance.IsWrongYear, faceDistance.Mapping, minimum, faceDistance.MinimumDateTime, ticksDelta); + int average = Get(rawAverage); + result = new(aboveTolerance, average, face.Location.NormalizedPixelPercentage.Value, faceDistance.IsWrongYear, faceDistance.Mapping, minimum, faceDistance.MinimumDateTime, ticksDelta); return result; } - internal static Models.Closest[] GetCollection(Models.PersonBirthday personBirthday, Models.Face face, DateTime minimumDateTime, List faceDistances) + internal static Models.Closest[] GetCollection(Models.Face face, DateTime minimumDateTime, List faceDistances) { Models.Closest[] results; - Models.Closest[] closestCollection = (from l in faceDistances select Get(personBirthday, face, minimumDateTime, l)).ToArray(); + Models.Closest[] closestCollection = (from l in faceDistances select Get(face, minimumDateTime, l)).ToArray(); results = (from l in closestCollection orderby l.Average, l.TicksDelta.HasValue, l.TicksDelta select l).ToArray(); return results; } diff --git a/Shared/Models/Stateless/Methods/IClosest.cs b/Shared/Models/Stateless/Methods/IClosest.cs index 62eb2d1..027faad 100644 --- a/Shared/Models/Stateless/Methods/IClosest.cs +++ b/Shared/Models/Stateless/Methods/IClosest.cs @@ -5,6 +5,6 @@ public interface IClosest Models.Closest[] TestStatic_Get(List faceDistances); - static Models.Closest[] GetCollection(Models.PersonBirthday personBirthday, Models.Face face, DateTime minimumDateTime, List faceDistances) => Closest.GetCollection(personBirthday, face, minimumDateTime, faceDistances); + static Models.Closest[] GetCollection(Models.Face face, DateTime minimumDateTime, List faceDistances) => Closest.GetCollection(face, minimumDateTime, faceDistances); } \ No newline at end of file