flask表单查询经纬度获取瓦片地图并拼接

flask表单查询经纬度获取瓦片地图并拼接

瓦片服务器:tileserver-gl
启动命令:docker run --rm -it -v $(pwd):/data -p 8080:80 klokantech/tileserver-gl

1. templates文件

404.html

{% extends "base.html" %}

{% block title %}Map Search - Page Not Found{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Not Found</h1>
</div>
{% endblock %}

500.html

{% extends "base.html" %}

{% block title %}Map Search - Internal Server Error{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Internal Server Error</h1>
</div>
{% endblock %}

base.html

{% extends "bootstrap/base.html" %}

{% block title %}Map Search{% endblock %}

{% block head %}
{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
{% endblock %}

{% block navbar %}
<div class="navbar navbar-inverse" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/">Map Search</a>
        </div>
        <div class="navbar-collapse collapse">
{#            <ul class="nav navbar-nav">#}
{#                <li><a href="/">Home</a></li>#}
{#            </ul>#}
        </div>
    </div>
</div>
{% endblock %}

{% block content %}
<div class="container">
    {% for message in get_flashed_messages() %}
    <div class="alert alert-warning">
        <button type="button" class="close" data-dismiss="alert">&times;</button>
        {{ message }}
    </div>
    {% endfor %}
    {% block page_content %}{% endblock %}
</div>
{% endblock %}

{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{% endblock %}

index.html

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Map Search{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>您好,请输入您要查询的地图经纬度坐标:</h1>
</div>
{{ wtf.quick_form(form) }}
{% endblock %}

2. app.py(主要逻辑)

import math
import os
import re

from flask import Flask, render_template, redirect, url_for
from flask_bootstrap import Bootstrap
from flask_moment import Moment
from flask_wtf import FlaskForm
from wtforms import FloatField, SubmitField
from wtforms.validators import DataRequired

import requests
import PIL.Image as Image

app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'

bootstrap = Bootstrap(app)
moment = Moment(app)


class QueryForm(FlaskForm):
    longitude = FloatField('经度:', validators=[DataRequired()])
    latitude = FloatField('纬度:', validators=[DataRequired()])
    query = SubmitField('查询')


@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404


@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500


@app.route('/', methods=['GET', 'POST'])
def index():
    longitude = None
    latitude = None
    pic_folder = 'pics'
    form = QueryForm()
    if form.validate_on_submit():
        longitude = form.longitude.data
        latitude = form.latitude.data
        tile_x, tile_y = deg2num(latitude, longitude)

        if not os.path.exists(pic_folder):
            os.mkdir(pic_folder)
            os.chdir(os.getcwd() + '/' + pic_folder)
            get_tiles(tile_x, tile_y)
            tiles_path = os.getcwd()
            merge_tiles(tiles_path)
        return redirect(url_for('index'))
    return render_template('index.html', form=form)


def deg2num(lat_deg, lon_deg, zoom=11):
    lat_rad = math.radians(lat_deg)
    n = 2.0 ** zoom
    tile_x = int((lon_deg + 180.0) / 360.0 * n)
    tile_y = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
    return tile_x, tile_y


def get_tiles(tile_x, tile_y):
    count = 0
    offset = 2
    for y in range(tile_y-offset, tile_y+offset):
        for x in range(tile_x-offset, tile_x+offset):
            url = 'http://localhost:8080/styles/klokantech-basic/11/{0}/{1}@2x.png'.format(x, y)
            print(url)
            img = requests.get(url).content
            count += 1
            img_name = '{0}-{1}-{2}.png'.format(count, x, y)
            with open(img_name, 'wb+') as file:
                file.write(img)


def merge_tiles(tiles_path):
    IMAGE_SIZE = 256
    IMAGE_ROW = 4
    IMAGE_COLUMN = 4
    IMAGE_PATH = tiles_path
    image_names = [name for name in os.listdir(IMAGE_PATH)]
    # 图片名字格式为'16-1073-718.png',因为每张瓦片图需要按序排列,所以需要按第一个数字排序
    re_digits = re.compile(r'(\d+)')
    image_names = sorted(image_names, key=lambda s: int(re_digits.split(s)[1]))

    to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW * IMAGE_SIZE))
    for y in range(1, IMAGE_ROW + 1):
        for x in range(1, IMAGE_COLUMN + 1):
            from_image = Image.open(IMAGE_PATH + '/' + image_names[IMAGE_COLUMN * (y - 1) + x - 1]).resize(
                (IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)
            print(image_names[IMAGE_COLUMN * (y - 1) + x - 1])
            to_image.paste(from_image, ((x - 1) * IMAGE_SIZE, (y - 1) * IMAGE_SIZE))
    return to_image.save(IMAGE_PATH + '/final.jpg')


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

  1. 输入经纬度8.5375和47.3790查询,可以得到对应的小瓦片图,合并后效果如下:
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值