想知道所在的城市有多少条道路?我用Python发现北京一共有1.5万条道路!

开发 后端
今天我们开启一个系列吧,关于城市道路的,本篇主要演示获取城市道路数据,接下来我们会在此基础上拓展1-2篇好玩的案例,敬请期待!

[[410624]]

本文转载自微信公众号「可以叫我才哥」,作者才哥。转载本文请联系可以叫我才哥公众号。

大家好,我是才哥。

最近被催更了,害~

今天我们开启一个系列吧,关于城市道路的,本篇主要演示获取城市道路数据,接下来我们会在此基础上拓展1-2篇好玩的案例,敬请期待!

好了,我们开始今天的案例介绍。

1. 需求分析

我们以北京为例,希望获取该城市全部道路名称信息,主要字段有道路id、道路名称及所在区,基于高德地图的api接口。

我们找到高德api文档:https://lbs.amap.com/api/webservice/guide/api/search#t8

在搜索POI部分发现了查询城市道路名称的关键字搜索接口如下,但是该接口最多只能返回1000个数据。很明显北京市不止1000条道路,那么如何获取全部道路呢?

关键字搜索

终于,我们发现多边形搜索的接口,它可以对指定的矩形区域内的道路进行搜索,这样我们就脑洞一个想法将北京市按照经纬度分割为若干小区域,如何搜索各个区域内的道路数据后汇总就可以了,为了尽可能不要有遗漏,我们可以将区域颗粒度划分的小一些。

多边形搜索

那么,新的问题也来了:如何进行经纬度区域划分呢?我们又找到了行政区域查询接口文档:https://lbs.amap.com/api/webservice/guide/api/district

该接口通过行政区名称关键字就可以返回该行政区域的边界经纬度,如何我们只需要取经纬度各自的最大最小值就可以得到北京市所在的矩形区域,接着对这个矩形区域进行细化即可。

行政区域查询

思路有了,我们就开始干活吧!

2. 获取行政区域边界数据

