如何在不重复的情况下更新Google Maps标记位置?

时间:2019-05-22 11:03:32

标签: javascript loops google-maps-api-3 setinterval google-maps-api-2

我每15秒进行一次API调用,并更新循环中的标记位置。它起作用,除了在更新后保留旧标记并在其顶部堆叠一个新标记之外。我无法提出解决此问题的逻辑。我尝试使用布尔值,但没有用。现在,我要检查是否未定义planeIcon,然后初始化一个新标记,如果已定义,则只是.setPosition()。这不会给我任何错误,但是图标要么根本不出现在屏幕上,要么开始堆叠。我做错了什么?

var map, marker1, marker2, myLatlng, icon;
var boo = true;
var planeIcon = [];
function initMap() {
    var infoWindow = new google.maps.InfoWindow();
    // Create a new StyledMapType object, passing it an array of styles,
    // and the name to be displayed on the map type control.
setInterval(
function () {
    axios.get('http://localhost:8888/lsapp/public/planes/')
        .then(function (response) {
            var infowindow = new google.maps.InfoWindow();
            var north = new google.maps.LatLng(90.0000, 0.0000);
            var northPole = new google.maps.Marker({
                position: {lat: 90.0000, lng: 0.0000},
                map: map
            });
            northPole.setIcon({
                path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
                scaledSize: new google.maps.Size(10, 10),
                scale: 6
            });

            for (var i = 0; i < 50; i++) {
                //console.log(response.data["states"][i]);
                console.log(response.data["states"][i]);

                var direction = new google.maps.LatLng(response.data["states"][i][6], response.data["states"][i][5]);
                var heading = google.maps.geometry.spherical.computeHeading(direction, north);

                myLatlng = new google.maps.LatLng(response.data["states"][i][6],response.data["states"][i][5]);
                    icon = {
                        path: "M 356.26958,135.02702 L 356.26958,249.31026 L 296.72689,289.12758 C 298.37366,285.78981 297.94877,282.22185 297.97085,278.70356 L 297.7704,238.6142 L 268.80878,238.44964 L 269.05561,285.18318 C  ",
                        fillColor: '#111111',
                        fillOpacity: 1,
                        scaledSize: new google.maps.Size(0.01, 0.01),
                        rotation: heading + response.data["states"][i][10],
                        scale: 0.02
                    }

                    if(planeIcon.length > 0) {
                        for (var j = 0; j < planeIcon.length; j++)
                        planeIcon[j].setPosition(myLatlng);
                    } else {
                        planeIcon.push(new google.maps.Marker({
                            position: {lat: response.data["states"][i][6], lng: response.data["states"][i][5]},
                            map: map,
                            title: response.data["states"][i][1],
                            icon: icon
                        }));
                    }
                    console.log(planeIcon);

......

有效代码段:https://codepen.io/Limpuls/full/rgpKjy

我创建了一个数组,并将所有新的标记对象推入其中。然后,我检查数组长度是否大于0,然后检查setLocation(),如果没有,则初始化新标记。不幸的是,它只输出一个平面而不是50,并且每15秒不更新一个平面位置,而是放置一个全新的随机平面位置。就像以前的泰国,然后是美国。

Axios每15秒获取一次,您会看到图标堆叠。

1 个答案:

答案 0 :(得分:1)

查看您正在使用的the API,第一个条目是飞机的唯一标识符。

一种选择是制作一个具有唯一ID作为键的标记数组。当有新数据到达时,请通过该唯一ID更新标记。然后,当足够长时间未收到标记的数据时,可以删除陈旧的标记。

  // in the global scope
  var planesArray = [];

  var bounds = map.getBounds();
  for (var i = 0; i < response.data["states"].length; i++) {
    var myLatlng = new google.maps.LatLng(response.data["states"][i][6], response.data["states"][i][5]);
    // limit to the planes currently in view on the map
    if (!bounds.contains(myLatlng))
      continue;
    inBoundCnt++;
    var direction = new google.maps.LatLng(response.data["states"][i][6], response.data["states"][i][5]);
    var heading = google.maps.geometry.spherical.computeHeading(direction, north);
    icon.rotation = heading + response.data["states"][i][10];

    var uniqueId = response.data["states"][i][0];
    // if marker doesn't already exist, make a new one
    if (!planesArray[uniqueId] || !planesArray[uniqueId].setPosition) {
      var planeIcon = new google.maps.Marker({
        position: myLatlng,
        map: map,
        title: response.data["states"][i][1],
        icon: icon,
        uniqueId: uniqueId,
        displayCnt: 0,
        timeStamp: now
      });
      google.maps.event.addListener(planeIcon, 'click', (function(planeIcon, i) {
        return function() {
          infowindow.setContent(response.data["states"][i][0].toLowerCase());
          infowindow.open(map, planeIcon);
          console.log(response.data["states"][i][0].toLowerCase());
        }
      })(planeIcon, i));
      planesArray[uniqueId] = planeIcon;
    } else {
      // if marker already exists, change its position
      planesArray[uniqueId].setPosition(myLatlng);
      planesArray[uniqueId].displayCnt++;
      planesArray[uniqueId].timeStamp = Date.now();
    }
  }

proof of concept fiddle

screenshot of resulting map

代码段:

var map, marker1, marker2, myLatlng, icon;
var boo = true;
var planeIcon;
var planesArray = [];

function initMap() {
  icon.scaledSize = new google.maps.Size(0.01, 0.01);
  var infoWindow = new google.maps.InfoWindow();
  setInterval(
    function() {
      axios.get('https://opensky-network.org/api/states/all')

        .then(function(response) {
          var now = Date.now();
          var infowindow = new google.maps.InfoWindow();
          var north = new google.maps.LatLng(90.0000, 0.0000);
          var northPole = new google.maps.Marker({
            position: {
              lat: 90.0000,
              lng: 0.0000
            },
            map: map
          });
          northPole.setIcon({
            path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
            scaledSize: new google.maps.Size(10, 10),
            scale: 6
          });
          var bounds = map.getBounds();
          console.log("processing " + response.data["states"].length + " entries");
          var inBoundCnt = 0;
          for (var i = 0; i < response.data["states"].length /* && i < 50 */ ; i++) {
            // console.log(i + ":" + response.data["states"][i]);
            var myLatlng = new google.maps.LatLng(response.data["states"][i][6], response.data["states"][i][5]);
            if (!bounds.contains(myLatlng))
              continue;
            inBoundCnt++;
            var direction = new google.maps.LatLng(response.data["states"][i][6], response.data["states"][i][5]);
            var heading = google.maps.geometry.spherical.computeHeading(direction, north);
            icon.rotation = heading + response.data["states"][i][10];

            var uniqueId = response.data["states"][i][0];
            if (!planesArray[uniqueId] || !planesArray[uniqueId].setPosition) {
              var planeIcon = new google.maps.Marker({
                position: myLatlng,
                map: map,
                title: response.data["states"][i][1],
                icon: icon,
                uniqueId: uniqueId,
                displayCnt: 0,
                timeStamp: now
              });
              google.maps.event.addListener(planeIcon, 'click', (function(planeIcon, i) {
                return function() {
                  axios.get('http://localhost:8888/lsapp/public/planes/' + response.data["states"][i][0].toLowerCase())
                    .then(function(res) {
                      div.innerHTML = '';
                      div.innerHTML += "<h5>" + res.data + "</h5>";
                    }).catch(function(error) {
                      // handle error
                      console.log(error);
                    });
                  infowindow.setContent(response.data["states"][i][0].toLowerCase());
                  infowindow.open(map, planeIcon);
                  console.log(response.data["states"][i][0].toLowerCase());
                }
              })(planeIcon, i));
              planesArray[uniqueId] = planeIcon;
            } else {
              // console.log("[" + i + "] moving " + uniqueId + " to " + myLatlng.toUrlValue(6));
              planesArray[uniqueId].setPosition(myLatlng);
              planesArray[uniqueId].displayCnt++;
              planesArray[uniqueId].timeStamp = Date.now();
            }
          }
          console.log("in bounds markers=" + inBoundCnt);
          // remove stale markers
          for (plane in planesArray) {
            var deltaT = now - planesArray[plane].timeStamp;
            // console.log("plane="+plane+" uniqueId="+planesArray[plane].uniqueId+" deltaT="+deltaT);
            if (deltaT > 10000) {
              console.log("removing " + plane + " deltaT=" + deltaT);
              planesArray[plane].setMap(null);
              delete planesArray[plane];
            }
          }
        })
        .catch(function(error) {
          // handle error
          console.log(error);
        })
        .finally(function() {
          // always executed
        });

    }, 10000);
  map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: 40.7127753,
      lng: -74.0059728
    },
    zoom: 8
  });
}
var icon = {
  path: "M 356.26958,135.02702 L 356.26958,249.31026 L 296.72689,289.12758 C 298.37366,285.78981 297.94877,282.22185 297.97085,278.70356 L 297.7704,238.6142 L 268.80878,238.44964 L 269.05561,285.18318 C 269.06227,292.68821 270.04683,297.17053 276.7074,301.30953 L 204.8529,348.4504 C 207.01499,345.12276 206.84863,341.2911 206.84863,337.51874 L 206.77165,295.05645 L 178.71508,294.89191 L 178.6328,342.1191 C 178.84508,349.00225 179.88792,356.28465 186.12004,360.54922 L 30.615857,462.16174 C 3.2664942,481.49054 8.4728732,501.69026 10.293349,521.73054 L 356.26958,404.23849 L 356.26958,582.78033 L 365.64921,648.51992 L 252.92924,731.45549 C 236.829,745.21163 238.89783,759.656 241.98635,773.74604 L 388.44003,735.48708 C 390.1301,775.95885 408.69374,776.66877 411.55996,735.56935 L 558.01364,773.82832 C 561.10216,759.73826 563.17099,745.29391 547.07076,731.53776 L 434.3508,648.6022 L 443.73041,582.86261 L 443.73041,404.32077 L 789.70665,521.73054 C 791.52713,501.6903 796.7335,481.57282 769.38414,462.24402 L 613.87995,360.6315 C 620.11205,356.3669 621.07263,349.08453 621.28491,342.20138 L 621.28491,294.97418 L 593.22834,295.13873 L 593.15851,338.35476 C 593.1282,342.1754 593.2504,345.43211 595.47226,348.97078 L 523.21031,301.39181 C 529.87094,297.25281 530.93773,292.77049 530.94439,285.26546 L 531.19122,238.53192 L 502.22959,238.69647 L 502.02452,278.95408 C 502.0435,282.62018 501.76549,285.90838 503.64551,289.27217 L 443.73041,249.39253 L 443.73041,135.10929 C 429.29576,-9.7066548 372.45267,-10.54689 356.26958,135.02702 z ",
  fillColor: '#111111',
  fillOpacity: 1,
  scale: 0.02
}
html,
body,
#map {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=geometry&callback=initMap"></script>