public void ReverseGeoCode_RadialSearch_ReturnsMaxCountResults() { // Read a file with data with points in and around London in a 20Km radius var data = GeoFileReader.ReadExtendedGeoNames(@"testdata\test_GB.txt").ToArray(); var rg = new ReverseGeoCode <ExtendedGeoName>(data); var center = rg.CreateFromLatLong(51.5286416, 0); //Exactly at 0 longitude so we test left/right of prime meridian var maxresults = 10; Assert.AreEqual(47, data.Length); //File should contain 47 records total var expected_ids = new[] { 2643741, 2646003, 2643743, 6690870, 2651621, 2655775, 2636503, 2634677, 2656194, 2653266 }; Assert.AreEqual(maxresults, expected_ids.Length); // Search from the/a center in London for all points in a 10Km radius, allowing only maxresults results var searchresults = rg.RadialSearch(center, 100000.0, maxresults).ToArray(); // Number of results should match length of expected_id array Assert.AreEqual(expected_ids.Length, searchresults.Length); // Check if each result is in the expected results array foreach (var r in searchresults) { Assert.IsTrue(expected_ids.Contains(r.Id)); } }
/// <summary> /// Reverse Geo Syncing for a folder /// </summary> /// <param name="metaFilesInDirectory">list of files to lookup</param> /// <param name="overwriteLocationNames">true = overwrite the location names, that have a gps location</param> /// <returns></returns> public List <FileIndexItem> LoopFolderLookup(List <FileIndexItem> metaFilesInDirectory, bool overwriteLocationNames) { InitReverseGeoCode(); metaFilesInDirectory = RemoveNoUpdateItems(metaFilesInDirectory, overwriteLocationNames); var subPath = metaFilesInDirectory.FirstOrDefault()?.ParentDirectory; new GeoCacheStatusService(_cache).StatusUpdate(subPath, metaFilesInDirectory.Count, StatusType.Total); foreach (var metaFileItem in metaFilesInDirectory.Select( (value, index) => new { value, index })) { // Create a point from a lat/long pair from which we want to conduct our search(es) (center) var place = _reverseGeoCode.CreateFromLatLong( metaFileItem.value.Latitude, metaFileItem.value.Longitude); // Find nearest var nearestPlace = _reverseGeoCode.NearestNeighbourSearch(place, 1).FirstOrDefault(); // Distance to avoid non logic locations var distanceTo = GeoDistanceTo.GetDistance( nearestPlace.Latitude, nearestPlace.Longitude, metaFileItem.value.Latitude, metaFileItem.value.Longitude); new GeoCacheStatusService(_cache).StatusUpdate(metaFileItem.value.ParentDirectory, metaFileItem.index, StatusType.Current); if (distanceTo > 35) { continue; } // if less than 35 kilometers from that place add it to the object metaFileItem.value.LocationCity = nearestPlace.NameASCII; // Catch is used for example the region VA (Vatican City) try { metaFileItem.value.LocationCountry = new RegionInfo(nearestPlace.CountryCode).NativeName; } catch (ArgumentException e) { Console.WriteLine(e); } metaFileItem.value.LocationState = GetAdmin1Name(nearestPlace.CountryCode, nearestPlace.Admincodes); } // Ready signal new GeoCacheStatusService(_cache).StatusUpdate(subPath, metaFilesInDirectory.Count, StatusType.Current); return(metaFilesInDirectory); }
public void ReverseGeoCode_RadialSearch_ReturnsCorrectResults() { // Read a file with data with points in and around London in a 20Km radius var data = GeoFileReader.ReadExtendedGeoNames(@"testdata\test_GB.txt").ToArray(); var rg = new ReverseGeoCode<ExtendedGeoName>(data); var center = rg.CreateFromLatLong(51.5286416, 0); //Exactly at 0 longitude so we test left/right of prime meridian Assert.AreEqual(47, data.Length); //File should contain 47 records total var expected_ids = new[] { 2640729, 2639577, 2642465, 2637627, 2633709, 2643339, 2634677, 2636503, 2652053, 2654710, 2643743, 2646003, 2643741, 2653941, 6690870, 2655775, 2651621, 2650497, 2656194, 2653266, 2648657, 2637433, 2652618, 2646057 }; // Search from the/a center in London for all points in a 10Km radius var searchresults = rg.RadialSearch(center, 100000.0).ToArray(); // Number of results should match length of expected_id array Assert.AreEqual(expected_ids.Length, searchresults.Length); // Check if each result is in the expected results array foreach (var r in searchresults) Assert.IsTrue(expected_ids.Contains(r.Id)); }
public void ReverseGeoCode_NearestNeighbourSearch_ReturnsCorrectResults() { // Read a file with data with points in and around London in a 20Km radius var data = GeoFileReader.ReadExtendedGeoNames(@"testdata\test_GB.txt").ToArray(); var rg = new ReverseGeoCode <ExtendedGeoName>(data); var center = rg.CreateFromLatLong(51.5286416, 0); //Exactly at 0 longitude so we test left/right of prime meridian Assert.AreEqual(47, data.Length); //File should contain 47 records total var expected_ids = new[] { 2640729, 2639577, 2642465, 2637627, 2633709, 2643339, 2634677, 2636503, 2652053, 2654710, 2643743, 2646003, 2643741, 2653941, 6690870, 2655775, 2651621, 2650497, 2656194, 2653266, 2648657, 2637433, 2652618, 2646057 }; // Search from the/a center in London for the first X points (where X == expected_ids.length) var searchresults = rg.NearestNeighbourSearch(center, expected_ids.Length).ToArray(); // Number of results should match length of expected_id array Assert.AreEqual(expected_ids.Length, searchresults.Length); // Check if each result is in the expected results array foreach (var r in searchresults) { Assert.IsTrue(expected_ids.Contains(r.Id)); } }
static void Main(string[] args) { MRArguments argument = UsageChecker.checkAndBuildArgument(args); var r = new ReverseGeoCode <ExtendedGeoName>(GeoFileReader.ReadExtendedGeoNames(@argument.cityDbFileInfo.FullName)); Parallel.ForEach(argument.targetDirs, (dir) => { if (dir.Name.Contains("@")) { Console.WriteLine("skipping {0}.already renamed. maybe.. it`s name contains @ character", dir.Name); return; } FileInfo[] files = dir.GetFiles(); if (files != null && files.Length > 0) { Dictionary <String, int> cCodeCounter = new Dictionary <String, int>(); Dictionary <String, int> cityCounter = new Dictionary <String, int>(); foreach (FileInfo file in files) { try { IEnumerable <MetadataExtractor.Directory> directories = ImageMetadataReader.ReadMetadata(file.FullName); GpsDirectory gpsDirectory = directories.OfType <GpsDirectory>().First(); if (gpsDirectory != null && gpsDirectory.GetGeoLocation() != null) { double lat = gpsDirectory.GetGeoLocation().Latitude; double lon = gpsDirectory.GetGeoLocation().Longitude; ExtendedGeoName result = r.NearestNeighbourSearch(r.CreateFromLatLong(lat, lon), 1).First(); String city = result.Name; if (cityCounter.TryGetValue(city, out int tvalue)) { cityCounter[city] = tvalue + 1; } else { cityCounter.Add(city, 1); } String ccode = result.CountryCode; if (cCodeCounter.TryGetValue(ccode, out int cvalue)) { cCodeCounter[ccode] = cvalue + 1; } else { cCodeCounter.Add(ccode, 1); } } } catch (Exception) { } } if (cCodeCounter.Count > 0) { int total = 0; String countryName = ""; int maxCountryCount = 0; foreach (String key in cCodeCounter.Keys) { int tempCCount = cCodeCounter[key]; total += tempCCount; if (tempCCount > maxCountryCount) { countryName = key; } } String cityName = ""; List <Tuple <String, int> > cities = new List <Tuple <String, int> >(); foreach (String key in cityCounter.Keys) { cities.Add(new Tuple <string, int>(key, cityCounter[key])); } Tuple <String, int>[] citiesArray = cities.OrderBy(tup => tup.Item2).ToArray(); String destination = dir.Name + " @" + countryName; if (citiesArray != null && citiesArray.Length > 0) { destination += (", " + citiesArray[0].Item1); cityName = citiesArray[0].Item1; if (citiesArray.Length > 1) { Console.WriteLine("second candidate citi name : {0}, count:{1}", citiesArray[1].Item1, citiesArray[1].Item2); int c1val = citiesArray[0].Item2; int c2val = citiesArray[1].Item2; if (c2val / (float)c1val > 0.4) { destination += ("," + citiesArray[1].Item1 + "... "); } } } bool moved = false; try { System.IO.Directory.Move(dir.FullName, dir.Parent.FullName + Path.DirectorySeparatorChar + destination); moved = true; } catch (Exception) { } Console.WriteLine("{0} has {2}/{1} gps data and almost file located [{3}@{4}]. then renaming it to {5} : {6}", dir.Name, files.Length, total, cityName, countryName, destination, moved ? "success" : "failed"); } else { Console.WriteLine("{0}`s {1} file has no gps data", dir.Name, files.Length); } } }); }