Jan 15, 2012

Integrating Google Maps in Salesforce

Requirement is to show the location of my Account on Google Maps. It looks difficult but actually it is very simple to implement.


Just create a new visualforce page with this code
<apex:page standardController="Account">

<script src="http://maps.google.com/maps?file=api">
</script>

<script type="text/javascript">

var map = null;
var geocoder = null;

var address = "{!Account.BillingStreet}, {!Account.BillingPostalCode} {!Account.BillingCity}, {!Account.BillingState}, {!Account.BillingCountry}";

function initialize() {
if(GBrowserIsCompatible())
{
  map = new GMap2(document.getElementById("MyMap"));
  map.addControl(new GMapTypeControl());
  map.addControl(new GLargeMapControl3D());
  
  geocoder = new GClientGeocoder();
  geocoder.getLatLng(
    address,
    function(point) {
      if (!point) {
        document.getElementById("MyMap").innerHTML = address + " not found";
      } else {
        map.setCenter(point, 13);
        var marker = new GMarker(point);
        map.addOverlay(marker);
        marker.bindInfoWindowHtml("Account Name : <b><i> {!Account.Name} </i></b> <br/> Address : "+address);
      }
    }
  );
}
}
</script>


<div id="MyMap" style="width:100%;height:300px"></div>
<script>
    initialize() ;
</script>

</apex:page>
As you can see that I have used standard controller so you need to pass the account Id in URL. Let's say if the page name is "GoogleMaps" then the URL will look something like this : ".../apex/GoogleMaps?id=YOUR_ACCOUNT_ID".






When you click on the balloon it will show you the Account name and the address, you can change it according to your need by changing the code of line "marker.bindInfoWindowHtml"


Use this page as in line visualforce page on native layout and enjoy the Google maps with Salesforce.


References
http://code.google.com/apis/maps/documentation/webservices/
http://code.google.com/apis/maps/index.html

