Geo-referencing panoramas with Google Maps

From Wiki
Revision as of 18:10, 4 November 2007 by WikiSysop (talk | contribs) (The simple way: source coloring)
Jump to: navigation, search


Google Maps provides simple and powerful ways to show people where your panorama was taken. But you have to decide which one to use -- the simple way is not powerful, and the powerful way is not simple. We will describe them separately.

The simple way

In any web page, you can easily create a link that the user can click, to bring up a separate Google Map page with your panorama location marked on it.

This simple way has limits. Most important: 1) the map page is separate, not part of your own page, 2) you can only mark one panorama, and 3) you cannot provide "click on the map to view the panorama" -- the map is for display only. But sometimes this is enough.

To use the simple method, all you need is to know the location of your pano, compose a title, then create a link patterned after this example: [1]

The link looks like this:

In this example, the location of the panorama is 46.25417 degrees North latitude and 119.286032 degrees West longitude. Notice that these numbers appear twice in the link: once in the "q=" clause and again in the "ll=" clause. The "t=k" parameter tells Google to show satellite imagery. The numbers after "spn=" are the width and height of the map, in degrees longitude and latitude. More about those in a moment.

The degrees latitude and longitude of your pano are easy to find, if you do not already know them. Just use your browser to bring up a Google Map that shows the general area where the pano was shot. Zoom in or out and pan around until you can see the location. Then double-click on the location of the pano. This will make Google center the map. When your pano is centered, click on Google's "Link to this page" link. That will cause the location and size to appear in your browser's address bar, in a format like what is shown above for "ll=" and "spn=". All you have to do then is fill in the "q=" clause.

The "spn=" parameters that specify width and height can also be computed, if you don't mind some math. The trick is to specify spn=spnLat,0.00001 where spnLat is computed using code like this: <source lang="js"> deg2rad = pi/180; rad2deg = 180./pi;

double latCenter = 46.230114; // latitude of the center of the map double sbase = 0.000020853; // fit to one particular dataset for (i=0; i<20; i++) { // compute spnLat for each of 20 zoom levels

 yCenter = ln(tan(pi/4+(latCenter*deg2rad)/2));
 yTop = yCenter + sbase*pow(2,i);
 yBot = yCenter - sbase*pow(2,i);
 latTop = rad2deg*(2*atan(exp(yTop))-pi/2);
 latBot = rad2deg*(2*atan(exp(yBot))-pi/2);
 spnLat = latTop - latBot;
 System.out.println("i = "+i+", spnLat = "+spnLat);

} </source> See the email archives at [2], [3], and [4] for discussion of why this works.

The powerful way

Google also provides a powerful Google Maps API that lets you embed the map in your page and display multiple markers with arbitrary labels that can contain links. This method is more complicated to use because you have to write JavaScript to embed in your web pages.

What you need

You need to obtain a valid Google key for the URL of your map. You can obtain a key at . NOTE: You need a Google account. If you don't have one, it will take several minutes to apply for one. No big deal, just a little time consuming. If you need to find out lat/lon values for your panorama location, you may want to install Google Earth: Set a placemark and read out the values...

Some caveats

Google Map is still (Oct. 2005) considered beta by Google. There are some known issues when integrating the applet in your webpage. The most important ones:

  • Don't embed the Javascript code somewhere in between <DIV>-Tags. This will break functionality with Internet Explorer.
  • If you display images in the balloon box, use <WIDTH> and <HEIGHT> for the image. Otherwise balloon size will be not correct if you click a placemark for the first time (Internet Explorer only)

The code to insert

The basic idea behind this code is: Use a static HTML page and load all data from a simple XML-file.

  • Don't forget to place your valid Google-key in the <HEAD>-Area of your HTML-page! e.g.:
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "">
    <html xmlns="">
      <script src="" type="text/javascript">
  • Place the formatted map somewhere on your page, e.g.:
     <div id="map" style="width: 800px; height: 600px">

  • Now you can cut and paste the following code to your HTML:
  <script type="text/javascript">
      // This will initialize your map
      var map = new GMap(document.getElementById("map"));
      map.addControl(new GLargeMapControl());
      map.addControl(new GMapTypeControl());
      map.setMapType( _HYBRID_TYPE ); 
      // Insert your initial map center and zoom below
      // Format is: (new GPoint(lng, lat), zoom)
      map.centerAndZoom(new GPoint(11.120984, 49.050060), 12);
      // array to hold copies of the markers 
      var gmarkers = [];
      // Download the data in from .xml and load it on the map.
      var request = GXmlHttp.create();"GET", "panoramas.xml", true);
      request.onreadystatechange = function() {
        if (request.readyState == 4) {
          var xmlDoc = request.responseXML;
          var markers = xmlDoc.documentElement.getElementsByTagName("marker");
          for (var i = 0; i < markers.length; i++) {
            var point = new GPoint(parseFloat(markers[i].getAttribute("lng")),
            var title = markers[i].getAttribute("title");
            var desc = markers[i].getAttribute("desc");
            var ref = markers[i].getAttribute("ref");
            var img = markers[i].getAttribute("img");
            // create the marker
            var html = "<font size='2'><b>"+title+"</b><br>"+desc+"<br><a href='"+ref+"' target='_blank'><img src='"+img+"' width='200' height='120'></img></a><br>Click image to open link</font>";
            var marker = new GMarker(point);
            marker.p_html = html;
            marker.p_name = title;
      // Maybe we have a lot of markers, so we use a single listener which will
      // forward to the respective info window
      GEvent.addListener(map, "click", function(overlay, point) {
  • Create your XML-file (it is called "panoramas.xml" in our example).

The format is:

      <marker lng="123.456" lat="123.456" title="The title of the Panorama" desc="Some further text" ref="http://url_to_your_panorama_page.html" img="http://url_to_your_thumbnail.jpg"/>

...(further lines like the above example)...


To have thumbnails displayed correctly, you must either use my standard size of 200x120pix or adapt the size-tags in the javascript.

Please note: This is basic code only. No error handling, no fuzzy features. Please feel free to add functionality and update this tutorial!

A working example
Documentation and API Discussion board: --Bvogl 23:05, 21 Oct 2005 (EDT)