Skip to content

Commit 5323c10

Browse files
committed
Update Animated tile layer.html
1 parent e224616 commit 5323c10

File tree

1 file changed

+132
-30
lines changed

1 file changed

+132
-30
lines changed

examples/Animated tile layer.html

Lines changed: 132 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,24 @@
1818
<script src="../dist/azure-maps-animations.js"></script>
1919

2020
<script type='text/javascript'>
21-
var map, layer;
22-
23-
//TODO: Migrate to Azure Maps weather tiles.
24-
25-
//Weather tile url from Iowa Environmental Mesonet (IEM): http://mesonet.agron.iastate.edu/ogc/
26-
var urlTemplate = 'https://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-{timestamp}/{z}/{x}/{y}.png';
27-
28-
//The time stamps values for the IEM service for the last 50 minutes broken up into 5 minute increments.
29-
var timestamps = ['900913-m50m', '900913-m45m', '900913-m40m', '900913-m35m', '900913-m30m', '900913-m25m', '900913-m20m', '900913-m15m', '900913-m10m', '900913-m05m', '900913'];
21+
var map, layer, timer;
22+
23+
//Base weather tile layer URL for radar data. {azMapsDomain} is a placeholder that is set automatically by the map, and will also automatically append the map credentials to the request.
24+
var urlTemplate = 'https://{azMapsDomain}/map/tile?api-version=2.0&tilesetId={tilesetId}&zoom={z}&x={x}&y={y}&timeStamp={timestamp}&tileSize=256&view=Auto';
25+
26+
//Details on the availability of the different weather layers.
27+
var weatherLayers = {
28+
'microsoft.weather.infrared.main': {
29+
interval: 10 * 60 * 1000, //10 minute interval
30+
past: 3 * 60 * 60 * 1000, //Data available up to 3 hours in the past.
31+
future: 0 //Forecast data not avaiable.
32+
},
33+
'microsoft.weather.radar.main': {
34+
interval: 5 * 60 * 1000, //5 minute interval
35+
past: 1.5 * 60 * 60 * 1000, //Data available up to 1.5 hours in the past.
36+
future: 1.5 * 60 * 60 * 1000 //Data available up to 1.5 hours in the future.
37+
}
38+
};
3039

3140
var displayMessages = [];
3241

@@ -47,30 +56,55 @@
4756

4857
//Wait until the map resources are ready.
4958
map.events.add('ready', function () {
50-
var tlOptions = [];
59+
//Load the radar layer by default.
60+
loadWeatherLayer('microsoft.weather.radar.main');
61+
});
62+
}
5163

52-
//Create a tile layer option for each time stamp.
53-
for (var i = 0; i < timestamps.length; i++) {
54-
tlOptions.push({
55-
tileUrl: urlTemplate.replace('{timestamp}', timestamps[i]),
56-
tileSize: 256,
57-
opacity: 0.8
58-
});
64+
function loadWeatherLayer(tilesetId){
65+
//If there is already a layer, stop it animating.
66+
if(layer){
67+
layer.stop();
68+
clearInterval(timer);
69+
}
5970

60-
//Optionally, create a message to display for each frame of the animation based on the time stamp.
61-
var msg = 'Current';
71+
//Get the current time.
72+
var now = new Date().getTime();
6273

63-
if (timestamps[i] != '900913') {
64-
msg += ' -' + timestamps[i].replace('900913-m', '') + 'in';
65-
}
74+
//Get the details for the requested weather layer.
75+
var layerInfo = weatherLayers[tilesetId];
76+
77+
//Calculate the number of timestamps.
78+
var numTimestamps = (layerInfo.past + layerInfo.future) / layerInfo.interval;
6679

67-
displayMessages.push(msg);
80+
var tlOptions = [];
81+
82+
for(var i = 0; i < numTimestamps; i++) {
83+
//Calculate time period for an animation frame. Shift the interval by one as the olds tile will expire almost immediately.
84+
var time = (now - layerInfo.past) + (i + 1) * layerInfo.interval;
85+
86+
//Create a tile layer option for each timestamp.
87+
tlOptions.push(createTileLayer(tilesetId, time));
88+
89+
//Optionally, create a message to display for each frame of the animation based on the time stamp.
90+
if(time === now){
91+
displayMessages.push('Current');
92+
} else {
93+
var dt = (time - now) / 1000 / 60;
94+
displayMessages.push(`${dt} minutes`);
6895
}
96+
}
6997

70-
//Create the animation manager.
71-
layer = new atlas.layer.AnimatedTileLayer({
98+
if(layer){
99+
layer.setOptions({
100+
tileLayerOptions: tlOptions
101+
});
102+
layer.play();
103+
} else {
104+
//Create the animation manager.
105+
layer = new atlas.layer.AnimatedTileLayer({
72106
tileLayerOptions: tlOptions,
73-
duration: timestamps.length * 1000, //Allow one second for each frame (tile layer) in the animation.
107+
duration: numTimestamps * 800, //Allow one second for each frame (tile layer) in the animation.
74108
autoPlay: true,
75109
loop: true
76110
});
@@ -81,22 +115,90 @@
81115
var msg = displayMessages[e.frameIdx];
82116
document.getElementById('messagePanel').innerText = msg;
83117
}
84-
});
118+
});
85119

