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 intial 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.







For more like this, see Ephemeral Exchange Why not join our forum, follow the blog or follow me on twitter to ensure you get updates when they are available.
Comments