""" openweatherradar.org app """
import os
import flask
from datetime import datetime, timedelta
import dash
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
import dash_core_components as dcc
import dash_html_components as html
import dash_leaflet as dl
from src.time_helper import round_time
server = flask.Flask(__name__)
N_TIMESTAMPS = 25
def round_time(dt=None, round_to=60):
"""Round a datetime object to any time lapse in seconds
dt : datetime.datetime object, default now.
roundTo : Closest number of seconds to round to, default 1 minute.
Author: Thierry Husson 2012 - Use it as you want but don't blame me.
"""
if dt == None: dt = datetime.now()
seconds = (dt.replace(tzinfo=None) - dt.min).seconds
rounding = (seconds + round_to / 2) // round_to * round_to
return dt + timedelta(0, rounding - seconds, -dt.microsecond)
app = dash.Dash(
__name__,
server=server,
meta_tags=[{"name": "viewport", "content": "width=device-width"}],
title='openweatherradar',
update_title=None,)
app.layout = html.Div([
dl.Map([dl.TileLayer(url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', maxZoom=13),
dl.TileLayer(url='https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lines/{z}/{x}/{y}{r}.png', minZoom=0, maxZoom=20),
dl.TileLayer(url='https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png', maxZoom=19),
dl.TileLayer(url="",
minNativeZoom=6,
maxNativeZoom=9,
id='radar_layer',
opacity=0.7,
crossOrigin=False,
updateWhenZooming=True,
tms=False)],
center=[52.5, 10],
zoom=5,
style={'width': '100%', 'height': '98vh', 'margin': "auto", "display": "block"}),
html.Div('2020/10/12/20/50', id='loop-timestamp', style={'display': 'None'}),
dcc.Interval(id='loop-radar-layer', interval=666),
],
)
@app.callback(Output('loop-timestamp', 'children'),
[Input('loop-radar-layer', 'n_intervals')])
def update_loop_timestamp(intervals):
if intervals is None:
raise PreventUpdate
now = datetime.utcnow()
now = round_time(now-timedelta(minutes=3), round_to=60*5)
return (now-timedelta(minutes=(N_TIMESTAMPS-int((intervals / N_TIMESTAMPS) % 1 * N_TIMESTAMPS))*5)).strftime('%Y/%m/%d/%H/%M')
@app.callback(Output('radar_layer', 'url'),
[Input('loop-timestamp', 'children')])
def update_radar_layer(timestamp):
time_url = f"https://api.meteointelligence.com/radar/data/{timestamp}"
return time_url + "/{z}/{x}/{y}.png"
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8050))
server.run(host='0.0.0.0',
port=port)
This is my full code. Please note that I run this application within docker container.
My problem now is that the loading is not smooth as we know this from e.g. Leaflet TimeDimension extension. You can see a runnng example with smooth updates of the layers: openweatherradar.org .