设置StreetViewPanorama的两个属性会导致竞争条件?

时间:2016-03-02 04:16:55

标签: javascript google-maps-api-3 google-street-view

我使用街景视图的javascript api打开特定位置的视图。我希望观众既可以在某一点上,又面向某个方向,所以我有这个电话(如documentation所示):

panorama.setOptions({
    pano: data.location.pano,
    pov: mypov
});

我认为通过实现这两个选项获取的图像必须是交错的,或者是某种东西,因为大约一半的时间屏幕会结束多个图像的拼接:

Jumbled image made up of random tiles from the same location

当我评论setPov时,视图当然面向错误的方向,但重叠的图像拼贴问题已经消失。此外,只要用户开始拖动鼠标,街道视图就会在正确的图像图块上稳定下来并丢弃不正确的图像图块。

有什么方法可以阻止这种情况吗?或者是否有"所有图像都已加载"事件我可以听,然后触发拖动事件或什么?

修改:这是一个jsfiddle演示:http://jsfiddle.net/p244m3qp/11/ 在我的浏览器中,如果我延长"结果"窗格尽可能大,它显示"马赛克"行为约占动画帧的1/3到1/2。

2 个答案:

答案 0 :(得分:0)

我想出了如何防止你的错误。 I am Getting Below error,How can i solve??

关键是在后台预加载街景。

首先,您需要创建两个全景div。

<script src="http://maps.googleapis.com/maps/api/js?language=en"></script>
<div id="err"></div>
<div id="pv-container">
  <div id="backscreen"></div>
  <div id="map-canvas"></div>
</div>

&lt; div id =“map-canvas”/&gt;重叠&lt; div id =“backscreen”/&gt;完全用CSS。

#pv-container {
  position: relative;
  height: 500px;
  width: 100%;
}
#map-canvas {
  border: solid thick #ccc;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
}
#backscreen {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  border: solid thick red;
}

您需要先更改背景的全景位置(全景和平移),然后设置为地图 - 画布div。 那时,您需要更改背景的标题(或可能是音高)。 这会在Google Maps API中生成缓存图片(我猜)。

function initialize() {
  var loc = {
      lat: 38.9002138,
      lng: -77.0364319
    },
    pov = {
      heading: 180,
      pitch: -5
    },
    svService = new google.maps.StreetViewService(),
    panorama = new google.maps.StreetViewPanorama(
            document.getElementById('map-canvas')),
    backscreen = new google.maps.StreetViewPanorama(
            document.getElementById('backscreen')),
    counter = 0;

  function updatePano(data, status) {
    if (status === google.maps.StreetViewStatus.OK) {
        var opts = {
        pano: data.location.pano,
        pov: {heading: pov.heading + 120 * (counter % 3), pitch: pov.pitch}
      };
      backscreen.setOptions(opts);
      backscreen.changed = function(key) {
        if (key === 'status' && backscreen.get('status') === 'OK') {
          var opts2 = Object.create(opts);
          opts2.heading += 5;
            backscreen.setOptions(opts2);
          setTimeout(function() {
                panorama.setOptions(opts);
          }, 100);

        }
      }
    } else {
      document.getElementById('err').textContent = "Failed to get panorama";
    }
    counter = (counter + 1) % 15;
  }

  setInterval(function() {
    svService.getPanorama({
      location: {
        lat: loc.lat + (counter * 0.0001),
        lng: loc.lng
      },
      radius: 35
    }, updatePano);
  }, 3000);

}

initialize();

http://jsfiddle.net/wf9a5m75/p244m3qp/31/

您可能对后台div中发生的事情感兴趣。 这里是: enter image description here

答案 1 :(得分:0)

来自@ wf9a5m75的答案并不适合我,但它让我朝着正确的方向前进,最终在Chrome中工作:我取代了单一电话

panorama.setOptions({
    pano: data.location.pano,
    pov: mypov
});

有两个被强制为串行的调用:

panorama.setPano(pano);
panorama.changed = function(key) {
    if (key === 'status') {
        // Just listen once!
        panorama.changed = function() {};
        panorama.setPov(mypov);
   }
};

所以加载需要两倍的时间,但至少它看起来并不可怕......

编辑:看起来像是known bug - 似乎你可以减少竞争条件,但不能真正阻止它。 :(