python 通过高德地图POI多边形搜索需要的数据

发布时间:2024年01月01日

高德文档地址:
https://lbs.amap.com/api/webservice/guide/api/search/

在这里插入图片描述

python代码实现

import requests
import json
import csv
import re
import warnings

#warnings.filterwarnings("ignore", category=SyntaxWarning)
from Coordin_transformlat import gcj02towgs84

def Get_poi_polygon(key,polygon,keywords,page):
    '''
    这是一个能够从高德地图获取poi数据的函数
    key:为用户申请的高德密钥
    polygon:目标城市四个点的坐标
    keywords:POI数据的类型
    page:当前页数
    '''
    #设置header
    header = {'User-Agent': "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50"}
    #121.95289,30.182445  122.429594,29.825665
    #将输进来的矩形进行格式化
    # Polygonstr = str(polygon[0]) + ',' + str(polygon[1]) + '|' + str(polygon[2]) + ',' + str(polygon[3])
    #直接使用某市的坐标即可
    Polygonstr = str(121.95289) + ',' + str(30.182445) + '|' + str(122.429594) + ',' + str(29.825665)

    #构建url
    url = 'https://restapi.amap.com/v3/place/polygon?polygon={}&key={}&keywords={}&page={}'.format(Polygonstr, key, keywords, page)
    print(url)
    #用get函数请求数据
    r = requests.get(url, headers=header)

    #设置数据的编码为'utf-8'
    r.encoding = 'utf-8'

    # 将请求得到的数据按照'utf-8'编码成字符串
    data = r.text
    return data

def Get_times_polygon(key,polygon,keywords):
    '''
    这是一个控制Get_poi_polygon申请次数的函数
    '''
    page = 1
    # 执行以下代码,直到count为0的时候跳出循环
    while True:
        # 调用第一个函数来获取数据
        result = Get_poi_polygon(key,polygon, keywords, page)
        # json.loads可以对获取回来JSON格式的数据进行解码
        content = json.loads(result)
        pois = content['pois']
        count = content['count']
        print(count)
        #如果区域内poi的数量大于800,则认为超过上限,返回False请求对区域进行切割
        if int(count) > 800:
            return False
        else:
            for i in range(len(pois)):
                name = pois[i]['name']
                location = pois[i]['location']
                if 'address' not in pois[i].keys():
                    address = str(-1)
                else:
                    address = pois[i]['address']
                adname = pois[i]['adname']
                result = gcj02towgs84(location)
                lng = result[0]
                lat = result[1]
                row = [name, address, adname, lng, lat]
                #调用写入函数来保存数据
                writecsv(row, keywords)
            if count == '0':
                break
                # 递增page
            page = page + 1

def writecsv(poilist,keywords):
    """
    这是写入成csv文件的函数
    :param poilist:
    :param keywords:
    :return: 输出的结果存放在代码文件夹下
    """
    with open('{}.csv'.format(keywords),'a',newline='',encoding='utf-8') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(poilist)

def get_city_scope(key, cityname):
    parameters = 'key={}&keywords={}&subdistrict={}&output=JSON&extensions=all'.format(key, cityname, 0)
    url = 'https://restapi.amap.com/v3/config/district?'
    # 设置header
    header = {'User-Agent': "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50"}
    res = requests.get(url,params=parameters)
    jsonData = res.json()
    if jsonData['status'] == '1':
        district = jsonData['districts'][0]['polyline']
        district_list = re.split(';|\|',district)
        xlist, ylist = [], []
        for d in district_list:
            xlist.append(float(d.split(',')[0]))
            ylist.append(float(d.split(',')[1]))
        xmax = max(xlist)
        xmin = min(xlist)
        ymax = max(ylist)
        ymin = min(ylist)
        return [xmin, ymax, xmax, ymin]
    else:
        print ('fail to acquire: {}'.format(jsonData['info']))


import GetPoi_keywords as gp

def Quadrangle(key,polygon,keywords):
    """
    :param key:高德地图密钥
    :param polygon: 矩形左上跟右下坐标的列表
    :param keywords: poi关键词
    :return:
    """
    #准备一个空列表,存放切割后的子区域
    PolygonList = []
    for i in range(len(polygon)):
        currentMinlat = round(polygon[i][0],6)#当前区域的最小经度
        currentMaxlat = round(polygon[i][2],6)#当前区域的最大经度
        currentMaxlon = round(polygon[i][1],6)#当前区域的最大纬度
        currentMinlon = round(polygon[i][3],6)#当前区域的最小纬度

        cerrnt_list = [currentMinlat, currentMaxlon, currentMaxlat, currentMinlon]
        #将多边形输入获取函数中,判断区域内poi的数量
        status = gp.Get_times_polygon(key,cerrnt_list,keywords)
        #如果数量大于800,那么返回False,对区域进行切分,否则返回区域的坐标对
        if status != False:
            print('该区域poi数量小于800,正在写入数据')
        else:
            #左上矩形
            PolygonList.append([
                currentMinlat, #左经
                currentMaxlon, #上纬
                (currentMaxlat+currentMinlat)/2, #右经
                (currentMaxlon+currentMinlon)/2]) #下纬
            #右上矩形
            PolygonList.append([
                (currentMaxlat+currentMinlat)/2,#左经
                currentMaxlon, #上纬
                currentMaxlat, #右经
                (currentMaxlon+currentMinlon)/2#下纬
            ])
            #左下矩形
            PolygonList.append([
                currentMinlat,#左经
                (currentMaxlon+currentMinlon)/2,#上纬
                (currentMaxlat+currentMinlat)/2,#右经
                currentMinlon#下纬
            ])
            #右下矩形
            PolygonList.append([
                (currentMaxlat+currentMinlat)/2,#左经
                (currentMaxlon+currentMinlon)/2,#上纬
                currentMaxlat,#右经
                currentMinlon#下纬
            ])
            print(len(PolygonList))
            if len(PolygonList) == 0:
                break
            else:
                Quadrangle(key,PolygonList,keywords)


#这里修改为自己的高德密钥
key ='637c56852aa38**************'

#这里修改自己的poi类型
keywords = '体育馆'

#这里输入想要查询的城市
city = '舟山市'

#调用高德查询行政区的API接口来返回矩形坐标对
Retance = gp.get_city_scope(key,city)

#存储区域矩形的列表
input_polygon = []
input_polygon.append(Retance)

Quadrangle(key,input_polygon,keywords)
#GCJ02/谷歌、高德 转换为 WGS84 gcj02towgs84
def gcj02towgs84(localStr):
    lng = float(localStr.split(',')[0])
    lat = float(localStr.split(',')[1])
    PI = 3.1415926535897932384626
    ee = 0.00669342162296594323
    a = 6378245.0
    dlat = transformlat(lng - 105.0, lat - 35.0)
    dlng = transformlng(lng - 105.0, lat - 35.0)
    radlat = lat / 180.0 * PI
    magic = math.sin(radlat)
    magic = 1 - ee * magic * magic
    sqrtmagic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * PI)
    mglat = lat + dlat
    mglng = lng + dlng
    return [lng * 2 - mglng,lat * 2 - mglat]
     
文章来源:https://blog.csdn.net/weixin_38148680/article/details/135324706
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。