51 lines
1.9 KiB
Python
51 lines
1.9 KiB
Python
from argparse import ArgumentParser
|
|
from pathlib import Path
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
from flask import Flask, send_file
|
|
|
|
|
|
def main():
|
|
parser = ArgumentParser()
|
|
parser.add_argument('--debug', action='store_true', help='Run in debug mode (auto-reload on change)')
|
|
arguments = parser.parse_args()
|
|
|
|
debug_mode: bool = arguments.debug
|
|
del arguments
|
|
|
|
app = Flask('map_server', static_folder='public', static_url_path='/')
|
|
osm_timeout = 3
|
|
http_code_ok = 200
|
|
|
|
@app.route('/')
|
|
def _index():
|
|
return app.send_static_file('index.html')
|
|
|
|
@app.route('/<int:zoom>/<int:x>/<int:y>.png')
|
|
def _tile(zoom: int, x: int, y: int):
|
|
tile_path = Path('data', str(zoom), str(x), f'{y}.png')
|
|
if tile_path.exists():
|
|
return send_file(tile_path)
|
|
if not tile_path.parent.exists():
|
|
tile_path.parent.mkdir(parents=True, exist_ok=True)
|
|
request = urllib.request.Request(f'https://tile.openstreetmap.org/{zoom}/{x}/{y}.png')
|
|
request.add_header('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:138.0) Gecko/20100101 Firefox/138.0')
|
|
request.add_header('Accept', 'image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5')
|
|
request.add_header('Accept-Language', 'en-US,en;q=0.5')
|
|
request.add_header('Accept-Encoding', 'gzip, deflate, br, zstd')
|
|
try:
|
|
with urllib.request.urlopen(request, timeout=osm_timeout) as response:
|
|
if response.status != http_code_ok:
|
|
return (f'tile.openstreetmap.org answer is not OK (status: {response.status}) : {response.read()}',
|
|
501)
|
|
tile_path.write_bytes(response.read())
|
|
return send_file(tile_path)
|
|
except urllib.error.URLError as error:
|
|
return f'Cannot retrieve tile: {error}', 501
|
|
|
|
app.run(host='0.0.0.0', port=8000, debug=debug_mode)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|