Skip to content

Search in Radius

This API supports multiple types of geo searches:

  • Search for geo points located within specified distance (radius) from a given point.
  • Search in radius based on metadata.

Blocking API

public List<GeoPoint> Backedless.Geo.getPoints( BackendlessGeoQuery geoQuery ) 
                                                       throws BackendlessException

Non-Blocking API

public void getPoints( BackendlessGeoQuery geoQuery,
                       AsyncCallback<List<GeoPoint>> responder )

where:

Argument                Description
geoQuery a query object encapsulating the search parameters. See the Running Search Queries section below for details.
responder a responder object which receives a callback when the method successfully returns search result or if an error occurs. Applies to the asynchronous method only.

Return Value

A collection of GeoPoint objects matching the search query. Each GeoPoint object contains the following properties:

Argument                Description
objectId ID assigned to geo point by Backendless when it is saved in the backend geo location storage.
latitude latitude of the geo point.
longitude longitude of the geo point.
categories an array of geo categories the point belong to.
metadata metadata associated with the geo point. Accepted values for this parameter are: String, Number (integer and double), and Data Service objects. Date values must be represented as number in the Unix timestamp format (number of milliseconds since January 1, 1970 at UTC). Learn more about using date in search queries for category, radius, or rectangular area search.
distance distance between the center point referenced in the search query and the geo point. The distance is always in units specified in the search query.

Since the search query may produce a large number of geo points, not all of them are returned at once. Instead, all found geo points are divided into 'pages'. The size of each page is determined by the pageSize parameter in the query object. The first response returns the first page. The query object includes methods for adjusting page size and offset. Subsequent search requests with the query object will return additional pages of data.

Calculating offset

All geo points in the entire search result are indexed. The index of the first geo point is 0. The offset parameter in the query object specifies the index from which to load the next page of geo points. For example, suppose the entire search result is 200 points. If the initial pageSize is 20, then only 20 geo points are returned in the first response. To get the second page of geo points, they should be loaded from offset 20, third from 40 and so on. The formula for calculating the offset is:
 [value of offset in the current response] + [size of current page ].

The geo points in the search results will be sorted by their proximity to the central point (center of the radius): the geo points that are closest to the central point will be listed first.

Running Search Queries

The geo query object includes multiple parameters, none of them are required. As a result, depending on which parameters contain values, the semantics of the search would change. Any search must be performed within at least one category. If no category names are provided, the search is performed in the Default category.

Search in categories with radius

Radius-based search establishes a circular area by setting the coordinates of a central point and a distance (radius). Backendless searches for geo points in the specified distance from the coordinates in the center and includes them into the search result. The value of the distance is interpreted based in the units parameter, which can be METERS, KILOMETERS, MILES, YARDS, FEET:

BackendlessGeoQuery geoQuery = new BackendlessGeoQuery();
geoQuery.addCategory( "Restaurants" );
geoQuery.setLatitude( 41.38 );
geoQuery.setLongitude( 2.15 );
geoQuery.setRadius( 10000d );
geoQuery.setUnits( Units.METERS );
List<GeoPoint> geoPoints = Backendless.Geo.getPoints( geoQuery );

Search in categories with radius and metadata

This is the same as above, with the difference that the search result includes only geo points with the matching metadata:

BackendlessGeoQuery geoQuery = new BackendlessGeoQuery();
geoQuery.addCategory( "Restaurants" );
geoQuery.setLatitude( 41.38 );
geoQuery.setLongitude( 2.15 );
geoQuery.setRadius( 10000d );
geoQuery.setUnits( Units.METERS );

HashMap<String, String> metaSearch = new HashMap<String, String>();
metaSearch.put( "Cuisine", "French"  );
metaSearch.put( "Athmosphere", "Romantic"  );
geoQuery.setMetadata( metaSearch );

List<GeoPoint> geoPoints = Backendless.Geo.getPoints( geoQuery );

Using dates in where clause when searching in radius

