【大数据】城市公交网络分析与可视化(四):绘制城市公交(地铁)线路图

内容介绍

梗概:爬取公交路径座标,处理成为符合高德地图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篇,有点写累了)

考虑到这个方法有些内容我还不理解,就不放代码了

在这里插入图片描述

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