将folium地图插入jinja模板

时间:2016-05-22 20:34:15

标签: python html flask jinja2 folium

我想将follium map插入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')的地图。

我该怎么做?

3 个答案:

答案 0 :(得分:4)

您可以使用folium_map.save('templates/map.html')保存生成的html。然后你可以使用jinja2到{% include "map.html" %}。生成的html在包含在 div 标记中时不会呈现地图,如果需要进行封装,请考虑使用iframescustom 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 %}

答案 1 :(得分:2)

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

这是文件结构

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

Folium地图文件( map.html )将通过我的 app.py 自动创建。在 app.py 上,我将创建2条主要路线:第一条是本国路线,它将呈现 index.html 并创建 map.html 。然后另一种方法是渲染叶片地图( map.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" width="600" height="600"></iframe>
    <h3><b style="background-color: lightcoral; color: lightcyan;">
        Render Folium on Flask done!
    </b></h3>
</body>
</html>

结果将像这样在浏览器上显示:

folium on flask

希望对您有帮助。

答案 2 :(得分:0)

使用iframe和render_template的另一种解决方案

<iframe class="map", src="/get_map" width="1100" height="600"></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不是必需的,但它是我尝试提供解决方案的一部分。显然,此解决方案不是线程安全的