Location-Based SOQL Queries
The geolocation custom field type allows you to create a field to store location values. A geolocation field identifies a location by its latitude and longitude. Standard addresses on Salesforce objects also include a geolocation field that, when populated, can be used in similar ways—with a few restrictions. You can compare and query the locations of both types, for example, to find the 10 closest accounts.
For more information and considerations to keep in mind, see Compound Fields in the Salesforce Object Reference.
Field Types That Support Location-Based SOQL Queries
SOQL supports using simple numeric values for latitude and longitude using the GEOLOCATION function. These values can come from standard numeric fields, user input, calculations, and so on. They can also come from the individual components of a geolocation field, which stores both latitude and longitude in a single logical field. If a geocoding service has populated the geolocation field of a standard address, you can also use latitude and longitude values directly from an address.
SOQL queries made using the SOAP and REST APIs also support using geolocation fields, including address fields that have a geolocation component, directly in SOQL statements. This often results in simpler SOQL statements. Compound fields can only be used in SOQL queries made through the SOAP and REST APIs.
SELECT Clause
1SELECT Name, Location__latitude__s, Location__longitude__s
2FROM Warehouse__c1SELECT Name, Location__c
2FROM Warehouse__c1{
2 "totalSize" : 10,
3 "done" : true,
4 "records" : [ {
5 "attributes" : {
6 "type" : "Warehouse__c",
7 "url" : "/services/data/v30.0/sobjects/Warehouse__c/a06D00000017O4nIAE"
8 },
9 "Name" : "Ferry Building Depot",
10 "Location__c" : {
11 "latitude" : 37.79302,
12 "longitude" : -122.394507
13 }
14 }, {
15 "attributes" : {
16 "type" : "Warehouse__c",
17 "url" : "/services/data/v30.0/sobjects/Warehouse__c/a06D00000017O4oIAE"
18 },
19 "Name" : "Aloha Warehouse",
20 "Location__c" : {
21 "latitude" : 37.786108,
22 "longitude" : -122.430152
23 }
24 },
25 ...
26 ]
27}WHERE Clause
- DISTANCE
- Calculates the distance between two locations in miles or kilometers.
- Usage: DISTANCE(mylocation1, mylocation2, 'unit') and replace mylocation1 and mylocation2 with two location fields, or a location field and a value returned by the GEOLOCATION function. Replace unit with mi (miles) or km (kilometers).
- GEOLOCATION
- Returns a geolocation based on the provided latitude and longitude. Must be used with the DISTANCE function.
- Usage: GEOLOCATION(latitude, longitude) and replace latitude and longitude with the corresponding geolocation, numerical code values.
1SELECT Name, Location__c
2FROM Warehouse__c
3WHERE DISTANCE(Location__c, GEOLOCATION(37.775,-122.418), 'mi') < 20ORDER BY Clause
1SELECT Name, StreetAddress__c
2FROM Warehouse__c
3WHERE DISTANCE(Location__c, GEOLOCATION(37.775,-122.418), 'mi') < 20
4ORDER BY DISTANCE(Location__c, GEOLOCATION(37.775,-122.418), 'mi')
5LIMIT 10How SOQL Treats Null Location Values
Geolocation fields are compound fields that combine latitude and longitude values to describe a specific point on Earth. Null values are valid only if both latitude and longitude are null.
A record that has an invalid geolocation field value is treated as though both values are null when used in SOQL WHERE DISTANCE() and ORDER BY clauses. A record that has a geolocation field in which either the latitude or longitude is null is treated as though the field has not been set.
1SELECT Name, Location__c
2FROM Warehouse__c
3LIMIT 5| Name | Location__c |
|---|---|
| Ferry Building Depot | null |
| Aloha Warehouse | (37.786108,-122.430152) |
| Big Tech Warehouse | null |
| S H Frank & Company | null |
| San Francisco Tech Mart | (37.77587,-122.399902) |
1SELECT Name, Location__latitude__s, Location__longitude__s
2FROM Warehouse__c
3LIMIT 5| Name | Location__latitude__s | Location__longitude__s |
|---|---|---|
| Ferry Building Depot | null | -122.394507 |
| Aloha Warehouse | 37.786108 | -122.430152 |
| Big Tech Warehouse | null | null |
| S H Frank & Company | 37.763662 | null |
| San Francisco Tech Mart | 37.77587 | -122.399902 |
When you create formula fields that you plan to use for DISTANCE calculations, select Treat blank fields as blanks in the Blank Field Handling section. If you select Treat blank fields as zeros, distances are calculated from 0°, 0°—the point where the equator intersects the prime meridian—when your geolocation fields have null values. On record detail pages, null geolocation values in DISTANCE formula fields that are set to Treat blank fields as zeros cause the formula fields to display as empty.
How SOQL Calculates and Compares Distances
The DISTANCE function approximates the haversine, or “great circle,” distance calculation within 0.0002%. This formula assumes that the Earth is a perfect sphere, when in fact it’s an ellipsoid: an irregular one. Errors from this assumption can be up to 0.55% crossing the equator, but are usually below 0.3%, depending on latitude and direction of travel.
The DISTANCE function is fine for calculating the 10 stores closest to a customer’s current location. But don’t fuel your plane for a flight from San Francisco to Sydney based on it.
1WHERE ( DISTANCE(Location__c, testLocation) < 0.05 )Although the errors are small for nearly identical distances, the errors can cause a location query to include or exclude expected locations. If your application requires precise distance calculations and comparisons, we recommend that you do your own math.
Location-Based SOQL Query Considerations
Location-based queries are supported in SOQL in Apex and in the SOAP and REST APIs. Keep in mind these considerations.
- DISTANCE and GEOLOCATION are supported in WHERE and ORDER BY clauses in SOQL, but not in GROUP BY. DISTANCE is supported in SELECT clauses.
- DISTANCE supports only the logical operators > and <, returning values within (<) or beyond (>) a specified radius.
- When using the GEOLOCATION function in SOQL queries, the geolocation field must precede the latitude and longitude coordinates. For example, DISTANCE(warehouse_location__c, GEOLOCATION(37.775,-122.418), 'km') works but DISTANCE(GEOLOCATION(37.775,-122.418), warehouse_location__c, 'km') doesn’t work.
-
Apex bind variables aren’t supported for the units parameter in the DISTANCE function. This query doesn’t work.
1String units = 'mi'; 2List<Account> accountList = 3 [SELECT ID, Name, BillingLatitude, BillingLongitude 4 FROM Account 5 WHERE DISTANCE(My_Location_Field__c, GEOLOCATION(10,10), :units) < 10];
For more information, see Compound Field Considerations and Limitations in the Salesforce Object Reference.