GeocodeService.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using Microsoft.AspNetCore.Http;
  2. using System.Net.Http.Json;
  3. using System.Text.Json;
  4. namespace OASystem.API.OAMethodLib.AMapApi
  5. {
  6. /// <summary>
  7. /// 高德地图API Service
  8. /// </summary>
  9. public class GeocodeService
  10. {
  11. private readonly string _apiKey = "2f5a9ef15f598df3170811f50787166a"; // 高德API Key
  12. private readonly HttpClient _httpClient;
  13. /// <summary>
  14. /// 初始化
  15. /// </summary>
  16. /// <param name="httpClient"></param>
  17. public GeocodeService(HttpClient httpClient)
  18. {
  19. _httpClient = httpClient;
  20. }
  21. /// <summary>
  22. /// 获取单个地址的经纬度
  23. /// </summary>
  24. /// <param name="address"></param>
  25. /// <returns></returns>
  26. public async Task<GeocodeResult> GetGeocodeAsync(string address)
  27. {
  28. if (string.IsNullOrEmpty(address)) return new GeocodeResult { Address = address, Status = "Failed", Info = "地址为空!" };
  29. string url = $"https://restapi.amap.com/v3/geocode/geo?key={_apiKey}&address={Uri.EscapeDataString(address)}";
  30. var response = await _httpClient.GetFromJsonAsync<JsonElement>(url);
  31. if (response.GetProperty("status").GetString() == "1" && response.GetProperty("geocodes").GetArrayLength() > 0)
  32. {
  33. var location = response.GetProperty("geocodes")[0].GetProperty("location").GetString();
  34. var coordinates = location.Split(',');
  35. return new GeocodeResult
  36. {
  37. Address = address,
  38. Longitude = double.Parse(coordinates[0]),
  39. Latitude = double.Parse(coordinates[1]),
  40. Status = "Success",
  41. Info = "OK"
  42. };
  43. }
  44. else
  45. {
  46. return new GeocodeResult
  47. {
  48. Address = address,
  49. Status = "Failed",
  50. Info = response.GetProperty("info").GetString()
  51. };
  52. }
  53. }
  54. /// <summary>
  55. /// 批量获取多个地址的经纬度
  56. /// </summary>
  57. /// <param name="addresses"></param>
  58. /// <param name="qpsLimit"></param>
  59. /// <returns></returns>
  60. public async Task<List<GeocodeResult>> GetGeocodesAsync(IEnumerable<string> addresses, int qpsLimit = 3)
  61. {
  62. var results = new List<GeocodeResult>();
  63. for (int i = 0; i < addresses.Count(); i += qpsLimit)
  64. {
  65. // 每次处理 qpsLimit 个地址
  66. var batch = addresses.Skip(i).Take(qpsLimit);
  67. // 创建并启动任务
  68. var tasks = batch.Select(GetGeocodeAsync).ToList();
  69. var batchResults = await Task.WhenAll(tasks);
  70. // 收集结果
  71. results.AddRange(batchResults);
  72. // 如果还有剩余请求,延迟一秒
  73. if (i + qpsLimit < addresses.Count())
  74. {
  75. await Task.Delay(1000);
  76. }
  77. }
  78. return results;
  79. }
  80. public class GeocodeResult
  81. {
  82. public string Address { get; set; }
  83. public double Latitude { get; set; }
  84. public double Longitude { get; set; }
  85. public string Status { get; set; }
  86. public string Info { get; set; }
  87. }
  88. }
  89. }