Point the streetview camera to a marker

28 October 2012

If you add a Google Streetview element to your page and set it to a certain location it often had not got the right heading and "looks" somewhere else. The visitors of your page have to rotate the view to look at the object you want to show them. There is a function in the API to put streetview on a certain location and let it look towards a marker.


This demo is a little more elaborate than we'll learn in this tutorial. It uses the geolocation of your device (exact location on GPS enabled devices, triangluated location or IP based on non-GPS devices).

To create this, you'll need an element on your page that will contain the Streetview element. Add a DIV with an ID of "streetview" to your page. I used an element with a 100% height, but you'll probably have other elements in your page, so you'd better fix the height at something like 300 pixels.

<div id="streetview" style="width:100%; height:300px;"></div>


That all HTML we need, the rest is Javascript. If it is just one location you want to show, it's quite easy. You'll need one function that's executed when the page finishes loading. What the code does is fairly simple. It calculates the POV heading for the streetview camera, based on two locations. You probably enter a address that's not exactly on the route the streetview car drove when taking the panoramic pictures. The streetview API moves the camera automatically to the nearest supported location. The second location is the location you entered. It then calculates the heading and sets it in the POV object of the streetview element.

Let me illustratie this with an image:


Location A is the location we enter in the script, and the second locaton is the nearest streetview point. This is enough to let the API calculate the heading of the streetview camera.

The code


First we need to add a script tag to the head of yourt page. If you already have some other scripts in your head, you can add this to that script tag. If you haven't got the Google Maps API included yet, you'll also need to do that:

<script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript"></script>


At first, we'll need to add the initialize function to the onload eventhandler of the page. This has to be done to execute the function after the page finishes loading.

window.onload = initialize();

Next is the complete initialize function. I'll paste the function completely here and the comments in the code will explain what the specific lines of codes do:

function initialize() {
  // initialize the geocoder API functions. We need this to convert the address to a geolocation (GPS coordinates)
  var geocoder =  new google.maps.Geocoder();
  // then we call the geocode function with the address we want to use as parameter
  geocoder.geocode( { 'address': '20 River Terrace, New York, NY, United States' }, function(results, status) {
    // set the lookTo var to contain the coordinates of the address entered above
    var lookTo = results[0].geometry.location;
    // if the address is found and the geocoder function returned valid coordinates
    if (status == google.maps.GeocoderStatus.OK) {
      // set the options for the panorama view
      var panoOptions = {
        position: lookTo,
        panControl: false,
        addressControl: false,
        linksControl: false,
        zoomControlOptions: false
      };
      // initialize a new panorama API object and point to the element with ID streetview as container
      var pano = new  google.maps.StreetViewPanorama(document.getElementById('streetview'),panoOptions);
      // initialize a new streetviewService object
      var service = new google.maps.StreetViewService;
      // call the "getPanoramaByLocation" function of the Streetview Services to return the closest streetview position for the entered coordinates
      service.getPanoramaByLocation(pano.getPosition(), 50, function(panoData) {
        // if the function returned a result
        if (panoData != null) {
          // the GPS coordinates of the streetview camera position
          var panoCenter = panoData.location.latLng;
          // this is where the magic happens!
          // the "computeHeading" function calculates the heading with the two GPS coordinates entered as parameters
          var heading = google.maps.geometry.spherical.computeHeading(panoCenter, lookTo);
          // now we know the heading (camera direction, elevation, zoom, etc) set this as parameters to the panorama object
          var pov = pano.getPov();
          pov.heading = heading;
          pano.setPov(pov);
          // set a marker on the location we are looking at, to verify the calculations were correct
          var marker = new google.maps.Marker({
            map: pano,
            position: lookTo
          });
        } else {
          // no streetview found :(
          alert('not found');
        }
      });
    } else {
      // there were no coordinates found for the address entered (or the address was not found)
      alert('Could not find your address :(');
    }
  });
}

