Search code examples
c#kendo-ui

How to force a tile layer in Kendo UI Map to reload its tiles?


I have a web application that displays a geographic map using Kendo UI Map, with 2 other layers displaying geofences and markers (bubbles). The tiles are typically supplied by Google, although other sources like OSM are also possible. I would like to have the possibility to temporarily (say 15 minutes) display traffic density too. To my best knowledge it is not possible to retrieve traffic density data from Google as separate data, but it IS possible to have the normal google tiles rendered with the traffic data on top of it.

That works. Unfortunately, if the user does not zoom or pan the map, the tile layer will be static, so after a short while the traffic data will be outdated. So I want to be able to periodically update the tiles.

I thought that I just have to change the URL of the bottom layer of my map (the layer with the geographic tiles) and voila. But alas, it appears to be not that simple. I jumped through hoops to get it working, asked ChatGPT for assistance (utterly useless), but to no avail.

The javascript function that should cause the tile layer to reload looks like this:

var baseUrl = "foo";

function refreshTrafficLayer(jsMapSelector) {

    var kMap = $(jsMapSelector).data("kendoMap");
    if (kMap) {
        if (trafficLayerEnabled) {

            var currentLayers = kMap.options.layers;
            var trafficLayer = kMap.layers[TRAFFICLAYER];

            // load the initial url that was supplied at construction time
            if (baseUrl == "foo") {
                baseUrl = trafficLayer.options.urlTemplate;
            }

            // force a unique url to avoid caching
            url = baseUrl + "&timestamp=" + new Date().getTime();
            
            // I have tried this:
            trafficLayer.options.urlTemplate = url;

            //and I have tried this:
            var newTileLayer = {
                type: "tile",
                urlTemplate: url
            };
            currentLayers[TRAFFICLAYER] = newTileLayer;
            
            // And tried several other variations on creating a new
            // layer and inserting it into the map, but none works

            // Set the updated layers options to the map
            kMap.setOptions({
                layers: currentLayers
            });

            // with or without this doesn't make any difference
            kMap.trigger("reset");
        }
    }
}

I have also searched the internet to find anything about reloading tiles within Kendo UI Map, but found nothing. How can I force that tile layer to reload?

Note: I understand that a workaround is to reload the entire page, which will cause a new map to be generated. However I would like to avoid that since the map is not the only thing that is displayed on the page, and reloading the entire page would cause a disturbing flicker.

/Edit: It would also be OK if I could force all layers to reload instead of just the tile layer.


Solution

  • It seems that when calling the setOptions the map will reuse the cached images from the initial load. If you have a layer bound to a dataSource, calling dataSource.read() would force the update, but in the current case the only option I can think of is destroying the map and then re-initializing it with the same options.

    let map = $("#map").getKendoMap();
    let options = map.options;
    map.destroy()
    $("#map").kendoMap(options);
    

    If you inspect the network requests in this example the map seems to fetch different tiles when the refresh button is clicked(no tiles are shown, as the endpoint does not expect a timestamp as part of the url, but the important thing is the map is not using the cached tile images).