schn0573 schn0573 - 3 months ago 52
Javascript Question

Weather radar loop on Google Maps API 3

I am trying to implement a looping radar animation on a google map. This site: http://mesonet.agron.iastate.edu/ogc/ provides radar images from the current time to 60 minutes ago.

Currently, I am loading these images and using a timer to add/remove each image to the map. This technically works, but the result is very choppy. There is noticable time where there is no radar image visable on the map. Lowering the timeout, only worsens the effect because the radar image does not have enough time to load before it is removed.

Are there any techniques to smooth out the animation? Or am I going about this all wrong?

Code

var map;
var imageArray = [];
function initialize() {
var mapOptions = {
zoom: 5,
center: new google.maps.LatLng(42.5, -95.5),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

//Load Images and add them to imageArray
tileNEX = new google.maps.ImageMapType({
getTileUrl: function(tile, zoom) {
return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime();
},
tileSize: new google.maps.Size(256, 256),
opacity:0.60,
name : 'NEXRAD',
isPng: true,
});
imageArray.push(tileNEX);

tileNEX5 = new google.maps.ImageMapType({
getTileUrl: function(tile, zoom) {
return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m05m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime();
},
tileSize: new google.maps.Size(256, 256),
opacity:0.60,
name : 'NEXRAD5',
isPng: true,
});
imageArray.push(tileNEX5);

tileNEX10 = new google.maps.ImageMapType({
getTileUrl: function(tile, zoom) {
return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m10m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime();
},
tileSize: new google.maps.Size(256, 256),
opacity:0.60,
name : 'NEXRAD10',
isPng: true,
optimized: false
});
imageArray.push(tileNEX10);

tileNEX15 = new google.maps.ImageMapType({
getTileUrl: function(tile, zoom) {
return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m15m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime();
},
tileSize: new google.maps.Size(256, 256),
opacity:0.60,
name : 'NEXRAD15',
isPng: true,
});
imageArray.push(tileNEX15);

tileNEX20 = new google.maps.ImageMapType({
getTileUrl: function(tile, zoom) {
return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m20m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime();
},
tileSize: new google.maps.Size(256, 256),
opacity:0.60,
name : 'NEXRAD20',
isPng: true,
});
imageArray.push(tileNEX20);


animateRadar(imageArray);


}

google.maps.event.addDomListener(window, 'load', initialize);

function animateRadar(images) {
map.overlayMapTypes.push(images[0]);//Add first image
var index = 0;
window.setInterval(function(){
map.overlayMapTypes.pop();//Remove previous image
index++;
if(index >= images.length){
index = 0;
}

map.overlayMapTypes.push(images[index]);//Add new image
}, 1000);
}

Answer

In hopes that this helps someone else, below is how I ended up solving the problem. Instead of adding/removing overlay images, I simply altered the opacity. This gave me a much smoother animation. The below example will cycle through the last 30 minutes of radar images.

  var map;

  function initialize() {
    var mapOptions = {
      zoom: 5,
      center: new google.maps.LatLng(42.5, -95.5),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

    //Load Images and add them to imageArray
    tileNEX = new google.maps.ImageMapType({
        getTileUrl: function(tile, zoom) {
            return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime(); 
        },
        tileSize: new google.maps.Size(256, 256),
        opacity:0.00,
        name : 'NEXRAD',
        isPng: true,
    });
    map.overlayMapTypes.push(tileNEX);

    tileNEX5 = new google.maps.ImageMapType({
        getTileUrl: function(tile, zoom) {
            return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m05m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime(); 
        },
        tileSize: new google.maps.Size(256, 256),
        opacity:0.00,
        name : 'NEXRAD5',
        isPng: true,
    });
    map.overlayMapTypes.push(tileNEX5);

    tileNEX10 = new google.maps.ImageMapType({
        getTileUrl: function(tile, zoom) {
            return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m10m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime(); 
        },
        tileSize: new google.maps.Size(256, 256),
        opacity:0.00,
        name : 'NEXRAD10',
        isPng: true,
        optimized: false
    });
    map.overlayMapTypes.push(tileNEX10);

    tileNEX15 = new google.maps.ImageMapType({
        getTileUrl: function(tile, zoom) {
            return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m15m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime(); 
        },
        tileSize: new google.maps.Size(256, 256),
        opacity:0.00,
        name : 'NEXRAD15',
        isPng: true,
    });
    map.overlayMapTypes.push(tileNEX15);

    tileNEX20 = new google.maps.ImageMapType({
        getTileUrl: function(tile, zoom) {
            return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m20m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime(); 
        },
        tileSize: new google.maps.Size(256, 256),
        opacity:0.00,
        name : 'NEXRAD20',
        isPng: true,
    });
    map.overlayMapTypes.push(tileNEX20);

    tileNEX25 = new google.maps.ImageMapType({
        getTileUrl: function(tile, zoom) {
            return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m25m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime(); 
        },
        tileSize: new google.maps.Size(256, 256),
        opacity:0.00,
        name : 'NEXRAD25',
        isPng: true,
    });
    map.overlayMapTypes.push(tileNEX25);

    tileNEX30 = new google.maps.ImageMapType({
        getTileUrl: function(tile, zoom) {
            return "http://mesonet.agron.iastate.edu/cache/tile.py/1.0.0/nexrad-n0q-900913-m30m/" + zoom + "/" + tile.x + "/" + tile.y +".png?"+ (new Date()).getTime(); 
        },
        tileSize: new google.maps.Size(256, 256),
        opacity:0.00,
        name : 'NEXRAD30',
        isPng: true,
    });
    map.overlayMapTypes.push(tileNEX30);

    animateRadar();


  }

  google.maps.event.addDomListener(window, 'load', initialize);

  function animateRadar() {
    var index = map.overlayMapTypes.getLength() - 1;

    window.setInterval(function(){

        map.overlayMapTypes.getAt(index).setOpacity(0.00);

        index--;
        if(index < 0){
            index = map.overlayMapTypes.getLength() - 1;
        }
        map.overlayMapTypes.getAt(index).setOpacity(0.60);
    }, 400);
  }

}

Comments