Removed both

faceDistanceLength.Length.Value / distanceTolerance
and
confidence / rangeFaceConfidence[1]
Removed ReviewLocationContainerDistanceTolerance
Added MoveToDecade
IFaceDistance.MappingFromFilterPost
ISorting.CanReMap
This commit is contained in:
Mike Phares 2023-09-04 23:25:31 -07:00
parent 600f6e7e2b
commit b2e2a66101
23 changed files with 275 additions and 239 deletions

View File

@ -26,7 +26,6 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
private readonly Serilog.ILogger? _Log; private readonly Serilog.ILogger? _Log;
private readonly int _FaceConfidencePercent; private readonly int _FaceConfidencePercent;
private readonly bool _DistanceRenameToMatch; private readonly bool _DistanceRenameToMatch;
private readonly float[] _RangeFaceConfidence;
private readonly bool _DistanceMoveUnableToMatch; private readonly bool _DistanceMoveUnableToMatch;
private readonly float _RectangleIntersectMinimum; private readonly float _RectangleIntersectMinimum;
private readonly List<string> _AllMappedFaceFiles; private readonly List<string> _AllMappedFaceFiles;
@ -34,7 +33,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
private readonly double _RangeDistanceToleranceAverage; private readonly double _RangeDistanceToleranceAverage;
private readonly List<string> _DuplicateMappedFaceFiles; private readonly List<string> _DuplicateMappedFaceFiles;
public E_Distance(bool distanceMoveUnableToMatch, bool distanceRenameToMatch, int faceConfidencePercent, float[] rangeDistanceTolerance, float[] rangeFaceConfidence, float[] rectangleIntersectMinimums) public E_Distance(bool distanceMoveUnableToMatch, bool distanceRenameToMatch, int faceConfidencePercent, float[] rangeDistanceTolerance, float[] rectangleIntersectMinimums)
{ {
_Debug = new(); _Debug = new();
_Moved = new(); _Moved = new();
@ -42,7 +41,6 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
_AllMappedFaceFiles = new(); _AllMappedFaceFiles = new();
_AllMappedFaceFileNames = new(); _AllMappedFaceFileNames = new();
_DuplicateMappedFaceFiles = new(); _DuplicateMappedFaceFiles = new();
_RangeFaceConfidence = rangeFaceConfidence;
_Log = Serilog.Log.ForContext<E_Distance>(); _Log = Serilog.Log.ForContext<E_Distance>();
_DistanceRenameToMatch = distanceRenameToMatch; _DistanceRenameToMatch = distanceRenameToMatch;
_FaceConfidencePercent = faceConfidencePercent; _FaceConfidencePercent = faceConfidencePercent;
@ -70,14 +68,16 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
{ {
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
throw new NotSupportedException(); throw new NotSupportedException();
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, _RangeFaceConfidence, face.Location.Confidence); if (face.Mapping?.MappingFromFilterPost is null)
throw new NotSupportedException();
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_FaceConfidencePercent, face.Location.Confidence);
wholePercentages = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution); wholePercentages = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding) if (face.FaceDistance?.Encoding is not null && face.FaceDistance.Encoding is FaceRecognitionDotNet.FaceEncoding faceEncoding)
faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages);
else else
{ {
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages); faceDistance = new(confidencePercent, mappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping?.MappingFromFilterPost, mappingFromItem.Id, mappingFromItem.IsWrongYear, wholePercentages);
lock (intersectFaces) lock (intersectFaces)
face.SetFaceDistance(faceDistance); face.SetFaceDistance(faceDistance);
} }
@ -336,7 +336,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
File.WriteAllLines(eDistanceContentFileName, results); File.WriteAllLines(eDistanceContentFileName, results);
} }
public static void SetFaceDistances(int maxDegreeOfParallelism, long ticks, ReadOnlyCollection<Face> distinctFilteredFaces) public static void PreFilterSetFaceDistances(int maxDegreeOfParallelism, long ticks, ReadOnlyCollection<Face> distinctFilteredFaces)
{ {
List<Face> faces = new(); List<Face> faces = new();
foreach (Face face in distinctFilteredFaces) foreach (Face face in distinctFilteredFaces)
@ -362,7 +362,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
throw new NotSupportedException(); throw new NotSupportedException();
progressBar.Tick(); progressBar.Tick();
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding); faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); FaceDistance faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages);
lock (face) lock (face)
face.SetFaceDistance(faceDistance); face.SetFaceDistance(faceDistance);
}); });
@ -419,7 +419,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
throw new NotSupportedException(); throw new NotSupportedException();
if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding) if (face.FaceDistance?.Encoding is not FaceRecognitionDotNet.FaceEncoding faceEncoding)
continue; continue;
faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages); faceDistance = new(face.Mapping.MappingFromLocation.ConfidencePercent, face.Mapping.MappingFromItem.GetDateTimeOriginalThenMinimumDateTime(), faceEncoding, face.Mapping.MappingFromFilterPost, face.Mapping.MappingFromItem.Id, face.Mapping.MappingFromItem.IsWrongYear, face.Mapping.MappingFromLocation.WholePercentages);
faceDistanceContainer = new(face, faceDistance); faceDistanceContainer = new(face, faceDistance);
collection.Add(faceDistanceContainer); collection.Add(faceDistanceContainer);
} }
@ -489,90 +489,6 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
return results; return results;
} }
private static void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, DateTime dateTime, DateTime yesterday, List<Record> records)
{
FileInfo fileInfo;
List<string> files = new();
FaceDistance? faceDistanceEncoding;
List<FaceDistance> faceDistanceLengths;
List<string> firstPassFailures = new();
List<FaceDistance> faceDistanceEncodings = new();
faceDistanceEncoding = new(records[0].FaceRecognitionDotNetFaceEncoding);
foreach (Record record in records)
{
files.Add(record.File);
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
}
if (faceDistanceEncoding is null)
throw new NullReferenceException(nameof(faceDistanceEncoding));
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
if (faceDistanceLengths.Count != files.Count)
throw new Exception();
for (int i = 0; i < files.Count; i++)
{
if (faceDistanceLengths[i].Length < locationContainerDistanceTolerance)
continue;
firstPassFailures.Add(files[i]);
}
faceDistanceEncoding = new(records[^1].FaceRecognitionDotNetFaceEncoding);
foreach (Record record in records)
{
files.Add(record.File);
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
}
if (faceDistanceEncoding is null)
throw new NullReferenceException(nameof(faceDistanceEncoding));
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
if (faceDistanceLengths.Count != files.Count)
throw new Exception();
for (int i = 0; i < files.Count; i++)
{
fileInfo = new(files[i]);
if (!fileInfo.Exists)
continue;
if (fileInfo.CreationTime > yesterday)
File.SetCreationTime(fileInfo.FullName, yesterday);
if (faceDistanceLengths[i].Length < locationContainerDistanceTolerance)
continue;
if (firstPassFailures.Contains(fileInfo.FullName))
continue;
File.SetCreationTime(fileInfo.FullName, dateTime);
}
}
void IDistance<MetadataExtractor.Directory>.ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
{
string? json;
List<Record> records = new();
int? lastDirectoryNumber = null;
DateTime dateTime = DateTime.Now;
DateTime yesterday = DateTime.Now.AddDays(-1);
Shared.Models.FaceEncoding? modelsFaceEncoding;
FaceRecognitionDotNet.FaceEncoding faceRecognitionDotNetFaceEncoding;
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
{
if (locationContainer.DirectoryNumber is null)
continue;
if (lastDirectoryNumber is not null && locationContainer.DirectoryNumber.Value != lastDirectoryNumber.Value)
{
if (records.Count > 2)
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, records);
records.Clear();
}
json = Metadata.Models.Stateless.Methods.IMetadata.GetFaceEncoding(locationContainer.Directories);
if (json is null)
continue;
modelsFaceEncoding = JsonSerializer.Deserialize<Shared.Models.FaceEncoding>(json);
if (modelsFaceEncoding is null)
throw new NotSupportedException();
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
lastDirectoryNumber = locationContainer.DirectoryNumber.Value;
}
if (records.Count > 2)
ReviewLocationContainerDistanceTolerance(locationContainerDistanceTolerance, dateTime, yesterday, records);
}
private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory) private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory)
{ {
string json; string json;
@ -622,14 +538,17 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
} }
} }
private static void SaveMappedForOutputResolutions(string eDistanceContentDirectory, float distanceTolerance, string personKeyFormatted, string? displayDirectoryName, List<Record> records, string directory) private static void SaveMappedForOutputResolutions(string eDistanceContentDirectory, float distanceTolerance, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName, List<Record> records, string directory)
{ {
int years;
string text; string text;
string fileName; string fileName;
FileInfo fileInfo; FileInfo fileInfo;
List<string> files = new(); List<string> files = new();
List<string> lines = new(); List<string> lines = new();
List<Mapped> results = new();
List<string> linkedOnce = new(); List<string> linkedOnce = new();
long ticks = DateTime.Now.Ticks;
string fileNameWithoutExtension; string fileNameWithoutExtension;
List<string> linkedTwice = new(); List<string> linkedTwice = new();
List<string> linkedThrice = new(); List<string> linkedThrice = new();
@ -639,7 +558,6 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
Uri uri = new(eDistanceContentDirectory); Uri uri = new(eDistanceContentDirectory);
Dictionary<string, int> keyValuePairs = new(); Dictionary<string, int> keyValuePairs = new();
List<FaceDistance> faceDistanceEncodings = new(); List<FaceDistance> faceDistanceEncodings = new();
List<Mapped> results = new();
foreach (Record record in records) foreach (Record record in records)
{ {
files.Add(record.File); files.Add(record.File);
@ -689,6 +607,10 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
continue; continue;
} }
} }
if (isCounterPersonYear)
(years, _) = Shared.Models.Stateless.Methods.IAge.GetAge(ticks, fileInfo.CreationTime.Ticks);
else
(years, _) = Shared.Models.Stateless.Methods.IAge.GetAge(fileInfo.CreationTime.Ticks, personKey);
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileInfo.Name)); fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileInfo.Name));
lines.Add("---"); lines.Add("---");
lines.Add("type: \"distance\""); lines.Add("type: \"distance\"");
@ -701,6 +623,10 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
lines.Add(string.Empty); lines.Add(string.Empty);
lines.Add($"![0]({uri.MakeRelativeUri(new(record.File)).OriginalString})"); lines.Add($"![0]({uri.MakeRelativeUri(new(record.File)).OriginalString})");
lines.Add($"__{fileNameWithoutExtension}__"); lines.Add($"__{fileNameWithoutExtension}__");
if (isCounterPersonYear)
lines.Add($"#{years}yrs-ago");
else
lines.Add($"#{years}yrs-old");
lines.Add(string.Empty); lines.Add(string.Empty);
lines.AddRange(results.Select(l => $"{l.Image}{Environment.NewLine}{l.Link}{Environment.NewLine}")); lines.AddRange(results.Select(l => $"{l.Image}{Environment.NewLine}{l.Link}{Environment.NewLine}"));
text = string.Join(Environment.NewLine, lines); text = string.Join(Environment.NewLine, lines);
@ -710,7 +636,7 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
MoveFiles(keyValuePairs, linkedOnce, linkedTwice, linkedThrice); MoveFiles(keyValuePairs, linkedOnce, linkedTwice, linkedThrice);
} }
void IDistance<MetadataExtractor.Directory>.SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float[] rangeDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, string personKeyFormatted, string? displayDirectoryName) void IDistance<MetadataExtractor.Directory>.SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName)
{ {
string? json; string? json;
List<Record> records = new(); List<Record> records = new();
@ -727,13 +653,13 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding); faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding)); records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
} }
string directory = Path.Combine(a2PeopleContentDirectory, rangeDistanceTolerance[1].ToString(), personKeyFormatted); string directory = Path.Combine(a2PeopleContentDirectory, locationContainerDistanceTolerance.ToString(), personKeyFormatted);
if (!Directory.Exists(directory)) if (!Directory.Exists(directory))
_ = Directory.CreateDirectory(directory); _ = Directory.CreateDirectory(directory);
if (records.Count > 0) if (records.Count > 0)
{ {
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory); WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
SaveMappedForOutputResolutions(eDistanceContentDirectory, rangeDistanceTolerance[1], personKeyFormatted, displayDirectoryName, records, directory); SaveMappedForOutputResolutions(eDistanceContentDirectory, locationContainerDistanceTolerance, personKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, records, directory);
} }
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directory); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directory);
} }

