在《利用百度鹰眼获取poi点周围任意范围内一心堂点位的方法》中,我提到了用百度鹰眼来实现选择poi点周边一定范围内一心堂点位的方法。
但由于自己水平问题,之前写的代码运行出错……
我还没去找原因,因为我找到了另一种实现同样需求的方法。
这就是利用百度地图api提供的批量算路功能来实现。这个方法比百度鹰眼更简单,因此理论上出错可能性更小。
基本思路
要获取某个poi点周边的一心堂点位,就必须在该poi点和所有一心堂点位之间建立连接,计算出poi点和每一个一心堂点位的距离,然后再根据需要对距离数字进行筛选,这样就选出了所需的一心堂点位。
百度地图api提供的批量算路功能:
- 根据起点和终点,批量计算路线的距离和耗时
- 可选择出行方案(驾车、骑行、步行)
- 融入出行策略(不走高速、常规路线、距离较短),路线和耗时计算考虑实时路况
- 驾车模式支持输入起点车头方向,提升准确性
- 步行时任意起终点之间的距离不得超过200KM,超过此限制会返回参数错误
- 一次最多计算50条路线,起终点个数之积不能超过50。 比如2个起点25个终点,50个起点1个终点等
如果我们把poi点视为起点,把一心堂的点位视为终点,就刚好满足了百度地图api的批量算路功能需求。
我们只需要距离信息,而批量算路功能提供了返回起点到终点的距离信息(根据选择交通方式的不同,距离信息会有变化)。
这样获得的距离信息是目标客户实际到达终点的路程长度,就比之前在百度鹰眼中获取两个点之间的直线距离科学得多。
由于poi点数量不会多,比如我遇到的是七八个或十来个,所以,可以一次性把它们封装到起点中。而一心堂点位很多(400多个,将来会更多),所以,可以让封装的起点每次与一个一心堂点位进行计算,这样就不会超过【起终点个数之积不能超过50】的限制。
以下是代码:
# coding: utf-8
# In[1]:
import os
import requests
import socket
import json
import pandas as pd
import datetime
import numpy as np
# In[97]:
class SelectPoi(object):
'''主要是方便在家里偷懒,不用改文件夹路径'''
if socket.gethostname()=='wanght':
root=r'C:\Users\wanght\OneDrive - 华庭.王'
else:
root=r'E:\OneDrive - 华庭.王'
yxt_path=yxt_path
def __init__(self,filename,scope,poi_path,method='walking'):
self.filename=filename
self.scope=scope
self.method=method'
self.poi_path=poi_path
#经纬度查询,火星坐标
def coordinate(self,query):
api='http://api.map.baidu.com/place/v2/search'
data={'region':'昆明',
'ret_coordtype':'gcj02ll',
'output':'json',
'ak':ak,
'query':query}
r=requests.get(url=api,params=data)
result=r.json()
if result['message']=='ok':
s=result['results'][0]['location'],r.json()
poi='{},{}'.format(str(s[0]['lat']),str(s[0]['lng']))
return poi
else:
print('所选poi点查询不到坐标')
def get_distance(self,d):
df=pd.read_excel(self.root+self.poi_path)
if not 'start' in df.columns.tolist():
df['start']=df['address'].map(self.coordinate)
else:
pass
start='|'.join(i for i in df['start'].tolist())
api='https://api.map.baidu.com/routematrix/v2/{}'.format(self.method)
data={'origins':start,
'destinations':d,
'coord_type':'gcj02',
'output':'json',
'ak':ak,
}
r=requests.get(url=api,params=data)
distances=[]
for each in r.json()['result']:
distances.append(each['distance']['value'])
df['distances']=distances
df=df[['address','distances']]
df=df[df.distances<=self.scope]
return df
def gen_data(self):
yxt=pd.read_excel(root+self.yxt_path)
yxt['destination']=yxt['lat'].map(str)+','+yxt['lng'].map(str)
yxt=yxt[['门店名称','门店地址','店铺id','destination']]
yxt['result']=yxt.apply(lambda row: self.get_distance(row['destination']), axis=1)
yxt=yxt[yxt['result'].map(len)>0]
df=yxt
data=df.reindex(df.index.repeat(df.result.str.len())).assign(result=np.concatenate(df.result.values))
data=data.sort_values(by='result',ascending=True)
summary=data.groupby(by='result').count()
summary=summary.reset_index()
summary=summary[['result','destination']]
summary=summary.rename(columns={'result':'poi','destination':'一心堂门店数'})
summary=summary.sort_values(by='一心堂门店数',ascending=False)
with pd.ExcelWriter('{}.xlsx'.format(self.filename)) as writer:
summary.to_excel(writer, sheet_name='汇总')
data.to_excel(writer, sheet_name='明细')
# In[98]:
changpeng=SelectPoi('changpeng',2000,poi_path)
# In[99]:
changpeng.gen_data()
代码中还实现了poi点坐标查询。如果已有坐标在原始文件中就无需查询了。
ps:没搞定简书中代码的缩进……
网友评论