131 lines
4.6 KiB
C#
131 lines
4.6 KiB
C#
using Infrastructure;
|
||
|
||
using System;
|
||
using System.Net.Http;
|
||
using System.Text.Json;
|
||
using System.Threading.Tasks;
|
||
|
||
using ZR.Common.Model;
|
||
|
||
namespace ZR.Common
|
||
{
|
||
/// <summary>
|
||
/// 腾讯地图服务
|
||
/// </summary>
|
||
public class TencentMapService
|
||
{
|
||
private readonly HttpClient _httpClient;
|
||
private readonly string _apiKey = AppSettings.GetConfig("TencentMap:KEY");
|
||
private const string BaseUrl = "https://apis.map.qq.com/";
|
||
|
||
public TencentMapService(HttpClient httpClient)
|
||
{
|
||
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 转换 GPS 经纬度到腾讯地图坐标
|
||
/// </summary>
|
||
/// <param name="locations">坐标点,格式:lat,lng;lat,lng</param>
|
||
/// <param name="type">转换类型,默认1表示GPS坐标转腾讯坐标</param>
|
||
/// <returns>转换后的坐标</returns>
|
||
public async Task<MapLocation> GetLocationTranslateAsync(string locations, int type = 1)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(locations))
|
||
{
|
||
throw new ArgumentException("坐标点不能为空", nameof(locations));
|
||
}
|
||
|
||
var url = $"{BaseUrl}ws/coord/v1/translate?locations={locations}&type={type}&key={_apiKey}";
|
||
|
||
try
|
||
{
|
||
var response = await _httpClient.GetAsync(url);
|
||
response.EnsureSuccessStatusCode();
|
||
|
||
var content = await response.Content.ReadAsStringAsync();
|
||
var mapResponse = JsonSerializer.Deserialize<MapApiResponse>(content, new JsonSerializerOptions
|
||
{
|
||
PropertyNameCaseInsensitive = true
|
||
});
|
||
|
||
if (mapResponse?.Status == 0 && mapResponse.Locations?.Count > 0)
|
||
{
|
||
return mapResponse.Locations[0];
|
||
}
|
||
else
|
||
{
|
||
throw new Exception($"坐标转换失败: {mapResponse?.Message}");
|
||
}
|
||
}
|
||
catch (HttpRequestException ex)
|
||
{
|
||
throw new Exception("请求腾讯地图API失败", ex);
|
||
}
|
||
catch (JsonException ex)
|
||
{
|
||
throw new Exception("解析腾讯地图API响应失败", ex);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据转换后的经纬度获取地址
|
||
/// </summary>
|
||
/// <param name="location">坐标点,格式:lat,lng</param>
|
||
/// <returns>地址信息</returns>
|
||
public async Task<string> GetLocationGeocoderAsync(string location)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(location))
|
||
{
|
||
throw new ArgumentException("坐标点不能为空", nameof(location));
|
||
}
|
||
|
||
var url = $"{BaseUrl}ws/geocoder/v1/?location={location}&key={_apiKey}";
|
||
|
||
try
|
||
{
|
||
var response = await _httpClient.GetAsync(url);
|
||
response.EnsureSuccessStatusCode();
|
||
|
||
var content = await response.Content.ReadAsStringAsync();
|
||
var geocoderResponse = JsonSerializer.Deserialize<MapGeocoderApiResponse>(content, new JsonSerializerOptions
|
||
{
|
||
PropertyNameCaseInsensitive = true
|
||
});
|
||
|
||
if (geocoderResponse?.Status == 0 && geocoderResponse.Result != null)
|
||
{
|
||
return geocoderResponse.Result.Address;
|
||
}
|
||
else
|
||
{
|
||
throw new Exception($"地理编码失败: {geocoderResponse?.Message}");
|
||
}
|
||
}
|
||
catch (HttpRequestException ex)
|
||
{
|
||
throw new Exception("请求腾讯地图API失败", ex);
|
||
}
|
||
catch (JsonException ex)
|
||
{
|
||
throw new Exception("解析腾讯地图API响应失败", ex);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 批量转换GPS坐标并获取地址
|
||
/// </summary>
|
||
/// <param name="locations">坐标点,格式:lat,lng;lat,lng</param>
|
||
/// <returns>转换后的坐标和地址信息</returns>
|
||
public async Task<(MapLocation Location, string Address)> GetLocationTranslateAndGeocoderAsync(string locations)
|
||
{
|
||
var translatedLocation = await GetLocationTranslateAsync(locations);
|
||
var locationString = $"{translatedLocation.Lat},{translatedLocation.Lng}";
|
||
var address = await GetLocationGeocoderAsync(locationString);
|
||
|
||
return (translatedLocation, address);
|
||
}
|
||
}
|
||
}
|