实际工作中,我们经常需要对下面这样的地址进行解析,获取其省、市、区、坐标或邮编。在数据量不大的情况下,当然可以手工处理。但是一旦要处理的地址成百上千条,就必须寻找更快捷的办法了。
深圳市招商物业管理有限公司
深圳市南山区太子路18号
深圳市南山区海昌街
深圳市罗湖区红桂一街环保50号院
深圳市罗湖区红桂一街2号
深圳市罗湖区红桂路2118号
深圳市罗湖区桂园街道红村社区红桂二街2号
深圳市罗湖区宝岗路
之前我是先获取全国各省市区的详情信息,然后用powerbi的自定义函数fnTextContainsAny()来在每一个地址中查找是否包含省市区详情的字段。这种方式运行效率低,而且要查多少个字段就得调用多少次fnTextContainsAny()。
今天突发奇想,能不能用百度地图api来实现这个功能。经过一番摸索,确定是可以的,遂记录下来。
地址解析的应用场景
最常见的莫过于对客户地址进行分析展示了。但由于种种原因,客户地址并不完整,这时就需要根据地址批量匹配各级行政区、邮编等。
我没用过快递的批量服务,我猜他们应该有成熟的解决方案。如果能用快递公司的方案直接进行地址解析,那是最好不过的了。
总体思路
先用百度地图的地理编码api,查找到地址对应的坐标,再用全球逆地理编码,根据查出的坐标来获取该坐标的详情信息。
第一步:批量获取地址的坐标
直接构造百度地图的地理编码api查询函数即可:
let
源 = (address as text) => let
源 = Json.Document(Web.Contents("http://api.map.baidu.com/geocoding/v3/?output=json&ak=你的ak&address="&address)),
result = 源[result],
location = result[location],
转换为表 = Record.ToTable(location),
转置表 = Table.Transpose(转换为表),
提升的标题 = Table.PromoteHeaders(转置表, [PromoteAllScalars=true]),
更改的类型 = Table.TransformColumnTypes(提升的标题,{{"lng", type number}, {"lat", type number}})
in
更改的类型
in
源
我贴的这个函数是个简化版(因为没有太多精确的要求),如果需要精确控制返回结果,可以在百度api返回结果中筛选precise、confidence和comprehension三个参数的值。
控制精确度
然后在地址列表中新建一列,调用此函数即可。
【注意】:个别地址可能超出百度允许的长度(84个字符),或查询不到结果而出错,这时可以选择保留错误,查找到出错的地址,手工修正下,再刷新即可。
再新建一列,把查出的坐标用逗号连接起来备用:
= Table.AddColumn(更改的类型2, "自定义", each [lat]&","&[lng])
第二步:根据坐标反查位置详情
还是基于百度地图的api构造调用函数:
= (poi as text) => let
源 = Json.Document(Web.Contents("http://api.map.baidu.com/reverse_geocoding/v3/?ak=你的ak&output=json&coordtype=wgs84ll&location="&poi)),
result = 源[result],
转换为表 = Record.ToTable(result),
Value = 转换为表{3}[Value],
转换为表1 = Record.ToTable(Value),
筛选的行 = Table.SelectRows(转换为表1, each ([Name] = "city" or [Name] = "district" or [Name] = "province")),
转置表 = Table.Transpose(筛选的行),
提升的标题 = Table.PromoteHeaders(转置表, [PromoteAllScalars=true]),
更改的类型 = Table.TransformColumnTypes(提升的标题,{{"province", type text}, {"city", type text}, {"district", type text}})
in
更改的类型
然后在地址列表中,调用此函数,参数为上一步最后用逗号连接起来的坐标。
返回结果非常丰富,取自己需要的即可:
逆地理编码返回结果
在我的需求中,我只需要返回省、市、区三级信息就足够了。
关于百度地图api
百度地图api调用需要申请ak,访问http://lbsyun.baidu.com/
注册账号即可申请,如果已有百度账号,可以直接登陆后申请。网上这类教程比较多,请自行搜索。
关于配额问题,一般免费额度够用了。如果要商用,要给百度交钱,那是另外一个话题了。目前我自己的需求用免费额度就满足要求了。
网友评论