【问题标题】:How to update multiple marker location simultaneously using JSON data? Leaflet JS如何使用 JSON 数据同时更新多个标记位置?传单 JS
【发布时间】:2015-12-20 07:39:39
【问题描述】:

我正在使用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 循环更新标记的移动。我不想每次获得位置更新时都使用清除图层功能添加新标记,因为我需要保存每个设备的移动历史以供以后使用。我应该怎么做才能让它工作?任何建议将不胜感激。

这是我的代码。 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);

【问题讨论】:

  • 嗯,有什么问题吗?您的第二个循环不起作用?拨打markerMove[j].setLatLng(newLatLng).update(); 不起作用?我看到在您的第二个循环中,您初始化了j=0,条件是您使用i,但j 变量永远不会更新。
  • @xxxmatko,感谢您的指正。我编辑了代码。是的,markerMove[j].setLatLng(newLatLng).update(); 没有给我任何结果。我做错了吗?需要你的帮助。

标签: javascript json dictionary leaflet


【解决方案1】:

我在调用setLatLng 方法时没有看到任何错误,但我想,有一个错误

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

当你想创建新的长纬度对象时,你应该调用new L.LatLng()(带有大 L 字母)或只是L.latLng(),这是一个快捷方法,它最后调用new L.LatLong()。检查您的属性 newLatLng 是否是正确的对象。

【讨论】:

  • 感谢您的帮助。是的,我已经更正了它,但仍然没有给我任何结果。然后,我尝试用更简单的代码来捕获错误,它说“markerMove[j] 未定义”。我不明白为什么它是未定义的。或者也许我以错误的方式使用数组?
  • 你能通过更正的代码吗?你的markermarkerMove 是在哪里定义的?
  • 这是我用来检查错误的更简单的代码:link。请检查一下。谢谢。
【解决方案2】:

您可以使用一个对象来存储标记,其 id 作为属性名,标记作为属性值。这将使事情变得容易得多。要存储以前的位置,您可以向每个标记添加一个数组来存储它们。这里用cmets的代码来解释一下:

// 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

【讨论】:

  • 非常感谢!真漂亮!我没想到工作可以用object来完成,你赐教!是的,也许使用数组来完成这项工作是一个坏主意,因为我不断收到未定义的数组错误。这让我很沮丧,因为没有教程或示例可以使用对象来完成这项工作。我会尝试在我的代码中应用它。谢谢!你救了我!
  • 不,谢谢,我们随时欢迎您。数组对象只是一个花哨的对象,它跟踪它的长度并具有一些额外的功能,例如 forEach 方法来循环它的属性等等。请参阅:MDN Array 普通对象可以将字符串作为键,而数组不能。所以在这种情况下,它就派上用场了。当使用数组并且你想找到一个标记时,你需要这样做:markers.forEach(function(marker){if (marker.id == obj.id) {//found}}) 但现在你可以简单地这样做:markers[obj.id]
  • 刚刚记得有一个不错的插件,添加到我的答案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多