Previously I described what Backendless Geoservice is, how to populate a Backendless backend with sample data and how to run partial match geo searches. In this post I will review the API for searching geopoints in a circular shaped area, or in radius. Searching for geopoints in radius must be confined to a specific geocategory. The API will return geopoints located within specified distance (radius) from a central point, all the points will belong to the specified category. Consider the sample code below:
Asynchronous sample (Android and Plain Java):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
BackendlessGeoQuery geoQuery = new BackendlessGeoQuery(); geoQuery.setLatitude( 32.555 ); geoQuery.setLongitude( -97.667 ); geoQuery.addCategory( "geoservice_sample" ); geoQuery.setIncludeMeta( true ); geoQuery.setRadius( 270d ); geoQuery.setUnits( Units.MILES ); Backendless.Geo.getPoints( geoQuery, new AsyncCallback<BackendlessCollection<GeoPoint>>() { @Override public void handleResponse( BackendlessCollection<GeoPoint> geoPointCollection ) { Iterator<GeoPoint> iterator = geoPointCollection.getCurrentPage().iterator(); while( iterator.hasNext() ) { GeoPoint geoPoint = iterator.next(); System.out.println( "GeoPoint - " + geoPoint ); } } @Override public void handleFault( BackendlessFault backendlessFault ) { System.out.println( "Server reported an error - " + backendlessFault.getMessage() ); } } ); |
Synchronous sample (Plain Java only):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
BackendlessGeoQuery geoQuery = new BackendlessGeoQuery(); geoQuery.setLatitude( 32.555 ); geoQuery.setLongitude( -97.667 ); geoQuery.addCategory( "geoservice_sample" ); geoQuery.setIncludeMeta( true ); geoQuery.setRadius( 270d ); geoQuery.setUnits( Units.MILES ); BackendlessCollection<GeoPoint> geoPointCollection = Backendless.Geo.getPoints( geoQuery ); Iterator<GeoPoint> iterator = geoPointCollection.getCurrentPage().iterator(); while( iterator.hasNext() ) { GeoPoint geoPoint = iterator.next(); System.out.println( "GeoPoint - " + geoPoint ); } |
The program output is:
1 2 3 4 5 6 7 8 |
GeoPoint - GeoPoint{objectId='6CB5FECA-B2C9-3002-FFC4-17D8D069A400', latitude=32.73569, longitude=-97.10807, categories=[geoservice_sample], metadata={city=ARLINGTON}, distance=34.87} GeoPoint - GeoPoint{objectId='D60EFC78-673D-0DA8-FFD7-53C8D8BF8D00', latitude=32.78306, longitude=-96.80667, categories=[geoservice_sample], metadata={city=DALLAS}, distance=52.519} GeoPoint - GeoPoint{objectId='AD1C546F-DD65-C4B7-FFA6-57ACD06B6C00', latitude=33.15067, longitude=-96.82361, categories=[geoservice_sample], metadata={city=FRISCO}, distance=64.025} GeoPoint - GeoPoint{objectId='1905CA4C-1C4B-1156-FF2A-C505999DA300', latitude=33.01984, longitude=-96.69889, categories=[geoservice_sample], metadata={city=PLANO}, distance=64.83} GeoPoint - GeoPoint{objectId='C594A668-B9A2-4D24-FF5A-D4F700DECB00', latitude=30.26715, longitude=-97.74306, categories=[geoservice_sample], metadata={city=AUSTIN}, distance=158.313} GeoPoint - GeoPoint{objectId='3729180E-E50A-674C-FFF2-CB27C4003C00', latitude=35.46756, longitude=-97.51643, categories=[geoservice_sample], metadata={city=OKLAHOMA CITY}, distance=201.644} GeoPoint - GeoPoint{objectId='00CF08C4-6C6D-8563-FF94-5E7FFD298B00', latitude=29.42412, longitude=-98.49363, categories=[geoservice_sample], metadata={city=SAN ANTONIO}, distance=222.036} GeoPoint - GeoPoint{objectId='8C946475-BA0A-CB8B-FF46-8D6E628E2F00', latitude=29.76328, longitude=-95.36327, categories=[geoservice_sample], metadata={city=HOUSTON}, distance=236.376} |
Synchronous sample:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
-(void)loadGeoPointsSync { NSLog(@"\n============ Loading geo points with the SYNC API ============"); @try { BackendlessGeoQuery *query = [BackendlessGeoQuery queryWithPoint:(GEO_POINT){.latitude=32.555, .longitude=-97.667} radius:270 units:MILES categories:@[@"geoservice_sample"]]; query.includeMeta = @YES; BackendlessCollection *points = [backendless.geoService getPoints:query]; NSLog(@"Total points in radius %@", points.totalObjects); while ([points getCurrentPage].count) { NSArray *geoPoints = [points getCurrentPage]; for (GeoPoint *geoPoint in geoPoints) { NSLog(@"%@", geoPoint); } points = [points nextPage]; } } @catch (Fault *fault) { NSLog(@"Server reported an error: %@", fault); return; } } |
Asynchronous sample:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
-(void)loadGeoPointsAsync { NSLog(@"\n============ Loading geo points with the ASYNC API ============"); BackendlessGeoQuery *query = [BackendlessGeoQuery queryWithPoint:(GEO_POINT){.latitude=32.555, .longitude=-97.667} radius:270 units:MILES categories:@[@"geoservice_sample"]]; query.includeMeta = @YES; [backendless.geoService getPoints:query response:^(BackendlessCollection *points) { NSLog(@"Total points in radius %@", points.totalObjects); [self nextPageAsync:points]; } error:^(Fault *fault) { NSLog(@"Server reported an error: %@", fault); }]; } |
Synchronous sample:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
func loadGeoPointsSync() { println("\n============ Loading geo points with the SYNC API ============") Types.try({ () -> Void in var query = BackendlessGeoQuery.queryWithPoint( GEO_POINT(latitude: 32.555, longitude: -97.667), radius: 270, units: MILES, categories: ["geoservice_sample"] ) as! BackendlessGeoQuery query.includeMeta = true var points = self.backendless.geoService.getPoints(query) println("Total points in radius \(points.totalObjects)") while points.getCurrentPage().count > 0 { var geoPoints = points.getCurrentPage() as! [GeoPoint] for geoPoint in geoPoints { println("\(geoPoint)") } points = points.nextPage() } }, catch: { (exception) -> Void in println("Server reported an error: \(exception as! Fault)") } ) } |
Asynchronous sample:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
func loadGeoPointsAsync() { println("\n============ Loading geo points with the ASYNC API ============") var query = BackendlessGeoQuery.queryWithPoint( GEO_POINT(latitude: 32.555, longitude: -97.667), radius: 270, units: MILES, categories: ["geoservice_sample"] ) as! BackendlessGeoQuery query.includeMeta = true backendless.geoService.getPoints( query, response: { (var points : BackendlessCollection!) -> () in println("Total points in radius \(points.totalObjects)") self.nextPageAsync(points) }, error: { (var fault : Fault!) -> () in println("Server reported an error: \(fault)") } ) } } |
The code above works with the geoservice_sample category. This is a category created when you request Backendless to install sample geodata. While developing this sample I used Backendless console to verify the code results. You can perform searches in radius using the console which visualizes the geopoints located in the circular area you get to define. Below is a screenshot from my testing:
To run searches in radius in console:
- Login to Backendless console, select your app and click the Geolocation icon.
- Select a geocategory where you would like to perform a search.
- Click the Map-driven navigation toggle located under the map.
- Click the Search in radius toggle.
- The map displays a circle which can be resized or moved – use the points on the circumference and the central one to resize and move. As you move/resize the circle, Backendless returns the geopoints located within the area and the console renders them on the map. The console also provides information about the selected radius and the coordinates of the central point.