'Loop through TileLayers with Leaflet
I'm building a webpage with Leaflet and Iowa State's NEXRAD data. The purpose of this webpage is to be able to input a radar station, and it will give you the current radar imagery for that station. You can see my current code in action by inputting a station such as KLWX, KMHX, or KLNX - to name a few:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.6.0/leaflet.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.6.0/leaflet.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<style>
#map {
width: 500px;
height: 500px;
position: absolute;
z-index: 500;
text-align: center;
left: 50%;
border-style: solid;
border-width: 2px;
border-color: black;
border-radius: 50%;
margin-left: -250px; /* Half of the width */
}
</style>
</head>
<body>
<div id="weathermap"></div>
<div style="float: left">
<form>
<b><label for="radstatzipList">Input Radar Station:</b> (e.g. KLNX)</label>
<br>
<input name="radstatzipList" id="radstatzipList">
<br>
<button id="radstatzipSubmit">Ok</button>
</form>
<div><b>Zip: <a id="radstatzip"></a></b></div>
<div><b>Coords: </b><a id="radstatcoords"></a></div>
</div>
<div style="float: right">
<a>Opacity</a>
<br>
<input id="opacitySlider" type="range" min="0" max="1" step="0.1" value="1">
<br>
<a>Zoom</a>
<br>
<input id="zoomSlider" type="range" min="5" max="20" step="1" value="7">
</div>
<script>
function setView(lat, lon, zoom, opac) {
document.getElementById('weathermap').innerHTML = "<div id='map' style='top: 135px;'></div>";
var map =
L.map('map',{
attributionControl: false, // Disable the autogenerated attribution
}).setView([lat, lon], zoom);
var osmLayer =
L.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
var nexradLayer =
L.tileLayer.wms("https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0q.cgi", {
layers: 'nexrad-n0q-900913',
format: 'image/png',
transparent: true,
attribution: "Weather data © 2012 IEM Nexrad"
}).addTo(map);
$('#zoomSlider').val(zoom);
nexradLayer.setOpacity(opac);
$('#opacitySlider').val(opac);
var opacitySlider = document.querySelector("#opacitySlider");
opacitySlider.addEventListener("input", function() {
nexradLayer.setOpacity(this.value);
});
var zoomSlider = document.querySelector("#zoomSlider");
zoomSlider.addEventListener("input", function() {
map.setZoom(this.value);
setTimeout(() => { map.setZoom(this.value) }, "200")
//map.setZoom(this.value);
});
}
// code to get the zip code from a radar station
var radstatzipSubmitBtn = document.getElementById('radstatzipSubmit');
radstatzipSubmitBtn.addEventListener('click', function handleClick() {
event.preventDefault();
var radstat = document.querySelector('[name="radstatzipList"]').value;
radstat = radstat.toUpperCase();
$.getJSON('https://steepatticstairs.github.io/weather/json/radarStations.json', function(data) {
var zippy = data[radstat][0];
var lati = data[radstat][1];
var longi = data[radstat][2];
//console.log(radstat + ": " + lati + ", " + longi);
document.getElementById('radstatcoords').innerHTML = radstat + ": " + lati + ", " + longi;
document.getElementById('radstatzip').innerHTML = zippy;
setView(lati, longi, 7, 1);
});
});
</script>
</body>
</html>
What this code will do is take the inputted radar station, get the latitude and longitude from a JSON file, and set the leaflet map view to reflect the inputted station. It will also get current radar imagery from Iowa State as mentioned above, and add it as a WMS TileLayer.
When I add the radar imagery, I provide these options:
var nexradLayer =
L.tileLayer.wms("https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0q.cgi", {
layers: 'nexrad-n0q-900913',
format: 'image/png',
transparent: true,
attribution: "Weather data © 2012 IEM Nexrad"
}).addTo(map);
and this will give me the current radar imagery.
HOWEVER, if I change the layers parameter to add something to the end of nexrad-n0q-900913, it will give me a layer for a different time. For example, if I put -m05m at the end of the string (nexrad-n0q-900913-m05m), it will give me radar data that is 5 minutes old. Similarly, -m20m will give me 20 minute old data, -m35m is 35 minutes old, and so on - all the way up to -m50m (50 minutes old), which is the farthest back it will go.
So my question is this: How can I loop through all of those timestamps, while using the WMS TileLayer?
I have tried putting the code that initializes the radar layer into a function with a parameter and passing the timestamp later, like so:
function initLayer(timestamp) {
var nexradLayer =
L.tileLayer.wms("https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0q.cgi", {
layers: `nexrad-n0q-900913${timestamp}`,
format: 'image/png',
transparent: true,
attribution: "Weather data © 2012 IEM Nexrad"
}).addTo(map);
}
//initializing like
initLayer(-m05m);
but I cannot reliably loop through each at a consistent interval, and further so, using a function in this way will reload the entire map, when I want to only reload the layer.
Any help is appreciated, I am truly stuck on this. Feel free to ask any clarifying questions.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
