+ Start a Discussion
UtrivUtriv 

Geocode Doesn't Work

I have the following vf page to generate geocode for one of my custom object. I am not able to using the following script. Can some one plz help what is wrong with the code???

 

 

 

 

<apex:page standardController="Establishment_Record__c">

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

<script type="text/javascript">

var map = null;
var geocoder = null;

var address = "{!Establishment_Record__c.PremiseStreet__c}, {!

Establishment_Record__c.PremiseCity__c}, {!

Establishment_Record__c.PremiseState__c}, {!

Establishment_Record__c.PremisePostalCode__c}";

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.openInfoWindow(document.createTextNode(address));
}
}
);
}
}
</script>
<div id="MyMap" style="width:90%;height:300px"></div>
<script>
initialize() ;
</script>

</apex:page>

colemabcolemab

You might consider geocode caching your data . . .

colemabcolemab

Also, fire bug's console might tell you what (if any) errors you have in your javascript.  That is assuming you use firefox.

TheSwamiTheSwami

It worked fine for me.  I change your custom object to use the Contact object instead

 

<apex:page standardController="Contact">
<script src="http://maps.google.com/maps?file=api">
</script>
<script type="text/javascript">
var map = null;
var geocoder = null;
var address = "{!contact.mailingcity}, {!contact.mailingstate}";
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.openInfoWindow(document.createTextNode(address));
}
}
);
}
}
</script>
<div id="MyMap" style="width:90%;height:300px"></div>
<script>
initialize() ;
</script>
</apex:page>

 

Then I opened the page by passing in an id: 

/apex/geocode?id=0037000000SjkLF

 

It showed me a map of the city and state of the Contact.

UtrivUtriv

Thank you colemab.. I followed the geocode caching link you sent but I am not able to populate geocodes in the lat and long fields...where as the geocodeneedsupdated field says "False" in it... I ran the Geocodeupdater class too but it didnt work..What wrong I am doing..could you please tell??

 

Thank you very much..

UtrivUtriv

Thank you Swami...Actually it worked for me too in my custom object but i was not able to populate the lat and long for the address....does your code populate the lat and long too???

colemabcolemab

Due to limits from both salesforce and google, the geocoding class will need to be scheduled to run at least once per day and will take a while to cache out the long / lat data (days depending on how many addresses you are processing on the inital run).

 

When you say "it didn't work", how do you know it didn't work?  Did you run a report showing all records where the last update was populated and get no records?    Do you have a log of your run of the class that you could share?

UtrivUtriv

I ran both the classes but no geocode was updated.. How can i change the auto update?? currently it auto updates at 1am..i cant wait till then..Also I have setup around 10 records where geocodeneedsupdated equals "True"...

 

Also, when i ran the schedulegeocodeupdater it shows me the following message at the bottom of the page.

 

Average test coverage across all Apex Classes and Triggers is 22%, at least 75% test coverage is required.

colemabcolemab

First, you can either manually run the main class over and over again (possibly by a button or anonymous apex) or you can schedule the wrapper class.  You can schedule the wrapper class thru anonymous apex (click here for documentation).  You should be able to schedule this at any time you want - not just 1 am.   I recommend 10x per hour if you have that many available scheduled job slots in your system.  I recommend 10x as it will get you to 2400 of the 2500 daily limit from google.

 

Secondly, if you read thru the code you will see that the geocoder processes untouched records first for initialization and only when those are all processed will it look at the out of date entries where geocodeneedsupdate = true.

 

To be processed, records need at least a billingcity and billing state combo OR a zip code.

 

Here is some text code for the wrapper class:

 

static testmethod void TestScheduleGoogleGeoCodeUpdater() {
		Test.startTest();
		
       // Schedule the test job  
        String jobId = System.schedule('TestScheduleGoogleGeoCodeUpdater',
                ScheduleGoogleGeoCodeUpdater.CRON_EXP, 
                 new ScheduleGoogleGeoCodeUpdater());
                 
     // Get the information from the CronTrigger API object  
        CronTrigger ct = [SELECT id, CronExpression, TimesTriggered, 
           NextFireTime
           FROM CronTrigger WHERE id = :jobId];
  
     // Verify the expressions are the same  
        System.assertEquals(ScheduleGoogleGeoCodeUpdater.CRON_EXP, 
           ct.CronExpression);
  
     // Verify the job has not run  
        System.assertEquals(0, ct.TimesTriggered);
        
     Test.stopTest();   	
   } // test method      

 

