如何使用JSON数据同时更新多个标记位置?宣传单JS

时间:2015-09-23 05:49:51

标签: javascript json dictionary leaflet

我正在使用Leaflet JS构建一个可以跟踪多个设备移动的交互式地图查看器。我正在使用JSON数据为每个标记设置纬度和经度。

JSON数据如下所示:

{"BMS":[{"id":"PR01","type":"prajurit","lat":"-6.248008","long":"107.004158"},{"id":"PR02","type":"prajurit","lat":"-6.224084","long":"106.653069"},{"id":"PR03","type":"kendaraan","lat":"-6.244316","long":"106.649734"}]}

数据包含3个设备的位置信息。

我已经成功设置了基于具有for循环的设备的纬度和经度的标记。但我无法使用setLatLngfor循环更新标记的移动。每次获得位置更新时,我都不想使用clear layer函数添加新标记,因为我需要保存每个设备的移动历史记录以供日后使用。我该怎么做才能让它发挥作用?任何建议将不胜感激。

这是我的代码。 setInterval旨在持续运行代码。我尝试使用数组变量作为标记变量,并标记每个标记(因为使用windows [variable_name]是不好的做法)。

window.setInterval(function(){

    ++z;
    //alert(z);

    function doSomething(data){
        jsonBmsData = JSON.parse(data);

    }

    $.get('get_jsondata.php', doSomething);

    if(z == 1){

        for(var i=0; i<jsonBmsData.BMS.length; ++i){

            marker[i][0] = jsonBmsData.BMS[i].id;
            marker[i][1] = jsonBmsData.BMS[i].type;
            marker[i][2] = jsonBmsData.BMS[i].lat;
            marker[i][3] = jsonBmsData.BMS[i].long;

            markerMove[i] = L.marker([marker[i][2],marker[i][3]])
            .bindPopup('ID Prajurit = ' + marker[i][0] + '<br>Tipe = ' + marker[i][1]
            + '<br>Lat = ' + [marker[i][2] + '<br>Long = ' + marker[i][3])
            .addTo(map);

        }

    } else if(z > 1){

        for(var j=0; j<jsonBmsData.BMS.length; ++j){

            marker[j][0] = jsonBmsData.BMS[j].id;
            marker[j][1] = jsonBmsData.BMS[j].type;
            marker[j][2] = jsonBmsData.BMS[j].lat;
            marker[j][3] = jsonBmsData.BMS[j].long;

            var newLatLng = new L.latLng(marker[j][2],marker[j][3]);

            markerMove[j].setLatLng(newLatLng).update();
            markerMove[j]._popup.setContent('ID Prajurit = ' + marker[j][0] + '<br>Tipe = ' + marker[j][1]
            + '<br>Lat = ' + [marker[j][2] + '<br>Long = ' + marker[j][3]);

        }

    }

},50);

2 个答案:

答案 0 :(得分:3)

您可以使用对象存储标记,其标识为propertyname,标记为属性值。它会让事情变得更容易。要存储先前的位置,您可以为每个标记添加一个数组以存储它们。这里的代码中有注释来解释:

// The object to store markers
var markers = {};

// Function for setting/updating markers
function setMarkers(data) {

  // Loop over the BMS array and handle each object
  data.BMS.forEach(function (obj) {

    // Check if there is already a marker with that id in the markers object
    if (!markers.hasOwnProperty(obj.id)) {
      // No marker with that id found in the markers object

      // Create it, and add it to the map, store into markers object
      markers[obj.id] = new L.Marker([obj.lat, obj.long]).addTo(map);

      // Add array to the marker instance to store the previous latlngs
      markers[obj.id].previousLatLngs = [];

    } else {
      // There is already a marker with that id in the markers object

      // Store the previous latlng
      markers[obj.id].previousLatLngs.push(markers[obj.id].getLatLng());

      // Set new latlng on marker
      markers[obj.id].setLatLng([obj.lat, obj.long]);
    }
  });
}

这是关于Plunker的一个有效例子; http://plnkr.co/edit/HrrnXh?p=preview

Leaflet有一个很酷的插件,名为Realtime。它确实符合您的要求和更多,但它期望GeoJSON集合作为数据,因此它不适用于您的数据集。如果您能够将数据转换为GeoJSON集合,那么值得一看:

GeoJSON:http://geojson.org/

演示:http://www.liedman.net/leaflet-realtime/

回购:https://github.com/perliedman/leaflet-realtime

答案 1 :(得分:0)

我在调用setLatLng方法时没有看到任何错误,但我认为,

中存在错误
var newLatLng = new L.latLng(marker[j][2],marker[j][3]); 

当您想要创建新的长lat对象时,您应该调用new L.LatLng()(带有大L字母)或L.latLng()这是同一个快捷方法,并调用new L.LatLong() in结束。检查您的财产newLatLng是否是正确的对象。