8

我正在Rails中开发Web应用程序。当我打开一个标记时,一个模式将弹出一个框中的街景。我可以打开一个或两个标记,但在此之后,我收到WebGL遇到的一个错误。我试图在网上寻找资源,但没有任何意义。请参阅下面的图片了解更多信息。任何帮助将不胜感激。重复使用模式中的Google Maps街景

First image with error

second image with error

这里是什么我的控制台日志看起来像一个形象:

console log

这里是我的webapp我的JavaScript代码。

<script type="text/javascript"> 
var handler = Gmaps.build('Google', { 
    markers: { 
     clusterer: { 
      gridSize: 60, 
      maxZoom: 20, 
      styles: [ 
       { 
        textSize: 10, 
        textColor: '#ff0000', 
        url: 'assets/creative/m1.png', 
        height: 60, 
        width: 60, 
       }, 
       { 
        textSize: 14, 
        textColor: '#ffff00', 
        url: 'assets/creative/m2.png', 
        height: 60, 
        width: 60, 
       }, 
       { 
        textSize: 18, 
        textColor: '#0000ff', 
        url: 'assets/creative/m3.png', 
        width: 60, 
        height: 60, 
       }, 
      ], 
     }, 
    }, 
}); 

var handler2 = Gmaps.build('Google'); 
var current; 
function initialize() { 
    handler.buildMap({ internal: {id: 'map'} }, function() { 
     markers_json = <%= raw @hash.to_json %>; 
     markers = _.map(markers_json, function (marker_json) { 
      marker = handler.addMarker(marker_json); 
      handler.fitMapToBounds(); 
      _.extend(marker, marker_json); 
      return marker; 
     }); 

     getLocation(); 

     markers.map(function (elem, index) { 
      google.maps.event.addListener(elem.getServiceObject(), 'click', function (evt) { 
       var id = elem.id, 
        number = elem.number, 
        name = elem.name, 
        zipcode = elem.zipcode, 
        tabid = elem.tabid, 
        latitude = elem.latitude, 
        longitude = elem.longitude; 

       $('.name').html('<h3 class=\'panel-title\'><i class=\'fa fa-id-card\'></i>' + number + '</h3>'); 
       $('.paneltb').html('<thead><tr><th>Panel</th><th>Location</th><th>Tab ID</th><th>Zip Code</th><th>Latitude</th><th>Longitude</th></tr></thead><tbody><tr><td>' + number + '</td><td>' + name + '</td><td>' + tabid + '</td><td>' + zipcode + '</td><td>' + latitude + '</td><td>' + longitude + '</td></tr></tbody>'); 

       pos = new google.maps.LatLng(latitude, longitude); 

       var div = document.getElementById('map2'); 
       var sv = new google.maps.StreetViewPanorama(div); 
       sv.setPosition(pos); 
       sv.setVisible(true); 

       // find the heading by looking from the google car pos to the venue pos 
       var service = new google.maps.StreetViewService(); 
       service.getPanoramaByLocation(pos, 50, function (result, status) { 
        if (status == google.maps.StreetViewStatus.OK) 
        { 
         carPos = result.location.latLng; 
         heading = google.maps.geometry.spherical.computeHeading(carPos, pos); 
         sv.setPov({ heading: heading, pitch: 0, zoom: 1 }); 
        } 
       }); 

       $('#myModal').modal('show'); 
       current = elem; 
      }); 
     }); 
    }); 
    // Create the search box and link it to the UI element. 
} 

function getLocation() { 
    if (navigator.geolocation) { 
     navigator.geolocation.getCurrentPosition(displayOnMap); 
    } else { 
     navigator.geolocation.getCurrentPosition(displayOnMapError); 
    } 
} 

function displayOnMap(position) { 
    marker2 = handler.addMarker({ 
     lat: position.coords.latitude, 
     lng: position.coords.longitude, 
     picture: { 
      url: "<%= asset_path 'creative/1499326997_Untitled-2-01.png' %>", 
      width: 48, 
      height: 48, 
     }, 
     infowindow: 'You are Here!', 
    }); 
    handler.map.centerOn(marker2); 
    handler.getMap().setZoom(10); 
} 

function displayOnMapError(position) { 
    marker2 = handler.addMarker({ 
     lat: 34.0522, 
     lng: -118.2437, 
     picture: { 
      url: "<%= asset_path 'creative/1499326997_Untitled-2-01.png' %>", 
      width: 48, 
      height: 48, 
     }, 
    }); 
    handler.map.centerOn(marker2); 
    handler.getMap().setZoom(10); 
} 

initialize(); 
</script> 

这是最初的代码,让模态弹出与我需要的信息。

$(".name").html("<h3 class='panel-title'><i class='fa fa-id-card'></i>"+number+"</h3>"); 
$(".paneltb").html("<thead><tr><th>Panel</th><th>Location</th><th>Tab ID</th><th>Zip Code</th><th>Latitude</th><th>Longitude</th></tr></thead><tbody><tr><td>"+number+"</td><td>"+ name + "</td><td>"+tabid+"</td><td>"+zipcode+"</td><td>"+latitude+"</td><td>"+longitude+"</td></tr></tbody>"); 