41 comments:

  1. Nice writeup as usual Forceguru. It really shows how simple it is to integrate Google Maps and Force.com, it really is that easy!

    I've done this lots of times myself, and I'd say that the natural next steps clients like to see if how to filter a list of Accounts by location. Checkout Find Nearby on the AppExchange or my sourcecode from Dreamforce on github(https://github.com/corycowgill/sfbusradar) to see how to query for records in Salesforce by location.

    ReplyDelete
  2. I try above but it is not working.Do i have to change any user settings

    ReplyDelete
  3. You may want to consider using v3 of the Google Maps API rather than v2 since it was deprecated May 19, 2010. Google's deprecation period is 3 years, so this code may not work as expected past May 2013.

    ReplyDelete
  4. This issue with using v3 of the API as I recall is that the v3 API limits based on IP address for calls like Geocoding, not Google Maps API Key. Since Salesforce runs on Multitenant architecture, v3 limits are shared across Salesforce not individual clients (keys). At least that's what I remember.

    ReplyDelete
  5. Error: testpage line 1, column 1: Content is not allowed in prolog
    Error: Content is not allowed in prolog.

    I am getting the following error when trying to save the code.

    ReplyDelete
  6. If you use the Google Maps API server-side, then the IP address limitation would likely be reached very quickly. Since it is recommended using client-side code (javascript) then there should not be a problem reaching limits as each user visiting the page will have their own quota limit. If you need to do batch geocoding, then it can be a problem.

    http://code.google.com/apis/maps/articles/geocodestrat.html

    I have recently developed a store locator using v3 of the API and it has been working without issue for the past few weeks with as many as 800 requests each day and an average of 500 per day.

    To avoid reaching geocoding limits, it was required to have the latitude and longitude populated and any other geocoding is done using the Javascript API.

    ReplyDelete
  7. Thanks for the great example! I came across one minor issue when I tried to use the sample code. As it is written maps weren't displaying at all. However, when I updated:

    marker.bindInfoWindowHtml("Account Name : {!Account.Name}
    Address : "+address);

    to:

    marker.openInfoWindow(document.createTextNode(address));

    everything worked perfectly.

    Wanted to share that change in case anyone else was having similar issues.

    Thanks again!

    - Dan

    ReplyDelete
    Replies
    1. Thanks Dan, There seems to be some problem with the code above. But your fix did the magic.

      Delete
    2. Hi Dan,

      I have changed the code! But I can't see the map,
      in fact it does not works! Some recommendation?

      Help! :(

      Regards, @lonso.

      Delete
    3. Hi Dan,
      For me also it is not working i am not able to get any map in my VF page.
      Please help me with some code....

      Thanks,
      Basha

      Delete
  8. I want to save the latitudes and longitudes in the account object and if possible re-use the stored values to display the location in a map.

    I was trying something like this by using the sample code above after the map has been displayed.
    However, it appears that when i try to use AJAX call,the map itself is not displayed even though i add the src attribute to my script tag.
    'type="text/javascript" src="/soap/ajax/23.0/connection.js"'


    The update of account is as follows:-


    acc = new sforce.SObject("Account");
    acc.Id = "{!Account.Id}";
    acc.lat__c = results[0].geometry.location.lat();
    acc.lon__c = results[0].geometry.location.lng();

    sforce.connection.update([acc], {
    onSuccess: function(result) {
    console.log("success")
    },
    onFailure: function(error) {
    console.log("error")
    },
    timeout: 5000
    });


    Any help would be much appreciated.
    Thanks
    Siim

    ReplyDelete
    Replies
    1. Hi Siim!!!

      I wanna do the same. Can you resolve your problem??
      I have a custom object, and now I get latitude and longitude, I use the
      code above, but I don't see that works, I don't see the map

      Do you have any tip?

      Regards
      @lonso!

      Delete
  9. sir i used above code but the code is not working properly.
    means the google map is not connecting with salesforce..

    ReplyDelete
  10. Hi ankit,

    How can We show different colored markers based on Country value of an account?
    Suppose if the country is "India" then I would like to show "green colored marker" and if the country is "US" then I would like to show "Red colored marker".

    ReplyDelete
  11. I had to make the change recommended by Dan to get the code working as well.

    Has anyone found a workaround for street fields that have multiple lines?

    ReplyDelete
  12. Does anyone know how to modify the code to work off of stored latitude longitude values instead of and address?

    ReplyDelete
    Replies
    1. Hi William!

      I am trying to do that! But no results by now! :(
      I am using the code above, but I can not see the map.

      Do you have any tip?

      Regards,
      @lonso.

      Delete
    2. William, I used the following in place of the billing address.

      {!SUBSTITUTE(JSENCODE(Account.BillingStreet),'\r\n',' ')}

      Delete
    3. Thanks Richard.
      Your soln worked.

      Replace this part ::
      var address = "{!Account.BillingStreet}, {!Account.BillingPostalCode}, {!Account.BillingCity}, {!Account.BillingState}, {!Account.BillingCountry}";
      with this...
      "{!SUBSTITUTE(JSENCODE(Account.BillingStreet),'\r\n',' ')}";

      Delete
  13. Hi ,

    Iam able to show account location,

    But I have another requirement of how to show all account info in visualforce page,
    Please let me know of how to do it>//???


    ReplyDelete
    Replies
    1. Arun Can share your code which worked for you..

      Delete
  14. This comment has been removed by the author.

    ReplyDelete
  15. Change this part:

    var address = "{!Account.BillingStreet}, {!Account.BillingPostalCode}, {!Account.BillingCity}, {!Account.BillingState}, {!Account.BillingCountry}";

    now it will work....

    ReplyDelete
  16. Hi, I am trying the code suggested by Ankit but i am not getting the map in my vf page.
    Can any body tell me where should i modify the code to get the map.

    Thanks,
    Basha

    ReplyDelete
  17. Sorry if my question is wrong, I'm quite new in visualforce coding.

    How can I put an array of accounts on a map?

    I used the following code to get the list of addresses of the accounts. but I don't know how to pass it to the script that creates the map:











    {!c.BillingStreet}, {!c.BillingPostalCode} {!c.BillingCity}, {!c.BillingState}, {!c.BillingCountry}

    ReplyDelete
    Replies
    1. seems that the code doesn't appear

      apex:pageBlock title="Viewing Accounts">
      apex:form id="theForm">
      apex:panelGrid columns="2">
      apex:outputLabel value="View:"/>
      apex:selectList value="{!filterId}" size="1">
      apex:actionSupport event="onchange" rerender="list"/>
      apex:selectOptions value="{!listviewoptions}"/>
      /apex:selectList>
      /apex:panelGrid>
      apex:dataList var="c" value="{!accounts}" id="list">
      {!c.BillingStreet}, {!c.BillingPostalCode} {!c.BillingCity}, {!c.BillingState}, {!c.BillingCountry}
      /apex:dataList>

      Delete
  18. i didn't get anything for main post

    ReplyDelete
  19. i was geting blank page.what changes should i do plz tell me

    ReplyDelete
  20. Getting a blank page,can't see any map.Can any one help ???

    ReplyDelete
  21. I am also getting a blank page.Do i have to change any setting?

    ReplyDelete
    Replies
    1. If you are using Chrome as your browser, then you will have to allow the "insecure" content to load by clicking on the shield to the right of the URL bar.

      Or, you can change any http:// to https://

      For example:
      src="https://maps.google.com/maps?file=api"

      Delete
  22. This comment has been removed by the author.

    ReplyDelete
  23. I am getting the Authorization error on same code.
    Please let me know if I have to make any initial settings.
    I have added the page to sites VF page list and also edit the public access settings please Help.

    ReplyDelete
  24. I'm trying to display accounts in google maps with the latitude and longitude reference but keep getting a message that tells me the website needs a different Google Maps API Key. Anyone knows what it means and what has to be done? Thanks!!

    ReplyDelete
  25. When i am used the above code in a Visual force page i am getting an error,
    "This web site needs a different Google Maps API key. A new key can be generated at http://code.google.com/apis/maps/documentation/javascript/v2/introduction.html#Obtaining_Key."

    ReplyDelete
  26. Can you help me here : -
    https://developer.salesforce.com/forums?id=906F0000000MGdgIAG
    Not working for Too Many Accounts. Shows only some of the accounts :(

    ReplyDelete
  27. Great insights. I look forward to reading what you're planning on next, because your post is a nice read.
    ivanka hot

    ReplyDelete
  28. If you employ the Google Maps API server-side, then the information processing address limitation would possible be reached terribly quickly. Since it's suggested mistreatment client-side code (java script) then there mustn't be a retardant reaching limits as every user visiting the page can have their own quota limit.

    ReplyDelete