View File

@ -344,7 +344,7 @@ public class D2_FaceParts
if (File.Exists(checkFile)) if (File.Exists(checkFile))
File.Delete(checkFile); File.Delete(checkFile);
} }
else if (face.Mapping?.MappingFromFilter.InSkipCollection is not null && face.Mapping.MappingFromFilter.InSkipCollection.Value) else if (face.Mapping?.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
{ {
if (File.Exists(checkFile)) if (File.Exists(checkFile))
File.Delete(checkFile); File.Delete(checkFile);

View File

@ -39,7 +39,7 @@ public partial class DlibDotNet
private readonly Models.Configuration _Configuration; private readonly Models.Configuration _Configuration;
private readonly bool _ArgZeroIsConfigurationRootDirectory; private readonly bool _ArgZeroIsConfigurationRootDirectory;
private readonly Map.Models.Configuration _MapConfiguration; private readonly Map.Models.Configuration _MapConfiguration;
private readonly List<(string, long)> _JLinkResolvedDirectories; private readonly List<(string Directory, long PersonKey)> _JLinkResolvedDirectories;
public DlibDotNet( public DlibDotNet(
List<string> args, List<string> args,
@ -107,7 +107,7 @@ public partial class DlibDotNet
_FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages); _FaceParts = new D2_FaceParts(_Configuration.PropertyConfiguration, imageCodecInfo, encoderParameters, filenameExtension, configuration.CheckDFaceAndUpWriteDates, configuration.OverrideForFaceLandmarkImages);
} }
_MapConfiguration = Get(configuration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension); _MapConfiguration = Get(configuration, _Faces.FileNameExtension, _Faces.HiddenFileNameExtension, _FaceParts.FileNameExtension);
_Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RangeFaceConfidence, configuration.RectangleIntersectMinimums); _Distance = new(configuration.DistanceMoveUnableToMatch, configuration.DistanceRenameToMatch, configuration.FaceConfidencePercent, configuration.RangeDistanceTolerance, configuration.RectangleIntersectMinimums);
if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory) if (_PropertyRootExistedBefore || !_ArgZeroIsConfigurationRootDirectory)
personContainers = new(new List<PersonContainer>()); personContainers = new(new List<PersonContainer>());
else else
@ -256,7 +256,7 @@ public partial class DlibDotNet
a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])"); a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])");
eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), _Configuration.PropertyConfiguration.ResultContent); eDistanceContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(E_Distance), _Configuration.PropertyConfiguration.ResultContent);
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), _Configuration.PropertyConfiguration.ResultSingleton); string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), _Configuration.PropertyConfiguration.ResultSingleton);
_ = Directory.CreateDirectory(Path.Combine(eDistanceContentDirectory, $"({ticks})")); _ = Directory.CreateDirectory(Path.Combine(eDistanceContentDirectory, $"{ticks}"));
if (runToDoCollectionFirst) if (runToDoCollectionFirst)
mapLogic = null; mapLogic = null;
else else
@ -338,7 +338,7 @@ public partial class DlibDotNet
} }
_Distance.Clear(); _Distance.Clear();
ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctFilteredItems); ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctFilteredItems);
ReadOnlyCollection<Mapping> distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, containers, mapLogic, distinctItems: true); ReadOnlyCollection<Mapping> distinctFilteredMappingCollection = SetCreationTimeAndGetMappings(_Configuration.PropertyConfiguration, eDistanceContentDirectory, containers, mapLogic, distinctItems: true);
if (runToDoCollectionFirst) if (runToDoCollectionFirst)
{ {
string json = JsonSerializer.Serialize(distinctFilteredMappingCollection); string json = JsonSerializer.Serialize(distinctFilteredMappingCollection);
@ -556,7 +556,7 @@ public partial class DlibDotNet
} }
} }
private ReadOnlyCollection<Mapping> GetMappings(Property.Models.Configuration propertyConfiguration, Container[] containers, MapLogic mapLogic, bool distinctItems) private ReadOnlyCollection<Mapping> SetCreationTimeAndGetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, Container[] containers, MapLogic mapLogic, bool distinctItems)
{ {
ReadOnlyCollection<Mapping> results; ReadOnlyCollection<Mapping> results;
int count = 0; int count = 0;
@ -602,7 +602,8 @@ public partial class DlibDotNet
mappingCollection.Add(face.Mapping); mappingCollection.Add(face.Mapping);
if (face.Mapping.MappingFromPerson is null || face.Mapping.MappingFromPerson.LocationContainersFiles.Count == 0) if (face.Mapping.MappingFromPerson is null || face.Mapping.MappingFromPerson.LocationContainersFiles.Count == 0)
continue; continue;
if (_Configuration.LocationContainerDistanceTolerance is null) Map.Models.Stateless.Methods.IMapLogic.SetCreationTime(face.Mapping.MappingFromItem, face.Mapping.MappingFromPerson);
if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null)
Map.Models.Stateless.Methods.IMapLogic.MoveToDecade(propertyConfiguration, face.Mapping.MappingFromItem, face.Mapping.MappingFromPerson); Map.Models.Stateless.Methods.IMapLogic.MoveToDecade(propertyConfiguration, face.Mapping.MappingFromItem, face.Mapping.MappingFromPerson);
} }
if (!anyValidFaces) if (!anyValidFaces)
@ -612,6 +613,8 @@ public partial class DlibDotNet
} }
} }
} }
if (_Configuration.MoveToDecade && _Configuration.LocationContainerDistanceTolerance is null)
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
results = new((from l in mappingCollection orderby l.MappingFromItem.Id select l).ToArray()); results = new((from l in mappingCollection orderby l.MappingFromItem.Id select l).ToArray());
return results; return results;
} }
@ -779,6 +782,7 @@ public partial class DlibDotNet
double? α; double? α;
int? eyeα; int? eyeα;
bool? isUsed; bool? isUsed;
bool? canReMap;
bool? eyeReview; bool? eyeReview;
Mapping mapping; Mapping mapping;
int notMapped = 0; int notMapped = 0;
@ -790,8 +794,11 @@ public partial class DlibDotNet
string deterministicHashCodeKey; string deterministicHashCodeKey;
MappingFromFilter mappingFromFilter; MappingFromFilter mappingFromFilter;
MappingFromLocation? mappingFromLocation; MappingFromLocation? mappingFromLocation;
MappingFromFilterPre mappingFromFilterPre;
MappingFromFilterPost mappingFromFilterPost;
bool? isFocusModel = GetIsFocusModel(item.Property); bool? isFocusModel = GetIsFocusModel(item.Property);
bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0; bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0;
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers; ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers;
ReadOnlyCollection<string> locationContainersFiles = new((from l in locationContainers select l.File).ToArray()); ReadOnlyCollection<string> locationContainersFiles = new((from l in locationContainers select l.File).ToArray());
foreach (Shared.Models.Face face in faces) foreach (Shared.Models.Face face in faces)
@ -799,10 +806,13 @@ public partial class DlibDotNet
wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id); wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null) if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
{ {
canReMap = null;
isUsed = null; isUsed = null;
isFocusPerson = null; isFocusPerson = null;
inSkipCollection = null; inSkipCollection = null;
mappingFromLocation = null; mappingFromLocation = null;
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed); mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed);
} }
else else
@ -814,17 +824,21 @@ public partial class DlibDotNet
(eyeReview, α) = Shared.Models.Stateless.Methods.IFace.GetEyeα(face.FaceParts); (eyeReview, α) = Shared.Models.Stateless.Methods.IFace.GetEyeα(face.FaceParts);
eyeα = α is null ? null : (int)Math.Round(Math.Abs(α.Value)); eyeα = α is null ? null : (int)Math.Round(Math.Abs(α.Value));
} }
confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, _Configuration.RangeFaceConfidence, face.Location.Confidence); confidencePercent = Shared.Models.Stateless.Methods.ILocation.GetConfidencePercent(_Configuration.FaceConfidencePercent, face.Location.Confidence);
faceAreaPermyriad = IMapping.GetAreaPermyriad(_Configuration.FaceAreaPermyriad, face.Location, face.OutputResolution); faceAreaPermyriad = IMapping.GetAreaPermyriad(_Configuration.FaceAreaPermyriad, face.Location, face.OutputResolution);
wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution); wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution); deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, face.Location, Shared.Models.Stateless.ILocation.Digits, face.OutputResolution);
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle); mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation);
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation); inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation); mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPersonOld(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed); mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed);
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
} }
mapping = new(mappingFromItem, mappingFromFilter, mappingFromLocation, mappingFromPhotoPrismCollection); mapping = new(mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
notMapped += mapLogic.UpdateMappingFromPerson(locationContainersFiles, wholePercentagesToPersonContainers, mapping); notMapped += mapLogic.UpdateMappingFromPerson(locationContainersFiles, wholePercentagesToPersonContainers, mapping);
face.SetMapping(mapping); face.SetMapping(mapping);
} }
@ -848,7 +862,6 @@ public partial class DlibDotNet
configuration.PersonCharacters.ToArray(), configuration.PersonCharacters.ToArray(),
configuration.RangeDaysDeltaTolerance, configuration.RangeDaysDeltaTolerance,
configuration.RangeDistanceTolerance, configuration.RangeDistanceTolerance,
configuration.SaveMappedRelations,
configuration.SaveSortingWithoutPerson, configuration.SaveSortingWithoutPerson,
configuration.SkipNotSkipDirectories, configuration.SkipNotSkipDirectories,
configuration.SortingMaximumPerKey, configuration.SortingMaximumPerKey,
@ -863,6 +876,7 @@ public partial class DlibDotNet
{ {
Mapping result; Mapping result;
bool? isUsed; bool? isUsed;
bool? canReMap;
int? eyeα = null; int? eyeα = null;
bool? isFocusPerson; bool? isFocusPerson;
bool? eyeReview = null; bool? eyeReview = null;
@ -873,15 +887,21 @@ public partial class DlibDotNet
string deterministicHashCodeKey; string deterministicHashCodeKey;
MappingFromFilter mappingFromFilter; MappingFromFilter mappingFromFilter;
MappingFromLocation? mappingFromLocation; MappingFromLocation? mappingFromLocation;
MappingFromFilterPre mappingFromFilterPre;
MappingFromFilterPost mappingFromFilterPost;
bool? isFocusModel = GetIsFocusModel(item.Property); bool? isFocusModel = GetIsFocusModel(item.Property);
bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0; bool ignoreXMatches = _JLinkResolvedDirectories.Count > 0;
long[] jLinkResolvedPersonKeys = _JLinkResolvedDirectories.Select(l => l.PersonKey).ToArray();
ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id); ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers = mapLogic.GetWholePercentagesToPersonContainers(item.Property?.Id);
if (item.Property?.Id is null) if (item.Property?.Id is null)
{ {
isUsed = null; isUsed = null;
canReMap = null;
isFocusPerson = null; isFocusPerson = null;
inSkipCollection = null; inSkipCollection = null;
mappingFromLocation = null; mappingFromLocation = null;
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed); mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed);
} }
else else
@ -889,12 +909,16 @@ public partial class DlibDotNet
wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(Shared.Models.Stateless.ILocation.Digits); wholePercentRectangle = Shared.Models.Stateless.Methods.ILocation.GetWholePercentages(Shared.Models.Stateless.ILocation.Digits);
deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, Shared.Models.Stateless.ILocation.Digits); deterministicHashCodeKey = IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, Shared.Models.Stateless.ILocation.Digits);
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle); mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, eyeα, eyeReview, wholePercentRectangle);
isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation);
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation); inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation); mappingFromFilterPre = new(inSkipCollection, isFocusModel, isFocusRelativePath);
canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
isUsed = mapLogic.IsUsed(ignoreXMatches, item.Property.Id.Value, wholePercentagesToPersonContainers, mappingFromLocation);
isFocusPerson = mapLogic.IsFocusPersonOld(_Configuration.SkipPersonWithMoreThen, _JLinkResolvedDirectories, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed); mappingFromFilter = new(isFocusModel, isFocusPerson, isFocusRelativePath, inSkipCollection, isUsed);
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
} }
result = new(mappingFromItem, mappingFromFilter, mappingFromLocation, mappingFromPhotoPrismCollection: null); result = new(mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
int notMapped = mapLogic.UpdateMappingFromPerson(locationContainersFiles, wholePercentagesToPersonContainers, result); int notMapped = mapLogic.UpdateMappingFromPerson(locationContainersFiles, wholePercentagesToPersonContainers, result);
return (result, notMapped); return (result, notMapped);
} }
@ -1144,8 +1168,8 @@ public partial class DlibDotNet
{ {
if (_Log is null) if (_Log is null)
throw new NullReferenceException(nameof(_Log)); throw new NullReferenceException(nameof(_Log));
DistanceLimits distanceLimits;
int? useFiltersCounter = null; int? useFiltersCounter = null;
DistanceLimits distanceLimits;
SortingContainer[] sortingContainers; SortingContainer[] sortingContainers;
FaceDistanceContainer[] filteredFaceDistanceContainers; FaceDistanceContainer[] filteredFaceDistanceContainers;
long? skipOlderThan = _Configuration.SkipOlderThanDays is null ? null : new DateTime(ticks).AddDays(-_Configuration.SkipOlderThanDays.Value).Ticks; long? skipOlderThan = _Configuration.SkipOlderThanDays is null ? null : new DateTime(ticks).AddDays(-_Configuration.SkipOlderThanDays.Value).Ticks;
@ -1175,7 +1199,7 @@ public partial class DlibDotNet
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers); E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
if (filteredFaceDistanceContainers.Length > 0) if (filteredFaceDistanceContainers.Length > 0)
{ {
int updated = mapLogic.UpdateFromSortingContainers(_Configuration.SaveIndividually, idToWholePercentagesToMapping, distanceLimits, sortingContainers); int updated = sortingContainers.Length == 0 ? 0 : mapLogic.UpdateFromSortingContainers(_Configuration.SaveIndividually, idToWholePercentagesToMapping, distanceLimits, sortingContainers);
List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(_Configuration.SaveIndividually, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToWholePercentagesToMapping, useFiltersCounter, sortingContainers.Length > 0); List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(_Configuration.SaveIndividually, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToWholePercentagesToMapping, useFiltersCounter, sortingContainers.Length > 0);
mapLogic.SaveContainers(_Configuration.SaveIndividually, updated, saveContainers); mapLogic.SaveContainers(_Configuration.SaveIndividually, updated, saveContainers);
} }
@ -1184,7 +1208,7 @@ public partial class DlibDotNet
private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces, ReadOnlyCollection<Mapping> mappingCollection, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping) private void SaveFaceDistances(long ticks, MapLogic mapLogic, ReadOnlyCollection<Shared.Models.Face> distinctFilteredFaces, ReadOnlyCollection<Mapping> mappingCollection, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, ReadOnlyDictionary<int, ReadOnlyDictionary<int, Mapping>> idToWholePercentagesToMapping)
{ {
E_Distance.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces); E_Distance.PreFilterSetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces);
ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers = E_Distance.GetFaceDistanceContainers(distinctFilteredFaces); ReadOnlyCollection<FaceDistanceContainer> faceDistanceContainers = E_Distance.GetFaceDistanceContainers(distinctFilteredFaces);
if (faceDistanceContainers.Count > 0) if (faceDistanceContainers.Count > 0)
{ {

View File

@ -42,8 +42,7 @@ public class Configuration
public string[]? MixedYearRelativePaths { get; set; } public string[]? MixedYearRelativePaths { get; set; }
public string? ModelDirectory { get; set; } public string? ModelDirectory { get; set; }
public string? ModelName { get; set; } public string? ModelName { get; set; }
public int? NumberOfJitters { get; set; } public bool? MoveToDecade { get; set; }
public int? NumberOfTimesToUpsample { get; set; }
public string? OutputExtension { get; set; } public string? OutputExtension { get; set; }
public int? OutputQuality { get; set; } public int? OutputQuality { get; set; }
public string[]? OutputResolutions { get; set; } public string[]? OutputResolutions { get; set; }
@ -75,8 +74,6 @@ public class Configuration
public bool? SaveFullYearOfRandomFiles { get; set; } public bool? SaveFullYearOfRandomFiles { get; set; }
public bool? SaveIndividually { get; set; } public bool? SaveIndividually { get; set; }
public string[]? SaveMappedForOutputResolutions { get; set; } public string[]? SaveMappedForOutputResolutions { get; set; }
public bool? SaveMappedRelations { get; set; }
public string[]? SaveMappedRelationsForOutputResolutions { get; set; }
public string[]? SavePropertyShortcutsForOutputResolutions { get; set; } public string[]? SavePropertyShortcutsForOutputResolutions { get; set; }
public string[]? SaveRandomForOutputResolutions { get; set; } public string[]? SaveRandomForOutputResolutions { get; set; }
public bool? SaveResizedSubfiles { get; set; } public bool? SaveResizedSubfiles { get; set; }
@ -142,6 +139,7 @@ public class Configuration
// if (configuration?.MixedYearRelativePaths is null) throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths)); // if (configuration?.MixedYearRelativePaths is null) throw new NullReferenceException(nameof(configuration.MixedYearRelativePaths));
if (configuration?.ModelDirectory is null) throw new NullReferenceException(nameof(configuration.ModelDirectory)); if (configuration?.ModelDirectory is null) throw new NullReferenceException(nameof(configuration.ModelDirectory));
if (configuration?.ModelName is null) throw new NullReferenceException(nameof(configuration.ModelName)); if (configuration?.ModelName is null) throw new NullReferenceException(nameof(configuration.ModelName));
if (configuration?.MoveToDecade is null) throw new NullReferenceException(nameof(configuration.MoveToDecade));
if (configuration?.OutputExtension is null) throw new NullReferenceException(nameof(configuration.OutputExtension)); if (configuration?.OutputExtension is null) throw new NullReferenceException(nameof(configuration.OutputExtension));
if (configuration?.OutputQuality is null) throw new NullReferenceException(nameof(configuration.OutputQuality)); if (configuration?.OutputQuality is null) throw new NullReferenceException(nameof(configuration.OutputQuality));
// if (configuration?.OutputResolutions is null) throw new NullReferenceException(nameof(configuration.OutputResolutions)); // if (configuration?.OutputResolutions is null) throw new NullReferenceException(nameof(configuration.OutputResolutions));
@ -173,7 +171,6 @@ public class Configuration
if (configuration?.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); if (configuration?.SaveFullYearOfRandomFiles is null) throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles));
if (configuration?.SaveIndividually is null) throw new NullReferenceException(nameof(configuration.SaveIndividually)); if (configuration?.SaveIndividually is null) throw new NullReferenceException(nameof(configuration.SaveIndividually));
// if (configuration?.SaveMappedForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveMappedForOutputResolutions)); // if (configuration?.SaveMappedForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveMappedForOutputResolutions));
if (configuration?.SaveMappedRelations is null) throw new NullReferenceException(nameof(configuration.SaveMappedRelations));
// if (configuration?.SavePropertyShortcutsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SavePropertyShortcutsForOutputResolutions)); // if (configuration?.SavePropertyShortcutsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SavePropertyShortcutsForOutputResolutions));
// if (configuration?.SaveRandomForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveRandomForOutputResolutions)); // if (configuration?.SaveRandomForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.SaveRandomForOutputResolutions));
if (configuration?.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); if (configuration?.SaveResizedSubfiles is null) throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles));
@ -226,6 +223,7 @@ public class Configuration
configuration.MixedYearRelativePaths ?? Array.Empty<string>(), configuration.MixedYearRelativePaths ?? Array.Empty<string>(),
configuration.ModelDirectory, configuration.ModelDirectory,
configuration.ModelName, configuration.ModelName,
configuration.MoveToDecade.Value,
configuration.OutputExtension, configuration.OutputExtension,
configuration.OutputQuality.Value, configuration.OutputQuality.Value,
configuration.OutputResolutions ?? Array.Empty<string>(), configuration.OutputResolutions ?? Array.Empty<string>(),
@ -257,7 +255,6 @@ public class Configuration
configuration.SaveFullYearOfRandomFiles.Value, configuration.SaveFullYearOfRandomFiles.Value,
configuration.SaveIndividually.Value, configuration.SaveIndividually.Value,
configuration.SaveMappedForOutputResolutions ?? Array.Empty<string>(), configuration.SaveMappedForOutputResolutions ?? Array.Empty<string>(),
configuration.SaveMappedRelations.Value,
configuration.SavePropertyShortcutsForOutputResolutions ?? Array.Empty<string>(), configuration.SavePropertyShortcutsForOutputResolutions ?? Array.Empty<string>(),
configuration.SaveRandomForOutputResolutions ?? Array.Empty<string>(), configuration.SaveRandomForOutputResolutions ?? Array.Empty<string>(),
configuration.SaveResizedSubfiles.Value, configuration.SaveResizedSubfiles.Value,