$('#myModal').modal('show'); 
current = elem; 

为了增加模态中添加以下代码内的街道视图:

pos = new google.maps.LatLng(latitude, longitude); 

var div = document.getElementById('map2'); 
var sv = new google.maps.StreetViewPanorama(div); 
sv.setPosition(pos); 
sv.setVisible(true); 

// find the heading by looking from the google car pos to the venue pos 
var service = new google.maps.StreetViewService(); 
service.getPanoramaByLocation(pos, 50, function (result, status) { 
    if (status == google.maps.StreetViewStatus.OK) { 
     carPos = result.location.latLng; 
     heading = google.maps.geometry.spherical.computeHeading(carPos, pos); 
     sv.setPov({ heading: heading, pitch: 0, zoom: 1 }); 
    } 
}); 

为了通过目前的经纬度,并长成街景,我不得不把它与模态被调用的功能相同。

UPDATE

我想不出如何设置var sv = new google.maps.StreetViewPanorama(div);因此它被设置一次和模态的每个实例被称为,而不是试图启动和重新启动一个新的实例重复使用相同的地图。

更新2

我无法弄清楚如何开始初始化此部分:

var sv = new google.maps.StreetViewPanorama(div); 

所以,当我打开一个模式就不会呈现一个新的地图,它只是重复使用相同的地图。我倾向于写另一个功能,但我需要一些指导。

更新3

别的东西,我注意到的是,当我点击一个标志,它会显示在街景中的模态尽显其方。当我点击一个又一个,有时它不会显示在所有,但在大多数情况下,它显示却在角落里非常小的,因为这形象:

update 3

我也注意到,代码widget-scene-canvas类来自谷歌地图不断改变自己从我原本是通过自己的身份证造型,当我点击超过第一张地图在不同的时间。

widget

回答

4

我发现我有更多的问题,我有三个确切的问题。感谢https://stackoverflow.com/a/19048363/7039895,我发现每次打开模式时都需要调整我的地图在模态中的大小。该模式被打开之后被放置脚本是:

$("#myModal").on("shown.bs.modal", function() { 
    google.maps.event.trigger(sv, "resize"); 
}); 

时,我注意到,一些地方,当我打开出现的第二个问题一个模式将会使谷歌街道地图,而其他人则呈现谷歌街景地图但它是纯黑色这样的形象:

error

我发现的是,我需要改变呈现的街道地图的缩放为0,因为它是在从车上的POV 1倍变焦什么,我的地图中的一些拖尾和长整型无法缩放,而其他的可能会取决于哪里他谷歌车拍了一张照片。下面是代码的通知在那里说:zoom我改变了从1变焦到0

var service = new google.maps.StreetViewService(); 
     service.getPanoramaByLocation(pos, 50, function(result, status) { 
      if (status == google.maps.StreetViewStatus.OK) 
      { 
       carPos = result.location.latLng; 
       heading = google.maps.geometry.spherical.computeHeading(carPos, pos); 
       sv.setPov({ heading: heading, pitch: 0, zoom: 0 }); 
      } 
     }) 

,我需要解决的最后一件事是WebGL发生里面存放弹出一个障碍错误。经过对我的进一步调查,我注意到我是在网络应用程序中,还是只是在探索谷歌地图,而不管它是什么。这似乎是一个铬一般错误,所以我看看这篇文章,特别是https://www.xtremerain.com/fix-rats-webgl-hit-snag-chrome/我跟着第一个例子,并从高级设置禁用(见下文)。

使用硬件加速时可用

之后,我回去和测试地图,每个位置用谷歌街景地图,显示打开,WebGL发生问题的错误不再出现。

这里是我的web应用程序的地图部分的最终代码:

var handler = Gmaps.build('Google', { 
       markers: 
         {clusterer: { 
         gridSize: 60, 
         maxZoom: 20, 
         styles: [ { 
          textSize: 10, 
          textColor: '#ff0000', 
          url: 'assets/creative/m1.png', 
          height: 60, 
          width: 60 } 
         , { 
          textSize: 14, 
          textColor: '#ffff00', 
          url:'assets/creative/m2.png', 
          height: 60, 
          width: 60 } 
         , { 
         textSize: 18, 
         textColor: '#0000ff', 
         url: 'assets/creative/m3.png', 
         width: 60, 
         height: 60} 
         ]}} 
      }); 

