高德地图之Python爬取上海市所有道路轮廓坐标
任務(wù)內(nèi)容:根據(jù)某個(gè)城市的經(jīng)緯度坐標(biāo)范圍,將城市范圍劃分成一個(gè)個(gè)的小網(wǎng)格,依次爬取每個(gè)網(wǎng)格內(nèi)的道路id,name,存儲至excel文件,然后再根據(jù)道路id,爬取每條道路的坐標(biāo)輪廓。
步驟:
step1:申請高德地圖的key,之后調(diào)用接口時(shí)會用到。
step2:根據(jù)高德地圖接口可獲取上海市的區(qū)域范圍的經(jīng)緯度坐標(biāo),此處可直接更改下圖中的參數(shù),例如,我想要上海市的區(qū)域坐標(biāo)范圍,那么可修改下圖中的參數(shù)。
?修改參數(shù)后點(diǎn)擊運(yùn)行,
查看 polyline字段。
處理polyline字段,獲得最大以及最小的longitude,latitude。?
step3:劃分網(wǎng)格,代碼如下:
maxlatitude = 122.247149 minlatitude = 120.856804 maxlongitude = 31.872716 minlongitude = 30.675593 def generalID(column_num,row_num):latitude = (maxlatitude - minlatitude)/column_numlongitude = (maxlongitude - minlongitude)/row_numprint("maxlatitude", maxlatitude,"minlatitude",minlatitude,"latitude",latitude,"column_num",column_num)polylists = []for i in range(column_num):left_latitude = minlatitude + latitude * irigh_latitude = minlatitude + latitude * (i+1)for j in range(row_num):temp = ""left_longitude = minlongitude + longitude * jrigh_longitude = minlongitude + longitude * (j+1)temp = str(left_latitude) + ',' + str(left_longitude) + '|' + str(righ_latitude) + ',' + str(righ_longitude)polylists.append(temp)return polylistsstep4:根據(jù)返回的坐標(biāo)對,查詢該網(wǎng)格下道路的id,使用接口
#https://restapi.amap.com/v3/place/polygon?key=你的Key&polygon= # 120.856804,30.675593|121.856804,31.675593&keywords="道路名"&types=190301&offset=20&page=1,代碼如下: #獲取每一頁的數(shù)據(jù) def get_page_road(polygon, page):req_url = search_url + "?polygon="+ polygon + "&keywords=" + quote(roadname) + "&types=" + \types + "&offset=" + str(20) + "&page=" + str(page) + "&extensions=all"+ "&output=json" + "&key=" + amap_web_keywith request.urlopen(req_url) as f:data = f.read()data = data.decode('utf-8')idlist = []datajson = json.loads(data) # 將字符串轉(zhuǎn)換為jsondatajson = datajson['pois']#print(datajson)for i in range(len(datajson)):if datajson[i]['cityname'] == "上海市":tmp = []tmp.append(datajson[i]['id'])tmp.append(datajson[i]['name'])idlist.append(tmp)#print(idlist)return idliststep5:將獲得的數(shù)據(jù)存儲至excel
def write_to_excel(polylist):book = xlwt.Workbook(encoding='utf-8', style_compression=0)sheet = book.add_sheet(roadname, cell_overwrite_ok=True)# 第一行(列標(biāo)題)sheet.write(0, 0, 'id')sheet.write(0, 1, 'name')j = 0for polygon in polylist:all_pages = get_roads(polygon)len_pages = len(all_pages)print(len_pages)k = 0for i in range(j,j+len_pages):# 每一行寫入sheet.write(i + 1, 0, all_pages[k][0])sheet.write(i + 1, 1, all_pages[k][1])k += 1j += len_pagesbook.save(r'' + roadname + '.xls')以上步驟所有代碼如下:
""" 獲取上海所有道路的id,name """ from urllib.request import quote from urllib import request import json import xlwt import test#https://restapi.amap.com/v3/place/polygon?key=你的key&polygon= # 120.856804,30.675593|121.856804,31.675593&keywords="道路名"&types=190301&offset=20&page=1 # &extensions=all amap_web_key = '你的key' search_url = 'https://restapi.amap.com/v3/place/polygon' roadname = "道路名" #roadname = "1515道路名" types = '190301'#根據(jù)高德給定的 https://lbs.amap.com/api/webservice/guide/api/district 獲得上海市四邊形邊界 maxlatitude = 122.247149 minlatitude = 120.856804 maxlongitude = 31.872716 minlongitude = 30.675593#polylist 存儲所有網(wǎng)格的四邊形邊界 def write_to_excel(polylist):book = xlwt.Workbook(encoding='utf-8', style_compression=0)sheet = book.add_sheet(roadname, cell_overwrite_ok=True)# 第一行(列標(biāo)題)sheet.write(0, 0, 'id')sheet.write(0, 1, 'name')j = 0for polygon in polylist:all_pages = get_roads(polygon)len_pages = len(all_pages)print(len_pages)k = 0for i in range(j,j+len_pages):# 每一行寫入sheet.write(i + 1, 0, all_pages[k][0])sheet.write(i + 1, 1, all_pages[k][1])k += 1j += len_pagesbook.save(r'' + roadname + '.xls')""" 根據(jù)范圍劃分網(wǎng)格,獲得每個(gè)網(wǎng)格的四邊形邊界 """ def generalID(column_num,row_num):latitude = (maxlatitude - minlatitude)/column_numlongitude = (maxlongitude - minlongitude)/row_numprint("maxlatitude", maxlatitude,"minlatitude",minlatitude,"latitude",latitude,"column_num",column_num)polylists = []for i in range(column_num):left_latitude = minlatitude + latitude * irigh_latitude = minlatitude + latitude * (i+1)for j in range(row_num):temp = ""left_longitude = minlongitude + longitude * jrigh_longitude = minlongitude + longitude * (j+1)temp = str(left_latitude) + ',' + str(left_longitude) + '|' + str(righ_latitude) + ',' + str(righ_longitude)polylists.append(temp)return polylists# def get_polys(maxlatitude, maxlongitude, minlatitude, minlongitude): # polylist = ["120.856804,30.675593|121.856804,31.675593", "120.856804,30.675593|121.856804,31.675593"] # return polylist#獲取所有頁的數(shù)據(jù) def get_roads(polygon):i = 1all_pages = []while True:results = get_page_road(polygon, i)if results == []:breakall_pages += resultsi += 1return all_pages#獲取每一頁的數(shù)據(jù) def get_page_road(polygon, page):req_url = search_url + "?polygon="+ polygon + "&keywords=" + quote(roadname) + "&types=" + \types + "&offset=" + str(20) + "&page=" + str(page) + "&extensions=all"+ "&output=json" + "&key=" + amap_web_keywith request.urlopen(req_url) as f:data = f.read()data = data.decode('utf-8')idlist = []datajson = json.loads(data) # 將字符串轉(zhuǎn)換為jsondatajson = datajson['pois']#print(datajson)for i in range(len(datajson)):if datajson[i]['cityname'] == "上海市":tmp = []tmp.append(datajson[i]['id'])tmp.append(datajson[i]['name'])idlist.append(tmp)#print(idlist)return idlist# poly = "120.856804,30.675593|121.856804,31.675593" # get_page_road(poly, 1) #polylist = get_polys(maxlatitude, maxlongitude, minlatitude, minlongitude) polylists = generalID(15, 15) print(polylists) write_to_excel(polylists)存到Excel中內(nèi)容如下:
接下來將根據(jù)獲得的id爬取每條道路的輪廓坐標(biāo)。
step6:讀取excel文件,獲得道路id,根據(jù)id,爬取道路輪廓坐標(biāo)。代碼如下:
注意:下面代碼中的poi_boundary_url暫時(shí)已經(jīng)不能用了,高德地圖可能已經(jīng)做了處理
""" 爬取上海市所有道路的形狀坐標(biāo),并以json文件格式存儲 """ from urllib.parse import quote from urllib import request import json import xlrd import ssl ssl._create_default_https_context = ssl._create_unverified_contextamap_web_key = '你的KEY' poi_search_url = "http://restapi.amap.com/v3/place/text" poi_boundary_url = "https://www.amap.com/service/poiInfo?query_type=IDQ&qii=true&need_utd=true&utd_sceneid=1000&addr_poi_merge=true&is_classify=true" cityname = "上海" classfiled = "道路名" read_file_dir = "道路名.xls" save_file_dir = "road.json" #no_sheet:sheet的編號,no_cell_value:列編號 no_sheet = 0 no_cell_value = 0# 根據(jù)id獲取邊界數(shù)據(jù) def getBounById(id):req_url = poi_boundary_url + "&key=" + amap_web_key + "&id=" + idwith request.urlopen(req_url) as f:data = f.read()data = data.decode('utf-8')dataList = []datajson = json.loads(data) # 將字符串轉(zhuǎn)換為jsondatajson = datajson['data']datajson = datajson['poi_list'][0]datajson = datajson['domain_list'][3]if datajson.get('value') != None:datajson = datajson['value']dataArr = [x.split('|') for x in datajson.split('_')]for i in dataArr:innerList = []#每個(gè)innerList存儲一對數(shù)據(jù)f = i[0].split(',')innerList.append(float(f[0]))innerList.append(float(f[1]))#print(innerList)dataList.append(innerList)return dataListdef readname():myWordbookr = xlrd.open_workbook(read_file_dir)mySheetsr = myWordbookr.sheets()mySheetr = mySheetsr[no_sheet]# 獲取列數(shù)nrows = mySheetr.nrowswith open(save_file_dir, "w") as fp:for i in range(1, nrows):id = mySheetr.cell_value(i, no_cell_value)roadname = mySheetr.cell_value(i, 1)address = mySheetr.cell_value(i, 2)boundarydata = getBounById(id)# attr = {"attributes":{"FID" : i,"名稱" : roadname}}# geometry = {"geometry":{"paths":boundarydata}}# t = {attr,geometry}# featlist = [t]# result = {featlist}# print(result)tmp = {"features": [{"attributes": {"FID": i,"名稱": roadname,"區(qū)": address,},"geometry": {"paths": [boundarydata]}}]}#加入延時(shí),否則爬取太快,容易導(dǎo)致錯(cuò)誤if i % 1000 == 0:delay = 20000while delay > 0:delay -= 1print(tmp)fp.write(json.dumps(tmp, indent=4, ensure_ascii=False))print('寫入成功')readname()# 根據(jù)獲取到的poi數(shù)據(jù)的id獲取邊界數(shù)據(jù) # dataList = getBounById('B0FFGQ7PQK') # print(type(dataList)) #print(str(dataList))參考文檔:https://blog.csdn.net/qq_34464926/article/details/79128211
github傳送門,歡迎點(diǎn)小星星啊~
以上。
?
總結(jié)
以上是生活随笔為你收集整理的高德地图之Python爬取上海市所有道路轮廓坐标的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cisco Packet Tracer
- 下一篇: TVM学习教程