Set initial streetview orientation towards a map marker

This is a snippet from the series described in Playing around with maps and streetview, which will use the service to find an appropriate panorama, given a location, and set the initial heading and pitch so that it’s orientated towards the marker

Objective

When you enable a panorama, by default it will be orientated towards a default view, which is not likely going to be looking at the location you have generated the streetview for. Here’s how to bring up the initial view looking in the direction of your marker (which is plotted on maps). All the preparatory setup has been done and the entire app is available on github – so this will just go through the technique for getting the right camera orientation. 

The code

You can use the StreetViewService to directly access the streetview data, passing to it a few options. Here I’m looking for outside views within some number of meters  (50) from my map marker. It’s asynchronous of course, so I’m returning a promise.

return new Promise (function (resolve, reject) {
       
      //https://developers.google.com/maps/documentation/javascript/3.exp/reference#StreetViewService
      ns.sv.getPanorama ({
        location:markerPosition,
        preference:google.maps.StreetViewPreference.BEST,
        radius:meters,
        source:"outdoor"
      } , function (result,status) {

The callback returns a result and status. Assuming we found something, from the location the default image location (cameraPosition), I can calculate the heading (the angle between) it and the marker using one of the maps geometry functions – this gives  a heading

if (result && status === "OK") {

          var cameraPosition = result.location.latLng;
          var zoom = 1;

          // the heading can be used to adjust the cameraposition towards the marker
          // https://developers.google.com/maps/documentation/javascript/geometry#Navigation
          spot.maps.sv = {
            pov: {
              heading:google.maps.geometry.spherical.computeHeading(cameraPosition , markerPosition),
              pitch:0
            },
            zoom:zoom
          };

which I’ll save for later, and also apply to the active panorama right now

 // point that at the pano
          var pov = spot.maps.sv.pov;
          ns.pano.setPano(result.location.pano);
          ns.pano.setPov ({
            heading:pov.heading,
            pitch:pov.pitch
          });
          ns.pano.setZoom (spot.maps.sv.zoom);
          resolve (ns.pano);
         }

and I’ll pass the handling of errors back to the caller

else {
           reject (status);
         }
       });
    });

The result

My test data consists of various MacDonald’s around the world. The calculation above sets the initial view to be looking at each one – just like this.

This image has an empty alt attribute; its file name is Screenshot%202017-03-13%20at%2012.43.45.png

For more like this, see Ephemeral Exchange