Google Earth API

Balloons

  1. Introduction
  2. Feature balloons
  3. HTML string balloons
  4. HTML DIV balloons
  5. Closing balloons

Introduction

Balloons are information windows displayed in the Google Earth Plugin, optionally associated with a feature. Their content can include HTML, CSS, or JavaScript. Most aspects of balloons can be controlled through the API:

Minimum and maximum height and width setMinHeight()
setMaxHeight()
setMinWidth()
setMaxWidth()
Background color setBackgroundColor()
*not applicable to feature balloons
Text color setForegroundColor()
*not applicable to feature balloons
The feature with which they are associated setFeature()
Whether or not to include a close button setCloseButtonEnabled()
The balloon contents setContentString()
setContentDiv()
Open or close a balloon ge.setBalloon(balloon_name);
ge.setBalloon(null);

The plugin supports three types of balloons:

Feature balloons

Feature balloons are the basic balloon type in the Google Earth Plugin. They must be attached to a feature, and their contents are automatically set to be the scrubbed contents of that feature's <description> element. Basic feature balloons don't need to be explicitly created.

Feature balloons can also be created with ge.createHtmlStringBalloon(), which allows you to control certain aspects of how the balloon is displayed:

var balloon = ge.createHtmlStringBalloon('');
balloon.setFeature(placemark);
balloon.setMinWidth(400);
balloon.setMaxHeight(400);
balloon.setCloseButtonEnabled(false);

Content scrubbing

When a feature balloon's description contents are scrubbed, the following code is removed:

  • JavaScript
  • CSS
  • <iframe> tags
  • <embed> tags
  • <object> tags

Scrubbing the contents is a security measure to prevent malicious code from executing in a balloon. However, if the content is known and trusted, there are a few methods available that will bring in all content without stripping any elements.

To illustrate these methods, we will be using an example point placemark from the AJAX API Playground:

var kmlString = '' +
'<?xml version="1.0" encoding="UTF-8"?>' +
'<kml xmlns="http://www.opengis.net/kml/2.2">' +
'  <Document>' +
'    <Style id="bstyle">' +
'      <BalloonStyle>' +
'        <text>' +
'          <![CDATA[' +
'            Species is $[species]<br>' +
'            Age is: $[age]' +
'          ]]>' +
'        </text>' +
'      </BalloonStyle>' +
'    </Style>' +
'    <Placemark id="example_placemark">' +
'      <styleUrl>#bstyle</styleUrl>' +
'      <name>Placemark 1</name>' +
'      <description>' +
'        <![CDATA[<a href="#" onclick="alert(\'Running some JavaScript!\');">Alert!</a><br>]]>' +
'      </description>' +
'      <ExtendedData>' +
'        <Data name="species">' +
'          <value>Badger</value>' +
'        </Data>' +
'        <Data name="age">' +
'          <value><![CDATA[<a href="#" onclick="alert(3);"> Click to see</a><br>]]></value>' +
'        </Data>' +
'      </ExtendedData>' +
'      <Point>' +
'        <coordinates>-122.4226,37.7792,0</coordinates>' +
'      </Point>' +
'    </Placemark>' +
'  </Document>' +
'</kml>');

var kmlObject = ge.parseKml(kmlString);
ge.getFeatures().appendChild(kmlObject);
var placemark = ge.getElementById('example_placemark');

getDescription()

The getDescription() method retrieves the feature's description content in its entirety. You can modify the content of the balloon by modifying the underlying feature. If you wish to override the scrubbing of the content in your balloon, you can take the output of getDescription() and feed it to a new htmlDivBalloon or htmlStringBalloon. You must also prevent the default feature balloon from appearing when the feature is clicked:

google.earth.addEventListener(placemark, 'click', function(event) {
  // Prevent the default balloon from appearing.
  event.preventDefault();

  var content = placemark.getDescription();
  var balloon = ge.createHtmlStringBalloon('');
  balloon.setFeature(placemark);
  balloon.setContentString(content);
  ge.setBalloon(balloon);
});

getBalloonHtml()

If your feature includes an <ExtendedData> element, you can use getBalloonHtml() to retrieve the contents of that element. Unsafe content will be stripped from the extended data - see the list of content that will be removed at the beginning of this section.

In the example below, we are using the same example KML shown at the beginning of this section. The contents of the KML's <ExtendedData> element are retrieved with getBalloonHtml() and added to the feature balloon with setContentString().

For more information about extended data elements, refer to Adding Custom Data in the KML Developer's Guide.

google.earth.addEventListener(placemark, 'click', function(event) {
  // Prevent the default balloon from appearing.
  event.preventDefault();

  var content = placemark.getBalloonHtml();
  var balloon = ge.createHtmlStringBalloon('');
  balloon.setFeature(placemark);
  balloon.setContentString(content);
  ge.setBalloon(balloon);
});

In the example above, clicking the Click to see link has no effect. The onclick property has been removed.

