39

I am currently using the Google Street View Panorama embed and I want to get the POV (more specifically heading) for a particular address.

Google does this via maps.google.com, where, given an address, it'll drop you into street view and it will face the right way. However, I can't seem to figure out / find documentation for a way to find the POV heading via the API.

I can get the Street View embed to work fine with a LatLng, but the camera is usually facing the wrong direction. Any ideas?

edit: clarity

I want to set the POV, but I don't know what value to set it to...

Kara
  • 6,115
  • 16
  • 50
  • 57
Benny Wong
  • 6,773
  • 5
  • 31
  • 25

6 Answers6

45

The latLng of the required address and the latLng of the panorama location (the position of the streetview car from where images are shot) are not the same. As far as I know, the API does not set the heading in the right direction of the address latlng, you will have to set it yourself.

This is how I did it, I used the StreetViewService to find the nearest panorama shot available and then calculated the Pov heading using the computeHeading method here

manubkk
  • 1,468
  • 12
  • 20
  • 16
    Awesome, exactly the answer I was looking for. Some more info for implementation: You need to load the geometry library: with parameter libraries=geometry. If you use use getPanoramaByLocation(), in your callback function you get the LatLng object of the street view car's position from the data object: var carLatLng = data.location.latLng; and use that against the LatLng object of your target to calculate the heading: var heading = google.maps.geometry.spherical.computeHeading(carLatLng, targetLatLng); to use with setPov() – Tilman Sep 30 '11 at 21:22
  • 1
    One confusing part about this is that `computeHeading()` returns a number in the range of -180 to 180, whereas the `heading` property of the pov object is expected to be between 0 and 360. I would have assumed simply adding 180 to result of `computeHeading()` would have done the trick, but I am getting inconsistent results. – Trevor Aug 14 '14 at 20:49
  • 1
    It should work both ways, check out their example (https://developers.google.com/maps/documentation/javascript/examples/streetview-events), they have set the initial heading to 270 but when you move around the getPov() returns -90 instead of 270 that was set. – manubkk Aug 15 '14 at 05:05
37

Just what manubkk said, I am using the following code to get the right SV heading

var $this = $(this),
  _lat = $this.data("lat"),
  _lng = $this.data("lng"),
  streetViewMaxDistance = 100;

var point = new google.maps.LatLng(_lat,_lng);
var streetViewService = new google.maps.StreetViewService();
var panorama = spaces.map.map.getStreetView();

// We get the map's default panorama and set up some defaults.
    // Note that we don't yet set it visible.


//panorama = spaces.map.map.getStreetView();

streetViewService.getPanoramaByLocation(point, streetViewMaxDistance, function (streetViewPanoramaData, status) {

    if(status === google.maps.StreetViewStatus.OK){

      var oldPoint = point;
          point = streetViewPanoramaData.location.latLng;

        var heading = google.maps.geometry.spherical.computeHeading(point,oldPoint);

        panorama.setPosition(point);
        panorama.setPov({
           heading: heading,
            zoom: 1,
            pitch: 0
        });
        panorama.setVisible(true);

    }else{
      $this.text("Sorry! Street View is not available.");
        // no street view available in this range, or some error occurred
    }
});
user7290573
  • 1,320
  • 1
  • 8
  • 14
vinay
  • 2,934
  • 1
  • 25
  • 18
4

The reason for this is that the street view POV is, by default the direction the truck was facing when the image was shot (go figure). You need to get the location of the truck and the location of the house and calculate a "heading" from the first location to the second:

// 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 {
        ...
        }

Another trick/trap using street view is that you need to obtain the closest street view to your address location by repeatedly calling getPanoramaByLocation with an increasing distance until you are either successful or reach some maximum distance. I solve this using this code:

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);
            }
        });
    }
Lawrence Dol
  • 63,018
  • 25
  • 139
  • 189
  • I don't know if this is a best practice or not, but the increment worked nicely. – Trevor Aug 14 '14 at 21:36
  • @Trevor: Yeah; I love a better way to do it. It seems stupid that Google doesn't have a way to get the closest view within some bounds. – Lawrence Dol Aug 14 '14 at 23:08
3

I found this page very helpful, thank you guys. I still needed to piece together the full solution from this and a few sources so I thought I would include it here for you.

<script>
var panorama;

  function loadStreetView() {

    var _lat = your_lat;
    var _lng = your_long;

    var target = new google.maps.LatLng(_lat,_lng);

    var sv = new google.maps.StreetViewService();

    panorama = new google.maps.StreetViewPanorama(document.getElementById('hero-street-view'));

    var pano = sv.getPanoramaByLocation(target, 50, function(result, status) {

      if (status == google.maps.StreetViewStatus.OK) {

        var heading = google.maps.geometry.spherical.computeHeading(result.location.latLng, target);

        panorama.setPosition(result.location.latLng);
        panorama.setPov({
           heading: heading,
           pitch: 0,
           zoom: 1
         });
        panorama.setVisible(true);

      }
      else {

        console.log("Cannot find a street view for this property.");
        return;

      }

    });
  }

  </script>

  <script async defer
  src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry&callback=loadStreetView">
  </script>
Joel
  • 384
  • 5
  • 18
-1

If you want to set the POV towards the street or 90 Degree Right / Left respective to that street I've implemented a solution.

Google Street View heading issue

I hope that will help.

Community
  • 1
  • 1
Hasanavi
  • 8,455
  • 2
  • 29
  • 35
-4

Can't tell if you want to get or set the POV

to set follow the instructions here: http://code.google.com/apis/maps/documentation/javascript/services.html#StreetViewPanoramas

var panoramaOptions = {
  position: fenway,
  pov: {
    heading: 34,
    pitch: 10,
    zoom: 1
  }
};

to get:

alert( panoramaOptions.pov.heading );
Galen
  • 29,976
  • 9
  • 71
  • 89