Python调用百度地图API(路线规划、POI检索)

时间:2024-04-15 16:11:11

项目的目的是为了查询某个点附近某些POI的最近距离,例如查询*到附近最近的商场的距离(时间)

1.百度地图API

程序中用到百度地图的两个API,分别是

(1)路线规划服务(又名Direction API):http://lbsyun.baidu.com/index.php?title=webapi/direction-api-v2

(2)地点检索服务(又名Place API):http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi

要用这两个API首先要申请一个key(应用类别必须是服务端),如下图:

路线规划服务

哎呀不想写了,直接上代码吧(代码有点bug,没能实现最后的功能,但是调API服务这些是没错的)

# -*- coding:utf-8 -*-
#获取最短路径及时间
import requests
import xlrd
from urllib2 import urlopen, quote
import json
import sys
import time
import math

reload(sys)
sys.setdefaultencoding("utf-8")

class derection:
    #这个函数是求两个坐标点的直线距离
    #参考http://blog.****.net/qq_29933359/article/details/53516440
    def getDistance(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 = 6371
        distance = math.acos(math.sin(lat1) * math.sin(lat2) + math.cos(lat1) * math.cos(lat2) * math.cos(abs(lon2 - lon1))) * R*1000
        # print distance
        return distance

    #直线距离少于2公里就选择步行
    def getwalkduration(self,origin,destination):
        # url=\'http://api.map.baidu.com/direction/v2/riding?\'
        url=\'http://api.map.baidu.com/direction/v1?mode=walking&region=武汉\'
        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))
        return distance, duration

    #这个函数是利用百度地图路线规划服务求距离POI的最近距离和最短时间
    def getduration(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))
        return distance,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 in range(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
        return destlist

    def findnearesttop10(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])
        return sorted_dict

if __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 = 10000000
        oriname=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=0
        for key,value in sorted_dict:
            count += 1
            top10[key]=value
            if count >= 10:
                break
        # print \'小区%s的top10是:%s\'%(oriname,top10)
        for key,value in top10.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:
                m = distance
                d=destination
            else:
                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)