#-*- coding:utf-8 -*-#获取最短路径及时间
importrequestsimportxlrdfrom urllib2 importurlopen, quoteimportjsonimportsysimporttimeimportmath
reload(sys)
sys.setdefaultencoding("utf-8")classderection:#这个函数是求两个坐标点的直线距离
#参考http://blog.csdn.net/qq_29933359/article/details/53516440
defgetDistance(self,origin,destination):
start_lat=origin.split(',')[0]
start_lng=origin.split(',')[1]
end_lat= destination.split(',')[0]
end_lng= destination.split(',')[1]
lat1= (math.pi / 180) *float(start_lat)
lat2= (math.pi / 180) *float(end_lat)
lon1= (math.pi / 180) *float(start_lng)
lon2= (math.pi / 180) *float(end_lng)#print start_lat,start_lng,end_lat,end_lng
#地球半径
R = 6371distance= math.acos(math.sin(lat1) * math.sin(lat2) + math.cos(lat1) * math.cos(lat2) * math.cos(abs(lon2 - lon1))) * R*1000
#print distance
returndistance#直线距离少于2公里就选择步行
defgetwalkduration(self,origin,destination):#url='http://api.map.baidu.com/direction/v2/riding?'
url='http://api.map.baidu.com/direction/v1?mode=walking®ion=武汉'output= 'json'ak= '···'uri= url + '&origin=' + origin + '&destination=' + destination + '&output=' + output + '&ak=' +ak
req=urlopen(uri)
res=req.read().decode()
temp=json.loads(res)
distance= temp['result']['routes'][0]['distance'] #那个0是因为它返回的routes是一个list,所以索引0就是第一条路线
duration = temp['result']['routes'][0]['duration']#print '距离%.2f千米,骑车耗时%d分钟' % (float(distance) / 1000, round(int(duration) / 60))
returndistance, duration#这个函数是利用百度地图路线规划服务求距离POI的最近距离和最短时间
defgetduration(self,origin,destination):
url= 'http://api.map.baidu.com/direction/v2/transit?'output= 'json'ak= '···'uri= url + '&origin=' + origin + '&destination=' + destination + '&output=' + output + '&ak=' +ak
req=urlopen(uri)
res=req.read().decode()
temp=json.loads(res)
distance=temp['result']['routes'][0]['distance']#那个0是因为它返回的routes是一个list,所以索引0就是第一条路线
duration=temp['result']['routes'][0]['duration']#print '距离%.2f千米,乘坐公交耗时%d分钟'%(float(distance)/1000,round(int(duration)/60))
returndistance,duration#这个函数是利用地点检索服务获取离中心点最近的POI(获取的POI数量在10个以内)
def getsortestfacility(self,origin): #选出直线距离最短的前十个设施
url='http://api.map.baidu.com/place/v2/search?&radius_limit=true'query= '公园$景区'tag='旅游景点'output= 'json'ak= '···'
for i in range(1000,6000,1000): #如果1000米距离内没有相关POI,就让半径增加1000
radius =str(i)
uri= url + '&query=' + query +'&tag='+tag+ '&location=' + origin + '&radius='+radius+'&output=' + output + '&ak=' +ak
req=urlopen(uri)
res=req.read().decode()
temp=json.loads(res)
destlist=[]
Num=len(temp['results']) #求返回的POI的个数,下面循环range要用到
if Num==0:#print'%d米内无相关POI'%i
continue
else:for i inrange(0,Num):
lat= temp['results'][i]['location']['lat']
lng= temp['results'][i]['location']['lng']
destination=str(lat)+','+str(lng)
destlist.append(destination)#存在POI就把POI的坐标加入数组
#print destlist
break
returndestlistdeffindnearesttop10(self,origin):
destinationdata=xlrd.open_workbook('C://Users//Administrator//PycharmProjects//···//shopping_cinema.xlsx')
destinationdata_sheet= destinationdata.sheet_by_index(1)
destinationdata_rowsNum=destinationdata_sheet.nrows
alldict={}for i in range(1,destinationdata_rowsNum):
lat= destinationdata_sheet.cell(i, 2).value
lng= destinationdata_sheet.cell(i, 1).value
destination=str(lat)+','+str(lng)
newdist=test.getDistance(origin,destination)
key=str(destination)
value=newdist
alldict[key]=value#alldict.fromkeys(key,value)
#print alldict
sorted_dict=sorted(alldict.items(), key=lambda alldict: alldict[1])returnsorted_dictif __name__ == '__main__':print "开始计算数据,请稍等..."start_time=time.time()
fh= open(r'C://Users//Administrator//PycharmProjects//···//xiaoqu_gongyuan.txt', "w")
origindata= xlrd.open_workbook('C://Users//Administrator//PycharmProjects//···//HousePrice.xlsx')
origindata_sheet= origindata.sheet_by_index(1)
origindata_rowsNum=origindata_sheet.nrows
test= derection() #实例化对象
for i in range(1, origindata_rowsNum):
m= 10000000oriname=origindata_sheet.cell(i, 0).value
orilat= origindata_sheet.cell(i, 1).value
orilng= origindata_sheet.cell(i, 2).value
origin=str(orilat)+','+str(orilng)
sorted_dict=test.findnearesttop10(origin)
top10={}
count=0for key,value insorted_dict:
count+= 1top10[key]=valueif count >= 10:break
#print '小区%s的top10是:%s'%(oriname,top10)
for key,value intop10.items():if value>1000:try:
destination=key
distance, duration= test.getduration(origin,destination) #方法必须由实例调用
except:#print '直线距离是%s米'%(distance)
continue
else:#duration=round(distance/72*60)
destination =key
distance,duration=test.getwalkduration(origin,destination)#print '步行距离%d米,耗时%d秒'%(distance,duration)
if distance
m=distance
d=destinationelse:continue
print '%s小区最短距离是%d米,最近的设施是:%s'%(oriname,m,d)#fh.write(str(name)+','+str(m))
fh.close()
end_time=time.time()print "全部数据处理完毕,用时%.2f秒" % (end_time - start_time)