工作中有个需求,是通过经纬度坐标获取地理位置信息(国家、行政区域等)。 比较直接的方法,是直接用百度的逆地理编码服务。

百度地图开放平台:全球逆地理编码

之前用过的是 V2 版本,但现在已经不维护了:

百度地图开放平台:常见问题

百度地图 V3 API 需要参数签名,官方文档又讲不清楚(压根没讲),这里记录一下

public static async Task<dynamic> GetAddressResultV3Async(double latitude, double longitude)
{
    try
    {
        var query = new
        {
            ak = "<your ak>",
            location = $"{latitude},{longitude}",
            output = "json",
            coordtype = "wgs84ll"
        };
        var baseAddress = "https://api.map.baidu.com";
        var url = $"/reverse_geocoding/v3".AppendObject(query);
        var sn = SignUrl(url);
        var signedUrl = url.AppendObject(new { sn });
        var httpClient = new HttpClient();
        var response = await httpClient.GetFromJsonAsync<dynamic>(baseAddress + signedUrl);
        return response;
    }
    catch (Exception ex)
    {
        return null;
    }

    static string SignUrl(string url)
    {
        const string SN = "<your sn>";
        return ComputeHashString(WebUtility.UrlEncode(url + SN)).ToLower();
    }

    static string ComputeHashString(string value)
    {
        return MD5.HashData(Encoding.UTF8.GetBytes(value)).ToHexString();
    }
}


public class Program
{
    public static async Task Main(string[] args)
    {
        var result = await GetAddressResultV3Async(23, 113);
        Debugger.Break();
    }
}

public static class HexExtentions
{
    public static string ToHexString(this byte[] value, string separator = "")
    {
        if (value == null || value.Length == 0) return string.Empty;

        return string.Join(separator, value.Select(i => $"{i:X2}"));
    }
}