0
votes

I'm using the Google Maps JavaScript API to display weather from a tile server. The tile server is available here: http://mesonet.agron.iastate.edu/ogc/

I'm displaying that tile server using an ImageMapType and adding it to the Google Map's overlayMapTypes:

<!DOCTYPE html>
<html>
    <head>
        <title>Map Test</title>
        <style type="text/css">
            html, body { height: 100%; margin: 0; padding: 0; }
            #map {
                width:90%;
                height: 90%;
                display:inline-block;
            }
        </style>
    </head>
<body>
<div id="map"></div>
<script type="text/javascript">

    var map;

    function initMap() {

        var mapOptions = {
            zoom: 8,
            center: new google.maps.LatLng(42.5, -95.5),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        map = new google.maps.Map(document.getElementById('map'), mapOptions);


        var 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
        });

        map.overlayMapTypes.setAt("0",tileNEX);

        setInterval(function (){console.log("resize"); google.maps.event.trigger(map, 'resize');}, 60000);
    }
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap">
</script>
</body>
</html>

This works fine (copy that into index.html and open it up with your browser to see), but now I want to refresh that weather overlay every X minutes.

The tile server shows current weather data, and that weather data is updated every 5 minutes. I'd like my weather data to automatically refresh to always show the current weather.

I've tried calling google.maps.event.trigger(map, 'resize'); to tell the map to repaint itself (look at the last line in my JavaScript), but that doesn't actually re-fetch the tiles- it just repaints the tiles it has already fetched.

I can remove the layer, recreate it, and then add it again, but that results in an annoying second when no weather is displayed.

My next idea is to create another weather layer in the background, then fade from the first layer to the second one, but that seems like overkill.

Isn't there a simple ImageMapType.refetchTiles() function?

1

1 Answers

2
votes

The problem is that triggering the resize-event doesn't force the loading of new tiles.(when you take a look at the network you will see that nothing will be loaded)

Changing the zoom will load new tiles:

function initMap() {

    var mapOptions = {
        zoom: 8,
        center: new google.maps.LatLng(42.5, -95.5),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(document.getElementById('map'), mapOptions);


    var tileNEX = new google.maps.ImageMapType({
        getTileUrl: function(tile, zoom) {
            //return if zoom is not an integer
            if(zoom%1)return null;

            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
    });

    map.overlayMapTypes.setAt("0",tileNEX);

    setInterval(function (){
      //this will change the zoom of the map  
      map.setZoom(map.getZoom()+.000000000000001);
      //this will change the zoom again and load fresh tiles
      map.setZoom(Math.round(map.getZoom()));

      }, 60000);
}

But, no matter what you try, this: that results in an annoying second when no weather is displayed will always be your problem, because it takes some time to load the tiles.