var current; 
function initialize(){ 
    handler.buildMap({ internal: {id: 'map'} }, function() { 

    markers_json = <%=raw @hash.to_json %>; 
    markers = _.map(markers_json, function(marker_json){ 
     marker = handler.addMarker(marker_json); 
     handler.fitMapToBounds(); 
     _.extend(marker, marker_json); 
     return marker; 
    }); 

    getLocation(); 



    markers.map(function(elem, index) { 

     google.maps.event.addListener(elem.getServiceObject(), "click", function(evt) { 
     var id = elem.id, 
      number = elem.number, 
      name = elem.name, 
      zipcode = elem.zipcode, 
      tabid = elem.tabid, 
      latitude = elem.latitude, 
      longitude = elem.longitude 



     $(".name").html("<h3 class='panel-title'><i class='fa fa-id-card'></i>"+number+"</h3>") 
     $(".paneltb").html("<thead><tr><th>Panel</th><th>Location</th><th>Tab ID</th><th>Zip Code</th><th>Latitude</th><th>Longitude</th></tr></thead><tbody><tr><td>"+number+"</td><td>"+ name + "</td><td>"+tabid+"</td><td>"+zipcode+"</td><td>"+latitude+"</td><td>"+longitude+"</td></tr></tbody>") 


     pos = new google.maps.LatLng(latitude, longitude); 
     var div = document.getElementById('map2'); 
     var sv = new google.maps.StreetViewPanorama(div); 



     sv.setPosition(pos); 
     sv.setVisible(true); 

     // find the heading by looking from the google car pos to the venue pos 
     var service = new google.maps.StreetViewService(); 
     service.getPanoramaByLocation(pos, 50, function(result, status) { 
      if (status == google.maps.StreetViewStatus.OK) 
      { 
       carPos = result.location.latLng; 
       heading = google.maps.geometry.spherical.computeHeading(carPos, pos); 
       sv.setPov({ heading: heading, pitch: 0, zoom: 0 }); 
      } 
     }) 

     $('#myModal').modal('show') 

      current = elem; 

     $("#myModal").on("shown.bs.modal", function() { 
    google.maps.event.trigger(sv, "resize"); 
}); 

     }); 
    }) 
    }); 
    // Create the search box and link it to the UI element. 


} 
function getLocation(){ 
    if(navigator.geolocation){ 
    navigator.geolocation.getCurrentPosition(displayOnMap); 
    } 
    else{ 
    navigator.geolocation.getCurrentPosition(displayOnMapError); 
    } 
}; 
function displayOnMap(position){ 

    marker2 = handler.addMarker({ 
    lat: position.coords.latitude, 
    lng: position.coords.longitude, 
    picture: { 
     url: "<%= asset_path 'creative/1499326997_Untitled-2-01.png' %>", 
     width: 48, 
     height: 48 
     }, 
    infowindow: "You are Here!" 
    }); 
    handler.map.centerOn(marker2); 
    handler.getMap().setZoom(10); 
}; 

function displayOnMapError(position){ 

    marker2 = handler.addMarker({ 
    lat: 34.0522, 
    lng: -118.2437, 
    picture: { 
     url: "<%= asset_path 'creative/1499326997_Untitled-2-01.png' %>", 
     width: 48, 
     height: 48 
     } 
    }); 
    handler.map.centerOn(marker2); 
    handler.getMap().setZoom(10); 
}; 




initialize(); 
2

这个问题其实,无关与WebGL和JS,(好样的没有),因为我猜是,每次点击一个位置的时候,你是一个初始化新的webGL实例,而不是重用您以前的地图(之前已初始化),这就是为什么您只能“在webGL遇到障碍之前打开1或2”的原因。

这对浏览器来说变得非常沉重,所以它决定是时候去吃午饭了。

正如我猜你正在尝试做的是使用ajax来渲染一个新的地图,然后会派上用场的是能够销毁之前初始化的地图,但不幸的是,谷歌地图API没有销毁地图实例的功能(Mapbox和其他API)。但谷歌官方解释它:

大家好,

首先,我们一直沉默在这个问题到现在道歉。

接下来,有一个简单的解决方法,即重用您的地图 实例。如果有一个很好的理由,你为什么不能这样做,我很想知道 。

我将此标记为“无法修复”,因为这在技术上很困难。 我们不确定有多少地方在泄漏:-( 此外,我们可能需要引入某种 map.destroy()方法。否则,我们如何知道您是否 规划重用地图?JavaScript没有析构函数,所以我们 无法知道你扔掉你的参考对象。

对不起,是坏消息。

所以你需要确保的是,每次渲染一个新的部分时,你并没有初始化一个新的地图,而是重新使用你刚开始初始化的那个。

你的问题,住在这里:

var sv = new google.maps.StreetViewPanorama(div); 

而你没有表现出太多你如何调用弹出的,所以我真的不能提出一个路径为您服务。让我知道这对你是否有意义。

+0

这是它的代码中的街道视图右侧下方的模式。 –

+0

$('#myModal')。modal('show')current = elem; }); –

+0

我不知道你是否使用教程,但无论如何,我的建议是你移动与打开和关闭该脚本的模式有关的所有内容,然后每次将“lnglat”传递给streetview实例用户打开它,无论你想要什么事件绑定。而且,从我所看到的,你已经这样做了,所以它不应该太困难。 – Crashtor