As you can see, the actual calculation of the heading and setting this to the streetview camera is not very complicated. Al the geocoder stuff and all of the "if nothing was found" checks take up most of the lines of code.

That's it! This is the complete code you can copy/paste directly in your website:

<!DOCTYPE html />
<html>
<head>
<title>Google Streetview heading on Marker</title>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,800' rel='stylesheet' type='text/css'>
  <style type="text/css">
  body {
    font-family: 'Open Sans', sans-serif;
    font-size: 14px;
    color: #333;
    background: #CCC; /* background color */ 
    padding: 0;
    margin: 0;
    height: 100%;
  }
  </style>
  <script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=false"></script>
  <script type="text/javascript">  
    window.onload = initialize();
 
    function initialize() {
      // initialize the geocoder API functions. We need this to convert the address to a geolocation (GPS coordinates)
      var geocoder =  new google.maps.Geocoder();
      // then we call the geocode function with the address we want to use as parameter
      geocoder.geocode( { 'address': '20 River Terrace, New York, NY, United States' }, function(results, status) {
        // set the lookTo var to contain the coordinates of the address entered above
        var lookTo = results[0].geometry.location;
        // if the address is found and the geocoder function returned valid coordinates
        if (status == google.maps.GeocoderStatus.OK) {
          // set the options for the panorama view
          var panoOptions = {
            position: lookTo,
            panControl: false,
            addressControl: false,
            linksControl: false,
            zoomControlOptions: false
          };
          // initialize a new panorama API object and point to the element with ID streetview as container
          var pano = new  google.maps.StreetViewPanorama(document.getElementById('streetview'),panoOptions);
          // initialize a new streetviewService object
          var service = new google.maps.StreetViewService;
          // call the "getPanoramaByLocation" function of the Streetview Services to return the closest streetview position for the entered coordinates
          service.getPanoramaByLocation(pano.getPosition(), 50, function(panoData) {
            // if the function returned a result
            if (panoData != null) {
              // the GPS coordinates of the streetview camera position
              var panoCenter = panoData.location.latLng;
              // this is where the magic happens!
              // the "computeHeading" function calculates the heading with the two GPS coordinates entered as parameters
              var heading = google.maps.geometry.spherical.computeHeading(panoCenter, lookTo);
              // now we know the heading (camera direction, elevation, zoom, etc) set this as parameters to the panorama object
              var pov = pano.getPov();
              pov.heading = heading;
              pano.setPov(pov);
              // set a marker on the location we are looking at, to verify the calculations were correct
              var marker = new google.maps.Marker({
                map: pano,
                position: lookTo
              });
            } else {
              // no streetview found :(
              alert('not found');
            }
          });
        } else {
          // there were no coordinates found for the address entered (or the address was not found)
          alert('Could not find your address :(');
        }
      });
    }
  </script>
</head>
<body>
  <div id="streetview" style="width:100%; height:100%"></div>  
</body>
</html>
You must have JavaScript enabled to use this form!

Leave a comment!

  1. Your mail is safe with me. It's only only used to display your Gravatar image!

5 comments

  1. Johan van Tongeren Gravatar

    Antonio

    21 November 2013

    Cool, tnx !

  2. Johan van Tongeren Gravatar

    sKuijers

    12 October 2013

    Thanks a million Johan! Explanation is clear en code works :D

  3. Johan van Tongeren Gravatar

    Dougy Hunt

    12 March 2013

    Geolocation for me is not working with this tutorial - seems to just find a building called the solaire...? The demo works but the tutorial code does not. How do I get the geolocation to work for street view like the demo?

  4. Johan van Tongeren Gravatar

    Thomas

    05 March 2013

    Thumbs up i could use your post on a little project. Having Streetview look the right way is a cool feature. http://nakmaps.de/

  5. Johan van Tongeren Gravatar

    Saikul Islam

    02 November 2012

    Thanks for your fabulous post. I appreciate the effort.......:)