阮一峰的新闻周刊介绍了高德的位置口令,高德本月推出了一个新功能,可以位需要提供准确位置的用户生成一个 6 位编码,其他人直接搜索这个编码就能找到那个位置,而不需要知道这个位置的名称。
文章后面说:要是国家出台统一算法就好了,为每个地点生成一个固定不变的位置码,用处就大了。
我想,这倒没有必要,为所有位置提供编码的方案不就是经纬度么?
经纬度在日常表达方面确实会有一些障碍,读起来不大方便,而且我不确定有多少人知道经纬度,虽然这是初中就学了的。
我设计了一个 8 位编码方案(BASE32,只包含数字和大写英文字母):
经纬度 1 度大约偏差 111 公里,精确到小数点后 3 位小数,可以控制偏差在 100 米范围内,对于日常使用是可以接受的。
总共 360,000 x 180,000 = 648 亿个点。
二进制 36 位可以表达(687 亿),也就是 5 Bytes。
BASE32 8 位足够可以表达了(10995 亿)(7 位只有 343 亿,差一点)。
在百度地图开放平台上用坐标拾取器获取两个坐标用来测试,结果如下:
- 华中科技大学的毛泽东像位置是
(114.420025,30.514723),精度控制到小数点后三位,换算过来就是BRLMVBKC

- 美国自由女神像位置是
(-74.044500, 40.689225),精度控制到小数点后三位,换算过来就是ARYMQF7B

Base32 字母出现的频率较多,为了减少英文字母的使用,我改成十六进制的表达方式,只多了一位而已,可以接受。测试结果如下:
- 华中科技大学的毛泽东像位置
(114.420025,30.514723)换算过来就是0C56CA8542 - 美国自由女神像位置
(-74.044500, 40.689225)换算过来就是0470C817E1
Python 代码示例:
# woody geo codec
import base64
# encode = base64.b32encode
# decode = base64.b32decode
encode = base64.b16encode
decode = base64.b16decode
def wgc_encode(lat:float, lon:float) -> str:
lat_num = int((lat + 180) * 1000)
lon_num = int((lon + 90) * 1000)
num = lat_num * 180000 + lon_num
return encode(num.to_bytes(5, byteorder="big")).decode()
def wgc_decode(code:str) -> tuple[float, float]:
num = int.from_bytes(decode(code))
lat_num = num // 180000
lon_num = num % 180000
print(lat_num, lon_num)
lat = (lat_num - 180000) / 1000
lon = (lon_num - 90000) / 1000
return lat, lon
for lat, lon in ((114.420025, 30.514723), (-74.044500, 40.689225)):
print((lat, lon))
code = wgc_encode(lat, lon)
print(code)
print(wgc_decode(code))