Add it to the class and re-run your test coverage, you should get 100% on the wrapper class.   For technical reasons, it isn't possible to get 100% on the geocoding class.  You should get at least 85% though.

 

BTW, the geo code caching is useful when you want to render more points simultaneously than google's service will allow.  If you are wanting to render just one point on the map, you can do the geocoding in javascript.  As long as you don't send more than 1 request per 200ms you should be fine.

 

Hope this helps .....

UtrivUtriv

I have done everything correct as you said..but my code coverage is 22%...i believe thats what stopping generating lat long for my records...how do I increase code coverage?

colemabcolemab

Is the 22% for the schedule wrapper or the main class?

 

If you look at the log from your code coverage, do you have an exception? If so, on what line?

 

If you have no exception, can you look at the code coverage and tell me what lines aren't being covered?

 

 

UtrivUtriv

22% is on wrapper class..schedulegooglegeocodeupdater...there is no exception...its just a warning saying at least 75% coverage is required...

 

Line 4 to 7 are highlighted in blue on ScheduleGoogleGeoCodeUpdater..

 

the code coverage for googlegeocodeupdater is 18% only.. AND most of the code is highlighted in red...and some in blue...


 

colemabcolemab

Here is the full wrapper class with test code (it gets 100% coverage in my system):

 

global class ScheduleGoogleGeoCodeUpdater implements Schedulable {

	// Run the job every day at 1 am
    public static String CRON_EXP = '0 0 1 * * ?';

	 global void execute(SchedulableContext ctx) {		
		GoogleGeoCodeUpdater.ProcessUpdates();	 	
	 } // execute 
       
   static testmethod void TestScheduleGoogleGeoCodeUpdater() {
		Test.startTest();
		
       // Schedule the test job  
        String jobId = System.schedule('TestScheduleGoogleGeoCodeUpdater',
                ScheduleGoogleGeoCodeUpdater.CRON_EXP, 
                 new ScheduleGoogleGeoCodeUpdater());
                 
     // Get the information from the CronTrigger API object  
        CronTrigger ct = [SELECT id, CronExpression, TimesTriggered, 
           NextFireTime
           FROM CronTrigger WHERE id = :jobId];
  
     // Verify the expressions are the same  
        System.assertEquals(ScheduleGoogleGeoCodeUpdater.CRON_EXP, 
           ct.CronExpression);
  
     // Verify the job has not run  
        System.assertEquals(0, ct.TimesTriggered);
        
     Test.stopTest();   	
   } // test method      
} // class ScheduleGoogleGeoCodeUpdater

 

As for your code coverage in the main class, I don't think I can help without a screen shot showing where the blue lines start turning red or a log that shows an exception . . .

UtrivUtriv

it exceeds 20000 characters so I can send you the details of my code coverage...

colemabcolemab

Are you now getting 100% coverage when running apex tests on just the schedule wrapper class?

 

As for the regular class, please post just the exception and/or the last line of blue code (right before the lines start turning red enmasse).

UtrivUtriv

if you can give me your email address, i can send you both the files as attachment.. becuase the blue and red lines are all over....and by the way..when i run the wrapper class, it shows 100 % code coverage but the googlegeocodeupdater shows only 18% at that time..

 

Thanks for the great help!

colemabcolemab

sorry but I look at this in depth while at work.   I promise you the geocoding class works in my dev system w/ 86% test coverage.

 

Are you trying to use the class exactly as posted (i.e. with the billing address on the account object) or are you changing it for use with something like a custom object?

 

If you are using it as posted, please make sure you have created the 4 fields exactly as named and defined in the write up. 

 

If you are not seeing an exception in your debug log, then the queries returned no results and I would recommend trying to run them in force.com explorer or eclipse IDE to confirm they don't return any results.

colemabcolemab

If you still can't get this working, please send me a private message on this board and I can probably take a look at your log this afternoon.

colemabcolemab

I have received your email and replied with notes from the logs.  Please check your email and reply ...