View File

@ -36,6 +36,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
string[] MixedYearRelativePaths, string[] MixedYearRelativePaths,
string ModelDirectory, string ModelDirectory,
string ModelName, string ModelName,
bool MoveToDecade,
string OutputExtension, string OutputExtension,
int OutputQuality, int OutputQuality,
string[] OutputResolutions, string[] OutputResolutions,
@ -67,7 +68,6 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
bool SaveFullYearOfRandomFiles, bool SaveFullYearOfRandomFiles,
bool SaveIndividually, bool SaveIndividually,
string[] SaveMappedForOutputResolutions, string[] SaveMappedForOutputResolutions,
bool SaveMappedRelations,
string[] SavePropertyShortcutsForOutputResolutions, string[] SavePropertyShortcutsForOutputResolutions,
string[] SaveRandomForOutputResolutions, string[] SaveRandomForOutputResolutions,
bool SaveResizedSubfiles, bool SaveResizedSubfiles,

View File

@ -13,7 +13,6 @@ public record Configuration(bool DeletePossibleDuplicates,
char[] PersonCharacters, char[] PersonCharacters,
int[] RangeDaysDeltaTolerance, int[] RangeDaysDeltaTolerance,
float[] RangeDistanceTolerance, float[] RangeDistanceTolerance,
bool SaveMappedRelations,
bool SaveSortingWithoutPerson, bool SaveSortingWithoutPerson,
string[] SkipNotSkipDirectories, string[] SkipNotSkipDirectories,
int SortingMaximumPerKey, int SortingMaximumPerKey,

View File

@ -110,6 +110,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
File.SetAttributes(checkFile, FileAttributes.Hidden); File.SetAttributes(checkFile, FileAttributes.Hidden);
} }
if (updated is null) if (updated is null)
{
foreach (SaveContainer saveContainer in saveContainers) foreach (SaveContainer saveContainer in saveContainers)
{ {
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists) if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists)
@ -122,6 +123,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (saveContainer.MakeAllHidden) if (saveContainer.MakeAllHidden)
File.SetAttributes(checkFile, FileAttributes.Hidden); File.SetAttributes(checkFile, FileAttributes.Hidden);
} }
}
foreach (SaveContainer saveContainer in saveContainers) foreach (SaveContainer saveContainer in saveContainers)
{ {
if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.ShortcutFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists) if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.ShortcutFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists)
@ -308,8 +310,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
ticks, ticks,
personContainers, personContainers,
readOnlyPersonKeyToCount)); readOnlyPersonKeyToCount));
locationContainers.AddRange(Stateless.MapLogic.GetLocationContainers(distance, locationContainers.AddRange(Stateless.MapLogic.GetLocationContainers(maxDegreeOfParallelism,
maxDegreeOfParallelism,
configuration, configuration,
ticks, ticks,
personContainers, personContainers,
@ -320,7 +321,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
if (lossCount != 0 || unableToMatchCount != 0) if (lossCount != 0 || unableToMatchCount != 0)
if (lossCount != 0 || unableToMatchCount != 0) if (lossCount != 0 || unableToMatchCount != 0)
{ } { }
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && configuration.SaveMappedRelations) if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && configuration.LocationContainerDistanceTolerance is not null)
Stateless.MapLogic.SaveMappedRelations(configuration, distance, a2PeopleContentDirectory, eDistanceContentDirectory, ticks, locationContainers, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection); Stateless.MapLogic.SaveMappedRelations(configuration, distance, a2PeopleContentDirectory, eDistanceContentDirectory, ticks, locationContainers, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection);
} }
_PersonKeyToCount = readOnlyPersonKeyToCount; _PersonKeyToCount = readOnlyPersonKeyToCount;
@ -616,8 +617,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
checkFile = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); checkFile = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}");
saveContainer = new(checkFile, directory, faceFileHolder); saveContainer = new(checkFile, directory, faceFileHolder);
} }
else else if (saveIndividually)
if (saveIndividually)
{ {
facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem); facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem);
facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}")); facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}"));
@ -694,7 +694,6 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
FaceDistance faceDistanceLength; FaceDistance faceDistanceLength;
List<int>? wholePercentagesCollection; List<int>? wholePercentagesCollection;
bool skipNotSkipCollectionAny = _SkipNotSkipCollection.Count > 0; bool skipNotSkipCollectionAny = _SkipNotSkipCollection.Count > 0;
float distanceTolerance = _Configuration.RangeDistanceTolerance[1];
for (int j = 0; j < faceDistanceLengths.Count; j++) for (int j = 0; j < faceDistanceLengths.Count; j++)
{ {
if (faceDistanceEncoding.WholePercentages is null) if (faceDistanceEncoding.WholePercentages is null)
@ -703,9 +702,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException(); throw new NotSupportedException();
if (j == i) if (j == i)
continue; continue;
if (_SkipCollection.TryGetValue(faceDistanceEncoding.Id, out wholePercentagesCollection) && wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value)) if (faceDistanceEncoding.Id is not null && _SkipCollection.TryGetValue(faceDistanceEncoding.Id.Value, out wholePercentagesCollection) && wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value))
continue; continue;
if (skipNotSkipCollectionAny && (!_SkipNotSkipCollection.TryGetValue(faceDistanceEncoding.Id, out wholePercentagesCollection) || !wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value))) if (faceDistanceEncoding.Id is not null && skipNotSkipCollectionAny && (!_SkipNotSkipCollection.TryGetValue(faceDistanceEncoding.Id.Value, out wholePercentagesCollection) || !wholePercentagesCollection.Contains(faceDistanceEncoding.WholePercentages.Value)))
continue; continue;
if (face.Mapping.MappingFromFilter.IsUsed is not null && face.Mapping.MappingFromFilter.IsUsed.Value) if (face.Mapping.MappingFromFilter.IsUsed is not null && face.Mapping.MappingFromFilter.IsUsed.Value)
continue; continue;
@ -714,7 +713,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException(); throw new NotSupportedException();
if (faceDistanceLength.Length == 0) if (faceDistanceLength.Length == 0)
continue; continue;
sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, distanceTolerance, faceDistanceEncoding, faceDistanceLength); sorting = ISorting.Get(_Configuration.FaceDistancePermyriad, faceDistanceEncoding, faceDistanceLength);
if (sorting.DistancePermyriad == 0) if (sorting.DistancePermyriad == 0)
continue; continue;
if (sorting.Id == faceDistanceEncoding.Id) if (sorting.Id == faceDistanceEncoding.Id)
@ -1184,7 +1183,39 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
public bool InSkipCollection(int id, MappingFromLocation mappingFromLocation) => public bool InSkipCollection(int id, MappingFromLocation mappingFromLocation) =>
_SkipCollection.TryGetValue(id, out List<int>? wholePercentagesCollection) && wholePercentagesCollection.Contains(mappingFromLocation.WholePercentages); _SkipCollection.TryGetValue(id, out List<int>? wholePercentagesCollection) && wholePercentagesCollection.Contains(mappingFromLocation.WholePercentages);
public bool? IsFocusPerson(int? skipPersonWithMoreThen, List<(string Directory, long PersonKey)> jLinkResolvedDirectories, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation) public bool? IsFocusPerson(int? skipPersonWithMoreThen, long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation)
{
bool? result;
ReadOnlyCollection<PersonContainer>? personContainers;
if (skipPersonWithMoreThen is null && jLinkResolvedPersonKeys.Length == 0)
result = null;
else if (wholePercentagesToPersonContainers is null)
result = null;
else if (!wholePercentagesToPersonContainers.TryGetValue(mappingFromLocation.WholePercentages, out personContainers))
result = null;
else
{
result = false;
foreach (PersonContainer personContainer in personContainers)
{
if (personContainer.Key is null)
continue;
if (skipPersonWithMoreThen is not null && _PersonKeyToCount.TryGetValue(personContainer.Key.Value, out int count) && count > 2 && count < skipPersonWithMoreThen.Value)
{
result = true;
break;
}
if (jLinkResolvedPersonKeys.Contains(personContainer.Key.Value))
{
result = true;
break;
}
}
}
return result;
}
public bool? IsFocusPersonOld(int? skipPersonWithMoreThen, List<(string Directory, long PersonKey)> jLinkResolvedDirectories, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation)
{ {
bool? result; bool? result;
ReadOnlyCollection<PersonContainer>? personContainers; ReadOnlyCollection<PersonContainer>? personContainers;

View File

@ -231,6 +231,7 @@ internal abstract class MapLogic
} }
} }
} }
_ = IPath.DeleteEmptyDirectories(personKeyDirectory);
} }
private static List<MappedFile> GetDisplayDirectoryAllFiles(string fileNameExtension, string personBirthdayFormat, ReadOnlyCollection<PersonContainer> personContainers) private static List<MappedFile> GetDisplayDirectoryAllFiles(string fileNameExtension, string personBirthdayFormat, ReadOnlyCollection<PersonContainer> personContainers)
@ -724,7 +725,7 @@ internal abstract class MapLogic
yield return new(l, Path.GetFileName(l)); yield return new(l, Path.GetFileName(l));
} }
private static List<(string, long)> GetGenealogicalDataCommunicationDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat) private static List<(string, long)> GetDirectoryAndTicksCollection(string[] jLinks, string personBirthdayFormat, string? rootDirectory)
{ {
List<(string, long)> results = new(); List<(string, long)> results = new();
string directory; string directory;
@ -732,12 +733,11 @@ internal abstract class MapLogic
string[] personKeyDirectories; string[] personKeyDirectories;
string[] personDisplayDirectoryNames; string[] personDisplayDirectoryNames;
string personKeyFormattedDirectoryName; string personKeyFormattedDirectoryName;
string? genealogicalDataCommunicationDirectory = Path.GetDirectoryName(genealogicalDataCommunicationFile);
foreach (string jLink in jLinks) foreach (string jLink in jLinks)
{ {
if (genealogicalDataCommunicationDirectory is null) if (rootDirectory is null)
continue; continue;
directory = Path.Combine(genealogicalDataCommunicationDirectory, jLink); directory = Path.Combine(rootDirectory, jLink);
if (!Directory.Exists(directory)) if (!Directory.Exists(directory))
continue; continue;
personDisplayDirectoryNames = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly); personDisplayDirectoryNames = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
@ -756,6 +756,14 @@ internal abstract class MapLogic
return results; return results;
} }
private static List<(string, long)> GetGenealogicalDataCommunicationDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat)
{
List<(string, long)> results;
string? genealogicalDataCommunicationDirectory = Path.GetDirectoryName(genealogicalDataCommunicationFile);
results = GetDirectoryAndTicksCollection(jLinks, personBirthdayFormat, genealogicalDataCommunicationDirectory);
return results;
}
private static string? TryToFind(char[] personCharacters, string a2PeopleSingletonDirectory, List<(string Directory, string DirectoryName, string DirectoryNameSplitFirst)> a2PeopleSingletonDirectories, string file, string path) private static string? TryToFind(char[] personCharacters, string a2PeopleSingletonDirectory, List<(string Directory, string DirectoryName, string DirectoryNameSplitFirst)> a2PeopleSingletonDirectories, string file, string path)
{ {
string? result; string? result;
@ -871,7 +879,6 @@ internal abstract class MapLogic
int? wholePercentages; int? wholePercentages;
string? checkDirectory; string? checkDirectory;
ProgressBar progressBar; ProgressBar progressBar;
string? yearDirectoryName;
string[] yearDirectories; string[] yearDirectories;
string personKeyFormatted; string personKeyFormatted;
string? personFirstInitial; string? personFirstInitial;
@ -927,22 +934,6 @@ internal abstract class MapLogic
personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly); personNameDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files) foreach (string file in files)
File.Delete(file); File.Delete(file);
yearDirectoryName = Path.GetFileName(yearDirectory);
if (!string.IsNullOrEmpty(yearDirectoryName) && yearDirectoryName.Length != 8)
{
checkDirectory = Path.Combine(personKeyFormattedDirectory, "abcdefgh");
if (Directory.Exists(checkDirectory))
{
MoveDirectory(personNameDirectories, checkDirectory);
if (!check)
check = true;
continue;
}
Directory.Move(yearDirectory, checkDirectory);
if (!check)
check = true;
continue;
}
foreach (string personNameDirectory in personNameDirectories) foreach (string personNameDirectory in personNameDirectories)
{ {
directoryNumber++; directoryNumber++;
@ -1070,33 +1061,6 @@ internal abstract class MapLogic
return results; return results;
} }
private static void MoveDirectory(string[] personNameDirectories, string destination)
{
string[] files;
string checkFile;
string checkDirectory;
string? personNameDirectoryName;
foreach (string personNameDirectory in personNameDirectories)
{
personNameDirectoryName = Path.GetFileName(personNameDirectory);
checkDirectory = Path.Combine(destination, personNameDirectoryName);
if (personNameDirectory == checkDirectory)
continue;
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
files = Directory.GetFiles(personNameDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
checkFile = Path.Combine(checkDirectory, Path.GetFileName(file));
if (checkFile == file)
continue;
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
}
}
}
internal static void SetKeyValuePairsAndAddToCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<long, PersonContainer> personKeyToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection, Dictionary<long, int> personKeyToCount, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer) internal static void SetKeyValuePairsAndAddToCollections(Configuration configuration, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<long, PersonContainer> personKeyToPersonContainer, ReadOnlyCollection<PersonKeyFormattedIdThenWholePercentages> personKeyFormattedIdThenWholePercentagesCollection, Dictionary<long, int> personKeyToCount, Dictionary<string, PersonContainer> personKeyFormattedToPersonContainer, Dictionary<long, List<PersonContainer>> personKeyToPersonContainerCollection, List<(PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer)
{ {
PersonBirthday? personBirthday; PersonBirthday? personBirthday;
@ -1291,7 +1255,7 @@ internal abstract class MapLogic
} }
} }
internal static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<int, List<(string, int)>> skipCollection, List<Record> records) internal static List<LocationContainer<MetadataExtractor.Directory>> GetLocationContainers(int maxDegreeOfParallelism, Configuration configuration, long ticks, ReadOnlyCollection<PersonContainer> personContainers, Dictionary<int, List<(string, int)>> skipCollection, List<Record> records)
{ {
List<LocationContainer<MetadataExtractor.Directory>> results = new(); List<LocationContainer<MetadataExtractor.Directory>> results = new();
List<MappedFile> mappedFiles = GetMappedFiles(configuration, personContainers, records); List<MappedFile> mappedFiles = GetMappedFiles(configuration, personContainers, records);
@ -1310,8 +1274,6 @@ internal abstract class MapLogic
} }
ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers = new(results.OrderBy(l => l.DirectoryNumber).ToArray()); ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers = new(results.OrderBy(l => l.DirectoryNumber).ToArray());
LookForPossibleDuplicates(configuration, locationContainers); LookForPossibleDuplicates(configuration, locationContainers);
if (configuration.LocationContainerDistanceTolerance is not null)
distance.ReviewLocationContainerDistanceTolerance(configuration.LocationContainerDistanceTolerance.Value, locationContainers);
return results; return results;
} }
@ -1558,7 +1520,10 @@ internal abstract class MapLogic
string checkDirectory; string checkDirectory;
WindowsShortcut windowsShortcut; WindowsShortcut windowsShortcut;
List<string> resolvedDirectories = new(); List<string> resolvedDirectories = new();
results = GetGenealogicalDataCommunicationDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat); if (string.IsNullOrEmpty(genealogicalDataCommunicationFile))
results = GetDirectoryAndTicksCollection(jLinks, personBirthdayFormat, a2PeopleContentDirectory);
else
results = GetGenealogicalDataCommunicationDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat);
if (results.Count == 0 || results.Count < jLinks.Length) if (results.Count == 0 || results.Count < jLinks.Length)
{ {
List<(string, string, string)> a2PeopleSingletonDirectories = new(); List<(string, string, string)> a2PeopleSingletonDirectories = new();
@ -1710,10 +1675,24 @@ internal abstract class MapLogic
return new(results); return new(results);
} }
internal static void SetCreationTime(MappingFromItem mappingFromItem, MappingFromPerson mappingFromPerson)
{
DateTime dateTime;
FileInfo fileInfo;
foreach (string locationContainersFile in mappingFromPerson.LocationContainersFiles)
{
fileInfo = new(locationContainersFile);
if (!fileInfo.Exists)
continue;
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
if (fileInfo.CreationTime != dateTime)
File.SetCreationTime(locationContainersFile, dateTime);
}
}
internal static void MoveToDecade(Property.Models.Configuration propertyConfiguration, MappingFromItem mappingFromItem, MappingFromPerson mappingFromPerson) internal static void MoveToDecade(Property.Models.Configuration propertyConfiguration, MappingFromItem mappingFromItem, MappingFromPerson mappingFromPerson)
{ {
string year; string year;
DateTime dateTime;
FileInfo fileInfo; FileInfo fileInfo;
string halfDecade; string halfDecade;
string checkDirectory; string checkDirectory;
@ -1744,24 +1723,20 @@ internal abstract class MapLogic
break; break;
if (mappingFromItem.DateTimeOriginal is null) if (mappingFromItem.DateTimeOriginal is null)
{ {
dateTime = mappingFromItem.MinimumDateTime;
year = mappingFromItem.MinimumDateTime.Year.ToString(); year = mappingFromItem.MinimumDateTime.Year.ToString();
halfDecade = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-"; halfDecade = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-";
} }
else else
{ {
dateTime = mappingFromItem.DateTimeOriginal.Value;
year = mappingFromItem.DateTimeOriginal.Value.Year.ToString(); year = mappingFromItem.DateTimeOriginal.Value.Year.ToString();
halfDecade = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-"; halfDecade = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-";
} }
if (fileInfo.CreationTime != dateTime)
File.SetCreationTime(locationContainersFile, dateTime);
if (halfDecade == yearDirectoryName) if (halfDecade == yearDirectoryName)
continue; continue;
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName); checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
if (!Directory.Exists(checkDirectory)) if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory); _ = Directory.CreateDirectory(checkDirectory);
File.Move(locationContainersFile, Path.Combine(checkDirectory, Path.Combine(checkDirectory, Path.GetFileName(locationContainersFile)))); File.Move(locationContainersFile, Path.Combine(checkDirectory, Path.GetFileName(locationContainersFile)));
} }
} }
@ -1807,6 +1782,7 @@ internal abstract class MapLogic
internal static void SaveMappedRelations(Configuration configuration, Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, string a2PeopleContentDirectory, string eDistanceContentDirectory, long ticks, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection) internal static void SaveMappedRelations(Configuration configuration, Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, string a2PeopleContentDirectory, string eDistanceContentDirectory, long ticks, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection)
{ {
bool isCounterPersonYear;
string personKeyFormatted; string personKeyFormatted;
string? displayDirectoryName; string? displayDirectoryName;
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
@ -1816,13 +1792,32 @@ internal abstract class MapLogic
using ProgressBar progressBar = new(collections.Count, message, options); using ProgressBar progressBar = new(collections.Count, message, options);
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections) foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
{ {
if (configuration.LocationContainerDistanceTolerance is null)
break;
progressBar.Tick(); progressBar.Tick();
if (collection.Count == 0) if (collection.Count == 0)
continue; continue;
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey); personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted); displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
distance.SaveMappedForOutputResolutions(a2PeopleContentDirectory, eDistanceContentDirectory, configuration.RangeDistanceTolerance, collection, personKeyFormatted, displayDirectoryName); distance.SaveMappedForOutputResolutions(a2PeopleContentDirectory, eDistanceContentDirectory, configuration.LocationContainerDistanceTolerance.Value, collection, collection[0].PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName);
} }
} }
internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation)
{
bool? result;
ReadOnlyCollection<PersonContainer>? personContainers;
if (wholePercentagesToPersonContainers is null)
result = null;
else
{
if (!wholePercentagesToPersonContainers.TryGetValue(mappingFromLocation.WholePercentages, out personContainers))
result = null;
else
result = personContainers.Any(l => IPerson.IsDefaultName(l) && l.Key is not null && IPersonBirthday.IsCounterPersonYear(new DateTime(l.Key.Value).Year) && !jLinkResolvedPersonKeys.Contains(l.Key.Value));
}
return result;
}
} }

