【大數據】城市公交網絡分析與可視化(四):繪製城市公交(地鐵)線路圖

內容介紹

梗概:爬取公交路徑座標,處理成爲符合高德地圖Map Lab線形圖的格式,通過該平臺繪製公交(地鐵)線路圖等

一些必要的知識點可在該系列博客的其他內容中獲得!

1 採用循環法獲取線路名

怎麼獲取一個城市有哪些線路名?遍歷前1000路公交。

有遺漏怎麼辦?想指點區域怎麼辦?見後文的“讀取文本”法。

實際上遍歷1000路公交基本能涵蓋一個城市大多數公交線路,遺漏的很多也是一些特殊的路線。

代碼

import requests
import json
import pandas as pd
import re

def Bus_inf(city,line):
    global bus_num  #全局變量,用於計算公交數目
    try:
        #獲取數據
        url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(city,line)
        r = requests.get(url).text
        rt = json.loads(r)
        #讀取當前公交線路主要信息
        dt = {}
        dt['line_name'] = rt['buslines'][0]['name'] #公交線路名字
        dt['polyname'] = rt['buslines'][0]['polyline'] #獲取行駛路徑
        bus_num+=1 #有效公交數+1
        
        """整理行車路徑格式符合高德地圖繪圖工具的要求"""        
        b=re.split("[;]",dt['polyname'])
        res=""
        for i in range(len(b)):
            tmp=re.split("[,]",b[i])
            if len(res)==0:
                res=res+"["+tmp[0]+","+tmp[1]+"]"
            else:
                res=res+",["+tmp[0]+","+tmp[1]+"]"
        dt['polyname'] =res
        
        return pd.DataFrame(dt,index=[bus_num]) #下標index爲“第幾條公交線”
    except:
        return pd.DataFrame()  #讀取數據失敗,返空

if __name__=="__main__":
    bus_num=0  #設置全局變量計算公交數目(通常默認就是0)
    city='蘇州' #需要查詢公交信息的城市
    for_num=1000 #遍歷的線路數[1路,for_num路],通常公交線路數小於1000,具體可參考8684等網站
    all_buslines=pd.DataFrame()     
    for i in range(1,for_num+1):
        all_buslines=pd.concat([all_buslines,Bus_inf(city,str(i)+'路')])  #不加這個'路'可能優先獲取地鐵
    
    print("Bus_info函數遍歷{}前{}路公交,有效公交線路數爲:{}個的情況下:".format(city,for_num,bus_num))
    all_buslines.to_csv("{}前{}路公交(有效線路數:{})基本信息.csv".format(city,for_num,bus_num),index=False,encoding='utf-8-sig')

繪製結果欣賞
繪圖平臺是 高德開放平臺|Map Lab
大城市數據量太大(如北京)高德讀不了,可以刪減一部分,或者分兩次讀入,但特別的卡…

平均一個城市五分鐘出結果吧,什麼是一勞永逸?這就叫一勞永逸!

廈門
寫這麼久的博客第一次知道咋去水印😁
在這裏插入圖片描述
蘇州
在這裏插入圖片描述

上海
在這裏插入圖片描述

如果獲取的是一個省的的公交,圖片會是長什麼樣呢?(巨卡)
四川
在這裏插入圖片描述

成都

在這裏插入圖片描述
2 採用文本讀取法獲取線路名

請上8684等網站獲取需要的公交線路名,前面的博客中提到很多次了,不贅述了。
代碼

import requests
import json
import pandas as pd
import re

def Bus_inf(city,line):
    global bus_num  
    try:
        url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(city,line)
        r = requests.get(url).text
        rt = json.loads(r)
        dt = {}
        dt['line_name'] = rt['buslines'][0]['name'] #公交線路名字
        dt['polyname'] = rt['buslines'][0]['polyline'] #獲取行駛路徑
        bus_num+=1 #有效公交數+1
        """整理行車路徑格式符合高德地圖繪圖工具的要求"""        
        b=re.split("[;]",dt['polyname'])
        res=""
        for i in range(len(b)):
            tmp=re.split("[,]",b[i])
            if len(res)==0:
                res=res+"["+tmp[0]+","+tmp[1]+"]"
            else:
                res=res+",["+tmp[0]+","+tmp[1]+"]"
        dt['polyname'] =res
        return pd.DataFrame(dt,index=[bus_num]) #下標index爲“第幾條公交線”
    except:
        return pd.DataFrame()  #讀取數據失敗,返回空


if __name__=="__main__":
    bus_num=0  #設置全局變量數值(通常默認就是0)
    city='青島' #需要查詢公交信息的城市
    all_buslines=pd.DataFrame()     
    with open("公交線路.txt", "r", encoding="utf-8") as f:
        bus_name = f.readlines()
    bus_name = bus_name[0].split(",") 
    for i in bus_name:  
        all_buslines=pd.concat([all_buslines,Bus_inf(city,i)]) 
    
    print("Bus_info函數遍歷{}前{}路公交,有效公交線路數爲:{}個的情況下:".format(city,for_num,bus_num))
    all_buslines.to_csv("{}前{}路公交(有效線路數:{})基本信息.csv".format(city,for_num,bus_num),index=False,encoding='utf-8-sig')

結果
青島市區所有線路
在這裏插入圖片描述

3 繪製地鐵線路圖

爲什麼前面繪製前面的公交圖不採用多種顏色?因爲線路很多的情況下,設置多個顏色效果也不是好(不好看)。但對於地鐵圖來說就挺理想的了。

這個方法和上面循環法類似,但記得要打開獲取的結果,人工篩查一下數據。

