【python】绘制地图:使用folium制作地图,可解决多数问题

Python使用folium制作地图并生成png图片

第一章 folium的方法和类的介绍(思维导图)
第二章 使用folium制作地图
第三章 folium实用功能进阶
第三章 使用Html2Image生成png图片
第四章 使用reportlab制作pdf报告



前言

提示:这里可以添加本文要记录的大概内容:
我讲一下我这个需求的来源,做的项目是一个地理空间查询和使用的系统,通过在前端调用高德地图api创建了一个查询区域,获取区域内的地理数据(数据库)。具体的需求就是,将查询区域和地理数据制作成一个覆盖率分析报告,报告中的其他内容都已完成,但报告中需要展示高德地图、查询区域、地理数据的完整图片这个功能卡了2个星期,主要原因是我对地理空间数据不熟悉,很多python相关库也不清楚,在构建图形的过程中走了很多弯路。
现在将整个实现过程梳理完成,希望对各位同道有帮助,跟其他文章和官网不同,本博客是以使用的优先级来讲解这个库。<我们靠所得来谋生,但靠给予来创造生活>
在这里插入图片描述


一、​folium是什么?

​folium是js上著名的地理信息可视化库leafet.js为Python提供的接口,通过它,我们可以通过在Python端编写代码操纵数据,来调用leaflet的相关功能,基于内建的osm或自行获取的osm资源和地图原件进行地理信息内容的可视化,以及制作优美的可交互地图,是通过不断添加图层元素来定义一个Map对象,最后以几种方式将Map对象展现出来。

而在Map对象的生成形式上,可以在定义所有的图层内容之后,将其保存为html文件在浏览器中独立显示,也可以基于jupyter notebook在一个ipynb文件嵌入对应的交互地图。

二、使用步骤

1.安装和导入库

官网链接:https://pypi.org/project/folium/

pip install folium

代码如下(示例):

import folium

2.创建地图或图层

如果对地图没有要求,可以直接创建地图,如果对地图有要求,可以通过设置参数或加载图层来实现。

def map2png(map_data,out_file='pdf.png'):
	# 1.直接构造,默认底图
	mo = folium.Map(location=[45.5236, -122.6750])
	# 2.替换成高德底图
    mo = folium.Map(location=location,  # [39.917834, 116.397036]
                    zoom_start=zoom_start,  # 13
                    tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}')
    # 3.添加图层
    mo = folium.Map(location=location,  # [39.917834, 116.397036]
                    zoom_start=zoom_start,  # 13
                    tiles=None)
    folium.TileLayer(
        tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
        attr="&copy; <a href=http://ditu.amap.com/>高德地图</a>",
        min_zoom=0,
        max_zoom=19,
        control=True,
        show=True).add_to(mo)
   	mo.save('test.html')

3.添加覆盖物

覆盖物就是地理空间常用的数据,包括点线面等,数据有多种来源,可以是数据库读出来、文件读出来的、或者网络传输geojson等。

import folium

def map2png(map_data,out_file='pdf.png'):
	# 1.直接构造,默认底图
	mo = folium.Map(location=[45.5236, -122.6750])
    # 添加一个点
	folium.Marker(
		location=[45.3311, -121.7113],
		popup="Timberline Lodge",
		icon=folium.Icon(color="green"),).add_to(m)
 #  添加一个线形   
	folium.PolyLine(
		locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]],
		color='green', weight=2, opacity=1).add_to(m)
 # 添加一个面
    folium.Polygon(
	    locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]], 
		color='green', weight=2, 
		fill=True,fill_color = 'red').add_to(mo)
	mo.save('test.html')

4.地图参数

我为什要在画完地图和覆盖物之后才说参数?这是有理由的。
folium的Map参数有很多,常用的比如location和zoom_start。很多时候都是创建地图的时候就带着(这不是很正确)。创建地图的的时候,我们很多时候是不知道地图的中心点和缩放级别的,这样就很麻烦,还要肉眼去看,一次次的调整。
Map有一个方法fit_bounds,可以实现根据图形内容自动调整中心点和缩放级别,fit_bounds方法的参数跟点线面的参数时一样的。使用fit_bounds的时候尽量不要设置location参数,使用[0,0]值。

import folium

def map2png(map_data,out_file='pdf.png'):
	# 1.直接构造,默认底图
	mo = folium.Map(location=[0, 0])
    # 添加一个点
	folium.Marker(
		location=[45.3311, -121.7113],
		popup="Timberline Lodge",
		icon=folium.Icon(color="green"),).add_to(m)
 	#  添加一个线形   
	folium.PolyLine(
		locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]],
		color='green', weight=2, opacity=1).add_to(m)
 	# 添加一个面
    folium.Polygon(
	    locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]], 
		color='green', weight=2, 
		fill=True,fill_color = 'red').add_to(mo)
    mo.fit_bounds([[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]])  # 根据范围缩放地图
	mo.save('test.html')

