使用实时数据更新热图

时间:2012-11-17 19:40:22

标签: javascript google-maps jquery websocket

我正在使用websockets将数据从服务器发送到客户端。这样可以正常工作,例如我可以显示服务器在收到客户端时发送的消息。 我能把它转换成经度和纬度。

因此,当数据从服务器收到时,它应该在我的html中绘制到地图上,但它似乎没有绘制任何内容。

我是javascript的新手,所以不确定我的代码是否正确。我想要理想的做法是很快收到数据,将其直接绘制在地图上,从而生成热图。这是代码的javascript端:

<script>
    $(document).ready(function() {
        var ws = new WebSocket("ws://" + "localhost" + ":" + "8888" + "/ws");
        var London = new google.maps.LatLng(51.507335, -0.127683);

    var map = new google.maps.Map(document.getElementById('map_canvas'), {
        center: London,
        zoom: 3,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var pointArray = new google.map.MVCArray([]);           
    ws.onmessage = function(evt){  
            //$("#display").append(evt.data + "<br />");

            var msg = JSON.parse(evt.data);
            var coordinates = msg.coordinates.coordinates;
            var latLng = new google.maps.LatLng(coordinates[1], coordinates[0]);
            console.log('received');
            pointArray.push(latLng);
            var heatmap = new google.maps.visualization.HeatmapLayer({
                data: pointArray
            });
            heatmap.setMap(map);

            //$("#display").append(latLng + "<br />");

            //console.log(evt.data);

    };

    ws.onclose = function(evt) {alert("Server connection terminated");};
   });      
    $("#open").click(function(evt){
    evt.preventDefault();
    $.post("/", $("#eventForm").serialize());   

});

</script>

是否有办法让收到的数据被存储到一个数组中,但是我不知道如何在收到数据的情况下用数组中的元素更新地图。 感谢

1 个答案:

答案 0 :(得分:2)

我不能确定这是否是唯一的问题,但你似乎在这里有一个范围问题 -

ws.onmessage = function (evt) {
    var msg = JSON.parse(evt.data);
    var coordinates = msg.coordinates.coordinates;
    var latLng = new google.maps.LatLng(coordinates[1], coordinates[0]);
};
...
var heatmap = new google.maps.visualization.HeatmapLayer({
    data: latLng
});

范围在javascript中的工作方式是latLng仅对声明的函数中的代码可用。解决这个问题的一个简单方法就是在它们共享的范围内声明它 -

var latLng;
ws.onmessage = function (evt) {
    var msg = JSON.parse(evt.data);
    var coordinates = msg.coordinates.coordinates;
    latLng = new google.maps.LatLng(coordinates[1], coordinates[0]);
};
...
var heatmap = new google.maps.visualization.HeatmapLayer({
    data: latLng
});

这将使clickLng中的代码的其他部分可以访问latLng。

其他一些可能的问题:

如果您想逐步将数据添加到地图中,那么您的结构通常有点偏差。您要做的是创建一个位于网页内的地图,然后不断向其添加数据 - 每次都不需要创建新地图。您可能应该做的是在ready函数内创建映射,而不是单击。

此外,Google地图中还有一个热图图层;如果为每个接收数据位创建新的热图,您将覆盖已放入之前热图的所有内容。鉴于您最近的编辑,看起来您已经达成了相同的结论。

我也不太确定你的websocket代码是否像它需要的那样好。 websocket“onmessage”函数不会立即返回结果:相反,它提供了有关如何处理将来任何时候进入的任何数据的说明。因此,如果您想在每次数据进入时更新地图,则无需在点击事件中对websockets执行任何操作。

这会导致代码结构松散 -

$(document).ready(function () {
    var ws = new WebSocket("ws://" + "localhost" + ":" + "8888" + "/ws");
    var London = new google.maps.LatLng(51.507335, -0.127683);

    var map = new google.maps.Map(document.getElementById('map_canvas'), {
        center: London,
        zoom: 3,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    });

    var pointArray = new google.map.MVCArray([]);
    ws.onmessage = function (evt) {
        var msg = JSON.parse(evt.data);
        var coordinates = msg.coordinates.coordinates;
        pointArray.push(new google.maps.LatLng(coordinates[1], coordinates[0]));
        var heatmap = new google.maps.visualization.HeatmapLayer({
            data: pointArray
        });
        heatmap.setMap(map);
    };

    $("#open").click(function (evt) {
        // whatever code you want click to do
    });
});

我无法测试任何此代码,因为我没有您的特定websocket设置,但希望这为您提供了更好的基础,从这里开始。