View File

@ -35,9 +35,19 @@ public interface IMapLogic
static List<(string, long)> GetJLinkDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat, char[] personCharacters, string a2PeopleSingletonDirectory, string a2PeopleContentDirectory) => static List<(string, long)> GetJLinkDirectories(string genealogicalDataCommunicationFile, string[] jLinks, string personBirthdayFormat, char[] personCharacters, string a2PeopleSingletonDirectory, string a2PeopleContentDirectory) =>
MapLogic.GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory); MapLogic.GetJLinkDirectories(genealogicalDataCommunicationFile, jLinks, personBirthdayFormat, personCharacters, a2PeopleSingletonDirectory, a2PeopleContentDirectory);
void TestStatic_SetCreationTime(Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) =>
SetCreationTime(mappingFromItem, mappingFromPerson);
static void SetCreationTime(Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) =>
MapLogic.SetCreationTime(mappingFromItem, mappingFromPerson);
void TestStatic_MoveToDecade(Property.Models.Configuration propertyConfiguration, Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) => void TestStatic_MoveToDecade(Property.Models.Configuration propertyConfiguration, Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) =>
MoveToDecade(propertyConfiguration, mappingFromItem, mappingFromPerson); MoveToDecade(propertyConfiguration, mappingFromItem, mappingFromPerson);
static void MoveToDecade(Property.Models.Configuration propertyConfiguration, Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) => static void MoveToDecade(Property.Models.Configuration propertyConfiguration, Shared.Models.MappingFromItem mappingFromItem, Shared.Models.MappingFromPerson mappingFromPerson) =>
MapLogic.MoveToDecade(propertyConfiguration, mappingFromItem, mappingFromPerson); MapLogic.MoveToDecade(propertyConfiguration, mappingFromItem, mappingFromPerson);
bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
MapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
} }

