private static void AdjustSpan(PhotoMetadata meta, TripDuration duration) { for (uint i = 0; i < duration.Spans.Length; i++) { if (meta.TakenDate > duration.Spans[i].EndTime) { duration.Spans[i].EndTime = meta.TakenDate; } if (meta.TakenDate < duration.Spans[i].StartTime) { duration.Spans[i].StartTime = meta.TakenDate; } if (duration.Parents != null) { for (uint j = 0; j < duration.Parents.Length; j++) { if (meta.TakenDate > duration.Parents[j].Spans[0].EndTime) { duration.Parents[j].Spans[0].EndTime = meta.TakenDate; } if (meta.TakenDate < duration.Parents[j].Spans[0].StartTime) { duration.Parents[j].Spans[0].StartTime = meta.TakenDate; } } } } }
private static void GenerateNewFilePath(PhotoMetadata meta) { var country = string.Empty; var level1 = string.Empty; var city = string.Empty; if (meta.Address.address_components != null) { foreach (var addr in meta.Address.address_components) { if (addr.types[0] == "country" && addr.types[1] == "political") { country = addr.long_name; } else if (addr.types[0] == "administrative_area_level_1" && addr.types[1] == "political") { level1 = addr.long_name; } else if (addr.types[0] == "locality" && addr.types[1] == "political") { city = addr.long_name; } } if (!string.IsNullOrWhiteSpace(country)) { if (string.IsNullOrWhiteSpace(city)) { if (meta.HasLocation) { meta.NewDirPath = string.Format(@"{0}/{1}", config.new_path, country); meta.NewFilePath = string.Format(@"{0}/{1}-{2}.jpg", meta.NewDirPath, meta.TakenDate.ToString("yyyy-MM-dd HH-mm-ss"), country); } else { meta.NewDirPath = string.Format(@"{0}/{1}/{2}", config.new_path, country, meta.Model); meta.NewFilePath = string.Format(@"{0}/{1}-{2}.jpg", meta.NewDirPath, meta.TakenDate.ToString("yyyy-MM-dd HH-mm-ss"), country); } } else { if (meta.HasLocation) { meta.NewDirPath = string.Format(@"{0}/{1}/{2}", config.new_path, country, city); meta.NewFilePath = string.Format(@"{0}/{1}-{2}-{3}.jpg", meta.NewDirPath, meta.TakenDate.ToString("yyyy-MM-dd HH-mm-ss"), country, city); } else { meta.NewDirPath = string.Format(@"{0}/{1}/{2}/{3}", config.new_path, country, city, meta.Model); meta.NewFilePath = string.Format(@"{0}/{1}-{2}-{3}.jpg", meta.NewDirPath, meta.TakenDate.ToString("yyyy-MM-dd HH-mm-ss"), country, city); } } } } else { meta.NewDirPath = string.Format(@"{0}/{1}", config.new_path, meta.TakenDate.ToString("yyyy-MM-dd")); meta.NewFilePath = string.Format(@"{0}/{1}.jpg", meta.NewDirPath, meta.TakenDate.ToString("yyyy-MM-dd HH-mm-ss")); } }
private static void CopyPhoto(PhotoMetadata meta) { try { if (!Directory.Exists(meta.NewDirPath)) { Directory.CreateDirectory(meta.NewDirPath); } if (!File.Exists(meta.NewFilePath)) { Console.WriteLine(string.Format("Copying file: {0}", meta.NewFilePath)); File.Copy(meta.FilePath, meta.NewFilePath); } else { meta.NewFilePath = string.Format("{0}_{1}.jpg", meta.NewFilePath, DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss-ffffff")); File.Copy(meta.FilePath, meta.NewFilePath); Console.WriteLine(string.Format("File exists: {0}", meta.NewFilePath)); } } catch (Exception e) { Console.WriteLine(string.Format("Error copying photo: {0}", e.Message)); } }
public static void ExpandDuration(PhotoMetadata meta) { if (!string.IsNullOrWhiteSpace(meta.Address.place_id)) { if (!cache.ContainsKey(meta.Address.place_id)) { cache.Add(meta.Address.place_id, InitTripDuration(meta)); } else { AdjustSpan(meta, cache[meta.Address.place_id]); } } }
public static bool TryGetAddress(PhotoMetadata meta, out GoogleAddressInfo address) { var result = false; address = new GoogleAddressInfo(); var foundAddress = false; var levelLimit = 3; var currentLevel = 0; foreach (var duration in cache.Values) { foreach (var span in duration.Spans) { if (LocateSameDay) { result = meta.TakenDate.Date >= span.StartTime.Date && meta.TakenDate.Date <= span.EndTime.Date; } else { result = meta.TakenDate >= span.StartTime && meta.TakenDate <= span.EndTime; } if (result) { foundAddress = true; currentLevel = duration.Location.address_components.Length; if (string.IsNullOrWhiteSpace(address.place_id)) { address = duration.Location; } else if (address.address_components.Length < currentLevel) { address = duration.Location; } if (currentLevel >= levelLimit) { break; } } } } result = foundAddress; return(result); }
private PhotoMetadata ParseExif() { try { var meta = new PhotoMetadata(); stream.Position = APP1_START_POSITION + APP1_HEADER_LENGTH; var count = Convert2BytesToShort(ReadBytes(2)); for (ushort i = 0; i < count; i++) { var tagId = Convert2BytesToTag(ReadBytes(2)); var tagType = ParseTagType(ReadBytes(2)); var length = Convert4BytesToInt(ReadBytes(4)); var valueBuffer = ReadBytes(4); if (tagId == ExifTagId.Make) { meta.Make = GetStringRefValue(valueBuffer, length); } else if (tagId == ExifTagId.Model) { meta.Model = GetStringRefValue(valueBuffer, length); } else if (tagId == ExifTagId.Date) { meta.TakenDate = GetDateRefValue(valueBuffer, length); } else if (tagId == ExifTagId.GPSOffset) { meta.GPS = ReadGPSInfo(Convert4BytesToInt(valueBuffer)); if (meta.GPS.LatRef == 'N' || meta.GPS.LatRef == 'S') { meta.HasLocation = true; } } } return(meta); } catch (Exception e) { Console.WriteLine(string.Format("Error parsing EXIF: {0}", e.Message)); return(null); } }
private static TripDuration InitTripDuration(PhotoMetadata meta) { TripDuration duration = new TripDuration(); duration.Location = meta.Address; duration.Spans = new TripSpan[1]; TripSpan span = new TripSpan(); span.StartTime = meta.TakenDate; span.EndTime = meta.TakenDate; duration.Spans[0] = span; var addressComponents = meta.Address.address_components; if (addressComponents != null && addressComponents.Length > 1) { duration.Parents = new TripDuration[addressComponents.Length - 1]; for (uint i = 1; i < addressComponents.Length; i++) { var placeId = string.Format("{0}_{1}", meta.Address.place_id, addressComponents[i].types[0]); if (!cache.ContainsKey(placeId)) { var address = new GoogleAddressInfo(); address.place_id = placeId; address.address_components = new GoogleAddressType[addressComponents.Length - i]; Array.Copy(addressComponents, 1, address.address_components, 0, address.address_components.Length); var higherDuration = new TripDuration(); higherDuration.Location = address; higherDuration.Spans = new TripSpan[1]; higherDuration.Spans[0] = span; cache.Add(placeId, higherDuration); } duration.Parents[i - 1] = cache[placeId]; } } return(duration); }
private static async Task GenerateAddress(PhotoMetadata meta) { if (meta.HasLocation) { GoogleAddressInfo addressInfo; if (TryGetLocation(meta.GPS, out addressInfo)) { meta.Address = addressInfo; } else { Console.WriteLine(string.Format("Loading address for {0}", meta.FilePath)); var foundAddress = false; var address = await GetAddress(meta.GPS).ConfigureAwait(false); googleCache.Add(address); foreach (var info in address.results) { if (info.types.Length == 2 && info.types[0] == "locality" && info.types[1] == "political") { addressCache.Add(info); meta.Address = info; foundAddress = true; break; } } if (!foundAddress) { foreach (var info in address.results) { if (info.types.Length == 2 && info.types[0] == "country" && info.types[1] == "political") { addressCache.Add(info); meta.Address = info; foundAddress = true; break; } } } } } }