其實這個模塊我可以認真寫寫,專門再寫篇博客的…emmmmmm…哪那麼多時間呀(;´д`)ゞ

直接可執行代碼

import requests
import json
import pandas as pd
import re
#或許公交信息:線路名、始發站、終點站、行車區間(座標)、路程、行車區間直線距離
def Bus_inf(city,line):
    global bus_num  #全局變量,用於計算公交數目
    try:
        #獲取數據
        url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(city,line)
        r = requests.get(url).text
        rt = json.loads(r)
        #讀取當前公交線路主要信息
        dt = {}
        dt['line_name'] = rt['buslines'][0]['name']
        dt['polyname'] = rt['buslines'][0]['polyline'] 
        bus_num+=1 #有效公交數+1
     
        b=re.split("[;]",dt['polyname'])
        res=""
        for i in range(len(b)):
            tmp=re.split("[,]",b[i])
            if len(res)==0:
                res=res+"["+tmp[0]+","+tmp[1]+"]"
            else:
                res=res+",["+tmp[0]+","+tmp[1]+"]"
        dt['polyname'] =res
        
        
        return pd.DataFrame(dt,index=[bus_num]) #下標index爲“第幾條公交線”
    except:
        return pd.DataFrame()  #讀取數據失敗,跳過


if __name__=="__main__":
    
    bus_num=0  #設置全局變量數值(通常默認就是0)
    city='福州' #需要查詢公交信息的城市
    for_num=20 #遍歷的線路數[1路,for_num路],通常公交線路數小於1000,具體可參考8684等網站
    all_buslines=pd.DataFrame()     
    for i in range(1,for_num+1):
        all_buslines=pd.concat([all_buslines,Bus_inf(city,'地鐵'+str(i)+'號線')])  #不加這個'路'可能優先獲取地鐵
    
    print("Bus_info函數遍歷{}前{}條地鐵,有效地鐵線路數爲:{}個的情況下:".format(city,for_num,bus_num))

    all_buslines.to_csv("{}前{}條地鐵(有效線路數:{})基本信息.csv".format(city,for_num,bus_num),index=False,encoding='utf-8-sig')

青島
注意:這裏有的線路獲取的數據不完整(如青島地鐵11號線),而且很多線路只是規劃線路(目前未開通),故圖片僅供參看!
在這裏插入圖片描述
北京
效果不好:有的線路有遺漏、且沒有那麼多顏色用來繪製
在這裏插入圖片描述

福州
福州地鐵什麼“地鐵接駁車”挺多的。
在這裏插入圖片描述

4 獲取地鐵基本信息

之前博客公交車代碼改一下就好了

import requests
import json
import pandas as pd
import time

#自己寫的用於記錄時間函數
def record_time(flag):
    if flag==0:
        global t0
        t0=time.time()
    else:
        t1=time.time()
        print("用時:%.2fs"%(t1-t0))  
    print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))


#獲取公交基本信息
def get_station(cityname,line):
    global bus_num
    #1、獲取當前公交線路數據
    url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(cityname,line)
    r = requests.get(url).text
    rt = json.loads(r)
    try:
        #2、讀取當前公交線路主要信息
        dt = {}
        dt['line_name'] = rt['buslines'][0]['name'] #公交線路名字
        dt['start_stop'] = rt['buslines'][0]['start_stop'] #始發站
        dt['end_stop'] = rt['buslines'][0]['end_stop'] #終點站
        dt['bounds'] = rt['buslines'][0]['bounds'] #行車區間)
        dt['distance'] = rt['buslines'][0]['distance'] #全程長度
        
        #3、獲取沿途站點站名、對應座標和“第幾站”信息
        station_name = []
        station_coords = []
        station_sequence = []
        for st in rt['buslines'][0]['busstops']:
            station_name.append(st['name'])
            station_coords.append(st['location'])
            station_sequence.append(st['sequence'])
        
        dt['station_name'] = station_name #沿途站點名
        dt['station_coords'] = station_coords #沿途站點座標
        dt['station_sequence'] = station_sequence #沿途站點第幾站
        bus_num+=1 #有效公交數+1

        return pd.DataFrame(dt)  #返回pd.DataFrame()類型
         
    except: #try語句部分出錯進入此部分(一般爲站點名錯誤)
        print('沒有{}公交'.format(line)) #輸出沒有的公交線路名字,可省略
        return pd.DataFrame([])  #返回空的pd.DataFrame類型

#獲取當前城市所有公交基本信息:線路名、行車區間、全程長度、沿途站點及座標
def Bus_info(city,for_num):
    all_bus=pd.DataFrame()
    for i in range(1,for_num+1):  
        all_bus=pd.concat([all_bus,get_station(city,'地鐵'+str(i)+'號線')])  #不加這個'路'可能優先獲取地鐵
    print("Bus_info函數遍歷{}前{}條地鐵,有效地鐵線路數爲:{}個".format(city,for_num,bus_num))
    all_bus.to_csv("{}前{}條地鐵(有效線路數:{})基本信息.csv".format(city,for_num,bus_num),index=False,encoding='utf-8-sig')


if __name__=="__main__":
    record_time(0)#用於記錄開始時間
    
    bus_num=0  #全局變量,計算有效遍歷的公交數
    city='青島' #需要查詢公交信息的城市
    for_num=4 
    Bus_info(city,for_num)

    record_time(1)#用於記錄結束時間並輸出用時


在這裏插入圖片描述
同理,可以繪製站點散點圖
在這裏插入圖片描述

5 通過geopandas包繪製路線圖

這個方法需要安裝 geopandas包 descartes包

(突然感覺,這篇博客博客完全可以拆分爲5篇博客,這個系列完全可以拆分至少20篇,有點寫累了)

考慮到這個方法有些內容我還不理解,就不放代碼了

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章