Subscribe

Appirio RSS Feed
Subscribe with Bloglines

Add to Google
Subscribe in NewsGator Online

Community

Appirio Technology Blog

Thursday, October 2, 2008

Google Earth Integration via Visualforce

 

The VisualForce "contentType" page attribute makes it easy to push data from Salesforce directly to other apps. Here, we'll review an example using Google Earth. We use KML to view Salesforce Opportunities on a 3D map. Let's start with the page itself:

    <apex:page controller="KMLController" cache="true" showHeader="false" contentType="application/vnd.google-earth.kml+xml">
    <kml xmlns="http://earth.google.com/kml/2.0">
    <Document>
    <name>Salesforce Opportunities</name>
    <apex:repeat value="{!oppList}" var="o">
    <Placemark>
    <name>{!o.Name}</name>
    <address>{!o.Account.BillingStreet} {!o.Account.BillingCity}, {!o.Account.BillingState} {!o.Account.BillingPostalCode}</address>
    <description>
    <![CDATA[
    <p><b>Account: </b>{!o.Account.Name}
    <p><b>Amount: </b>${!o.Amount}
    <p><b>Close Date: </b>{!MONTH(o.CloseDate)}/{!DAY(o.CloseDate)}/{!YEAR(o.CloseDate)}
    ]]>
    </description>
    </Placemark>
    </apex:repeat>
    </Document>
    </kml>
    </apex:page>
    Note the following:
      • The contentType="application/vnd.google-earth.kml+xml" attribute notifies the browser that the page content should be passed to Google Earth.

      • The cache="true" attribute addresses this IE security issue.

      • The meat of the page is in an <apex:repeat> block that iterates over a list of Opportunities. In this example, we're mapping the opportunity address, but you could use the Geocoding API to specify a Point with specific longitude and latitude coordinates

        The page controller retrieves a List of Opportunity objects based on a comma-delimited URL parameter:

        public class KMLController {

        public Opportunity[] oppList {get; set;}

        public KMLController() {

        String sel = '';

        if (null != ApexPages.currentPage().getParameters().get('sel')) {

        sel = ApexPages.currentPage().getParameters().get('sel');

        }

        String[] idList = sel.split(',', 0);

        oppList = [SELECT Id, Name, Amount, CloseDate,

        Account.Name, Account.BillingStreet, Account.BillingCity,

        Account.BillingState, Account.BillingPostalCode

        FROM Opportunity

        WHERE id IN :idList];

        }

        }

        Finally, an Opportunity custom button is used to invoke the VisualForce page, passing a list of selected Opportunity Id's from a List View or Related List:

        var sel = {!GETRECORDIDS( $ObjectType.Opportunity)};

        if (!sel.length) {

        alert("Please select at least one opportunity for mapping.");

        } else {

        var d = new Date(); // Append milliseconds to URL to avoid browser caching

        url= "/apex/KMLPush?ms=" + d.getTime() + "&sel=" + {!GETRECORDIDS( $ObjectType.Opportunity)};

        window.location.href=url;

        }

        When the button is clicked, the selected Opportunities will be displayed (via KML) in Google Earth.

        10-2-2008 8-50-13 PM

        If the KML file doesn't open properly, you might need to manually add the following Windows registry entries:

        [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\Content Type]

        [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\Content Type\application/vnd.google-earth.kml+xml]

        "Extension"=".kml"

        [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\Content Type\application/vnd.google-earth.kmz]

        "Extension"=".kmz"

        1 comment:

        Anonymous said...

        Dan,
        This is great and I got it working on my system. What changes would be needed to adapt it for Google Maps?

        Would contentType="application/x-www-form-urlencoded" and kml xmlns="http://maps.google.com/maps/geo". Also would I need to include the SF server key?
        Thanks.