/
renix
/
TravelGuide
Обзор
Документация
Войти
/
renix
/
TravelGuide
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
back/Services/OpenRouteService.cs
193 строки
7 KB
atikinvobud
Alghorithm
09 апр 2025, 23:04
09 апр 2025, 23:04
74b8200
Код
Авторство
О чём код?
using System; using System.Net.Http; using System.Threading.Tasks; using MongoDB.Driver; using Newtonsoft.Json.Linq; using System.Globalization; using System.Text.Json.Nodes; using back.Models; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; using System.Text; using back.DTOs.OpenRouteDTO; using System.Text.Json; using back.Models.Entities; namespace back.Services; public class OpenRouteService { private const string token ="5b3ce3597851110001cf6248b83f8485c8ed4e73874d41ce3eb2ac25"; private readonly HttpClient httpClient; private readonly Context context; private readonly MatrixService matrixService; public OpenRouteService(HttpClient httpClient, Context context, MatrixService matrixService) { this.httpClient = httpClient; this.context = context; this.matrixService = matrixService; } private async Task<List<LandmarkEntity>> GetAllLandmarksAsync() { // Здесь просто заглушка – в реальной реализации используйте БД return await context.Landmarks.ToListAsync(); } public async Task<string> GetRouteAsync(double startLat, double startLon, double endLat, double endLon) { string url = string.Format(CultureInfo.InvariantCulture, "https://api.openrouteservice.org/v2/directions/foot-walking?api_key={0}&start={1},{2}&end={3},{4}", token, startLon, startLat, endLon, endLat); HttpResponseMessage response = await httpClient.GetAsync(url); if (response.IsSuccessStatusCode) { string responseBody = await response.Content.ReadAsStringAsync(); return responseBody; } else { return $"Ошибка: {response.StatusCode} - {response.Content.ReadAsStringAsync().Result}"; } } public async Task<(double lat, double lon)> GeoCodeAsync(string address) { string url = $"https://api.openrouteservice.org/geocode/search?api_key={token}&text={Uri.EscapeDataString(address)}&boundary.country=RU"; HttpResponseMessage response = await httpClient.GetAsync(url); if (!response.IsSuccessStatusCode) return (0, 0); string responseBody = await response.Content.ReadAsStringAsync(); JObject data = JObject.Parse(responseBody); if (data["features"] != null && data["features"]!.HasValues) { foreach (var feature in data["features"]!) { var properties = feature["properties"]; if (properties != null && properties["country_a"]?.ToString() == "RUS") // Фильтруем по России { double lon = feature["geometry"]!["coordinates"]![0]!.Value<double>(); double lat = feature["geometry"]!["coordinates"]![1]!.Value<double>(); return (lat, lon); } } } return (0, 0); } public async Task<string> ReverseGeocodeAsync(double latitude, double longitude) { string latitudeStr = latitude.ToString(CultureInfo.InvariantCulture); string longitudeStr = longitude.ToString(CultureInfo.InvariantCulture); string url =$"https://api.openrouteservice.org/geocode/reverse?api_key={token}&point.lon={longitudeStr}&point.lat={latitudeStr}&layers=address"; HttpResponseMessage response = await httpClient.GetAsync(url); if (response.IsSuccessStatusCode) { string responseBody = await response.Content.ReadAsStringAsync(); // JObject data = JObject.Parse(responseBody); return responseBody; } else { string error = await response.Content.ReadAsStringAsync(); return $"Ошибка: {response.StatusCode} - {error}"; } } public async Task GetDistMatrix() { var existingMatrix = matrixService.GetDistanceMatrixAsync(); if (existingMatrix != null) { Console.WriteLine("Matrix already exists in DB."); return; } var data = await context.Landmarks.Select(l => new { l.Longtitude, l.Latitude }).ToListAsync(); List<double[]> result = data.Select(d => new double[] { d.Longtitude, d.Latitude }).ToList(); var requestData = new { locations = result, metrics = new string[] { "duration" }, units = "m" }; string apiUrl = "https://api.openrouteservice.org/v2/matrix/driving-car"; string jsonRequest = JsonConvert.SerializeObject(requestData); httpClient.DefaultRequestHeaders.Add("Authorization", token); var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); HttpResponseMessage response = await httpClient.PostAsync(apiUrl, content); response.EnsureSuccessStatusCode(); string responseContent = await response.Content.ReadAsStringAsync(); var responseObject = JsonConvert.DeserializeObject<dynamic>(responseContent); var durationsArray = responseObject!.durations; List<double[]> durations = new List<double[]>(); foreach (var row in durationsArray) { durations.Add(row.ToObject<double[]>()); } await matrixService.SaveOrUpdateDistanceMatrixAsync(durations); } public async Task AddLandmark(double latitude, double longitude) { var source = new double[] { longitude, latitude }; var data = await context.Landmarks.Select(l => new { l.Longtitude, l.Latitude }).ToListAsync(); List<double[]> locations = data.Select(d => new double[] { d.Longtitude, d.Latitude }).ToList(); locations.Add(source); List<int> destinationsIndices = new List<int>(); for (int i = 0;i<locations.Count-1;i++) { destinationsIndices.Add(i); } var requestData = new { locations = locations, destinations = destinationsIndices, sources = new List<int> { locations.Count - 1 }, metrics = new string[] { "duration" }, units = "m" }; string apiUrl = "https://api.openrouteservice.org/v2/matrix/driving-car"; string jsonRequest = JsonConvert.SerializeObject(requestData); httpClient.DefaultRequestHeaders.Remove("Authorization"); httpClient.DefaultRequestHeaders.Add("Authorization", token); var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); HttpResponseMessage response = await httpClient.PostAsync(apiUrl, content); response.EnsureSuccessStatusCode(); string responseContent = await response.Content.ReadAsStringAsync(); var responseObject = JsonConvert.DeserializeObject<dynamic>(responseContent); var durationsArray = responseObject!.durations; List<double> temp = new List<double>(); foreach (var row in durationsArray) { temp.AddRange(row.ToObject<double[]>()); } temp.Add(0.0); List<double[]> durations = matrixService.GetDistanceMatrixAsync() ?? new List<double[]>(); durations.Add(temp.ToArray()); for (int i = 0; i < durations.Count - 1; i++) { durations[i] = durations[i].Concat(new double[] { durations[durations.Count - 1][i] }).ToArray(); } await matrixService.SaveOrUpdateDistanceMatrixAsync(durations); } }