使用带有标记的谷歌街景视图,如何将POV指向标记?

时间:2010-07-07 20:09:53

标签: 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.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);
    }
});

如您所见,我在街景视图中添加了地址标记。我的问题是,街景指向北方,标记位于南方。对于非特定地址,如何指定街景视图应指向地址的标记而不是默认指向北方?

3 个答案:

答案 0 :(得分:4)

原因是街景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 {
        ...
        }

使用街景的另一个技巧/陷阱是,您需要通过反复调用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);
            }
        });
    }

答案 1 :(得分:3)

结帐this sample。即使它是V2,您也可以重用代码。基本上,您需要调用computeAngle(markerLatLng,streetviewPanoLatLng),并将Street View pano的偏航设置为返回值。

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;
 }

答案 2 :(得分:2)

基于代码的简单示例:

  1. 获取要查看的位置(使用地理编码器)
  2. 获取StreetViewPanorama的位置(一旦状态发生变化,使用getLocation()方法,替代方法是使用getPosition()方法的结果)。
  3. 使用geometry library的computeHeading方法计算从摄像头到地址的标题。
  4. 使用setPov()方法设置该标题。
  5. 延迟使标记移动到正确的位置(删除它会使标记留在左上角)。如果不使用标记则不需要。
  6. 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);
    }
    

    working fiddle

    工作代码段:

    &#13;
    &#13;
    var geocoder = new google.maps.Geocoder();
    var myStreetView = null;
    var marker = null;
    
    function geocodeAddress() {
      // var address = "344 Laguna Dr, Milpitas, CA  95035";
      var address = document.getElementById('address').value;
      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);
    }
    google.maps.event.addDomListener(window, 'load', geocodeAddress);
    &#13;
    html,
    body,
    #map_canvas {
      height: 100%;
      width: 100%;
    }
    &#13;
    <script src="http://maps.google.com/maps/api/js?libraries=geometry"></script>
    <input id="address" type="text" value="344 Laguna Dr, Milpitas, CA  95035" />
    <input id="geoBtn" type="button" value="Go" />
    <div id="map_canvas"></div>
    &#13;
    &#13;
    &#13;