上一篇文章我们实现了对区市级shp文件的自动下载和转换,现在我们想要进一步标注出每一个地级市或区的行政中心来作为整个地区的中心,效果如下:
可以看到,我们在上一次自动下载的shp底图中标注了上海市各区的人民政府驻地,用人民政府所在地作为区或市的中心有很多益处:
接下来看如何使用Python完成这一需求,首先根据网络爬虫的思想,从高德开放平台提供的API来查询经纬度坐标,使用高德提供的API需要注册自己账号并申请KEY。需要注意的是,经纬度每日查询是有限额的(3万次/每日),对于日常开发来讲足够使用了。但并不建议你同时注册和使用高德/百度开放平台,因为它们所使用的坐标系不同,经纬度无法通用。查询功能的代码如下:
import requests
import re
from bs4 import BeautifulSoup
headers = {
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
}
l1_name = []
def get_location(location):
gaode_api_url = "https://restapi.amap.com/v3/geocode/geo?address=" + str(location) + "&output=XML&key=5ffb29f6dfb07ce65ff4fd7424798a85"
response = requests.get(gaode_api_url, headers=headers)
Soup = BeautifulSoup(response.content, 'lxml')
l1 = Soup.find('location')
if Soup.location == None:
print("查询点:{0},坐标为:{1}".format(str(location), 0))
else:
print("查询点:{0},坐标为:{1}".format(str(location), l1.text))
if Soup.location == None:
l1_name.append([str(location), 0])
else:
l1_name.append([str(location), l1.text])
#------测试----------
#loc = "乌鲁木齐市人民政府"
#get_location(loc)
#------测试----------
假如我们以乌鲁木齐市人民政府为测试案例,运行上述代码后有:
查询点:乌鲁木齐市人民政府,坐标为:87.616842,43.825390
可以看到乌鲁木齐市人民政府的坐标被成功返回了,接下来我们反查经纬度坐标来查看查询结果是否正确:
从坐标反查的结果来看与我们的预期相符且没有误差。说明代码可用,接下来我们可以批量查询我国所有县级市、直辖市的人民政府所在地,代码如下:
import pandas as pd
path = 'D:/Desktop/location.xlsx'
location_data = pd.DataFrame(pd.read_excel(path))
location_name = location_data['location']
通过导入所有市政府名称组成的excel文件,形成一个list列表,对列表内的每一名称遍历使用最初定义的查询函数:
import time
n = 1
print('----------------开始查询---------------')
for i in range(len(location_name)):
print('{0}:'.format(n))
get_location(location_name[i])
n = n + 1
time.sleep(0)
print('----------------查询结束---------------')
加入time库和time.sleep()函数是为了在大规模查询时增加查询间隔,防止由于查询过快过多而被禁用。运行结果如下:
----------------开始查询---------------
1:
查询点:淮北市人民政府,坐标为:116.798331,33.956253
2:
查询点:铜陵市人民政府,坐标为:117.811195,30.945191
3:
查询点:池州市人民政府,坐标为:117.491446,30.664992
4:
查询点:阜阳市人民政府,坐标为:115.814305,32.890235
5:
查询点:黄山市人民政府,坐标为:118.337370,29.714629
6:
查询点:马鞍山市人民政府,坐标为:118.506865,31.668825
7:
查询点:亳州市人民政府,坐标为:115.778617,33.845007
8:
查询点:安庆市人民政府,坐标为:117.056170,30.524241
9:
查询点:芜湖市人民政府,坐标为:118.442460,31.354350
10:
查询点:宣城市人民政府,坐标为:118.759012,30.939247
11:
查询点:滁州市人民政府,坐标为:118.333417,32.255903
12:
查询点:六安市人民政府,坐标为:116.519827,31.735896
13:
查询点:淮南市人民政府,坐标为:117.018592,32.585358
14:
查询点:蚌埠市人民政府,坐标为:117.389721,32.916288
15:
查询点:合肥市人民政府,坐标为:117.227308,31.820570
16:
查询点:宿州市人民政府,坐标为:116.964203,33.647641
17:
查询点:風順堂區人民政府,坐标为:0
18:
查询点:望德堂區人民政府,坐标为:0
19:
查询点:花地瑪堂區人民政府,坐标为:0
20:
查询点:聖方濟各堂區人民政府,坐标为:0
21:
查询点:路氹填海區人民政府,坐标为:0
22:
查询点:嘉模堂區人民政府,坐标为:0
23:
查询点:大堂區人民政府,坐标为:0
24:
查询点:花王堂區人民政府,坐标为:0
25:
查询点:门头沟区人民政府,坐标为:116.101472,39.940239
26:
查询点:延庆区人民政府,坐标为:115.973607,40.457739
27:
查询点:顺义区人民政府,坐标为:116.655315,40.129810
28:
查询点:密云区人民政府,坐标为:116.843317,40.376999
29:
查询点:怀柔区人民政府,坐标为:116.636983,40.317422
30:
查询点:朝阳区人民政府,坐标为:125.288095,43.833909
31:
查询点:平谷区人民政府,坐标为:117.108060,40.139731
32:
查询点:通州区人民政府,坐标为:121.073720,32.065936
33:
查询点:大兴区人民政府,坐标为:116.341483,39.726917
34:
查询点:西城区人民政府,坐标为:116.365511,39.912590
35:
查询点:昌平区人民政府,坐标为:116.232442,40.218006
36:
查询点:东城区人民政府,坐标为:116.416154,39.928119
37:
查询点:石景山区人民政府,坐标为:116.222992,39.906287
38:
查询点:房山区人民政府,坐标为:116.143486,39.748823
39:
查询点:海淀区人民政府,坐标为:116.298331,39.959956
40:
查询点:丰台区人民政府,坐标为:116.286710,39.858707
41:
查询点:万州区人民政府,坐标为:108.408661,30.807667
42:
查询点:涪陵区人民政府,坐标为:107.392814,29.701423
43:
查询点:渝中区人民政府,坐标为:106.568896,29.552736
44:
查询点:大渡口区人民政府,坐标为:106.482332,29.484506
45:
查询点:江北区人民政府,坐标为:106.574394,29.606252
46:
查询点:沙坪坝区人民政府,坐标为:106.456859,29.540862
47:
查询点:九龙坡区人民政府,坐标为:106.510574,29.502328
48:
查询点:南岸区人民政府,坐标为:106.644447,29.501260
49:
查询点:北碚区人民政府,坐标为:106.395612,29.805107
50:
查询点:綦江区人民政府,坐标为:106.655598,29.021228
51:
查询点:大足区人民政府,坐标为:105.721733,29.707032
52:
查询点:渝北区人民政府,坐标为:106.630713,29.721928
................................................
查询点:金华市人民政府,坐标为:119.647229,29.079208
475:
查询点:绍兴市人民政府,坐标为:120.580465,30.030177
476:
查询点:衢州市人民政府,坐标为:118.854866,28.969112
477:
查询点:杭州市人民政府,坐标为:120.209947,30.245853
----------------查询结束---------------
可以看到所有城市的人民政府坐标都被查询到了,但仅仅是查询仍不够,我们需要保存这段经纬度信息至Excel以作他用:
result = open('D:/Desktop/data.xls', 'w', encoding='gbk')
result.write('name\tlong\n')
for m in range(len(l1_name)):
for n in range(len(l1_name[m])):
result.write(str(l1_name[m][n]))
result.write('\t')
result.write('\n')
result.close()
通过一个简单的双for循环我们将列表的内容写入到了桌面上的data.xls:
接下来就可以在ArcGIS中显示这些经纬度坐标了:
以上就完成了我们最终需求。
即便是人民政府,也存在着重名的情况,作者在校对坐标点的合理性时就发现,上海市下辖了普陀区,而舟山市也下辖了普陀区,而上述代码默认查询了舟山市的普陀区,那么问题就是如何在没有先验知识的情况下对代码进行改进,从而对重名的地区加以区分或者警示。另一方面,双重for循环在大样本集下的效率是极地的,还需要考虑如何进一步提高代码的效率。