View File

@ -9,29 +9,31 @@ public record class FaceDistance : Properties.IFaceDistance
public int? ConfidencePercent { init; get; } public int? ConfidencePercent { init; get; }
public DateTime DateTimeOriginalThenMinimumDateTime { init; get; } public DateTime DateTimeOriginalThenMinimumDateTime { init; get; }
public object? Encoding { init; get; } public object? Encoding { init; get; }
public int Id { init; get; } public MappingFromFilterPost? MappingFromFilterPost { init; get; }
public int? Id { init; get; }
public bool? IsWrongYear { init; get; } public bool? IsWrongYear { init; get; }
public double? Length { init; get; } public double? Length { init; get; }
public int? WholePercentages { init; get; } public int? WholePercentages { init; get; }
[JsonConstructor] [JsonConstructor]
public FaceDistance(int? confidencePercent, DateTime dateTimeOriginalThenMinimumDateTime, object? encoding, int id, bool? isWrongYear, double? length, int? wholePercentages) public FaceDistance(int? confidencePercent, DateTime dateTimeOriginalThenMinimumDateTime, object? encoding, MappingFromFilterPost? mappingFromFilterPost, int? id, bool? isWrongYear, double? length, int? wholePercentages)
{ {
ConfidencePercent = confidencePercent; ConfidencePercent = confidencePercent;
DateTimeOriginalThenMinimumDateTime = dateTimeOriginalThenMinimumDateTime; DateTimeOriginalThenMinimumDateTime = dateTimeOriginalThenMinimumDateTime;
Encoding = encoding; Encoding = encoding;
MappingFromFilterPost = mappingFromFilterPost;
Id = id; Id = id;
IsWrongYear = isWrongYear; IsWrongYear = isWrongYear;
Length = length; Length = length;
WholePercentages = wholePercentages; WholePercentages = wholePercentages;
} }
public FaceDistance(int? confidencePercent, DateTime dateTimeOriginalThenMinimumDateTime, object? encoding, int id, bool? isWrongYear, int? wholePercentages) : public FaceDistance(int? confidencePercent, DateTime dateTimeOriginalThenMinimumDateTime, object? encoding, MappingFromFilterPost? mappingFromFilterPost, int id, bool? isWrongYear, int? wholePercentages) :
this(confidencePercent, dateTimeOriginalThenMinimumDateTime, encoding, id, isWrongYear, null, wholePercentages) this(confidencePercent, dateTimeOriginalThenMinimumDateTime, encoding, mappingFromFilterPost, id, isWrongYear, null, wholePercentages)
{ } { }
public FaceDistance(FaceDistance faceDistance, double length) : public FaceDistance(FaceDistance faceDistance, double length) :
this(faceDistance.ConfidencePercent, faceDistance.DateTimeOriginalThenMinimumDateTime, null, faceDistance.Id, faceDistance.IsWrongYear, length, faceDistance.WholePercentages) this(faceDistance.ConfidencePercent, faceDistance.DateTimeOriginalThenMinimumDateTime, null, faceDistance.MappingFromFilterPost, faceDistance.Id, faceDistance.IsWrongYear, length, faceDistance.WholePercentages)
{ } { }
public FaceDistance(object encoding) => Encoding = encoding; public FaceDistance(object encoding) => Encoding = encoding;

