美文网首页Python
寻找最短的换乘车站

寻找最短的换乘车站

作者: 凉风有信2020 | 来源:发表于2021-04-11 01:23 被阅读0次

今天是2021.4.11,距离上次写博客已经有半年之久了,遥想半年之前,刚刚结束了在新浪的实习,踏上坎坷的秋招之路。那时的我才发现,自己掌握的知识竟是如此匮乏,不仅深度和广度都远远不够,甚至连基础都掌握不牢,技能更是一穷二白,而这一悲惨的现状竟然延续到了今天。

回顾过去的半年,虽然找到了工作,写完了毕业论文,但在专业技术上仍然可以说是顿足不前,寒假带回去的两本书原封不动的带了回来,电脑却又新购置了一台,属实让人汗颜。

今天破天荒的登上了博客,原因是完成了一个小的功能,虽然代码仍然写得惨不忍睹,但是结果还是不错的,我也有了动力写写2021年的第一篇博客。

起因是和同门聊到租房,我一边抱怨我和女票的单位离的有一点远不知道怎么租房,一边在百度地图上想要在两个单位间找到一个中点,作为租房的候选位置。找来找去发现中点附近的车站到我俩的单位都得换乘,没有一个车站能够让我们不经过换乘就到达各自的单位。就在我百无聊赖的一个个车站乱点时,我发现每个车站都会标明经过该车站的所有公交车。此时我脑中冒出一个想法,如果爬取两人所在公司门口车站中所有的公交车,再将其路线图复现出来,找到经过两人公司门口公交车线路的交点,不就能够找到所有租房的可能了吗。之后再找到最合适的点就不在话下了。

