/// <summary> /// Integruje výsledky od externího poskytovatele do odpovědi /// </summary> /// <param name="providerResults">výsledky od externího poskytovatele výškopisu</param> /// <param name="elevationResponse">referencována odpověď do které chceme výsledky zapsat</param> private static void IntegrateResults(List <Result> providerResults, ref ElevationResponse elevationResponse) { if (providerResults == null) { elevationResponse.status = ElevationResponses.INCOMPLETE; } foreach (Result result in elevationResponse.result) { if (result.elevation != -1) { continue; } Result providerResult = providerResults.Find(r => r.location.Equals(result.location)); if (providerResult == null) { //Google rád ořezává počet desetinných míst - kontrola s počtem, který Google vrací (ten je taky variabilní) string number = providerResults[0].location.lat.ToString(CultureInfo.InvariantCulture); int length = number.Substring(number.IndexOf(".")).Length - 1; double lat = Math.Round(result.location.lat, length); double lng = Math.Round(result.location.lng, length); providerResult = providerResults.Find(r => r.location.Equals(new Location(lat, lng))); } result.elevation = providerResult.elevation; result.resolution = providerResult.resolution; } //Vrácení kompletní odpovědi elevationResponse.status = ElevationResponses.OK; }
public async Task <ElevationResponse> JsonRequest(string key, string locations, string source) { WebOperationContext webOperationContext = WebOperationContext.Current; IncomingWebRequestContext incomingWebRequestContext = webOperationContext.IncomingRequest; string uri = incomingWebRequestContext.UriTemplateMatch.RequestUri.ToString(); Console.WriteLine("{0}: Request (JsonRequest) to {1}", DateTime.Now, uri); logger.Info("Request (JsonRequest) to {0}", uri); var elevationResponse = new ElevationResponse(); var requestHandler = new RequestHandler(); try { //Stopwatch s = Stopwatch.StartNew(); elevationResponse = await requestHandler.HandleRequest(key, locations, source); //Console.WriteLine("Request took {0} ms", s.ElapsedMilliseconds); } catch (Exception e) { Console.WriteLine(e); logger.Error(e); elevationResponse.status = e.Message; } return(elevationResponse); }
/// <summary> /// Zpracuje požadavek /// </summary> /// <param name="key">API klíč</param> /// <param name="locations">Řetezec lokací</param> /// <param name="source">Zdroj</param> /// <returns>Odpověď služby</returns> public async Task <ElevationResponse> HandleRequest(string key, string locations, string source) { if (source == "approx") { approx = true; source = null; } //Zjištění validity API klíče //Stopwatch s = Stopwatch.StartNew(); (bool existingUser, bool premiumUser) = CheckApiKey(key); if (!existingUser) { return(new ElevationResponse(ElevationResponses.INVALID_KEY, null)); } //Console.WriteLine("User search: {0} ms",s.ElapsedMilliseconds); //Parsování a kontrola lokací v URL IEnumerable <Location> parsedLocations = ParseLocations(locations).ToList(); //Console.WriteLine("Number of locs: {0}", parsedLocations.ToList().Count); //Vytvoření odpovědi s lokacemi var elevationResponse = new ElevationResponse(parsedLocations); //Nalezení nejbližího bodu v DB (pokud nebyl nebyl přímo vybrán source) List <Location> locsWithoutElevation; if (source == null) { //s.Restart(); locsWithoutElevation = (List <Location>)GetPointsFromDbParallel(parsedLocations, ref elevationResponse, premiumUser, false); //Console.WriteLine("Getting points from DB parallel: {0} ms", s.ElapsedMilliseconds); if (locsWithoutElevation.Count == 0) { elevationResponse.status = ElevationResponses.OK; return(elevationResponse); } } else { locsWithoutElevation = (List <Location>)parsedLocations; } //Aproximace if (approx) { //s.Restart(); locsWithoutElevation = (List <Location>)Approximate(locsWithoutElevation, ref elevationResponse, premiumUser, false); //Console.WriteLine("Approximation: {0} ms", s.ElapsedMilliseconds); if (locsWithoutElevation.Count == 0) { return(elevationResponse); } } //Načtení hodnot (které nebyly nalezeny v DB) z externích poskytovatelů výškopisu List <Result> providerResults = null; try { //s.Restart(); providerResults = await GetElevation(locsWithoutElevation, source); //Console.WriteLine("Getting info from external sources: {0} ms", s.ElapsedMilliseconds); } catch (Exception e) { Console.WriteLine(e.Message); logger.Error(e); } //Integrace výsledků do odpovědi IntegrateResults(providerResults, ref elevationResponse); return(elevationResponse); }
/// <summary> /// Paralelně provede pokus o nalezení nejbližšího bodu a použití jeho výšky /// </summary> /// <param name="locations">kolekce lokací pro které chceme získat výšku</param> /// <param name="elevationResponse">referencovaná odpověď do které chceme výsledky zapsat</param> /// <param name="premiumUser">Prémiový uživatel</param> /// <param name="spheroid">Použít sféroid pro výpočet vzdálenosti (pomalejší)</param> /// <returns>Kolekce lokací pro které nebyla nalezena výška</returns> private static IEnumerable <Location> GetPointsFromDbParallel(IEnumerable <Location> locations, ref ElevationResponse elevationResponse, bool premiumUser, bool spheroid) { var locsWithoutElevation = new List <Location>(); List <ResultDistance> resultDistances; try { resultDistances = PostgreDbConnector.GetClosestPointWithinParallel(locations, WITHIN_DISTANCE, premiumUser, spheroid); } catch (Exception e) { Console.WriteLine(e.Message); logger.Error(e); throw; } foreach (Result result in elevationResponse.result) { ResultDistance closest = resultDistances.Find(rd => rd.Result.location.Equals(result.location)); if (closest.Distance <= MAX_DISTANCE && closest.Distance >= 0) { result.elevation = closest.Result.elevation; result.resolution = closest.Result.resolution != -1 ? closest.Result.resolution : closest.Distance; } else { locsWithoutElevation.Add(result.location); } } return(locsWithoutElevation); }
/// <summary> /// Provede pokus o nalezení nejbližšího bodu a použití jeho výšky /// </summary> /// <param name="locations">kolekce lokací pro které chceme získat výšku</param> /// <param name="elevationResponse">referencovaná odpověď do které chceme výsledky zapsat</param> /// <param name="premiumUser">Prémiový uživatel</param> /// <param name="spheroid">Použít sféroid pro výpočet vzdálenosti (pomalejší)</param> /// <returns>Kolekce lokací pro které nebyla nalezena výška</returns> private static IEnumerable <Location> GetPointsFromDb(IEnumerable <Location> locations, ref ElevationResponse elevationResponse, bool premiumUser, bool spheroid) { var locsWithoutElevation = new List <Location>(); foreach (Result result in elevationResponse.result) { var closest = new ResultDistance(); try { closest = PostgreDbConnector.GetClosestPointWithin(result.location, WITHIN_DISTANCE, premiumUser, spheroid); } catch (Exception e) { Console.WriteLine(e.Message); logger.Error(e); } if (closest.Distance <= MAX_DISTANCE && closest.Distance >= 0) { result.elevation = closest.Result.elevation; result.resolution = closest.Result.resolution != -1 || closest.Result.resolution != 0 ? closest.Result.resolution : closest.Distance; } else { locsWithoutElevation.Add(result.location); } } return(locsWithoutElevation); }
/// <summary> /// Provede pokus o aproximaci výšky zadaných lokací /// </summary> /// <param name="locations">kolekce lokací pro které chceme aproximovat výšku</param> /// <param name="elevationResponse">referencovaná odpověď do které chceme výsledky zapsat</param> /// <param name="premiumUser">Prémiový uživatel</param> /// <param name="spheroid">Použít sféroid pro výpočet vzdálenosti (pomalejší)</param> /// <returns>Kolekce lokací pro které nebyla aproximována výška</returns> private static IEnumerable <Location> Approximate(IEnumerable <Location> locations, ref ElevationResponse elevationResponse, bool premiumUser, bool spheroid) { var locsWithoutElevation = new List <Location>(); foreach (Location location in locations) { Result result = Approximation.Average(location, WITHIN_DISTANCE_APPROX, premiumUser, spheroid); if (result == null) { locsWithoutElevation.Add(location); continue; } elevationResponse.result.Find(er => er.location.Equals(location)).elevation = result.elevation; elevationResponse.result.Find(er => er.location.Equals(location)).resolution = result.resolution; } return(locsWithoutElevation); }