SHA256
117 lines
3.8 KiB
C#
117 lines
3.8 KiB
C#
using Microsoft.AspNetCore.WebUtilities;
|
|
using Microsoft.Extensions.Options;
|
|
using Somnia.GuestLog.Models.Configuration;
|
|
using Somnia.GuestLog.Models.DTOs;
|
|
using Somnia.GuestLog.Utils;
|
|
|
|
namespace Somnia.GuestLog.Services.AddressQuery;
|
|
|
|
public class NominatimAddressQueryService(
|
|
IHttpClientFactory httpClientFactory,
|
|
ILogger<NominatimAddressQueryService> logger,
|
|
IOptions<AddressQueryConfig> configOptions
|
|
) : IAddressQueryService
|
|
{
|
|
private const string defaultBaseAddr = "https://nominatim.openstreetmap.org";
|
|
private const string defaultUserAgent = "Somnia-GuestLog";
|
|
private const string apiUri = "/search";
|
|
|
|
private readonly AddressQueryConfig config = configOptions.Value;
|
|
|
|
|
|
public async Task<List<AddressResultDTO>> SearchAddressAsync(string query)
|
|
{
|
|
var http = GetHttpClient();
|
|
List<AddressResultDTO> rsList = [];
|
|
|
|
try
|
|
{
|
|
string uri = GetRequestUri(query);
|
|
List<ApiResult> apiList = (await http.GetFromJsonAsync<List<ApiResult>>(uri)) ?? [];
|
|
|
|
foreach (ApiResult result in apiList)
|
|
{
|
|
if (result.Address is null)
|
|
{
|
|
logger.LogWarning("Skipping result without address details. '{result}'", result);
|
|
continue;
|
|
}
|
|
|
|
string? alpha3CountryCode = CountryCodesUtils.Alpha2ToAlpha3(result.Address.Country_code);
|
|
|
|
rsList.Add(new()
|
|
{
|
|
HouseNumber = result.Address.House_number,
|
|
AddressRoad = result.Address.Road ?? result.Address.Square,
|
|
AddressCity = result.Address.City ?? result.Address.Municipality ?? result.Address.Town ?? result.Address.Village,
|
|
AddressProvince = result.Address.Province,
|
|
AddressState = result.Address.State,
|
|
AddressCountry = result.Address.Country,
|
|
ZipCode = result.Address.Postcode,
|
|
AddressCountryCode = alpha3CountryCode
|
|
});
|
|
}
|
|
|
|
return rsList;
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
logger.LogError(ex, "Error getting info from API!");
|
|
return [];
|
|
}
|
|
}
|
|
|
|
|
|
private HttpClient GetHttpClient()
|
|
{
|
|
HttpClient client = httpClientFactory.CreateClient();
|
|
|
|
Uri baseAddr = new(config.ServiceURL ?? defaultBaseAddr);
|
|
|
|
client.BaseAddress = baseAddr;
|
|
client.DefaultRequestHeaders.UserAgent.ParseAdd(config.UserAgent ?? defaultUserAgent);
|
|
if (config.ResultLang is not null)
|
|
{
|
|
client.DefaultRequestHeaders.AcceptLanguage.ParseAdd(config.ResultLang);
|
|
}
|
|
|
|
return client;
|
|
}
|
|
|
|
private static string GetRequestUri(string query)
|
|
{
|
|
return QueryHelpers.AddQueryString(apiUri, [
|
|
new KeyValuePair<string, string?>("format", "jsonv2"),
|
|
new KeyValuePair<string, string?>("addressdetails", "1"),
|
|
new KeyValuePair<string, string?>("layer", "address"),
|
|
new KeyValuePair<string, string?>("q", query),
|
|
]);
|
|
}
|
|
|
|
private record class ApiResultAddress(
|
|
string? House_number = null,
|
|
string? Road = null,
|
|
string? Square = null,
|
|
string? City = null,
|
|
string? Municipality = null,
|
|
string? Village = null,
|
|
string? Town = null,
|
|
string? Province = null,
|
|
string? State = null,
|
|
string? Country = null,
|
|
string? Postcode = null,
|
|
string? Country_code = null
|
|
);
|
|
|
|
private record class ApiResult(
|
|
string? Osm_type = null,
|
|
long? Osm_id = null,
|
|
string? Category = null,
|
|
string? AddressType = null,
|
|
string? Name = null,
|
|
string? Display_name = null,
|
|
ApiResultAddress? Address = null
|
|
);
|
|
|
|
|
|
} |