写在前面
很长一段时间内,我都在研究在线地图的开发者文档,百度地图和高德地图的开发者中心提供了丰富的在线地图服务,虽然有一定的权限限制,但不得不说,还是给我的科研工作提供了特别方便的工具,在博客前面我先放上这两个在线地图开放平台的web API的地址链接:
- 百度地图开放平台
- 高德地图开放平台
- Python3.7
- Spyder编译器(也可以用pycharm,不过建议用Spyder,因为编译过程中产生的变量太多,基本上都是json数据,我都是一边看一边写,这里Spyder优势明显)
- chrome浏览器
folium介绍及相关设置
folium基础功能
folium参数设置
先看两行代码:
import folium line_road = folium.Map(location=[31.,120.],zoom_start=15, tiles = 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}', attr = 'default')
- location参数,设置展示地图的中心坐标点,就是说,比如你想看无锡市,可以设置成无锡市市中心的经纬度坐标
- zoom_start是地图缩放等级,最高差不多可以到19还是20,如果想看大场景,就设小一点,想看局部地图就设大一点
- tiles这个参数很重要,设置的是你的地图格式,默认的是OpenStreetMap,我这里把它改成了’http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}’,表示我用的是高德地图作为底图。为啥要改呢,因为每个不同的地图公司,用的坐标系不一样,高德地图和google地图、soso地图、aliyun地图、mapabc地图所用坐标相同,都是国测局(GCJ02)坐标,和百度地图用的坐标系不一样,如果直接拿百度坐标系下的经纬度画在高德地图上,那就会整体偏移,使用之前必须进行坐标转换
- 其他用默认参数
获取道路参数
高德地图获取道路经纬度的API介绍
先看接口:
http://restapi.amap.com/v3/road/roadname?parameters
这个接口和高德地图其他功能的接口一样,后面的parameters是需要写的参数,每个参数之间用&隔开,其中keywords是道路名,这个参数必填,当然还有key也是必填的。现在来看看这一段的具体怎么写,比如我想获取的是无锡市钱荣路的经纬度:
# -*- coding: utf-8 -*- """ Created on Mon Mar 30 16:54:32 2020 @author: HP """ import json import pandas as pd from urllib.request import urlopen, quote import folium import numpy as np road = quote('钱荣路') key = YourKey # 换成你自己申请的key url = 'http://restapi.amap.com/v3/road/roadname?city=0510&key=%s&keywords=%s' % (key, road) req = urlopen(url) res = req.read().decode() temp = json.loads(res) roads = temp['roads'] pos = [] # 由于道路可能分段,比如钱荣路会分成钱荣路普通段和钱荣路高架,这都属于钱荣路的路段,因此必须要都取出来 for p in range(len(roads)): pos.extend(roads[p]['polylines']) pos_cal = [] line_qrroad = folium.Map(location=[31.,120.],zoom_start=15, tiles = 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}', attr = 'default') for i in range(len(pos)): m = pos[i].split(';') lat_lon = [] for j in range(len(m)): n = m[j].split(',') n = list(map(float, n)) n[0],n[1] = n[1],n[0] lat_lon.append(n) pos_cal.append(n) folium.PolyLine(lat_lon,weight = 5, color = 'red',opacity = 0.8).add_to(line_qrroad) line_qrroad.save('lineqrroad.html') map_qrroad = folium.Map(location=[31.,120.],zoom_start=15, tiles = 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}', attr = 'default') for point in range(len(pos_cal)): folium.CircleMarker(location=[pos_cal[point][0],pos_cal[point][1]], radius=4,popup='popup', color='red',fill=True, fill_color='red').add_to(map_qrroad) map_qrroad.save('render.html')
现在这段程序,已经没法解析出经纬度了,运行的话,会报如下错误:
runfile('D:/python/folium/qianrongroad.py', wdir='D:/python/folium') Traceback (most recent call last): File "D:\python\folium\qianrongroad.py", line 26, in <module> roads = temp['roads'] KeyError: 'roads'
意思就是说,没有‘road’这个key,我试图把请求串输入浏览器,返回的结果如下:
{
"info":"INSUFFICIENT_PRIVILEGES","infocode":"10012","status":"0","sec_code_debug":"d41d8cd98f00b204eecf8427e","key":"ea12ed719e4ed13862dd0c6512","sec_code":"d41d8cd98f00b204eecf8427e"}
# 由于道路可能分段,比如钱荣路会分成钱荣路普通段和钱荣路高架,这都属于钱荣路的路段,因此必须要都取出来 for p in range(len(roads)): pos.extend(roads[p]['polylines'])
上面这个循环,注释已经解释清楚了,一条路可能会被高德分成好几部分,当然这是科学的,比如完整的钱荣路是分成了钱荣路普通路段和高架路段的。也就是说解析出来的roads的长度是2,分别是roads[0]和roads[1],而经纬度数据则在roads[p][‘polylines’]里面。
for i in range(len(pos)): m = pos[i].split(';') lat_lon = [] for j in range(len(m)): n = m[j].split(',') n = list(map(float, n)) n[0],n[1] = n[1],n[0] lat_lon.append(n) pos_cal.append(n)
for point in range(len(pos_cal)): folium.CircleMarker(location=[pos_cal[point][0],pos_cal[point][1]], radius=4,popup='popup', color='red',fill=True, fill_color='red').add_to(map_qrroad)
百度坐标系下的坐标点转换成高德坐标系下的坐标点
import json from urllib.request import urlopen, quote import folium import os def BaiduMap2AMap(data): polylines = [] for i in range(len(data)): poly = [] for j in range(len(data[i])): url = 'https://restapi.amap.com/v3/assistant'\ '/coordinate/convert?locations=%f,%f&coordsys=baidu'\ '&key=YourKey'%(data[i][j][1], data[i][j][0]) req = urlopen(url) res = req.read().decode() temp = json.loads(res) location = temp['locations'].split(',') location = list(map(float,location)) location[0], location[1] = location[1], location[0] poly.append(location) polylines.append(poly) return polylines
结语
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/198984.html原文链接:https://javaforall.net
