using System.IO; using System.Windows.Media; using Azaion.Common.DTO; using Azaion.Common.DTO.Queue; using MessagePack; namespace Azaion.Common.Database; [MessagePackObject] public class Annotation { private static string _labelsDir = null!; private static string _imagesDir = null!; private static string _thumbDir = null!; public static Dictionary DetectionClassesDict = null!; public static void Init(DirectoriesConfig config, Dictionary detectionClassesDict) { _labelsDir = config.LabelsDirectory; _imagesDir = config.ImagesDirectory; _thumbDir = config.ThumbnailsDirectory; DetectionClassesDict = detectionClassesDict; } [Key("n")] public string Name { get; set; } = null!; [Key("mn")] public string OriginalMediaName { get; set; } = null!; [IgnoreMember]public TimeSpan Time { get; set; } [IgnoreMember]public string ImageExtension { get; set; } = null!; [IgnoreMember]public DateTime CreatedDate { get; set; } [IgnoreMember]public string CreatedEmail { get; set; } = null!; [IgnoreMember]public RoleEnum CreatedRole { get; set; } [IgnoreMember]public SourceEnum Source { get; set; } [IgnoreMember]public AnnotationStatus AnnotationStatus { get; set; } [IgnoreMember]public DateTime ValidateDate { get; set; } [IgnoreMember]public string ValidateEmail { get; set; } = null!; [Key("d")] public IEnumerable Detections { get; set; } = null!; [Key("t")] public long Milliseconds { get; set; } [Key("lat")]public double Lat { get; set; } [Key("lon")]public double Lon { get; set; } #region Calculated [IgnoreMember] public List Classes => Detections.Select(x => x.ClassNumber).ToList(); [IgnoreMember] public string ImagePath => Path.Combine(_imagesDir, $"{Name}{ImageExtension}"); [IgnoreMember] public string LabelPath => Path.Combine(_labelsDir, $"{Name}.txt"); [IgnoreMember] public string ThumbPath => Path.Combine(_thumbDir, $"{Name}{Constants.THUMBNAIL_PREFIX}.jpg"); [IgnoreMember] public bool IsSplit => Name.Contains(Constants.SPLIT_SUFFIX); private CanvasLabel? _splitTile; [IgnoreMember] public CanvasLabel? SplitTile { get { if (!IsSplit) return null; if (_splitTile != null) return _splitTile; var startCoordIndex = Name.IndexOf(Constants.SPLIT_SUFFIX, StringComparison.Ordinal) + Constants.SPLIT_SUFFIX.Length; var coordsStr = Name.Substring(startCoordIndex, 14).Split('_'); _splitTile = new CanvasLabel { Left = double.Parse(coordsStr[1]), Top = double.Parse(coordsStr[2]), Width = double.Parse(coordsStr[0]), Height = double.Parse(coordsStr[0]) }; return _splitTile; } } [IgnoreMember] public string TimeStr => $"{Time:h\\:mm\\:ss}"; private List<(Color Color, double Confidence)>? _colors; [IgnoreMember] public List<(Color Color, double Confidence)> Colors => _colors ??= Detections .Select(d => (DetectionClassesDict[d.ClassNumber].Color, d.Confidence)) .ToList(); private string? _className; [IgnoreMember] public string ClassName { get { if (string.IsNullOrEmpty(_className)) { var detectionClasses = Detections.Select(x => x.ClassNumber).Distinct().ToList(); _className = detectionClasses.Count > 1 ? string.Join(", ", detectionClasses.Select(x => DetectionClassesDict[x].UIName)) : DetectionClassesDict[detectionClasses.FirstOrDefault()].UIName; } return _className; } } #endregion Calculated } [MessagePackObject] public class AnnotationImage : Annotation { [Key("i")] public byte[] Image { get; set; } = null!; } public enum AnnotationStatus { None = 0, Created = 10, Edited = 20, Validated = 30, Deleted = 40 }