getBalloonHtmlUnsafe()

If you know and trust the source of the KML, you can call getBalloonHtmlUnsafe() to include active content from the <ExtendedData> element:

google.earth.addEventListener(placemark, 'click', function(event) {
  // Prevent the default balloon from appearing.
  event.preventDefault();

  var content = placemark.getBalloonHtmlUnsafe();
  var balloon = ge.createHtmlStringBalloon('');
  balloon.setFeature(placemark);
  balloon.setContentString(content);
  ge.setBalloon(balloon);
});

Clicking the Click to see link in this case will execute the JavaScript, displaying the value of the age Data element.

Reference

HTML string balloons

HTML string balloons can contain any HTML or CSS markup, or JavaScript code. They are created with createHtmlStringBalloon(), and their content is defined using setContentString() — string balloons do not use any content present in a feature's description.

HTML string balloons do not need to be attached to a feature. If no feature is specified with setFeature(), the balloon will be displayed in the center of the current view. To display an HTML string balloon, pass the balloon object to ge.setBalloon().

Tip: The default onclick behavior for a feature in Earth is the display of a feature balloon. If you wish to display an HTML string balloon instead, you must override the default behavior.

Source: http://developers.google.com/earth/documentation/samples/html_string_balloon_example.html

google.earth.addEventListener(placemark, 'click', function(event) {
  // Prevent the default balloon from popping up.
  event.preventDefault();

  var balloon = ge.createHtmlStringBalloon('');
  balloon.setFeature(placemark); // optional
  balloon.setContentString(
      ' <object width="200" height="150"><param name="movie" '
    + 'value="http://www.youtube.com/v/6mrG_bsqC6k&hl=en&fs=1"/>'
    + '<param name="allowFullScreen" value="true"/>'
    + '<embed src="http://www.youtube.com/v/6mrG_bsqC6k&hl=en&fs=1" '
    + 'type="application/x-shockwave-flash" allowfullscreen="true" '
    + 'width="200" height="150"></embed></object>');

  ge.setBalloon(balloon);
});

Reference

HTML DIV balloons

HTML DIV balloons use a given <div> element as the content to show inside the balloon. The DIV is reparented to the plugin's internal DOM structure. All HTML, CSS markup, and JavaScript code is acceptable in an HTML DIV balloon.

HTML DIV balloons must be explicitly created with createHtmlDivBalloon() and displayed with setBalloon(). Content must be added to a DIV element on the page, before being set with setContentDiv().

Tip: The default onclick behavior for a feature in Earth is the display of a feature balloon. If you wish to display an HTML DIV balloon instead, you must override the default behavior.

A simple DIV balloon can be created as follows:

var balloon = ge.createHtmlDivBalloon('');
balloon.setFeature(placemark);
var div = document.createElement('DIV');
div.innerHTML = 'Any <em>HTML</em>, CSS, or JavaScript goes here.';
balloon.setContentDiv(div);
ge.setBalloon(balloon);

The following example copies the content from a specified element on the page into a new DIV, then displays that content in a balloon. This is the basis for dynamically generated pages, with placemarks displaying when page links are clicked. In the example below, the placemarks are hard-coded, but they could be generated from data in a database or flat file.

Source: http://developers.google.com/earth/documentation/samples/html_div_balloon_example.html

Within the initialization callback function (initCB() in our examples):

// Create the placemarks and points.
window.placemark0 = ge.createPlacemark('');
var point0 = ge.createPoint('');
point0.setLatitude(12.342);
point0.setLongitude(54.321);
placemark0.setGeometry(point0);
ge.getFeatures().appendChild(placemark0);

// Add an event listener to each of the 'results' list items.
// If/else statement is a fix for IE behavior.
var divs = document.getElementById('results').getElementsByTagName('li');
for (var i = 0; i < divs.length; i++) {
  var singleDiv = divs[i];
  if (singleDiv.addEventListener)
    singleDiv.addEventListener('click', makeClickHandler(divs[i].id), false);
  else if (singleDiv.attachEvent)
    singleDiv.attachEvent('onclick', makeClickHandler(divs[i].id));
}

Outside of initCB():

function makeClickHandler(id) {
  return function() {
    var balloon = ge.createHtmlDivBalloon('');
    // Attach this balloon to the placemark.
    balloon.setFeature(window['placemark' + id]);
    var div = document.createElement('DIV');
    // Populate the new div with the appropriate list item from the 'results' div.
    div.innerHTML = document.getElementById('results').getElementsByTagName('li')[id].innerHTML;
    balloon.setContentDiv(div);
    ge.setBalloon(balloon);
  }
}

Finally, within the body of the page:

<div id="results">
  <p><strong>Show:</strong></p>
  <ul>
    <li id="0">great swimming</li>
    <li id="1">sharks!</li>
    <li id="2">sea lions</li>
  </ul>
</div>

Reference

Closing balloons

To close a balloon:

ge.setBalloon(null);

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.