【问题标题】:speed up update of a heat map加快热图的更新
【发布时间】:2014-06-02 00:24:11
【问题描述】:

我有几组相对较大的数据(大约 86.000 个纬度和经度点)显示不同年份的全球温度分布。我用热图表示这些数据,为此我使用谷歌地图库。我的目标是显示/动画化一系列 X 年的全球温度变化。因此,对于每个选定的年份,我需要更改/更新一个新的热图,以显示该年的全球温度分布。我设法编写了一个代码,通过滚动范围栏或按下前进/后退按钮来更新热图。我面临的问题是,更新需要很长时间(大约 3-4 秒)。那么,我的问题是,有什么办法可以加快更新速度?

这是我为更新热图所做的: 首先,我的数据是一个数组(长度为 86.000),其中每个元素具有以下值:纬度、经度、x1 年温度、x2 年温度、...、xn 年温度。 所以,每年的经纬度坐标都是固定的。

这是我初始化热图的代码:

var map, heatmap, heatmapData;

function initialize() {
    heatmapData = new google.maps.MVCArray();
    var mapOptions = {
            zoom: 2,
            center: new google.maps.LatLng(5,45),
            mapTypeId: google.maps.MapTypeId.TERRAIN
    };

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

    //Take data of 1st year
    for (var i = 1; i < data.length; i+=1) {
            var latLng = new google.maps.LatLng(data[i][2], data[i][1]);
            var temperature = data[i][3]
            var weightedLoc = {
                    location: latLng,
                    weight:temperature
            };
            heatmapData.push(weightedLoc);
    };

    heatmap = new google.maps.visualization.HeatmapLayer({
            data: heatmapData,
            dissipating: false,
            map: map,
            opacity: 0.8,
            radius: 1.2
    });

    heatmap.setMap(map);

}

而我的更新函数是这样的:

function update(year){

    var index = year-firstYear+3;

    //just change value of temperature
    heatmapData.forEach(function(elm, i){
        elm.weight=data[i+1][index];
    });

    heatmap.set('data',heatmapData);
}

如何改进此代码以获得更快的性能? 提前谢谢!

【问题讨论】:

    标签: google-maps animation google-maps-api-3 map heatmap


    【解决方案1】:

    渲染热图所消耗的大部分时间实际上是在谷歌地图热图功能上,除非你想构建自己的热图功能,否则你几乎无能为力。

    您可以通过使用简单的 for 循环而不是使用 foreach 来加速更新函数来改进您的代码。

    //just change value of temperature
        heatmapData.forEach(function(elm, i){
            elm.weight=data[i+1][index];
        });
    
    //you could use instead:
      for(var i=0, len=heatmapData.length; i< len; i++) {
          heatmapData[i].weight = data[i+1][index];
      }
    

    看看这里比较不同循环选项的性能:http://jsperf.com/for-vs-foreach/37

    由于您已经在内存中拥有 DATA,因此用少量数组替换一个大数组并处理原始数据数组不会是一个大内存问题。

    var heatbyyear = [];
    for (var j=3 ; j < yearsOfData; j++) {
        heatbyyear.push([]);
    }
    for (var i = 1; i < data.length; i+=1) {
            //Take data of 1st year
            var thisyear = [];
            var latLng = new google.maps.LatLng(data[i][2], data[i][1]);
            var temperature = data[i][3]
            var weightedLoc = {
                    location: latLng,
                    weight:temperature
            };
            heatmapData.push(weightedLoc);
            for (var j=3 ; j < yearsOfData; j++) {
                heatbyyear[j].push(data[i][j]);
            }
    };
    data = null;
    

    然后您只需调用:

    function update(year){
    
        var index = year-firstYear+3;
    
    
        heatmap.set('data',heatbyyear[index]);
    }
    

    【讨论】:

    • 感谢您的回答!但是我怎样才能遍历一个谷歌 MVCArray 并使用一个简单的 for 循环来分配温度值呢?由于它不是一个实际的数组,我无法像普通数组一样访问该元素。 //这会返回“未定义”:heatmapData[i].weight
    猜你喜欢
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 2019-08-31
    相关资源
    最近更新 更多