View File

@ -12,29 +12,33 @@ public class Mapping : Properties.IMapping
public string? _SegmentC; public string? _SegmentC;
protected SortingContainer? _SortingContainer; protected SortingContainer? _SortingContainer;
public int? By => _By; public int? By => _By;
public MappingFromFilterPost MappingFromFilterPost { init; get; }
public MappingFromFilterPre MappingFromFilterPre { init; get; }
public MappingFromItem MappingFromItem { init; get; } public MappingFromItem MappingFromItem { init; get; }
public MappingFromFilter MappingFromFilter { init; get; } public MappingFromFilter MappingFromFilter { init; get; }
public MappingFromLocation? MappingFromLocation { init; get; } public MappingFromLocation? MappingFromLocation { init; get; }
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
public MappingFromPerson? MappingFromPerson => _MappingFromPerson; public MappingFromPerson? MappingFromPerson => _MappingFromPerson;
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
public string? SegmentC => _SegmentC; public string? SegmentC => _SegmentC;
public SortingContainer? SortingContainer => _SortingContainer; public SortingContainer? SortingContainer => _SortingContainer;
[JsonConstructor] [JsonConstructor]
public Mapping(int? by, MappingFromItem mappingFromItem, MappingFromFilter mappingFromFilter, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, MappingFromPerson? mappingFromPerson, string? segmentC, SortingContainer? sortingContainer) public Mapping(int? by, MappingFromFilter mappingFromFilter, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, MappingFromPerson? mappingFromPerson, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, string? segmentC, SortingContainer? sortingContainer)
{ {
_By = by; _By = by;
_SegmentC = segmentC; _SegmentC = segmentC;
MappingFromItem = mappingFromItem;
MappingFromFilter = mappingFromFilter; MappingFromFilter = mappingFromFilter;
MappingFromFilterPost = mappingFromFilterPost;
MappingFromFilterPre = mappingFromFilterPre;
MappingFromItem = mappingFromItem;
MappingFromLocation = mappingFromLocation; MappingFromLocation = mappingFromLocation;
MappingFromPhotoPrismCollection = mappingFromPhotoPrismCollection;
_MappingFromPerson = mappingFromPerson; _MappingFromPerson = mappingFromPerson;
MappingFromPhotoPrismCollection = mappingFromPhotoPrismCollection;
_SortingContainer = sortingContainer; _SortingContainer = sortingContainer;
} }
public Mapping(MappingFromItem mappingFromItem, MappingFromFilter mappingFromFilter, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) : public Mapping(MappingFromFilter mappingFromFilter, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection) :
this(null, mappingFromItem, mappingFromFilter, mappingFromLocation, mappingFromPhotoPrismCollection, null, null, null) this(null, mappingFromFilter, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null)
{ } { }
public override string ToString() public override string ToString()

