新增腾讯地图

This commit is contained in:
zpc 2025-08-18 12:58:01 +08:00
parent eed70324fd
commit 15469c5164
6 changed files with 405 additions and 4 deletions

View File

@ -7,6 +7,11 @@ using System.Web;
using Org.BouncyCastle.Utilities;
using System.Net;
using ZR.Common;
using ZR.Model.Dto;
using Infrastructure.Model;
using System.Threading.Tasks;
using ZR.Common.Model;
namespace ZR.Admin.WebApi.Controllers
{
@ -18,6 +23,143 @@ namespace ZR.Admin.WebApi.Controllers
[ApiExplorerSettings(GroupName = "webapi")]
public class WebApiController : BaseController
{
private readonly TencentMapService _tencentMapService;
public WebApiController(TencentMapService tencentMapService)
{
_tencentMapService = tencentMapService;
}
/// <summary>
/// 转换 GPS 经纬度到腾讯地图坐标
/// </summary>
/// <param name="request">坐标转换请求参数</param>
/// <returns>转换后的坐标</returns>
[HttpPost]
[Route("GetLocationTranslate")]
public async Task<IActionResult> GetLocationTranslate([FromBody] CoordinateTranslateRequest request)
{
try
{
if (request == null || string.IsNullOrWhiteSpace(request.Locations))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationTranslateAsync(request.Locations, request.Type);
return SUCCESS(result);
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
}
/// <summary>
/// 根据坐标获取地址信息
/// </summary>
/// <param name="request">地理编码请求参数</param>
/// <returns>地址信息</returns>
[HttpPost]
[Route("GetLocationGeocoder")]
public async Task<IActionResult> GetLocationGeocoder([FromBody] GeocoderRequest request)
{
try
{
if (request == null || string.IsNullOrWhiteSpace(request.Location))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationGeocoderAsync(request.Location);
return SUCCESS(result);
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
}
/// <summary>
/// 批量转换GPS坐标并获取地址
/// </summary>
/// <param name="request">坐标转换请求参数</param>
/// <returns>转换后的坐标和地址信息</returns>
[HttpPost]
[Route("GetLocationTranslateAndGeocoder")]
public async Task<IActionResult> GetLocationTranslateAndGeocoder([FromBody] CoordinateTranslateRequest request)
{
try
{
if (request == null || string.IsNullOrWhiteSpace(request.Locations))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationTranslateAndGeocoderAsync(request.Locations);
return SUCCESS(new
{
Location = result.Location,
Address = result.Address
});
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
}
/// <summary>
/// 转换 GPS 经纬度到腾讯地图坐标 (GET方式)
/// </summary>
/// <param name="locations">坐标点格式lat,lng;lat,lng</param>
/// <param name="type">转换类型默认1表示GPS坐标转腾讯坐标</param>
/// <returns>转换后的坐标</returns>
[HttpGet]
[Route("/webapi/GetLocationTranslate")]
[AllowAnonymous]
public async Task<IActionResult> GetLocationTranslateGet([FromQuery] string locations, [FromQuery] int type = 1)
{
try
{
if (string.IsNullOrWhiteSpace(locations))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationTranslateAsync(locations, type);
return SUCCESS(result);
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
}
/// <summary>
/// 根据坐标获取地址信息 (GET方式)
/// </summary>
/// <param name="location">坐标点格式lat,lng</param>
/// <returns>地址信息</returns>
[HttpGet]
[Route("/webapi/GetLocationGeocoder")]
[AllowAnonymous]
public async Task<IActionResult> GetLocationGeocoderGet([FromQuery] string location)
{
try
{
if (string.IsNullOrWhiteSpace(location))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "坐标点不能为空");
}
var result = await _tencentMapService.GetLocationGeocoderAsync(location);
return SUCCESS(result);
}
catch (Exception ex)
{
return ToResponse(ResultCode.CUSTOM_ERROR, ex.Message);
}
}
}
}

View File

@ -84,6 +84,10 @@ if (!string.IsNullOrEmpty(GaoDeKey))
{
GeoCodeService.ApiKey = GaoDeKey;
}
// 注册腾讯地图服务
builder.Services.AddHttpClient();
builder.Services.AddSingleton<TencentMapService>();
builder.Services.AddMvc(options =>
{
options.Filters.Add(typeof(GlobalActionMonitor));//全局注册

View File

@ -125,5 +125,8 @@
"tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
"vuePath": "", //egD:\Work\ZRAdmin-Vue3
"uniappPath": "D:\\Work" //h5
},
"TencentMap": {
"Key": "2DYBZ-V4N3W-VQ4RA-Y22V5-BXA2E-53FYV" //key
}
}

View File

@ -0,0 +1,122 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace ZR.Common.Model
{
/// <summary>
/// 腾讯地图坐标对象
/// </summary>
public class MapLocation
{
/// <summary>
/// 纬度
/// </summary>
[JsonPropertyName("lat")]
public double Lat { get; set; }
/// <summary>
/// 经度
/// </summary>
[JsonPropertyName("lng")]
public double Lng { get; set; }
}
/// <summary>
/// 腾讯地图API响应对象
/// </summary>
public class MapApiResponse
{
/// <summary>
/// 状态码
/// </summary>
[JsonPropertyName("status")]
public int Status { get; set; }
/// <summary>
/// 状态信息
/// </summary>
[JsonPropertyName("message")]
public string Message { get; set; }
/// <summary>
/// 请求ID
/// </summary>
[JsonPropertyName("request_id")]
public string RequestId { get; set; }
/// <summary>
/// 坐标列表
/// </summary>
[JsonPropertyName("locations")]
public List<MapLocation> Locations { get; set; }
}
/// <summary>
/// 腾讯地图地理编码结果
/// </summary>
public class MapGeocoderResult
{
/// <summary>
/// 地址
/// </summary>
[JsonPropertyName("address")]
public string Address { get; set; }
}
/// <summary>
/// 腾讯地图地理编码API响应
/// </summary>
public class MapGeocoderApiResponse
{
/// <summary>
/// 状态码
/// </summary>
[JsonPropertyName("status")]
public int Status { get; set; }
/// <summary>
/// 状态信息
/// </summary>
[JsonPropertyName("message")]
public string Message { get; set; }
/// <summary>
/// 请求ID
/// </summary>
[JsonPropertyName("request_id")]
public string RequestId { get; set; }
/// <summary>
/// 地理编码结果
/// </summary>
[JsonPropertyName("result")]
public MapGeocoderResult Result { get; set; }
}
/// <summary>
/// 坐标转换请求参数
/// </summary>
public class CoordinateTranslateRequest
{
/// <summary>
/// 坐标点格式lat,lng;lat,lng
/// </summary>
public string Locations { get; set; }
/// <summary>
/// 转换类型1-GPS坐标转腾讯坐标
/// </summary>
public int Type { get; set; } = 1;
}
/// <summary>
/// 地理编码请求参数
/// </summary>
public class GeocoderRequest
{
/// <summary>
/// 坐标点格式lat,lng
/// </summary>
public string Location { get; set; }
}
}

View File

@ -0,0 +1,130 @@
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);
}
}
}