folium地图不显示加载不出来空白问题解决
问题描述
想要使用folium新建一张地图,代码如下:
import folium
# define the national map
city_map = folium.Map(location=[39.93, 116.40], zoom_start=10)
# save national map
city_map.save('test_03.html')
但是运行完之后的 test_03.html 文件打开后是空白的,加载不出来
解决过程
首先了解了一下folium是在线加载资源,并且看到test_03.html文件非常小
只有4kb,说明里面的样式资源确实是在线加载
然后了解到folium也提供了离线版本,使用方式如下:
import folium
from offline_folium import offline
# define the national map
city_map = folium.Map(location=[39.93, 116.40], zoom_start=10)
# save national map
city_map.save('test_03.html')
(直接把offline引用即可)
pip install offline_folium
先安装offline_folium
python -m offline_folium
然后执行offline_folium下载资源
然后这一步我报错了
python -m offline_folium
Downloading files to D:\Anaconda3\lib\site-packages\offline_folium\local
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\leaflet.js
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\jquery-3.7.1.min.js
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\bootstrap.bundle.min.js
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\leaflet.awesome-markers.js
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\leaflet.css
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\bootstrap.min.css
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\bootstrap.min.css
Traceback (most recent call last):File "D:\Anaconda3\lib\urllib\request.py", line 1317, in do_openencode_chunked=req.has_header('Transfer-encoding'))File "D:\Anaconda3\lib\http\client.py", line 1229, in requestself._send_request(method, url, body, headers, encode_chunked)File "D:\Anaconda3\lib\http\client.py", line 1275, in _send_requestself.endheaders(body, encode_chunked=encode_chunked)File "D:\Anaconda3\lib\http\client.py", line 1224, in endheadersself._send_output(message_body, encode_chunked=encode_chunked)File "D:\Anaconda3\lib\http\client.py", line 1016, in _send_outputself.send(msg)File "D:\Anaconda3\lib\http\client.py", line 956, in sendself.connect()File "D:\Anaconda3\lib\http\client.py", line 1384, in connectsuper().connect()File "D:\Anaconda3\lib\http\client.py", line 928, in connect(self.host,self.port), self.timeout, self.source_address)File "D:\Anaconda3\lib\socket.py", line 727, in create_connectionraise errFile "D:\Anaconda3\lib\socket.py", line 716, in create_connectionsock.connect(sa)
TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。During handling of the above exception, another exception occurred:Traceback (most recent call last):File "D:\Anaconda3\lib\runpy.py", line 193, in _run_module_as_main"__main__", mod_spec)File "D:\Anaconda3\lib\runpy.py", line 85, in _run_codeexec(code, run_globals)File "D:\Anaconda3\lib\site-packages\offline_folium\__main__.py", line 25, in <module>download_all_files()File "D:\Anaconda3\lib\site-packages\offline_folium\__main__.py", line 13, in download_all_filesdownload_url(js_url)File "D:\Anaconda3\lib\site-packages\offline_folium\__main__.py", line 19, in download_urlcontents = urlopen(url).read().decode("utf8")File "D:\Anaconda3\lib\urllib\request.py", line 222, in urlopenreturn opener.open(url, data, timeout)File "D:\Anaconda3\lib\urllib\request.py", line 525, in openresponse = self._open(req, data)File "D:\Anaconda3\lib\urllib\request.py", line 543, in _open'_open', req)File "D:\Anaconda3\lib\urllib\request.py", line 503, in _call_chainresult = func(*args)File "D:\Anaconda3\lib\urllib\request.py", line 1360, in https_opencontext=self._context, check_hostname=self._check_hostname)File "D:\Anaconda3\lib\urllib\request.py", line 1319, in do_openraise URLError(err)
urllib.error.URLError: <urlopen error [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。>
python -m执行的是offline_folium\ __ main__.py
打开这个文件看看,在python环境的site-packages中
if __name__ == "__main__":print(f"Downloading files to {dest_path}")download_all_files()
是把这些资源文件下载到本地
dest_path在from .paths import dest_path
打开offline_folium\paths.py
dest_path = pkg_resources.resource_filename('offline_folium', "local")
说明下载在offline_folium\ local目录下
打开看看果然是
报错在 File “D:\Anaconda3\lib\site-packages\offline_folium\ __ main__.py”, line 13, in download_all_files
也就是这里
for _, js_url in folium.folium._default_css:download_url(js_url)
这是去folium库下的folium.py文件拿到地址进行下载,也就是说,这个地址可能没下载成功
然后去folium\folium.py看看,也在site-packages中
_default_js = [("leaflet", "https://cdn.jsdelivr.net/npm/leaflet@1.9.3/dist/leaflet.js"),("jquery", "https://code.jquery.com/jquery-3.7.1.min.js"),("bootstrap","https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.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.9.3/dist/leaflet.css"),("bootstrap_css","https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css",),# glyphicons came from Bootstrap 3 and are used for Awesome Markers("glyphicons_css","https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css",),("awesome_markers_font_css","https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.2.0/css/all.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
]
报错的是_default_css ,对比一下前面已经下载的
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\leaflet.css
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\bootstrap.min.css
Downloading D:\Anaconda3\lib\site-packages\offline_folium\local\bootstrap.min.css
后面报错,说明bootstrap.min.css后面的安装失败了
("awesome_markers_font_css","https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.2.0/css/all.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
也就是这三个还没下载,自己打开这三个地址看看
发现都能打开
就直接挨个把这三个网页里所有的字都粘下来,在offline_folium\local中新建文本,粘进去,再改名成对应的all.min.css leaflet.awesome-markers.css leaflet.awesome.rotate.min.css
然后看起来都完工了,再执行一次创建地图文件的程序
又有报错:
Traceback (most recent call last):File "d:/zpx/python_pro/1/比武图/2.py", line 6, in <module>city_map.save('test_03.html')File "D:\Anaconda3\lib\site-packages\branca\element.py", line 228, in savehtml = root.render(**kwargs)File "D:\Anaconda3\lib\site-packages\branca\element.py", line 406, in renderreturn self._template.render(this=self, kwargs=kwargs)File "D:\Anaconda3\lib\site-packages\jinja2\environment.py", line 1295, in renderself.environment.handle_exception()File "D:\Anaconda3\lib\site-packages\jinja2\environment.py", line 942, in handle_exceptionraise rewrite_traceback_stack(source=source)File "<template>", line 4, in top-level template codeFile "D:\Anaconda3\lib\site-packages\branca\element.py", line 204, in renderreturn self._template.render(this=self, kwargs=kwargs)File "D:\Anaconda3\lib\site-packages\jinja2\environment.py", line 1295, in renderself.environment.handle_exception()File "D:\Anaconda3\lib\site-packages\jinja2\environment.py", line 942, in handle_exceptionraise rewrite_traceback_stack(source=source)File "<template>", line 2, in top-level template codeFile "D:\Anaconda3\lib\site-packages\branca\element.py", line 204, in renderreturn self._template.render(this=self, kwargs=kwargs)File "D:\Anaconda3\lib\site-packages\jinja2\environment.py", line 1295, in renderself.environment.handle_exception()File "D:\Anaconda3\lib\site-packages\jinja2\environment.py", line 942, in handle_exceptionraise rewrite_traceback_stack(source=source)File "<template>", line 1, in top-level template codeFile "D:\Anaconda3\lib\site-packages\offline_folium\offline.py", line 14, in get_codecontents = f.read()
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa0 in position 7802: illegal multibyte sequence
说的是 offline_folium\offline.py里14行位置读文件时,系统默认使用 GBK 编码尝试读取文件,但文件实际是 UTF-8 编码
def get_code(self):"""Opens the link and returns the response's content."""if self.code is None:with open(self.url, "r") as f:contents = f.read()self.code = contentsreturn self.code
可以看到读的时候没指定用什么格式解码,应该是刚才报错的那些css js文件的编码格式问题
直接给它指定为用utf-8编码
def get_code(self):"""Opens the link and returns the response's content."""if self.code is None:with open(self.url, "r", encoding='utf-8') as f:contents = f.read()self.code = contentsreturn self.code
保存一下这个修改,然后再执行创建地图
这次文件大小看起来没毛病了,但是打开之后,依旧是空白的
这次看起来能够放缩,还有小手可以拖动了,就是图是空白的,说明缺瓦片(看来在线瓦片也加载不到)
folium.Map方法参数里有
tiles:地图样式,默认为OpenStreetMap
attr:如果设置非内建地图样式,则需要传入这个值,可以理解为你选择的地图样式名称
这个 tiles:地图样式就是瓦片地址,默认是加载在线的,不用传,现在手动传一下
瓦片样式可以从下面这个地址里找找想要的(除了国内免费在线的,也可以下载离线的,地址填文件地址即可)
https://zhuanlan.zhihu.com/p/446067690
我就用了其中一个高德的
import folium
from offline_folium import offline
# define the national map
city_map = folium.Map(location=[39.93, 116.40], zoom_start=10,tiles= 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}',attr='111',)
# save national map
city_map.save('test_03.html')
注意这个attr也得填,填什么都无所谓,相当于给自定义的瓦片样式起个名
这次再生成
打开终于没问题了,(右下角那个就是刚才给样式起的名)