View File

@ -0,0 +1,23 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record MappingFromFilterPost(bool? CanReMap,
bool? InSkipCollection,
bool? IsFocusPerson)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, MappingFromFilterPostGenerationContext.Default.MappingFromFilterPost);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(MappingFromFilterPost))]
public partial class MappingFromFilterPostGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,23 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record MappingFromFilterPre(bool? InSkipCollection,
bool? IsFocusModel,
bool? IsFocusRelativePath)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, MappingFromFilterPreGenerationContext.Default.MappingFromFilterPre);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(MappingFromFilterPre))]
public partial class MappingFromFilterPreGenerationContext : JsonSerializerContext
{
}

View File

@ -5,7 +5,6 @@ namespace View_by_Distance.Shared.Models.Methods;
public interface IDistance<T> public interface IDistance<T>
{ {
void ReviewLocationContainerDistanceTolerance(float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers); void SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName);
void SaveMappedForOutputResolutions(string a2PeopleContentDirectory, string eDistanceContentDirectory, float[] rangeDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers, string personKeyFormatted, string? displayDirectoryName);
} }

View File

@ -6,7 +6,8 @@ public interface IFaceDistance
public int? ConfidencePercent { init; get; } public int? ConfidencePercent { init; get; }
public DateTime DateTimeOriginalThenMinimumDateTime { init; get; } public DateTime DateTimeOriginalThenMinimumDateTime { init; get; }
public object? Encoding { init; get; } public object? Encoding { init; get; }
public int Id { init; get; } public MappingFromFilterPost? MappingFromFilterPost { init; get; }
public int? Id { init; get; }
public bool? IsWrongYear { init; get; } public bool? IsWrongYear { init; get; }
public double? Length { init; get; } public double? Length { init; get; }
public int? WholePercentages { init; get; } public int? WholePercentages { init; get; }

View File

