寻找最短的换乘车站

今天是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()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342