weather.openportguide.de
  1. You are here:  
  2. Home
  3. Weather
  4. Description
  5. Animation

Language Switcher

Select your language

  • English (UK)
  • Deutsch

Main Menu

  • Weather forecasts
    • Weather data
    • Weather animation
      • Leaflet - particle animation
    • Weather tiles
      • variables
      • timesteps
      • actual weather tiles full screen map
      • demo weather tiles on full screen map
    • Meteograms
      • JSON-Meteogram
    • Individual forecasts maps - variables
      • Individual forecast maps - parameters
    • Weather API
      • Weather API - Variables
      • Weather API - Timesteps
  • Terms of use
  • unlocking of weather data
  • Change Log
  • About
  • Disclaimer
  • Privacy

Login Form

  • Forgot your password?
  • Forgot your username?
  • Create an account

Weather animation

The weather animation can be used using the "leaflet" JavaScript library.

Required components for using the weather animation (download the required files as .zip, except javascript_vars.js and javascript_vars_rtofs.js, read explanation below:

  • Leaflet 1.3.1 or newer (mapping frame work)
  • jQuery 3.3.1 or newer (necessary to load the json data from the openportguide server)
  • The modified version of Leaflet-Velocity (here the Leaflet-Velocity-original for information) (necessary for the animated layer):
    leaflet-velocity.css
    leaflet-velocity.js
    IE_workarounds.js
  • The modified version of Leaflet.TimeDimension (here the Leaflet.TimeDimension original for information) (necessary for the time slider):
    iso8601.min.js
    leaflet.timedimension.noLayers.src.js
    leaflet.timedimension.control.min.css
  • Some variable values are directly loaded from the openportguide server. In contrast to all files above, this files are changing continuosly and have to be loaded from the openportguide server each time an animated layer should be displayed! (All files above can be downloaded and placed on the own server or implemented in the own software, but not the following two files):
    javascript_vars.js
    javascript_vars_rtofs.js

Useful components to use the weather animation:

  • Nice basemaps as background for the weather animation: Esri-Leaflet 2.1.4 or newer

 

Options that affect the appearance of the weather animation:

All options can be tested with the configurator and the complete code for displaying the page can be show, cut and paste, see https://weather.openportguide.org/map_leaflet.html. The configurator should be used with Google Chrome!

Option Typ Default Description
displayValues boolean true Determines whether the values are displayed at the mouse position.
velocityType text "Velocity" Used to describe the displayed values at the mouse position.
emptyString text "Unavailable" Appears when there are no mouse position values.
angleConvention text "meteoCW" The "angleConvention" option refers to the convention used to express the wind direction as an angle from north direction in the control. It can be any combination of "bearing" (angle toward which the flow goes) or "meteo" (angle from which the flow comes), and "CW" (angle value increases clock-wise) or "CCW" (angle value increases counter clock-wise). If not given defaults to "meteoCW".
speedUnit text "m/s" Indicates in which unit the speed is displayed at the mouse position. The following values are possible:
"m/s" for meters per second
"km/h" for kilometers per hour
"kt" for knot
"Bft" for Beaufort
minVelocity floating point 0 Velocity at which particle intensity is minimum (m/s)
maxVelocity floating point 10 Velocity at which particle intensity is maximum (m/s)
velocityScale floating point 0.005 Scale for wind velocity (completely arbitrary--this value looks nice)
particleAge Integer 90 max number of frames a particle is drawn before regeneration
lineWidth integer 1 Line width of a drawn particle
particleMultiplier floating point 0.003333 Particle count scalar (completely arbitrary--this values looks nice)
frameRate integer 15 Desired frames per second
colorScale array ["rgb(36,104,180)",   Color scale (first color value corresponds to "minVelocity", last color value corresponds to "maxVelocity", the color values are equally distributed between "minVelocity" and "maxVelocity" and the number of color values is arbitrary.
 "rgb(60,157,194)",  
 "rgb(128,205,193 )",  
 "rgb(151,218,168 )",  
 "rgb(198,231,181)",  
 "rgb(238,247,217)",  
 "rgb(255,238,159)",  
 "rgb(252,217,125)",  
 "rgb(255,182,100)",  
 "rgb(252,150,75)",  
 "rgb(250,122,52)",  
 "rgb(245,64,32)",  
 "rgb(237,45,28)",  
 "rgb(220,24,32)",  
 "rgb(180,0,35)"]  

 

Code Example:

<!DOCTYPE html>
<html>
<head>

<title>Leaflet - Particle animation</title>

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<!-- Load Leaflet 1.3.1 -->
<link rel="stylesheet" href="/leaflet/leaflet.css" integrity="sha256-NUykZmi4kbsqfyw0XgSwmjUlpqW/u74zu5ibK9DuiSY=" crossorigin=""/>
<script src="/leaflet/leaflet.js" integrity="sha256-VxczYNPPl3vWEQjM566cf3Le5VD0hnABQ1iohWuvfqc=" crossorigin=""></script>

<!-- Load Esri Leaflet 2.1.4 -->
<script src="/esri-leaflet/esri-leaflet.js" integrity="sha256-5QgVwsPW6/SFxy0erdtA6j9XK682s/cOIrUiq8BuYGw=" crossorigin=""></script>

<!-- Load JQuery 3.3.1 -->
<script src="/jquery-3.3.1.min.js" integrity="sha256-oozPintQUive6gzYPN7KIhwY/B+d8+5rPTxI1ZkgaFU=" crossorigin=""></script>

<!--leaflet-velocity-->
<link rel="stylesheet" href="/leaflet-velocity_tkws/leaflet-velocity.css" />
<script src="/leaflet-velocity_tkws/leaflet-velocity.js"></script>
<script src="/leaflet-velocity_tkws/IE_workarounds.js"></script>

<!--for timeslider-->
<script type="text/javascript" src="/leafletTimeDimension/iso8601.min.js"></script>
<script type="text/javascript" src="/leafletTimeDimension/leaflet.timedimension.noLayers.src.js"></script>
<link rel="stylesheet" href="/leafletTimeDimension/leaflet.timedimension.control.min.css" />

<!--load variable values from server-->
<script type="text/javascript" src="/weather/javascript_vars.js"></script>
<script type="text/javascript" src="/weather/javascript_vars_rtofs.js"></script>

<style>
body { margin:0; padding:0; }
#map { position: absolute; top:0; bottom:0; right:0; left:0; z-index:1; }
</style>
</head>
<body>
<div id="map"></div>

<script>
var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
var OpenStreetMap = new L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib, opacity: 0.4}),
Topographic = new L.esri.basemapLayer('Topographic', {opacity: 0.4}),
Streets = new L.esri.basemapLayer('Streets', {opacity: 0.4}),
NationalGeographic = new L.esri.basemapLayer('NationalGeographic', {opacity: 0.4}),
Oceans = new L.esri.basemapLayer('Oceans', {opacity: 0.4}),
Gray = new L.esri.basemapLayer('Gray', {opacity: 0.4}),
DarkGray = new L.esri.basemapLayer('DarkGray'),
Imagery = new L.esri.basemapLayer('Imagery'),
ShadedRelief = new L.esri.basemapLayer('ShadedRelief', {opacity: 0.4});


