3

I've successfully used geolocation in a list controller:

public class NearbySiteProgramListCon {
// ApexPages.StandardSetController must be instantiated
// for standard list controllers
public ApexPages.StandardSetController setCon {
    get {
        if(setCon == null) {
            setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                [SELECT Name, Start_Date__c, End_Date__c, ID FROM SiteProgram__c
                Where End_Date__c > Today AND
                DISTANCE(Location__c, GEOLOCATION(42.301165, -71.057052), 'mi') < 200
                Order by Name]));
        }
        return setCon;
    }
    set;
}

When I try to get more general in a new function, I get the following error:

Error: Compile Error: unexpected token: 'lat' at line 40 column 54

Trying the "{!lat}" instead of just "lat" didn't work either.

Here's the function. I want to be able to refresh the list for different regions via commandLinks in the Visualforce page.

public void getLocalSites(Decimal lat, Decimal lon, integer dist) {

setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                [SELECT Name, Start_Date__c, End_Date__c, ID FROM SiteProgram__c
                Where End_Date__c > Today AND
                DISTANCE(Location__c, GEOLOCATION(lat, long), 'mi') < 20   //line 40 is here
                Order by Name]));

}

Does the Geolocation function not take variables? Is there something wrong with trying to reset the list controller? I can write multiple functions with the distance and coordinates hard-coded, but I'd prefer not to.

Edited to Add

Here is the dynamic string I ended up using:

String query = 
'SELECT Name, Start_Date__c, End_Date__c, ID From SiteProgram__c WHERE End_Date__c > Today' + ' AND ' +
'DISTANCE(Location__c, GEOLOCATION(' + +lat.format()+','+lon.format() + '), \'mi\') < ' + dist + 
' ORDER BY Name';
3

Binding a variable requires a colon to start the binding. The correct syntax for your function would be:

public void getLocalSites(Decimal lat, Decimal lon, integer dist) {

setCon = new ApexPages.StandardSetController(Database.getQueryLocator(
                [SELECT Name, Start_Date__c, End_Date__c, ID FROM SiteProgram__c
                Where End_Date__c > Today AND
                DISTANCE(Location__c, GEOLOCATION(:lat, :long), 'mi') < 20   //line 40 is here
                Order by Name]));
}

However, a quick test suggests that you can't bind variables that way. Instead, you'll apparently need to build a string dynamically:

String query = 'SELECT ... WHERE ... DISTANCE(Location__c, '+lat.format()+','+long.format()+') < 20 ...';
  • Building the string dynamically worked. Thanks for pointing me in the right direction. – Jagular Dec 24 '14 at 16:45
3

Just a footnote - bind variables in GEOLOCATION are coming in Summer 15 https://developer.salesforce.com/releases/release/Summer15/queries

1

Wow - I actually found documentation of this... https://help.salesforce.com/apex/HTViewHelpDoc?id=custom_field_geolocate_overview.htm

Says: Apex bind variables aren’t supported for the DISTANCE or GEOLOCATION functions ...

Use a database query like this one instead

double latitude = 10;
double longitude = 20;
double distance = 30;
Database.query('SELECT ID, Name, Location__latitude__s,Location __longitude__s FROM Party__c where '+ 'DISTANCE(Location__c,GEOLOCATION('+latitude+','+longitude+' ),\'mi\') < '+distance);

Consistency is boring ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.