将 folium 地图插入到 jinja 模板中

Posted

技术标签:

【中文标题】将 folium 地图插入到 jinja 模板中【英文标题】:Insert the folium maps into the jinja template 【发布时间】:2016-09-19 15:33:35 【问题描述】:

我想将 follium 地图插入到 jinja 模板中。

run.py

from flask import Flask, render_template

app = Flask(__name__)



@app.route('/')
def index():
    start_coords = (46.9540700, 142.7360300)
    folium_map = folium.Map(location=start_coords, zoom_start=14)
    folium_map.save()
    return render_template('index.html', folium_map=folium_map)


    if __name__ == '__main__':
    app.run(debug=True)

template/index.html - Flask 的 jinja 模板

% extends "layout.html" %
% block title %Test% endblock %
% block head %
 super() 
% endblock %
% block body %
**<div><!--Folium map here--> folium_map </div>**
% endblock %

我的网站显示当前行:

<folium.folium.Map object at 0x00000000069D5DA0>

但我需要在这个 div 块中生成方法 follium_map.save('map.html') 的地图。

我该怎么做?

【问题讨论】:

取决于你在做什么,你可能只想使用:github.com/rochacbruno/Flask-GoogleMaps。 【参考方案1】:

也许它可以成为解决方案。首先,我们将 Folium 地图保存为 templates 文件夹中的 html 文件。然后我们创建一个 Flask 路由来渲染另一个 html 文件。在那个 html 文件上,我们创建一个调用我们地图的 iframe 元素。

这是文件结构

proectApp
├── app.py
└── templates
    ├── index.html
    └── map.html

Folium 地图文件 (ma​​p.html) 将从我的 app.py 中自动创建。在 app.py 我将创建 2 个主要路线:第一个是主路线,它将呈现 index.html 并创建 ma​​p.html。然后另一个是渲染folium地图(ma​​p.html)。以下是代码:

app.py

from flask import Flask, render_template
import folium

app = Flask(__name__)

@app.route('/')
def index():
    start_coords = (-6.1753924, 106.8271528)
    folium_map = folium.Map(
        location=start_coords, 
        zoom_start=17
    )
    folium_map.save('templates/map.html')
    return render_template('index.html')

@app.route('/map')
def map():
    return render_template('7_map.html')

if __name__ == '__main__':
    app.run(debug=True)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Folium Map</title>
</head>
<body>
    <h1>Render Folium on Flask ?</h1>
    <iframe class="map", src="/map"  ></iframe>
    <h3><b style="background-color: lightcoral; color: lightcyan;">
        Render Folium on Flask done!
    </b></h3>
</body>
</html>

结果会在浏览器上显示如下:

希望对你有帮助。

【讨论】:

您需要将return render_template('7_map.html') 更改为return render_template('map.html') 否则您将收到jinja2.exceptions.TemplateNotFound: 7_map.html 错误。【参考方案2】:

使用 iframe 和 render_template 的不同解决方案

<iframe class="map", src="/get_map"  ></iframe>

加上python烧瓶代码

# a hack going on here as web servers are caching folium generated template
# randomly move to a new name and then use render_template
@app.route('/get_map')
def get_map():
    r = int(random.triangular(0,100))
    t = "templates/map_i.html"
    for i in range(0,100):
        f = t.format(i=i)
        if os.path.exists(f):
            os.remove(f)
    f = t.format(i=r)
    shutil.copy("templates/map.html", f)

    r = make_response(render_template(os.path.split(f)[1]))
    r.cache_control.max_age = 0
    r.cache_control.no_cache = True
    r.cache_control.no_store = True
    r.cache_control.must_revalidate = True
    r.cache_control.proxy_revalidate = True
    return r

在渲染 httpd(在 AWS beanstalk 上)/flask 调试环境之前如果没有复制到随机文件名,则不会获取 folium html 模板的新实例。 cache_control 不是必需的,但它是我试图找到解决方案的一部分。显然这个解决方案不是线程安全的

【讨论】:

【参考方案3】:

您可以使用folium_map.save('templates/map.html') 保存生成的html。然后你可以使用 jinja2 到% include "map.html" %。当包装在 div 标签中时,生成的 html 不会呈现地图,如果需要封装,请考虑使用 iframes 或 custom folium templates。

文件结构

myapp
├── run.py
└── templates
    ├── index.html
    └── layout.html

run.py

from flask import Flask, render_template
import folium

app = Flask(__name__)

@app.route('/')
def index():
    start_coords = (46.9540700, 142.7360300)
    folium_map = folium.Map(location=start_coords, zoom_start=14)
    folium_map.save('templates/map.html')
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

layout.html

<!DOCTYPE HTML>
<head>
  <title>% block title %% endblock %</title>
</head>
<body>
  <header>% block head %% endblock %</header>
  % block body %% endblock %
</body>
</html>

index.html

% extends "layout.html" %
% block title % Test % endblock %
% block head %  super()  % endblock %
% block body %
    % include "map.html" %
% endblock %

【讨论】:

谢谢!在找到您的答案之前,我一直在努力做到这一点。我希望添加一个将坐标数据返回给python的javascript函数。有没有办法添加 JS 以某种方式插入到 folium 生成的 html 中? 在这个例子中,我想这可以通过在调用render_template...之前修改map.html或layout.html来实现,或者你可以生成一个临时布局文件并使用一个变量来引用它在 index.html 的 extends 块内。 谢谢,在调用 render_template 之前修改 map.html 有效!

以上是关于将 folium 地图插入到 jinja 模板中的主要内容,如果未能解决你的问题,请参考以下文章

将 folium 地图导出为 png

无法将 altair 可视化作为弹出窗口插入到叶地图中

folium:绘制地图的模块

设置地图边界并在Folium地图的循环中停止无休止的平移

将多个 Vega/vincent 图表添加到 Folium 弹出窗口

使用 Python 地图绘制工具 -- folium 全攻略