想到这里,我十分激动。说干就。。。晚上再干吧,还得改论文呢,ε=(´ο`*)))唉。

到了晚上,我强忍住LOL一把的冲动,打开了百度地图,观察了一会儿,发现此事可行!原因是可以在源代码里找到路线上每一个点的数据,包含站点名,left到左边界相对位置,和top到上边界的相对位置。


线路上每一个点的相对位置.png

然后我简单尝试了一下,requests.get果然是爬不到源代码的,放弃,那就一个个粘呗。

过了一会儿,我终于粘好了8条线路的数据,写出了我第一个代码

import re

point_list = []
html = """数据"""
data_list = html.split("</div>")
for data in data_list[:-2]:
    title = re.search('title=\"(.*?)\"', data).group(1)
    left = float(re.search('left: (.*?)px;', data).group(1))
    top = 937-float(re.search('top: (.*?)px;', data).group(1))
    if title == "北京市海淀区G109(晋元桥)":
        p1 = (left, top) 
    if title == "北京市海淀区万柳西路":
        p2 = (left, top) 
    if title and title != "我的家" and title != "北京市海淀区G109(晋元桥)" and title != "北京市海淀区万柳西路" :
        point_list.append([left,top,title])
distance = ((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)**0.5
for point in point_list:
    point[0] = (point[0]-p1[0])/distance*100
    point[1] = (point[1]-p1[1])/distance*100
print(point_list)

import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False ## 设置正常显示符号

X = np.array([point[0] for point in point_list])
Y = np.array([point[1] for point in point_list])

plt.figure(figsize=(10,10))
plt.plot(X, Y)
# plt.ylim(ymin = 0, ymax = 937)
# plt.xlim(xmin = 0, xmax = 1365)

for i in range(len(point_list)):
    plt.scatter(point_list[i][0], int(point_list[i][1]), color='b')
    
txt = [point[2] for point in point_list]
plt.rcParams['font.sans-serif']=['SimHei']    
for i in range(len(point_list)):
    plt.annotate(txt[i], xy = (point_list[i][0], point_list[i][1]), xytext = (point_list[i][0]+.1, point_list[i][1]+1))

程序的大概意思就是找到每个点的横纵坐标和名字,然后把它描绘出来。但是由于这个坐标是相对坐标,所以肯定是不准的,你缩小一下地图,这些坐标都会变化。但我们最后要把所线路放到一张图上,比例尺一定要一样,这里我选择在地图上找两个固定的点p1(x1,y1)和p2(x2,y2),p1和p2的距离distance=(x1 - x2)2 + (y1 - y2)2)**0.5。每次读取了坐标信息后的点p(x,y)后,将((x-x1)/distance, (y-y1)/distance)作为该点的真实坐标。因为两固定点之间距离是固定的,除去distance之后就将比例尺统一了。

整出来就是这么一个样子:(其实前面还有好几版,开始写的根本跑不出来。。。)


第一条路线,耶

而原图是这么一个样子:


原图
我giao,大概方向是对的,但是失真很明显,为什么会失真呢,后来才发现是因为画图时自动把Y轴拉长了。。。继续

把所有线路叠加之后的效果:


单人线路图

单人线路图有一个问题,百度地图上的相对坐标都是整数,所以带来了失真,导致本来该在一起的站点在图上错开了。我的做法是找到一个公共点,对比不同线路在这个点上的误差,对没条线路坐标进行更新,简单来说就是差多少补多少。最后虽然还是没有完全重合,但是总归是好些了。

最后就是把两张图重合在一起,再找到相交的站点,这一步同样需要两张图间的同步,找到一个公共站点消除误差,不然误差有点大。得到最后的图:


最后,放大看还是很不错的

再把相交站点和通过的线路加上:


站点和线路

齐活!虽然不知道这个是代码怎么跑起来的,但是:


又不是不能用
附上代码
import re

name1 = 马赛克
name2 = 马赛克

point_list_list1 = []
html_list1 = [
"""
马赛克
""",
]

point_list_list2 = []
html_list2 = [
"""
马赛克
""",
]

for index in range(len(html_list1)):
    html = html_list1[index]
    point_list = []
    data_list = html.split("</div>")
    for data in data_list[:-2]:
        title = re.search('title=\"(.*?)\"', data).group(1)
        left = float(re.search('left: (.*?)px;', data).group(1))
        top = 937-float(re.search('top: (.*?)px;', data).group(1))
        if title == "北京市海淀区G109(晋元桥)":
            p1 = (left, top) 
        if title == "北京市海淀区万柳西路":
            p2 = (left, top) 
        if title and title != "我的家" and title != "北京市海淀区G109(晋元桥)" and title != "北京市海淀区万柳西路" :
            point_list.append([left,top,title,name1[index]])
    distance = ((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)**0.5
    for point in point_list:
        point[0] = (point[0]-p1[0])/distance*100
        point[1] = (point[1]-p1[1])/distance*100
        
    for point in point_list:
        if point[2] == '马赛克':
            cur_loc = (point[0], point[1])
        if point[2] == '马赛克':
            p1_loc = (point[0], point[1])
            
    for point in point_list:
        point[0] = point[0] - (cur_loc[0] - simble_loc[0])
        point[1] = point[1] - (cur_loc[1] - simble_loc[1])
    point_list_list1.append(point_list)
    
for index in range(len(html_list2)):
    html = html_list2[index]
    point_list = []
    data_list = html.split("</div>")
    for data in data_list[:-2]:
        title = re.search('title=\"(.*?)\"', data).group(1)
        left = float(re.search('left: (.*?)px;', data).group(1))
        top = 937-float(re.search('top: (.*?)px;', data).group(1))
        if title == "北京市海淀区G109(晋元桥)":
            p1 = (left, top) 
        if title == "北京市海淀区万柳西路":
            p2 = (left, top) 
        if title and title != "我的家" and title != "北京市海淀区万柳西路" and title != "北京市海淀区G109(晋元桥)" :
            point_list.append([left,top,title,name2[index]])
    distance = ((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)**0.5
    for point in point_list:
        point[0] = (point[0]-p1[0])/distance*100
        point[1] = (point[1]-p1[1])/distance*100
        
    for point in point_list:
        if point[2] == '马赛克':
            cur_loc = (point[0], point[1])
        if point[2] == '马赛克':
            p2_loc = (point[0], point[1])
            
    for point in point_list:
        point[0] = point[0] - (cur_loc[0] - simble_loc[0])
        point[1] = point[1] - (cur_loc[1] - simble_loc[1])
    point_list_list2.append(point_list)
    
for point_list in point_list_list2:
    for point in point_list:
        point[0] = point[0] - (p2_loc[0] - p1_loc[0])
        point[1] = point[1] - (p2_loc[1] - p1_loc[1])

station_line_dic1 = dict()
for point_list in point_list_list1:
    for point in point_list:
        station = point[2]
        line = point[3]
        if station not in station_line_dic1.keys():
            station_line_dic1[station] = []
        station_line_dic1[station].append(line)
        
station_line_dic2 = dict()
for point_list in point_list_list2:
    for point in point_list:
        station = point[2]
        line = point[3]
        if station not in station_line_dic2.keys():
            station_line_dic2[station] = []
        station_line_dic2[station].append(line)
        
import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(100,100))
# plt.ylim(ymin = -200, ymax = 200)
# plt.xlim(xmin = -200, xmax = 200)

already_txt1 = []

for point_list in point_list_list1:
    X = np.array([point[0] for point in point_list])
    Y = np.array([point[1] for point in point_list])
    plt.plot(X, Y , color="orange")
        
    for i in range(len(point_list)):
        plt.scatter(point_list[i][0], int(point_list[i][1]), color='b')

    txt = [point[2] for point in point_list]
    plt.rcParams['font.sans-serif']=['SimHei']    
    for i in range(len(point_list)):
        if txt[i] not in already_txt1:
            plt.annotate(txt[i], xy = (point_list[i][0], point_list[i][1]), xytext = (point_list[i][0]+.1, point_list[i][1]+1))
            already_txt1.append(txt[i])

already_txt2 = []
            
for point_list in point_list_list2:
    X = np.array([point[0] for point in point_list])
    Y = np.array([point[1] for point in point_list])
    plt.plot(X, Y , color="blue")
        
    for i in range(len(point_list)):
        plt.scatter(point_list[i][0], int(point_list[i][1]), color='b')

    txt = [point[2] for point in point_list]
    plt.rcParams['font.sans-serif']=['SimHei']    
    for i in range(len(point_list)):
        if txt[i] not in already_txt2:
            plt.annotate(txt[i], xy = (point_list[i][0], point_list[i][1]), xytext = (point_list[i][0]+.1, point_list[i][1]+1))
            already_txt2.append(txt[i])

for txt1 in already_txt1:
    for txt2 in already_txt2:
        if txt1 == txt2:
            print(txt1)
            print("马赛克:", station_line_dic1[txt1])
            print("马赛克:", station_line_dic2[txt1])
            


plt.show()

相关文章

  • 寻找最短的换乘车站

    今天是2021.4.11,距离上次写博客已经有半年之久了,遥想半年之前,刚刚结束了在新浪的实习,踏上坎坷的秋招之路...

  • 武汉地铁2号线与4号线换乘经验

    1、武昌火车站到汉口火车站换乘推荐换乘站点:中南路站乘4号线中南站下,站台对面乘2号线。2、汉口火车站到武昌火车站...

  • 武汉2号线和4号线换乘经验

    1、武昌火车站到汉口火车站换乘推荐换乘站点:中南路站乘4号线中南站下,站台对面乘2号线。2、汉口火车站到武昌火车站...

  • 广度优先搜索

    一种用来解决最短路径的算法。这个最短不是时间或者距离的最短而是边最少。欢聚话说就是做地铁的时候换乘最少。 图简介 ...

  • 如何坐公交到韶山

    湘潭到韶山可以坐公交到达,在江南步步高傍边车站换乘,到韶山其他线路可以在韶山高铁站或韶山火车站换乘。 那...

  • 胶南利群之行二

    今天清晨六点二十五出发,乘坐公交车308路在青岛市立医院车站,换乘隧道三,穿越隧道,在黄岛市机关办公中心车站,换乘...

  • 英语表达:“换乘站“英语,必收藏!

    换乘站专门用于一个城市轨道交通系统,其表示的是一个或多个铁路车站,可让乘客跨线乘坐列车,无需离开车站购买车票。换乘...

  • 火车换乘请注意车站是否同站

    最近有朋友买票,由于春节客流量大,有些平时的火车临时调了车站,以前在广州东发车的调到广州站,很多人不注意看票...

  • 寻找最短路径

    这方面的经典算法,有Dijkstra算法和Floyd算法。 下面简单说一下基于Dijkstra算法略作小改动的一个...

  • UIcollectionVIew

    放图规则: 寻找最短边数组保存每一列的高度, 已做为寻找最短边 设置公用属性 1 按钮的size 2. 列数 3....

网友评论

    本文标题:寻找最短的换乘车站

    本文链接:https://www.haomeiwen.com/subject/plwokltx.html