3

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

2
  • If you use PNG overlays then the best exemple would be this one : apps.socib.es/Leaflet.TimeDimension/examples/example10.html . Are the PNG locally on your computer or online ? If they are online and open, can you share a fiddle of your code ?
    – Léo M
    Oct 7, 2019 at 13:34
  • @ Léo M Thanks for your quick reply! I looked into this example but could not really understand how to adapt it to my work. The PNGs are not available online. I have uploaded 5 files along with the code in this link drive.google.com/drive/folders/….
    – Toraha
    Oct 7, 2019 at 14:38

1 Answer 1

1

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";
5
  • It looks like the statement var slider = document.getElementById('slider'); is missing before slider.oninput call.
    – TomazicM
    Oct 7, 2019 at 19:36
  • 1
    Looks like it is not needed, the code works without, as well as this example: jsfiddle.net/k39ne8r4 (but I'm a bit surprised it does actually ...)
    – Léo M
    Oct 7, 2019 at 19:45
  • Each day one can learn something new :-)
    – TomazicM
    Oct 7, 2019 at 20:08
  • Indeed :) That's strange, even a slider.max = 10 works to set the maximum ... I always used Jquery or getElementById() for those, never realized it could work without (not in all cases though I suppose).
    – Léo M
    Oct 7, 2019 at 20:42
  • Thank you so much @LéoM!! It works. I really appreciate your time and effort.
    – Toraha
    Oct 8, 2019 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.