86120
//Add the layer to the map.
87121
map.layers.add(layer, 'labels');
88-
});
122+
123+
//Setup an interval timer to shift the layers (remove oldest, add newest) based on the update interval of the tile layer.
124+
timer = setInterval(intervalHandler(tilesetId), layerInfo.interval);
125+
}
126+
}
127+
128+
function createTileLayer(tilesetId, time){
129+
//Create an ISO 8601 timestamp string.
130+
//JavaScripts format for ISO string includes decimal seconds and the letter "Z" at the end that is not supported. Use slice to remove this.
131+
var timestamp = new Date(time).toISOString().slice(0, 19);
132+
133+
//Create a tile layer option for each timestamp.
134+
return {
135+
tileUrl: urlTemplate.replace('{tilesetId}', tilesetId).replace('{timestamp}', timestamp),
136+
tileSize: 256, //Weather tiles only available in 256 pixel size.
137+
opacity: 0.9,
138+
maxSourceZoom: 15 //Weather tiles only available to zoom level 15. If you zoom in closer, the map may pull tiles from level 15 to fill the map.
139+
};
140+
}
141+
142+
function intervalHandler(tilesetId) {
143+
return function(){
144+
//Get the details for the requested weather layer.
145+
var layerInfo = weatherLayers[tilesetId];
146+
147+
//Calculate time period for an animation frame. Shift the interval by one as the olds tile will expire almost immediately.
148+
var time = (now - layerInfo.past) + (i + 1) * layerInfo.interval;
149+
150+
//Create an ISO 8601 timestamp string.
151+
//JavaScripts format for ISO string includes decimal seconds and the letter "Z" at the end that is not supported. Use slice to remove this.
152+
var timestamp = new Date(time).toISOString().slice(0, 19);
153+
154+
//Get the current tile layer options from the animation layer.
155+
var layers = layer.getOptions().tileLayerOptions;
156+
157+
//Remove the oldest tile layer options.
158+
tlOptions.shift();
159+
160+
//Add the newest tile layer options.
161+
tlOptions.push(createTileLayer(tilesetId, time));
162+
163+
//Update the animation layer.
164+
layer.setOptions({ tileLayerOptions: tlOptions });
165+
}
166+
}
167+
168+
function updateTileLayer(elm){
169+
var tilesetId = elm.options[elm.selectedIndex].value;
170+
loadWeatherLayer(tilesetId);
171+
}
172+
173+
function setSpeed(elm){
174+
var speed = parseFloat(elm.options[elm.selectedIndex].value);
175+
176+
layer.setOptions({ speedMultiplier: speed });
89177
}
90178
</script>
91179
</head>
92180
<body onload="GetMap()">
93181
<div id="myMap" style="position:relative;width:100%;min-width:290px;height:600px;"></div>
94182

95183
<div style="position:absolute;top:15px;left:15px;border-radius:5px;padding:5px;background-color:white;">
184+
Select weather overlay:
185+
<select onchange="updateTileLayer(this)">
186+
<option value="microsoft.weather.radar.main" selected="selected">Radar</option>
187+
<option value="microsoft.weather.infrared.main">Infrared</option>
188+
</select>
189+
<br/><br/>
96190
<input type="button" value="Play" onclick="layer.play();" />
97191
<input type="button" value="Pause" onclick="layer.pause();" />
98192
<input type="button" value="Stop" onclick="layer.stop();" />
99193
<input type="button" value="Reset" onclick="layer.reset();" />
194+
<br/><br/>
195+
Speed:
196+
<select onchange="setSpeed(this)">
197+
<option value="0.5">0.5x</option>
198+
<option value="1" selected="selected">1x</option>
199+
<option value="2">2x</option>
200+
<option value="5">5x</option>
201+
</select>
100202
</div>
101203

102204
<div id="messagePanel" style="position: absolute;top: 20px;right: 20px;background-color: white;padding: 2px;border-radius: 15px;width: 110px;text-align: center;"></div>
@@ -105,8 +207,8 @@
105207
<legend><h1 style="font-size:16px">Animated tile layer</h1></legend>
106208
This sample shows how to animate an sequence of tile layers smoothly.
107209
This example uses the AnimatedTileLayer to animate through an array of tile layers.
108-
For this sample weather radar tiles from the <a href="https://www.mesonet.agron.iastate.edu/ogc/">Iowa Environmental Mesonet of Iowa State University</a>
109-
over the USA are animated for the last 50 minutes in 5 minute increments.
210+
For this sample weather data from Azure Maps through the <a href="https://docs.microsoft.com/en-us/rest/api/maps/renderv2/getmaptilepreview">Reader services</a> are used.
211+
Infrared data is updated every 10 minutes and available for 3 hours in the past. Radar data updated every 5 minutes and available 1.5 hours past and future forecast.
110212
This sample uses the open source <a href="https://github.com/Azure-Samples/azure-maps-animations" target="_blank">Azure Maps Animation module</a>
111213
</fieldset>
112214
</body>

0 commit comments

Comments
 (0)