Google maps 使用带有标记的google street view,如何将POV指向标记?

Google maps 使用带有标记的google street view,如何将POV指向标记?,google-maps,google-maps-api-3,google-maps-markers,google-street-view,Google Maps,Google Maps Api 3,Google Maps Markers,Google Street View,我有一个简单的街景,用于显示给定地址的街景: var geocoder = new google.maps.Geocoder(); var address = "344 Laguna Dr, Milpitas, CA 95035"; geocoder.geocode( { 'address': address}, function(results, status) { //alert (results); if (status == google.maps.G

我有一个简单的街景,用于显示给定地址的街景:

var geocoder = new google.maps.Geocoder();
var address = "344 Laguna Dr, Milpitas, CA  95035";
geocoder.geocode( { 'address': address}, 
    function(results, status) {
        //alert (results);
    if (status == google.maps.GeocoderStatus.OK) {
        //alert(results[0].geometry.location);
        myStreetView = new google.maps.StreetViewPanorama(document.getElementById("map_canvas"));
        myStreetView.setPosition(results[0].geometry.location);
        var marker = new google.maps.Marker({
            position: results[0].geometry.location, 
            map: myStreetView, 
            title:address
        });
        //alert ("yay");
    } else {
        alert("Geocode was not successful for the following reason: " + status);
    }
});
如您所见,我在街景中添加了一个地址标记。我的问题是,街景是指向北方的,而标志是指向南方的。对于非特定地址,如何指定街景应指向地址的标记,而不是默认情况下指向北方?

签出。即使是V2版本,您也可以重用代码。基本上,您需要调用computeAngle(markerLatLng,StreetViewPanolatling),并将街景全景的偏航设置为返回值

function computeAngle(endLatLng, startLatLng) {
  var DEGREE_PER_RADIAN = 57.2957795;
  var RADIAN_PER_DEGREE = 0.017453;

  var dlat = endLatLng.lat() - startLatLng.lat();
  var dlng = endLatLng.lng() - startLatLng.lng();
  // We multiply dlng with cos(endLat), since the two points are very closeby,
  // so we assume their cos values are approximately equal.
  var yaw = Math.atan2(dlng * Math.cos(endLatLng.lat() * RADIAN_PER_DEGREE), dlat)
         * DEGREE_PER_RADIAN;
  return wrapAngle(yaw);
}

function wrapAngle(angle) {
  if (angle >= 360) {
    angle -= 360;
  } else if (angle < 0) {
    angle += 360;
  }
  return angle;
 }
函数计算角(endLatLng,starttlng){
var DEGREE_PER_弧度=57.2957795;
var弧度每度=0.017453;
var dlat=endLatLng.lat()-startatlng.lat();
var dlng=endLatLng.lng()-startatlng.lng();
//我们将dlng乘以cos(endLat),因为两点非常接近,
//所以我们假设它们的cos值近似相等。
var yaw=Math.atan2(dlng*Math.cos(endLatLng.lat()*弧度/度),dlat)
*度/弧度;
返回绞盘(偏航);
}
函数缠绕(角度){
如果(角度>=360){
角度-=360;
}否则,如果(角度<0){
角度+=360;
}
返回角;
}

原因是街景POV默认为拍摄图像时卡车所面对的方向(见图)。您需要获得卡车的位置和房屋的位置,并计算从第一个位置到第二个位置的“航向”,然后将您的街景位置设置为卡车的位置,以及您刚刚计算的航向:

// adrloc=target address
// svwloc=street-view truck location
svwService.getPanoramaByLocation(adrloc,svwdst,function(dta,sts) {
    if(sts==google.maps.StreetViewStatus.OK) {
        var svwloc=dta.location.latLng;
        var svwhdg=google.maps.geometry.spherical.computeHeading(svwloc,adrloc);
        var svwmap=avwMap.getStreetView();
        svwmap.setPosition(svwloc);
        svwmap.setPov({ heading: svwhdg, pitch: 0 });
        svwMarker=new google.maps.Marker({ map:svwmap, position: adrloc });
        svwmap.setVisible(true);
        }
    else {
        ...
        }
使用street view的另一个技巧/陷阱是,您需要通过不断增加的距离反复调用
getPanoramaByLocation
来获取距离您的地址位置最近的街景,直到您成功或达到某个最大距离。我使用以下代码解决此问题:

var SVW_MAX=100; // maximum street-view distance in meters
var SVW_INC=10;  // increment street-view distance in meters
var svwService=new google.maps.StreetViewService(); // street view service
var svwMarker=null; // street view marker

// NOTE: avwMap is the aerial view map, code not shown
...
resolveStreetView(avwMap.getCenter(),SVW_INC); 
...

var resolveStreetView=function(adrloc,svwdst) {
    svwService.getPanoramaByLocation(adrloc,svwdst,function(dta,sts) {
        if(sts==google.maps.StreetViewStatus.OK) {
            var svwloc=dta.location.latLng;
            var svwhdg=google.maps.geometry.spherical.computeHeading(svwloc,adrloc);
            var svwmap=avwMap.getStreetView();
            svwmap.setPosition(svwloc);
            svwmap.setPov({ heading: svwhdg, pitch: 0 });
            svwMarker=new google.maps.Marker({ map:svwmap, position: adrloc });
            svwmap.setVisible(true);
            }
        else if(svwdst<SVW_MAX) {
            resolveStreetView(adrloc,svwdst+SVW_INC);
            }
        });
    }
var SVW_MAX=100;//最大街景距离(米)
var SVW_INC=10;//以米为单位增加街景距离
var svwService=new google.maps.StreetViewService();//街景服务
var svwMarker=null;//街景标志
//注:avwMap为鸟瞰图,代码未显示
...
resolveStreetView(avwMap.getCenter(),SVW_公司);
...
var ResolvetStreetView=函数(adrloc、svwdst){
getPanoramaByLocation(adrloc、svwdst、function(dta、sts){
如果(sts==google.maps.StreetViewStatus.OK){
var svwloc=dta.location.latLng;
var svwhdg=google.maps.geometry.spheremic.computeHeading(svwloc,adrloc);
var svwmap=avwMap.getStreetView();
svwmap.setPosition(svwloc);
svwmap.setPov({标题:svwhdg,音高:0});
svwMarker=new google.maps.Marker({map:svwmap,position:adrloc});
svwmap.setVisible(true);
}

else if(svwdst基于代码的简单示例:

  • 获取要查看的位置(使用地理编码器)
  • 获取的位置(使用getLocation()方法在其状态更改后,另一种方法是使用getPosition()方法的结果)
  • 使用的computeHeading方法计算从摄影机到地址的标题
  • 使用setPov()方法设置该标题
  • 延迟标记,使其到达正确的位置(移除标记后,标记将保留在左上角)。如果不使用标记,则不需要
  • 工作代码段:

    var geocoder=new google.maps.geocoder();
    var myStreetView=null;
    var-marker=null;
    函数geocodeAddress(){
    //var address=“加利福尼亚州米尔皮塔斯市拉古纳区344号,邮编95035”;
    var address=document.getElementById('address')。值;
    地理编码({
    “地址”:地址
    },功能(结果、状态){
    //警报(结果);
    if(status==google.maps.GeocoderStatus.OK){
    //警报(结果[0]。几何体。位置);
    myStreetView=new google.maps.StreetViewPanorama(document.getElementById(“地图画布”);
    myStreetView.setPosition(结果[0].geometry.location);
    google.maps.event.addListenerOnce(myStreetView,'status_changed',function(){
    var heading=google.maps.geometry.spherical.computeHeading(myStreetView.getLocation().latLng,结果[0].geometry.location);
    myStreetView.setPov({
    标题:标题,
    音高:0
    });
    setTimeout(函数(){
    marker=新的google.maps.marker({
    位置:结果[0]。geometry.location,
    地图:myStreetView,
    标题:地址
    });
    if(marker&&marker.setMap)marker.setMap(myStreetView);
    }, 500);
    });
    }否则{
    警报(“地理编码因以下原因未成功:“+状态”);
    }
    });
    google.maps.event.addDomListener(document.getElementById('geoBtn'),'click',geocodeAddress);
    }
    google.maps.event.addDomListener(窗口“加载”,地理编码地址);
    html,
    身体,
    #地图画布{
    身高:100%;
    宽度:100%;
    }
    
    
    这里也有同样的问题。这个答案在链接的示例中有效,但不能解决OP的问题。标记和全景都设置为完全相同的位置(
    结果[0]。几何体。位置
    )所以,<代码>计算机角>代码>总是返回<代码> 0代码>代码。然而,在实际全景图中,标记不显示在相机的正确位置(在道路中间)。,但在路边,与实际建筑相对。这里也有人问:答案指向一个工作示例:谢谢,除了
    geometry.spherec.computeHeading
    的两个参数都是
    LatLng
    myStreetView.getLocation().latLng
    返回一个
    latLng
    实例,但您还需要从您的位置创建一个新实例,
    new google.maps.latLng(结果[0].g
    
    function geocodeAddress() {
      var address = "344 Laguna Dr, Milpitas, CA  95035";
      geocoder.geocode({
        'address': address
      }, function(results, status) {
        //alert (results);
        if (status == google.maps.GeocoderStatus.OK) {
          //alert(results[0].geometry.location);
          myStreetView = new google.maps.StreetViewPanorama(document.getElementById("map_canvas"));
          myStreetView.setPosition(results[0].geometry.location);
          google.maps.event.addListenerOnce(myStreetView, 'status_changed', function() {
            var heading = google.maps.geometry.spherical.computeHeading(myStreetView.getLocation().latLng, results[0].geometry.location);
            myStreetView.setPov({
              heading: heading,
              pitch: 0
            });
            setTimeout(function() {
              marker = new google.maps.Marker({
                position: results[0].geometry.location,
                map: myStreetView,
                title: address
              });
              if (marker && marker.setMap) marker.setMap(myStreetView);
            }, 500);
          });
    
        } else {
          alert("Geocode was not successful for the following reason: " + status);
        }
      });
      google.maps.event.addDomListener(document.getElementById('geoBtn'), 'click', geocodeAddress);
    }