/// <summary> /// /// </summary> /// <param name="filename"></param> /// <returns></returns> public List<Location> getAllLocationsStream(string filename) { try { List<Location> lLocations = new List<Location>(); using (StreamReader sr = new StreamReader(filename)) { string line; while ((line = sr.ReadLine()) != null) { string[] data = line.Split(new[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries); string Name = getName(data); double Latitude = getLatitude(data); double Longitude = getLongitude(data); Location loc = new Location(Name, Latitude, Longitude); lLocations.Add(loc); } sr.Close(); } return lLocations; } catch (Exception ex) { throw ex; } }
/// <summary> /// /// </summary> /// <param name="Latitude"></param> /// <param name="Longitude"></param> /// <param name="maxDistance"></param> /// <param name="maxResults"></param> /// <returns> /// /api/GetLocations?Latitude=52.950175&Longitude=4.766285&maxDistance=10000&maxResults=100 /// </returns> public List<Location> Get(double Latitude, double Longitude, int maxDistance, int maxResults) { List<Location> lLocations = new List<Location>(); using (GeoQuerys gq = new GeoQuerys()) { Location location = new Location("P1",Latitude, Longitude); lLocations = gq.GetLocations(location, maxDistance, maxResults); } return lLocations; }
public void GetLocationsTest() { GeoQuerys target = new GeoQuerys(); // TODO: Initialize to an appropriate value Location pLocation = new Location("P1", double.Parse("52.2165425"), double.Parse("5.4778534")); // TODO: Initialize to an appropriate value int maxDistance = 10000; // TODO: Initialize to an appropriate value int maxResults = 100; // TODO: Initialize to an appropriate value SearchResults sr = new SearchResults(); SearchResults actual; sr.StartSearch("52.2165425", "5.4778534", maxDistance.ToString(), maxResults.ToString()); actual = target.GetLocations(pLocation, maxDistance, maxResults, sr); actual.EndSearch(""); Assert.AreEqual(maxResults.ToString(), actual.maxResults); }
/// <summary> /// Method to search locations close to other one /// </summary> /// <param name="pLocation">Location</param> /// <param name="maxDistance">Max Distance</param> /// <param name="maxResults">Max number of Results</param> /// <returns></returns> public SearchResults GetLocations(Location pLocation, int maxDistance, int maxResults, SearchResults sr) { List<Location> filteredList = new List<Location>(); SearchResults srDetailed = sr; try { //Get all Locations List<Location> lLocations = new List<Location>(); using (GeoData gData = new GeoData()) { DateTime t1 = DateTime.UtcNow; lLocations = gData.getAllLocations(); DateTime t2 = DateTime.UtcNow; TimeSpan t = t2 - t1; double d = t.TotalSeconds; srDetailed.ReadDataDuration = d; srDetailed.FileRecords = lLocations.Count; } //Sort by Distance //Added Parallelism List<Location> SortedList = lLocations.AsParallel().WithDegreeOfParallelism(4).OrderBy(o => o.CalculateDistance(pLocation)).ToList(); //Filter the Locations with the same Distance, Longitude and Latitude List<Location> filterRepeated = SortedList.AsParallel().WithDegreeOfParallelism(4).GroupBy(x => new { x.Distance, x.Longitude, x.Latitude }) .Select(g => g.First()) .ToList(); //Filter by the max Number of Results filteredList = filterRepeated.Where(x => x.Distance <= maxDistance).Take(maxResults).ToList(); srDetailed.Locations = filteredList; } catch(Exception ex) { throw ex; } return srDetailed; }
public SearchResults GetLocations(string Latitude, string Longitude, string maxDistance, string maxResults) { ///I've implmented a class to register the Exceptions and traces of the application. ///This Trace class is connected with a 3rd Party System called franrodriguez.loggly.com using (Trace t = new Trace("SearchService", "GetLocations")) { using (SearchResults sr = new SearchResults()) { SearchResults srDetailed = new SearchResults(); try { //Start the Search sr.StartSearch(Latitude, Longitude, maxDistance, maxResults); //Lock the object to manage the interlocking of the request lock (this.ThisLock) { //Call to the internal Controller to make the search using (IGeoQuerys gq = new GeoQuerys()) { Location location = new Location("P1", double.Parse(Latitude), double.Parse(Longitude)); srDetailed = gq.GetLocations(location, Int32.Parse(maxDistance), Int32.Parse(maxResults),sr); //End the Search srDetailed.EndSearch(""); } } } catch (Exception e) { t.Error(e.Message.ToString(), e); srDetailed.EndSearch(e.Message.ToString()); } //Give back the json object return srDetailed; } } }
/// <summary> /// Calculates the distance between this location and another one, in meters. /// </summary> public double CalculateDistance(Location location) { try { var rlat1 = Math.PI * Latitude / 180; var rlat2 = Math.PI * location.Latitude / 180; var rlon1 = Math.PI * Longitude / 180; var rlon2 = Math.PI * location.Longitude / 180; var theta = Longitude - location.Longitude; var rtheta = Math.PI * theta / 180; var dist = Math.Sin(rlat1) * Math.Sin(rlat2) + Math.Cos(rlat1) * Math.Cos(rlat2) * Math.Cos(rtheta); dist = Math.Acos(dist); dist = dist * 180 / Math.PI; dist = dist * 60 * 1.1515; Distance = dist * 1609.344; } catch { Distance = 0; } return Distance; }
/// <summary> /// Method to search locations close to other one /// </summary> /// <param name="pLocation">Location</param> /// <param name="maxDistance">Max Distance</param> /// <param name="maxResults">Max number of Results</param> /// <returns></returns> public async Task<List<Location>> GetLocationsAsync(Location pLocation, int maxDistance, int maxResults) { List<Location> filteredList = new List<Location>(); try { //Get all Locations List<Location> lLocationsJoined = new List<Location>(); using (GeoData gData = new GeoData()) { int totalL = 1000000; int paralellism = 100000; int nThreads = totalL / paralellism; int[] arrayRanges = new int[nThreads]; for (int i = 0; i < nThreads; i++) arrayRanges[i] = i * paralellism; IEnumerable<Task<List<Location>>> getLocationsTasksQuery = from range in arrayRanges select gData.getAllLocationsByRange(range,paralellism); // Use ToArray to execute the query and start the getLocations tasks. Task<List<Location>>[] downloadTasks = getLocationsTasksQuery.ToArray(); List<Location>[] lLocations = await Task.WhenAll(downloadTasks); } //Sort by Distance List<Location> SortedList = lLocationsJoined.OrderBy(o => o.CalculateDistance(pLocation)).ToList(); //Filter the Locations with the same Distance, Longitude and Latitude List<Location> filterRepeated = SortedList.GroupBy(x => new { x.Distance, x.Longitude, x.Latitude }) .Select(g => g.First()) .ToList(); //Filter by the max Number of Results filteredList = filterRepeated.Where(x => x.Distance <= maxDistance).Take(maxResults).ToList(); } catch { throw; } return filteredList; }
/// <summary> /// /// </summary> /// <param name="path"></param> /// <param name="encoding"></param> /// <returns></returns> public async Task<List<Location>> geLocationsByRange(string filename, int index, int offset) { try { List<Location> lLocations = new List<Location>(); using (StreamReader sr = new StreamReader(filename)) { string line; int lineNbr = 0; int cont = 0; while ((line = await sr.ReadLineAsync()) != null) { lineNbr++; if (lineNbr >= index) { string[] data = line.Split(new[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries); string Name = getName(data); double Latitude = getLatitude(data); double Longitude = getLongitude(data); Location loc = new Location(Name, Latitude, Longitude); lLocations.Add(loc); cont++; } if (cont == offset) break; } sr.Close(); } return lLocations; } catch { throw; } }
/// <summary> /// Method to get the Location using File.ReadAllLines and ParallelFor /// </summary> /// <param name="filename"></param> /// <returns></returns> public List<Location> getAllLocationsStreamParallel(string filename) { try { List<Location> lLocations = new List<Location>(); string[] AllLines = File.ReadAllLines(filename); var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 4 }; Parallel.For(0, AllLines.Length, options, i => { try { string[] data = AllLines[i].Split(new[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries); string Name = getName(data); double Latitude = getLatitude(data); double Longitude = getLongitude(data); Location loc = new Location(Name, Latitude, Longitude); lock (lLocations) { lLocations.Add(loc); } } catch { } }); return lLocations; } catch(Exception ex) { throw ex; } }