我正在使用Vue JS和Flask构建一个非常基本的CARTO应用程序。完整的代码可以在in this github repository中找到。
该应用程序的工作方式如下:
用户以模式形式选择一个选项,然后单击“可视化”按钮。这将发送一个名为loadMap
的Vue方法,该方法将发送带有查询字符串(由query
计算的属性)值作为有效载荷的POST请求。
然后,它将路由重定向到另一个模板(map.html
),并采用从SQL API调用生成的变量(features
)。
此变量是一个GeoJSON,它将填充地图的数据源。
问题在于执行重定向后,地图模板无法呈现。这是我的Python代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from flask import Flask, render_template, request, url_for, redirect
app = Flask(__name__, static_folder='static', template_folder='templates')
@app.route('/')
def home():
"""Displays the homepage."""
return render_template('index.html')
@app.route('/query', methods=['POST'])
def query():
data = request.get_json()
query = data['query']
return redirect(url_for('map', query=query))
@app.route('/map', methods=['GET'])
def map():
query = request.args['query']
url = 'https://ramiroaznar.carto.com/api/v2/sql?q={}&format=geojson'.format(query)
session = requests.Session()
r = session.get(url)
features = r.json()
return render_template('map.html', features=features)
if __name__ == '__main__':
app.run(debug=True)
看起来POST和GET调用正确完成,但是随后重定向未启动,因此未加载地图:
如何解决此问题?有没有更优雅的方法来实现这一目标(使用API调用中的数据加载新网站)?
答案 0 :(得分:0)
尝试呈现模板而不是重定向。
@app.route('/query', methods=['POST'])
def query():
data = request.get_json()
query = data['query']
return render_template('map.html', query=query)
希望这会有所帮助:P
答案 1 :(得分:0)
问题出在我的js代码中。因此,我修复了将映射逻辑移动到vue实例的问题。为了避免使用两个模板,我还简化了python代码。现在该应用程序可以运行了,但是我应该重构js代码以提高性能(加载时间太长)和可伸缩性(地图逻辑应再次移至vue实例之外)。您可以找到工作示例in this glitch repository。
以下代码段是我的Flask python代码...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
from flask import Flask, render_template, request, url_for, redirect
app = Flask(__name__, static_folder='static', template_folder='templates')
@app.route('/')
def home():
"""Displays the homepage."""
return render_template('index.html')
@app.route('/data', methods=['GET'])
def data():
query = request.args.get('query')
url = 'https://ramiroaznar.carto.com/api/v2/sql?q={}&format=geojson'.format(query)
session = requests.Session()
r = session.get(url)
features = r.json()
return features
if __name__ == '__main__':
app.run(debug=True)
...这是我的js代码:
Vue.config.ignoredElements = [/as-\w+/];
const vm = new Vue({
el: "#app",
data: {
geometryType: 'cities',
map: false,
features: {}
},
computed: {
query: function() {
let table = ''
if (this.geometryType == 'cities'){
table = 'ne_10m_populated_places_simple';
} else {
table = 'world_borders';
}
return `select * from ${table}`
}
},
methods: {
loadMap: function() {
this.map = true;
this.$http.get('/data', {params: {query: this.query}} ).then(response => {
this.features = JSON.parse(response.bodyText);
console.log(this.features);
}, response => {
console.log('an error ocurred')
})
}
},
watch: {
features: function() {
const map = new mapboxgl.Map({
container: 'map',
style: carto.basemaps.voyager,
center: [10.151367,51.172455],
zoom: 2,
scrollZoom: false
});
const nav = new mapboxgl.NavigationControl({ showCompass: false });
map.addControl(nav, 'top-left');
carto.setDefaultAuth({
username: 'cartovl',
apiKey: 'default_public'
});
console.log(this.features);
const source = new carto.source.GeoJSON(this.features);
const viz = new carto.Viz();
const layer = new carto.Layer('layer', source, viz);
layer.addTo(map, 'watername_ocean');
}
}
})