[GIS] Leaflet- How to use time dimension plugin with image overlay

javascriptleaflet

I am very new at Javascript.

I am trying to create animation with my monthly soil moisture output (.png format) on OpenStreetMap using the Leaflet package. I could use the time slider plugin to move images but I also want a play button that is available in the 'TimeDimension' plugin.

I have 150 images to display. I looked into the demo but I could not understand where to start as a beginner.

Is there any simplified example or instruction of using the plugin?

This is how it looks like

Best Answer

Here's a solution without using the TimeDimension plugin (because this plugin is meant to be used primarily with WMS and GeoJSON, they have an example with ImageOverlay but say that it is just a "proof-of-concept" and I find it overly complicated for the result).

I coded with the following assumptions based on what you sent:

  • All the PNG files are named in the following syntax: month_year.png with only the first 3 letters of the month and a uppercase at the first letter of the month.
  • Your PNG files are stored at the same place as the script. If not, modify the variable urlPrefix

enter image description here

HTML

<div id="map"></div>
<div class="slidecontainer">
      <input type="range" min="1" max="100" value="1" class="slider" id="slider"><label id="sliderLabel"></label>
</div>
<button id="play">Play</button><button id="stop">Stop</button>

JS

var map = L.map('map').setView([22, 78.5], 5, {
    crs: L.CRS.EPSG4326
});

var basemaps = {
    'Topo Map': L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
        crs: L.CRS.EPSG4326
    }),

    'Geo World Map': L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', {
        crs: L.CRS.EPSG4326
    }),

};

L.control.layers(basemaps).addTo(map);

basemaps["Topo Map"].addTo(map);

var bounds = new L.LatLngBounds(
    new L.LatLng(40, 59),
    new L.LatLng(4, 98));
map.fitBounds(bounds);



var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']

// add all your years here (e.g. [1982,1983,1984,1985])
var years = [1982]

//storing all possible times
var timeValues = []
for(var i in years){
    for(var y in months){
        timeValues.push(months[y]+"_"+years[i])
    }
}

//setting max value of the slider
document.getElementById("slider").max = ""+timeValues.length+"";

//setting default label of the slider
document.getElementById("sliderLabel").innerHTML = timeValues[0]

//change the prefix of the url if your images are not in the same folder as your script
var urlPrefix = ""

var url = urlPrefix+timeValues[0]+".png"

var imageOverlay = new L.ImageOverlay(url, bounds, {
    opacity: 0.7,
    interactive: false,

}).addTo(map);


//function when sliding
slider.oninput = function() {
  //changing the label
  document.getElementById("sliderLabel").innerHTML = timeValues[this.value-1]
  //setting the url of the overlay
  imageOverlay.setUrl(urlPrefix+timeValues[this.value-1]+".png")
}

var playTimeOut;

function play() {
    playTimeOut = setTimeout(function () {
        //increasing the slider by 1 (if not already at the end)
        var val = document.getElementById("slider").value
        console.log(val)
        //if end of slider, stopping
        if(val == document.getElementById("slider").max){
            clearTimeout(playTimeOut);
              //hidding the stop button
              document.getElementById('stop').style.display = "none";
              //showing the play button
              document.getElementById('play').style.display = "block";
        }
        else{
        document.getElementById("slider").value = Number(val)+1
        play()
        }
        //changing the label
        document.getElementById("sliderLabel").innerHTML = timeValues[Number(val)-1]
        //setting the url of the overlay
        imageOverlay.setUrl(urlPrefix+timeValues[Number(val)-1]+".png")

    }, 1000);
}

document.getElementById('play').onclick = function(e){
  play()
  //showing the stop button
  document.getElementById('stop').style.display = "block";
  //hidding the play button
  document.getElementById('play').style.display = "none";
}

document.getElementById('stop').onclick = function(e){
  clearTimeout(playTimeOut);
  //hidding the stop button
  document.getElementById('stop').style.display = "none";
  //showing the play button
  document.getElementById('play').style.display = "block";
}

//hidding the stop button by default
document.getElementById('stop').style.display = "none";