The search query used to retrieve geo points may reference date values. These values must be stored as a number of milliseconds since January 1st, 1970 at UTC. The example below demonstrates the usage of a date/time timestamp in a search condition:

Search in radius by date by using synchronous call:

public void searchByDateInRadiusSync() throws ParseException
{
  try
  {
    // date
    SimpleDateFormat dateFormat = new SimpleDateFormat( "dd.MM.yyyy 'at' HH:mm" );
    Date updated = dateFormat.parse( "17.01.2015 at 12:00" );

    // create
    GeoPoint geoPoint = new GeoPoint( 21.306944, -157.858333 );
    geoPoint.setCategories( Arrays.asList( "City", "Coffee" ) );
    geoPoint.addMetadata( "Name", "Starbucks" );
    geoPoint.addMetadata( "City", "Honolulu" );
    geoPoint.addMetadata( "Parking", true );
    geoPoint.addMetadata( "updated", new Date().getTime() );

    geoPoint = Backendless.Geo.savePoint( geoPoint );
    Log.i( "MYAPP", String.format( "searchByDateInRadius -> point: %s", geoPoint ) );

    // search
    BackendlessGeoQuery query = new BackendlessGeoQuery( 21.30, -157.85, 50, 
                                                         Units.KILOMETERS );
    query.addCategory( "City" );
    query.setWhereClause( String.format( "updated > %d", updated.getTime() ) );
    query.setIncludeMeta( true );

    List<GeoPoint> points = Backendless.Geo.getPoints( query );
    Log.i( "MYAPP", String.format( "searchByDateInRadius GETPOINTS: %s", 
                                   points.getCurrentPage() ) );
  }
  catch( BackendlessException e )
  {
    Log.e( "MYAPP", String.format( "searchByDateInRadius FAULT = %s", e ) );
  }
}

Search in radius by date by using asynchronous call:

public void searchByDateInRadiusAsync() throws ParseException
{
  // date
  SimpleDateFormat dateFormat = new SimpleDateFormat( "dd.MM.yyyy 'at' HH:mm" );
  final Date updated = dateFormat.parse( "17.01.2015 at 12:00" );

  // create
  GeoPoint geoPoint = new GeoPoint( 21.306944, -157.858333 );
  geoPoint.setCategories( Arrays.asList( "City", "Coffee" ) );
  geoPoint.addMetadata( "Name", "Starbucks" );
  geoPoint.addMetadata( "City", "Honolulu" );
  geoPoint.addMetadata( "Parking", true );
  geoPoint.addMetadata( "updated", new Date().getTime() );

  Backendless.Geo.savePoint( geoPoint, new AsyncCallback<GeoPoint>()
  {
    @Override
    public void handleResponse( GeoPoint geoPoint )
    {
      Log.i( "MYAPP", String.format( "searchByDateInRadius -> point: %s", geoPoint ) );

      // search
      BackendlessGeoQuery query = new BackendlessGeoQuery( 21.30, -157.85, 50, 
                                                           Units.KILOMETERS );
      query.addCategory( "City" );
      query.setWhereClause( String.format( "updated > %d", updated.getTime() ) );
      query.setIncludeMeta( true );

      Backendless.Geo.getPoints( query, new AsyncCallback<List<GeoPoint>>()
      {
        @Override
        public void handleResponse( List<GeoPoint> points )
        {
          Log.i( "MYAPP", String.format( "searchByDateInRadius GETPOINTS: %s", 
                                         points.getCurrentPage() ) );
        }

        @Override
        public void handleFault( BackendlessFault fault )
        {
          Log.e( "MYAPP", String.format( "searchByDateInRadius FAULT = %s", fault ) );
        }
      } );
    }

    @Override
    public void handleFault( BackendlessFault fault )
    {
      Log.e( "MYAPP", String.format( "searchByDateInRadius SAVEPOINT: %s", fault ) );
    }
  } );
}

Requesting meta in response

Geo points returned in the search results do not include their metadata properties by default. The search query object includes a property which can be used to request the metadata to be included. This property can be used with any search options described above. The syntax for requesting metadata in response is described in the Search in Category section.