关于Folium库的基础使用,可以查看官方文档,或者很多知友、博客的分享,这里不再详述。本文主要以一个简单的示例讲解如何更换底图,以及进行坐标变换。
1.坐标变换
地球上同一个地理位置的经纬度,在不同的坐标系中,会有少量偏移,国内目前常见的坐标系主要分为三种:
地球坐标系——WGS84:常见于GPS设备,Google地图等国际标准的坐标体系。
火星坐标系——GCJ-02:中国国内使用的被强制加密后的坐标体系,高德坐标就属于该种坐标体系。
百度坐标系——BD-09:百度地图所使用的坐标体系,是在火星坐标系的基础上又进行了一次加密处理。坐标偏移
在上图中,蓝色线条位置应该是准确的位置,但是由于坐标系不统一,导致定位标志所示的位置发生了偏移。坐标偏移修正(坐标变换)
转换方法一:关于坐标转换,可以参见python库 :coord-convertpypi.org
官方给出的API调用方法如下:
from coord_convert.transform import wgs2gcj, wgs2bd, gcj2wgs, gcj2bd, bd2wgs, bd2gcj
lon, lat = 120, 40
gcj_lon, gcj_lat = wgs2gcj(lon, lat)
bd_lon, bd_lat = wgs2bd(lon, lat)
print(gcj_lon, gcj_lat) # the result should be: 120.00567568355486 40.0013047896019
转换方法二:网上可以搜到很多转换代码,可根据自己的情况进行适当调整,本文采用的为;python3实现GPS经纬度坐标(WGS84)国测局火星坐标(GCJ02)百度坐标(BD09)相互转换_Python_开开的博客-CSDN博客blog.csdn.net
2.底图更换
folium库默认是基于OpenStreetMap的,但是可能由于信息更新不及时,有时候OpenStreetMap的数据是不准确的。这就需要更换底图,如高德地图,或者Google地图等。
m = folium.Map(
location=[38.96, 117.78],
zoom_start=12,
# tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}', # 高德街道图
# tiles='http://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', # 高德卫星图
tiles='https://mt.google.com/vt/lyrs=s&x={x}&y={y}&z={z}', # google 卫星图
# tiles='https://mt.google.com/vt/lyrs=h&x={x}&y={y}&z={z}', # google 地图
attr='default'
)
如果需要更换底图,仅需调整tiles参数URL即可。
这里给出google地图的一些参数设置:
''' lyrs可以设置为不同的参数,分别代表不同形式的地图,可以尝试
lyrs=
h = roads only
m = standard roadmap
p = terrain
r = somehow altered roadmap
s = satellite only
t = terrain only
y = hybrid
'''
卫星图效果如下:
高德街道图:
卫星图效果如果条件允许,建议选择google地图,高德和百度在放大到一定程度时,会没有卫星图显示。
关于高德地图瓦片URL的解析可以参见:不睡觉的怪叔叔:OpenLayers教程十二:多源数据加载之使用XYZ的方式加载瓦片地图zhuanlan.zhihu.comhttps://www.jianshu.com/p/e34f85029fd7www.jianshu.com
在Stack Overflow上有如下问答,可做Mapbox的参考:How do I use mapbox tiles with folium?gis.stackexchange.com
示例代码(高德):
import numpy as np
import folium
from folium import plugins
def PlotLineOnMap():
# 给出的坐标系为GCJ-02,如果需要测试google地图,需要进行坐标转换
Lat = [40.8352, 40.8342, 40.8335, 40.8323, 40.8311, 40.8308, 40.8304, 40.8315, 40.8325, 40.8332, 40.8339, 40.8345,
40.8352]
Lon = [114.8886, 114.8883, 114.8881, 114.8877, 114.8873, 114.8888, 114.8902, 114.8909, 114.8916, 114.8919, 114.8922,
114.8917, 114.8886]
tri = np.array(list(zip(Lat, Lon)))
san_map = folium.Map(
location=[40.8329, 114.8898],
zoom_start=16,
tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}', # 高德街道图
# tiles='http://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', # 高德卫星图
attr='default')
folium.PolyLine(tri,color='#3388ff').add_to(san_map)
marker_cluster = plugins.MarkerCluster().add_to(san_map)
for lat,lon in zip(Lat,Lon):
folium.Marker([lat,lon], color='red').add_to(marker_cluster)
san_map.save('test.html')
def main():
PlotLineOnMap()
if __name__ == '__main__':
main()