直接按照开发者文档的案例演示编写代码如下:

  1. import requests 
  2. import pandas as pd 
  3. import os 
  4.  
  5. url = 'https://restapi.amap.com/v3/config/district?' 
  6. key = '你的key' # 自己在高德开放平台注册一个即可 
  7. keywords = '北京' # 可以换成你所在的城市 
  8. params = { 
  9.     'key':key
  10.     'keywords':keywords, 
  11.     'subdistrict':0, 
  12.     'extensions':'all',         
  13.     } 
  14.  
  15. r = requests.get(url,params=params) 
  16. data = r.json() 
  17. polyline = data['districts'][0]['polyline'
  18. polyline_list = polyline.split(';'
  19. df = pd.DataFrame(polyline_list,columns=['经纬度']) 
  20. df[['经度','纬度']] = df['经纬度'].str.split(',',n=1,expand=True).astype(float
  21.  
  22. # 获取区域边界经纬度 
  23. latitude_max = df['经度'].max() 
  24. latitude_min =  df['经度'].min() 
  25. longitude_max =  df['纬度'].max() 
  26. longitude_min =  df['纬度'].min() 

最后,矩形区域的四个点的经纬度如下:

  1. 左上角:115.423411,41.060816 
  2.  
  3. 右上角:117.514625,41.060816 
  4.  
  5. 左下角:115.423411,39.442758 
  6.  
  7. 右下角:117.514625,39.442758 

矩形区域

上图中我们可以看到矩形区域很多部分不属于北京,所以在后续的道具数据采集的时候需要进行判断道具归属省份是否为北京。

3. 将行政区域分块

既然我们得到了北京所属矩形区域的边界点经纬度,那么直接这个矩形区域进行网格化就行了,处理过程比较简单,直接看代码:

  1. # 绘制网格,这里按照20*20共400个网格 
  2. def get_polygons(latitude_num,longitude_num): 
  3. #    latitude_num = 20 
  4. #    longitude_num = 20 
  5.     latitude_step = (latitude_max - latitude_min)/latitude_num 
  6.     longitude_step = (longitude_max - longitude_min)/longitude_num 
  7.     polygons = [] 
  8.     for i in range(latitude_num): 
  9.         latitude_leftup = latitude_min + latitude_step * i 
  10.         latitude_rightdown = latitude_min + latitude_step * (i+1) 
  11.         for j in range(longitude_num): 
  12.             longitude_leftup = longitude_max - longitude_step * j 
  13.             longitude_rightdown = longitude_max - longitude_step * (j+1)         
  14.             polygon = f'{latitude_leftup},{longitude_leftup}|{latitude_rightdown},{longitude_rightdown}' 
  15.             polygons.append(polygon)      
  16.      
  17.     return polygons 

我们得到了用于区域搜索经纬度坐标对如下:

  1. # polygons  
  2. ['115.423411,41.060816|115.5279717,40.979913100000005'
  3.  '115.423411,40.979913100000005|115.5279717,40.8990102'
  4.  '115.423411,40.8990102|115.5279717,40.8181073'
  5.  '115.423411,40.8181073|115.5279717,40.7372044'
  6. ... 

网格化

4. 获取道路数据

到这一步,我们只需要遍历全部的坐标对polygons,然后搜索该区域内满足归属省份为北京市的全部道路即可。

  1. # 获取指定区域指定page的道路数据并存到本地 
  2. def get_road(polygon,page): 
  3.     url = 'https://restapi.amap.com/v3/place/polygon?' 
  4.     params = { 
  5.         'key':key
  6.         'polygon':polygon, 
  7.         'keywords':'道路名'
  8.         'types':190301, 
  9.         'offset':20, 
  10.         'page':page, 
  11.         'extensions':'all',         
  12.         }   
  13.     r = requests.get(url,params=params)     
  14.     data = r.json()       
  15.     pois = data['pois'
  16.     file_name = '北京道路名称数据.csv' 
  17.     for poi in pois: 
  18.         if poi['pname'] =='北京市'
  19.             df = pd.DataFrame({ 
  20.                 'road_id' : poi['id'], 
  21.                 'road_name' : poi['name'], 
  22.                 'road_adname' : poi['adname'
  23.             },index=[0]) 
  24.             if os.path.exists(file_name): 
  25.                 df.to_csv(file_name, mode='a', header=False
  26.                   index=None, encoding='utf_8_sig'
  27.             else
  28.                 df.to_csv(file_name, index=None, encoding='utf_8_sig'
  29.  
  30.     return pois  
  31. # 这里分为20*20共400个区域 
  32. polygons = get_polygons(20,20)    
  33. for i,polygon in enumerate(polygons): 
  34.     page = 1 
  35.     while True
  36.         pois = get_road(polygon, page) 
  37.         if pois == []: 
  38.             break 
  39.         page += 1 
  40.     print(f'\r正在爬取第{i+1}/400个区域的道路数据',end=''

最终,我们得到了北京一共有14994条道路,其中各区道路数分别如下:

道路数
顺义区 2164
大兴区 1826
通州区 1310
朝阳区 1264
海淀区 1088
房山区 912
密云区 907
西城区 896
东城区 818
昌平区 801
平谷区 770
丰台区 673
延庆区 553
门头沟区 378
怀柔区 372
石景山区 262
总计 14994

 

责任编辑:武晓燕 来源: 可以叫我才哥
相关推荐

2023-04-13 08:00:59

路由协议动态路由

2010-09-06 09:21:01

私有云

2010-09-02 15:16:06

私有云

2020-08-04 08:48:34

数据弹屏技术

2021-12-06 08:03:53

IP地址程序

2018-04-17 09:28:08

陈奕迅评论秘密

2017-08-21 10:05:57

Python影评 爬虫

2014-01-21 17:36:58

2019-01-30 12:59:25

数据科学数据管理职业

2022-07-11 10:04:37

软件开发编码

2024-06-03 08:15:00

2021-04-30 15:30:54

大数据互联网数据分析

2023-09-13 13:22:14

2013-05-16 10:15:11

信息泄密彭博Bloomberg

2023-04-17 14:08:31

微信数据训练信息

2021-10-26 22:25:24

Windows 11Windows微软

2022-04-12 16:39:55

数据泄露网络攻击

2018-08-27 07:01:33

数据分析数据可视化租房

2012-12-12 09:52:18

程序员

2020-05-16 13:25:03

分析网购数据
点赞
收藏

51CTO技术栈公众号