var startTime = new Date(Date.UTC(GFS_server_year, GFS_server_month - 1, GFS_server_day, GFS_server_hour));
var actualTime = new Date(Date.UTC(GFS_server_year, GFS_server_month - 1, GFS_server_day, GFS_server_hour + 6)); //actual time is about 6 hours ahead to the first forecast timestep
var endTime = new Date(Date.UTC(GFS_server_year, GFS_server_month - 1, GFS_server_day, GFS_server_hour + ((GFS_timesteps-1)*GFS_interval)));
var dataTimeInterval = startTime.toISOString() + "/" + endTime.toISOString();
var actualInterval = GFS_interval*2 ; // show only every second available timestep (GFS_interval is "3" hours
var baseIndex = 1; // index of the wind10mArray containing the layer nearest to the actual time (2 if actualIndex==GFS_Index, 1 if actualIndex==GFS_Index*2)
var dataPeriod = "PT" + (actualInterval) + "H";
var wind10mBaseURL = 'weather/wind10m/';
var wind10mBaseName = 'wind10m_{h}h';
var wind10mName = '';
var wind10mArray = [];


var startTimeRTOFS = new Date(Date.UTC(RTOFS_server_year, RTOFS_server_month - 1, RTOFS_server_day, RTOFS_server_hour));
var actualTimeRTOFS = new Date(Date.UTC(RTOFS_server_year, RTOFS_server_month - 1, RTOFS_server_day, RTOFS_server_hour + 6));
var endTimeRTOFS = new Date(Date.UTC(RTOFS_server_year, RTOFS_server_month - 1, RTOFS_server_day, RTOFS_server_hour + ((RTOFS_timesteps-1)*RTOFS_interval)));
var dataTimeIntervalRTOFS = startTimeRTOFS.toISOString() + "/" + endTimeRTOFS.toISOString();
var actualIntervalRTOFS = RTOFS_interval*2 ; // show only every second available timestep
var baseIndexRTOFS = 1; // index of the seaSurfaceCurrent Array containing the layer nearest to the actual time (2 if actualIndex==RTOFS_Index, 1 if actualIndex==RTOFS_Index*2)
var dataPeriodRTOFS = "PT" + (actualIntervalRTOFS) + "H";
var seaSurfaceCurrentBaseURL = 'weather/sea_surface_current/';
var seaSurfaceCurrentBaseName = 'sea_surface_current_{h}h';
var seaSurfaceCurrentName = '';
var seaSurfaceCurrentArray = [];


