2023-03-15 10:09:46 +01:00
|
|
|
|
using BeWo.Data.Entities;
|
2023-03-17 13:53:40 +01:00
|
|
|
|
using BS.Shared.DataContracts;
|
2023-03-15 10:09:46 +01:00
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Configuration;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.Web;
|
|
|
|
|
|
|
2023-03-17 13:53:40 +01:00
|
|
|
|
namespace BeWo.Service.ServiceUtils.DistanceCalculator
|
2023-03-15 10:09:46 +01:00
|
|
|
|
{
|
2023-03-17 13:53:40 +01:00
|
|
|
|
public class GoogleDistanceMatrixApi : IDistanceAPI
|
2023-03-15 10:09:46 +01:00
|
|
|
|
{
|
|
|
|
|
|
public class Response
|
|
|
|
|
|
{
|
|
|
|
|
|
public string Status { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty(PropertyName = "origin_addresses")]
|
|
|
|
|
|
public string[] OriginAddresses { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
[JsonProperty(PropertyName = "destination_addresses")]
|
|
|
|
|
|
public string[] DestinationAddresses { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public Row[] Rows { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public class Data
|
|
|
|
|
|
{
|
|
|
|
|
|
public int Value { get; set; }
|
|
|
|
|
|
public string Text { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class Element
|
|
|
|
|
|
{
|
|
|
|
|
|
public string Status { get; set; }
|
|
|
|
|
|
public Data Duration { get; set; }
|
|
|
|
|
|
public Data Distance { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class Row
|
|
|
|
|
|
{
|
|
|
|
|
|
public Element[] Elements { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private string Key { get; set; }
|
|
|
|
|
|
private string Url { get; set; }
|
|
|
|
|
|
|
2023-03-22 13:25:43 +01:00
|
|
|
|
private AddressRouteMatrix Matrix { get; set; }
|
|
|
|
|
|
|
2023-03-17 13:53:40 +01:00
|
|
|
|
private Address[] OriginAddresses { get; set; }
|
|
|
|
|
|
private Address[] DestinationAddresses { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public GoogleDistanceMatrixApi()
|
2023-03-15 10:09:46 +01:00
|
|
|
|
{
|
|
|
|
|
|
var appSettings = ConfigurationManager.AppSettings;
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(appSettings["GoogleDistanceMatrixApiUrl"]))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("GoogleDistanceMatrixApiUrl is not set in AppSettings.");
|
|
|
|
|
|
}
|
|
|
|
|
|
Url = appSettings["GoogleDistanceMatrixApiUrl"];
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(appSettings["GoogleDistanceMatrixApiKey"]))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("GoogleDistanceMatrixApiKey is not set in AppSettings.");
|
|
|
|
|
|
}
|
|
|
|
|
|
Key = appSettings["GoogleDistanceMatrixApiKey"];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-22 13:25:43 +01:00
|
|
|
|
public void RequestMissingData(ref AddressRouteMatrix matrix, IEnumerable<Address> origins, IEnumerable<Address> destinations)
|
2023-03-17 13:53:40 +01:00
|
|
|
|
{
|
2023-03-22 13:25:43 +01:00
|
|
|
|
Matrix = matrix;
|
|
|
|
|
|
OriginAddresses = origins.ToArray();
|
|
|
|
|
|
DestinationAddresses = destinations.ToArray();
|
2023-03-17 13:53:40 +01:00
|
|
|
|
|
2023-03-22 13:25:43 +01:00
|
|
|
|
var task = GetMatrix();
|
2023-03-17 13:53:40 +01:00
|
|
|
|
|
|
|
|
|
|
task.Wait();
|
|
|
|
|
|
|
|
|
|
|
|
if (task.Exception is object)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw task.Exception;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-22 13:25:43 +01:00
|
|
|
|
public async Task<AddressRouteMatrix> GetMatrix()
|
2023-03-15 10:09:46 +01:00
|
|
|
|
{
|
|
|
|
|
|
using (var client = new HttpClient())
|
|
|
|
|
|
{
|
|
|
|
|
|
var uri = new Uri(GetRequestUrl());
|
|
|
|
|
|
|
|
|
|
|
|
HttpResponseMessage response = await client.GetAsync(uri);
|
|
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("GoogleDistanceMatrixApi failed with status code: " + response.StatusCode);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var content = await response.Content.ReadAsStringAsync();
|
2023-03-17 13:53:40 +01:00
|
|
|
|
|
2023-03-22 13:25:43 +01:00
|
|
|
|
return FillMatrix(JsonConvert.DeserializeObject<Response>(content));
|
2023-03-15 10:09:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-22 13:25:43 +01:00
|
|
|
|
public AddressRouteMatrix FillMatrix(Response response)
|
2023-03-17 13:53:40 +01:00
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < response.Rows.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var row = response.Rows[i];
|
2023-03-22 13:25:43 +01:00
|
|
|
|
var origin = OriginAddresses[i];
|
2023-03-17 13:53:40 +01:00
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < row.Elements.Length; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var element = row.Elements[j];
|
2023-03-22 13:25:43 +01:00
|
|
|
|
var destination = DestinationAddresses[j];
|
2023-03-17 13:53:40 +01:00
|
|
|
|
|
2023-03-22 13:25:43 +01:00
|
|
|
|
var route = Matrix.GetRoute(origin, destination);
|
2023-03-17 13:53:40 +01:00
|
|
|
|
|
2023-03-22 13:25:43 +01:00
|
|
|
|
route.Distance_in_meter = element.Distance.Value;
|
|
|
|
|
|
route.Distance_in_meter_txt = element.Distance.Text;
|
|
|
|
|
|
route.Time_in_seconds = element.Duration.Value;
|
|
|
|
|
|
route.Time_in_seconds_txt = element.Duration.Text;
|
2023-03-17 13:53:40 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-22 13:25:43 +01:00
|
|
|
|
return Matrix;
|
2023-03-17 13:53:40 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public AddressRoute ToAddressRoute(Response.Element element)
|
|
|
|
|
|
{
|
|
|
|
|
|
var res = new AddressRoute();
|
|
|
|
|
|
|
|
|
|
|
|
res.Distance_in_meter = element.Distance.Value;
|
|
|
|
|
|
res.Distance_in_meter_txt = element.Distance.Text;
|
|
|
|
|
|
res.Time_in_seconds = element.Duration.Value;
|
|
|
|
|
|
res.Time_in_seconds_txt = element.Duration.Text;
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-03-15 10:09:46 +01:00
|
|
|
|
private string GetRequestUrl()
|
|
|
|
|
|
{
|
2023-03-22 13:25:43 +01:00
|
|
|
|
var originAddresses = OriginAddresses.Select(str => AddressRouteManager.AddressToString(str)).Select(HttpUtility.UrlEncode).ToArray();
|
2023-03-17 13:53:40 +01:00
|
|
|
|
var origins = string.Join("|", originAddresses);
|
2023-03-22 13:25:43 +01:00
|
|
|
|
var destinationAddresses = DestinationAddresses.Select(str => AddressRouteManager.AddressToString(str)).Select(HttpUtility.UrlEncode).ToArray();
|
2023-03-17 13:53:40 +01:00
|
|
|
|
var destinations = string.Join("|", destinationAddresses);
|
2023-03-15 10:09:46 +01:00
|
|
|
|
return $"{Url}?origins={origins}&destinations={destinations}&key={Key}";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|