dotnet-geo-management/Svrnty.GeoManagement.Google/Mapping/GoogleAddressMapper.cs

86 lines
2.8 KiB
C#

using GoogleApi.Entities.Common;
using GoogleApi.Entities.Maps.Geocoding.Common;
using Svrnty.GeoManagement.Abstractions.Models;
namespace Svrnty.GeoManagement.Google.Mapping;
/// <summary>
/// Maps Google Geocoding API responses to Address models
/// </summary>
internal static class GoogleAddressMapper
{
public static Abstractions.Models.Address? MapToAddress(Result? googleResult)
{
if (googleResult == null)
return null;
var components = googleResult.AddressComponents;
if (components == null || !components.Any())
return null;
var line1 = BuildLine1(components);
var line2 = GetComponentValue(components, "subpremise");
var city = GetCity(components);
var subdivision = GetSubdivision(components);
var postalCode = GetComponentValue(components, "postal_code") ?? string.Empty;
var country = GetComponentValue(components, "country") ?? string.Empty;
var location = googleResult.Geometry?.Location != null
? new GeoPoint((decimal)googleResult.Geometry.Location.Latitude, (decimal)googleResult.Geometry.Location.Longitude)
: null;
return new Abstractions.Models.Address(Normalized: true)
{
Line1 = line1,
Line2 = line2,
City = city,
Subdivision = subdivision,
PostalCode = postalCode,
Country = country,
Location = location,
Note = null
};
}
private static string BuildLine1(IEnumerable<AddressComponent> components)
{
var streetNumber = GetComponentValue(components, "street_number");
var route = GetComponentValue(components, "route");
if (!string.IsNullOrWhiteSpace(streetNumber) && !string.IsNullOrWhiteSpace(route))
return $"{streetNumber} {route}";
return route ?? streetNumber ?? string.Empty;
}
private static string GetCity(IEnumerable<AddressComponent> components)
{
return GetComponentValue(components, "locality")
?? GetComponentValue(components, "postal_town")
?? GetComponentValue(components, "administrative_area_level_2")
?? string.Empty;
}
private static string GetSubdivision(IEnumerable<AddressComponent> components)
{
return GetComponentValue(components, "administrative_area_level_1") ?? string.Empty;
}
private static string? GetComponentValue(IEnumerable<AddressComponent> components, string type)
{
var component = components.FirstOrDefault(c =>
c.Types.Any(t => t.ToString().ToLower().Replace("_", "") == type.Replace("_", "")));
return component?.ShortName;
}
public static GeoPoint? MapToGeoPoint(Result? googleResult)
{
if (googleResult?.Geometry?.Location == null)
return null;
return new GeoPoint(
(decimal)googleResult.Geometry.Location.Latitude,
(decimal)googleResult.Geometry.Location.Longitude
);
}
}