var map = new L.map('map', {
center: [54.04, 9.07],
zoom: 4,
layers: [Imagery],
timeDimension: true,
timeDimensionOptions: {
timeInterval: dataTimeInterval,
period: dataPeriod,
currentTime: actualTime
},
timeDimensionControl: true,
timeDimensionControlOptions: {
loopButton: false,
limitSliders: false,
playButton: false,
speedSlider: false
}
});

var baseMaps = {
"OpenStreetMap": OpenStreetMap,
"Topographic": Topographic,
"Streets": Streets,
"NationalGeographic": NationalGeographic,
"<span style='color: gray'>Gray</span>": Gray,
"DarkGray": DarkGray,
"Imagery": Imagery,
"ShadedRelief": ShadedRelief,
"Oceans": Oceans,
};

var layerControl = new L.control.layers(baseMaps);
layerControl.addTo(map);

var wind10mLayerGroup = new L.layerGroup([], {});
wind10mArray.length = map.timeDimension._availableTimes.length;

var actualTimeIndex = map.timeDimension._currentTimeIndex;

// load data (u, v grids) from weather.openportguide.de
layerControl.addOverlay(wind10mLayerGroup, 'wind10m');
updateLayer(wind10mArray[actualTimeIndex]);

window.setInterval(function() { //check if time index changed
if (actualTimeIndex != map.timeDimension._currentTimeIndex) {
actualTimeIndex = map.timeDimension._currentTimeIndex;
updateLayer(wind10mArray[actualTimeIndex]);
}
},100);

function updateLayer(Layer){ //updates the actual layer
wind10mLayerGroup.clearLayers();
wind10mName = wind10mBaseName.replace(/{h}/g, (actualTimeIndex - baseIndex) * actualInterval);

$.getJSON(wind10mBaseURL + wind10mName + ".json", function (data) {
this[wind10mName] = L.velocityLayer({
displayValues: true,
displayOptions: {
velocityType: "Wind",
emptyString: "No wind data",
angleConvention: "bearingCW",
speedUnit: "Bft"
},
data: data,
minVelocity: 0,
maxVelocity: 30,
velocityScale: 0.002,
particleAge: 90,
lineWidth: 1,
particleMultiplier: 0.0033,
frameRate: 15,
colorScale: ["#2468b4", "#3c9dc2", "#80cdc1", "#97daa8", "#c6e7b5", "#eef7d9", "#ffee9f", "#fcd97d", "#ffb664", "#fc964b", "#fa7034", "#f54020", "#ed2d1c", "#dc1820", "#b40023"]
});

wind10mLayerGroup.addLayer(this[wind10mName]);
wind10mArray[actualTimeIndex] = wind10mLayerGroup.getLayer(wind10mLayerGroup.getLayerId(this[wind10mName]));
wind10mLayerGroup.addTo(map);
});
}
</script>
</body>
</html>

 

Hints:

If base maps with bright colors, e.g. Openstreetmap be used as a background, the weather animation is hard to see.
In this case, the opacity of the base layer can simply be reduced and the image darkens due to the black background, such as:
var OpenStreetMap = new L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib, opacity: 0.4});

 

There is a big difference in which browser is used, so here's a note on compatibility with the various browsers:

Browser Recommendation Remarks
Chrome very good The animation runs on PCs of all performance classes with a very low resource consumption.
Opera good The animation runs on PCs of all performance classes with a reasonable resource consumption.
Firefox rather not recommended The animation runs smoothly on powerful machines, even if the mouse is moved over the map. However, the CPU load is up to 10 times higher than when viewing with Chrome.
Edge not recommended The animation does not run smoothly even on powerful PCs when the mouse is moved on the map.
Internet Explorer not recommended The animation does not run smoothly even on powerful PCs when the mouse is moved on the map.
Also, because of the incompatibility with some of the newer components of Java, the animation is only executable with additional code (see above). Since the Internet Explorer is not developed further, its use is to be seen only as absolute emergency solution.

 

In order to provide you with the best online experience this website uses cookies. Delete cookies

In order to provide you with the best online experience this website uses cookies. By using our website, you agree to our use of cookies.

For more information see the privacy information of this page: http://weather.openportguide.org/index.php/en/privacy

I agree