其他参数和方法我这里列举出来,供同学们参考。

folium.Map(
    location=None,  # 中心点
    width='100%',  # 基于浏览器左上角的屏幕宽的比例
    height='100%',  # 基于浏览器左上角的屏幕高德比例
    left='0%',  # 基于浏览器左侧占比
    top='0%',  # 基于浏览器顶部占比
    position='relative',  # 地图位置
    tiles='OpenStreetMap',  # 多个str参数(map自己的),也可以是瓦片
    attr=None,  # 设置瓦片时,需要传值
    min_zoom=0,  # 最小缩放级别
    max_zoom=18,  # 最大缩放级别 30
    zoom_start=10, # 开始缩放级别
    min_lat=-90,
    max_lat=90,
    min_lon=-180,
    max_lon=180,
    max_bounds=False,
    crs='EPSG3857', # 定义投影地理点的坐标参考系
    control_scale=False,
    prefer_canvas=False,
    no_touch=False,  # 是否禁止手动操作,默认为False
    disable_3d=False, # 加速CSS 3D加载
    png_enabled=False, # map是否可以生成图片,设置为true后可以使用map._to_png(),不建议使用,需要服务器安装浏览器包而且他的方法过时了。
    zoom_control=True, # 地图上显示缩放控件,默认为True
    **kwargs}
)

5.生成html

map.save()函数会生成一个html网页,默认保存在py的同一级目录下,因为我们项目的需求,保存成html在读出来生成png,这个读写过程有点浪费,所以我这里获取到html的页面内容,不调用save方法,直接将html的内容传给html2image库生成图片。

import folium

def map2png(map_data,out_file='pdf.png'):
	# 1.直接构造,默认底图
	mo = folium.Map(location=[0, 0])
    # 添加一个点
	folium.Marker(
		location=[45.3311, -121.7113],
		popup="Timberline Lodge",
		icon=folium.Icon(color="green"),).add_to(m)
  	#  添加一个线形   
	folium.PolyLine(
		locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]],
		color='green', weight=2, opacity=1).add_to(m)
 	# 添加一个面
    folium.Polygon(
	    locations=[[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]], 
		color='green', weight=2, 
		fill=True,fill_color = 'red').add_to(mo)
    mo.fit_bounds([[38.68,115.67],
					[38.85,115.48],
					[38.65,115.37],
					[38.68,115.67]])  # 根据范围缩放地图
    root = mo.get_root()
    html = root.render()  # 这个拿到的就是一个html的内容
    # mo.save('text.html')

6.其他

本博客开始就介绍了,folium是js上著名的地理信息可视化库leafet.js为Python提供的接口,我研究了相关底层发现主要是些js+css。因为众所周知的原因,国内访问国外的接口会存在限制,这些借口在未来可能成为程序的漏洞(有些无法加载,这里不考虑图层瓦片,图层瓦片至少可以用国内图层的)。# noqa标记的就是告诉程序可能出错的,忽略警告。

_default_js = [
    ('leaflet',
     'https://cdn.jsdelivr.net/npm/leaflet@1.6.0/dist/leaflet.js'),
    ('jquery',
     'https://code.jquery.com/jquery-1.12.4.min.js'),
    ('bootstrap',
     'https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js'),
    ('awesome_markers',
     'https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.js'),  # noqa
    ]

_default_css = [
    ('leaflet_css',
     'https://cdn.jsdelivr.net/npm/leaflet@1.6.0/dist/leaflet.css'),
    ('bootstrap_css',
     'https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css'),
    ('bootstrap_theme_css',
     'https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css'),  # noqa
    ('awesome_markers_font_css',
     'https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css'),  # noqa
    ('awesome_markers_css',
     'https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css'),  # noqa
    ('awesome_rotate_css',
     'https://cdn.jsdelivr.net/gh/python-visualization/folium/folium/templates/leaflet.awesome.rotate.min.css'),  # noqa
    ]

在这里插入图片描述
针对可能出现的加载问题,建议将这些库文件放在本地,替换html中的链接。
此处可参考https://blog.csdn.net/weixin_42148809/article/details/120969710

总结

提示:这里对文章进行总结:

本博客是以使用的优先级来讲解这个库。<我们靠所得来谋生,但靠给予来创造生活>

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我辈李想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值