@ -4,11 +4,13 @@ public interface IMapping
{ {
public int? By { get; } public int? By { get; }
public string? SegmentC { get; } public MappingFromFilterPost MappingFromFilterPost { init; get; }
public MappingFromFilterPre MappingFromFilterPre { init; get; }
public MappingFromItem MappingFromItem { init; get; } public MappingFromItem MappingFromItem { init; get; }
public MappingFromLocation? MappingFromLocation { init; get; } public MappingFromLocation? MappingFromLocation { init; get; }
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
public MappingFromPerson? MappingFromPerson { get; } public MappingFromPerson? MappingFromPerson { get; }
public List<MappingFromPhotoPrism>? MappingFromPhotoPrismCollection { init; get; }
public string? SegmentC { get; }
public SortingContainer? SortingContainer { get; } public SortingContainer? SortingContainer { get; }
} }

View File

@ -3,6 +3,7 @@ namespace View_by_Distance.Shared.Models.Properties;
public interface ISorting public interface ISorting
{ {
public bool CanReMap { init; get; }
public int DaysDelta { init; get; } public int DaysDelta { init; get; }
public int DistancePermyriad { init; get; } public int DistancePermyriad { init; get; }
public int Id { init; get; } public int Id { init; get; }

View File

@ -6,6 +6,7 @@ namespace View_by_Distance.Shared.Models;
public record class Sorting : Properties.ISorting public record class Sorting : Properties.ISorting
{ {
public bool CanReMap { init; get; }
public int DaysDelta { init; get; } public int DaysDelta { init; get; }
public int DistancePermyriad { init; get; } public int DistancePermyriad { init; get; }
public int Id { init; get; } public int Id { init; get; }
@ -13,17 +14,18 @@ public record class Sorting : Properties.ISorting
public int WholePercentages { init; get; } public int WholePercentages { init; get; }
[JsonConstructor] [JsonConstructor]
public Sorting(int daysDelta, int distancePermyriad, int id, bool older, int wholePercentages) public Sorting(bool canReMap, int daysDelta, int distancePermyriad, int id, bool older, int wholePercentages)
{ {
CanReMap = canReMap;
DaysDelta = daysDelta; DaysDelta = daysDelta;
DistancePermyriad = distancePermyriad; DistancePermyriad = distancePermyriad;
Id = id; Id = id;
WholePercentages = wholePercentages;
Older = older; Older = older;
WholePercentages = wholePercentages;
} }
public Sorting(Mapping mapping, MappingFromLocation mappingFromLocation) : public Sorting(Mapping mapping, MappingFromLocation mappingFromLocation) :
this(0, 0, mapping.MappingFromItem.Id, false, mappingFromLocation.WholePercentages) this(false, 0, 0, mapping.MappingFromItem.Id, false, mappingFromLocation.WholePercentages)
{ } { }
public override string ToString() public override string ToString()

View File

@ -45,10 +45,10 @@ public interface ILocation
static string GetLeftPadded(int locationDigits, string value) => static string GetLeftPadded(int locationDigits, string value) =>
Location.GetLeftPadded(locationDigits, value); Location.GetLeftPadded(locationDigits, value);
int TestStatic_GetConfidencePercent(int faceConfidencePercent, float[] rangeFaceConfidence, double confidence) => int TestStatic_GetConfidencePercent(int faceConfidencePercent, double confidence) =>
GetConfidencePercent(faceConfidencePercent, rangeFaceConfidence, confidence); GetConfidencePercent(faceConfidencePercent, confidence);
static int GetConfidencePercent(int faceConfidencePercent, float[] rangeFaceConfidence, double confidence) => static int GetConfidencePercent(int faceConfidencePercent, double confidence) =>
Location.GetConfidencePercent(faceConfidencePercent, rangeFaceConfidence, confidence); Location.GetConfidencePercent(faceConfidencePercent, confidence);
string TestStatic_GetLeftPadded(int locationDigits, int value) => string TestStatic_GetLeftPadded(int locationDigits, int value) =>
GetLeftPadded(locationDigits, value); GetLeftPadded(locationDigits, value);

View File

@ -8,9 +8,9 @@ public interface ISorting
static Models.Sorting[] Sort(List<Models.Sorting> collection) => static Models.Sorting[] Sort(List<Models.Sorting> collection) =>
(from l in collection orderby l.DistancePermyriad, l.DaysDelta select l).ToArray(); (from l in collection orderby l.DistancePermyriad, l.DaysDelta select l).ToArray();
Models.Sorting TestStatic_Get(int faceDistancePermyriad, float distanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) => Models.Sorting TestStatic_Get(int faceDistancePermyriad, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) =>
Get(faceDistancePermyriad, distanceTolerance, faceDistanceEncoding, faceDistanceLength); Get(faceDistancePermyriad, faceDistanceEncoding, faceDistanceLength);
static Models.Sorting Get(int faceDistancePermyriad, float distanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) => static Models.Sorting Get(int faceDistancePermyriad, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) =>
Sorting.Get(faceDistancePermyriad, distanceTolerance, faceDistanceEncoding, faceDistanceLength); Sorting.Get(faceDistancePermyriad, faceDistanceEncoding, faceDistanceLength);
} }

View File

@ -114,9 +114,9 @@ internal abstract class Location
return result; return result;
} }
internal static int GetConfidencePercent(int faceConfidencePercent, float[] rangeFaceConfidence, double confidence) internal static int GetConfidencePercent(int faceConfidencePercent, double confidence)
{ {
int result = (int)(confidence / rangeFaceConfidence[1] * faceConfidencePercent); int result = (int)(confidence * faceConfidencePercent);
return result; return result;
} }

View File

@ -3,9 +3,11 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
internal abstract class Sorting internal abstract class Sorting
{ {
internal static Models.Sorting Get(int faceDistancePermyriad, float distanceTolerance, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength) internal static Models.Sorting Get(int faceDistancePermyriad, Models.FaceDistance faceDistanceEncoding, Models.FaceDistance faceDistanceLength)
{ {
Models.Sorting result; Models.Sorting result;
if (faceDistanceLength.Id is null)
throw new NotSupportedException();
if (faceDistanceLength.Length is null) if (faceDistanceLength.Length is null)
throw new NotSupportedException(); throw new NotSupportedException();
if (faceDistanceLength.WholePercentages is null) if (faceDistanceLength.WholePercentages is null)
@ -13,8 +15,9 @@ internal abstract class Sorting
TimeSpan timeSpan = new(faceDistanceLength.DateTimeOriginalThenMinimumDateTime.Ticks - faceDistanceEncoding.DateTimeOriginalThenMinimumDateTime.Ticks); TimeSpan timeSpan = new(faceDistanceLength.DateTimeOriginalThenMinimumDateTime.Ticks - faceDistanceEncoding.DateTimeOriginalThenMinimumDateTime.Ticks);
bool older = timeSpan.TotalMilliseconds < 0; bool older = timeSpan.TotalMilliseconds < 0;
int daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0); int daysDelta = (int)Math.Round(Math.Abs(timeSpan.TotalDays), 0);
int distancePermyriad = (int)(faceDistanceLength.Length.Value / distanceTolerance * faceDistancePermyriad); int distancePermyriad = (int)(faceDistanceLength.Length.Value * faceDistancePermyriad);
result = new(daysDelta, distancePermyriad, faceDistanceLength.Id, older, faceDistanceLength.WholePercentages.Value); bool canReMap = faceDistanceLength.MappingFromFilterPost?.CanReMap is not null && faceDistanceLength.MappingFromFilterPost.CanReMap.Value;
result = new(canReMap, daysDelta, distancePermyriad, faceDistanceLength.Id.Value, older, faceDistanceLength.WholePercentages.Value);
return result; return result;
} }

View File

@ -231,25 +231,19 @@ public partial class UnitTestCalculations
public void TestGetConfidencePercent() public void TestGetConfidencePercent()
{ {
int faceConfidencePercent = 100; int faceConfidencePercent = 100;
float minimum, target, maximum, value, check; float value, check;
minimum = 0.8f;
target = 0.8f;
maximum = int.MaxValue;
value = 0f; value = 0f;
check = ILocation.GetConfidencePercent(faceConfidencePercent, new float[] { minimum, target, maximum }, value); check = ILocation.GetConfidencePercent(faceConfidencePercent, value);
Assert.IsTrue(check == 0); Assert.IsTrue(check == 0);
target = 0.8f;
value = 0.4f; value = 0.4f;
check = ILocation.GetConfidencePercent(faceConfidencePercent, new float[] { minimum, target, maximum }, value); check = ILocation.GetConfidencePercent(faceConfidencePercent, value);
Assert.IsTrue(check == 50); Assert.IsTrue(check == 40);
target = 0.8f;
value = 0.8f; value = 0.8f;
check = ILocation.GetConfidencePercent(faceConfidencePercent, new float[] { minimum, target, maximum }, value); check = ILocation.GetConfidencePercent(faceConfidencePercent, value);
Assert.IsTrue(check == 100); Assert.IsTrue(check == 80);
target = 0.8f;
value = 1.6f; value = 1.6f;
check = ILocation.GetConfidencePercent(faceConfidencePercent, new float[] { minimum, target, maximum }, value); check = ILocation.GetConfidencePercent(faceConfidencePercent, value);
Assert.IsTrue(check == 200); Assert.IsTrue(check == 160);
NonThrowTryCatch(); NonThrowTryCatch();
} }