Blog

How to search for geopoints in a radius

by on March 4, 2015

Some of our other articles have covered what Backendless Geoservice is, how to populate a Backendless backend with sample data and how to run partial match geo searches. In this post, we will review the API for searching for geopoints in a circular shaped area or radius.

Searching for geopoints in a radius must be confined to a specific geocategory. The API will return geopoints located within the specified distance (radius) from a central point, all the points will belong to the specified category. Consider the sample code below:

    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<List>() {
       @Override
       public void handleResponse(List geoPoints) {
           for (GeoPoint geoPoint : geoPoints)
               Log.i(TAG, "GeoPoint - " + geoPoint);
       }
    
       @Override
       public void handleFault(BackendlessFault fault) {
           Log.e(TAG, fault.getMessage());
       }
    });

    val geoQuery = BackendlessGeoQuery()
    geoQuery.latitude = 32.555
    geoQuery.longitude = -97.667
    geoQuery.addCategory("geoservice_sample")
    geoQuery.isIncludeMeta = true
    geoQuery.radius = 270.0
    geoQuery.units = Units.MILES
    
    Backendless.Geo.getPoints(geoQuery, object : AsyncCallback<List> {
       override fun handleResponse(geoPoints: List) {
           for (geoPoint in geoPoints)
               Log.i(TAG, "GeoPoint - $geoPoint")
       }
       override fun handleFault(fault: BackendlessFault) {
           Log.e(TAG, fault.message)
       }
    })

    BackendlessGeoQuery *geoQuery = [BackendlessGeoQuery new];
    geoQuery.geoPoint = [[GeoPoint alloc] initWithLatitude:32.555 longitude:-97.667];
    geoQuery.categories = @[@"geoservice_sample"];
    geoQuery.includemetadata = YES;
    geoQuery.radius = @270;
    [geoQuery setUnitsWithUnits:UnitsMILES];
        
    [Backendless.shared.geo getPointsWithGeoQuery:geoQuery responseHandler:^(NSArray *points) {
        for (GeoPoint *point in points) {
            NSLog(@"GeoPoint - %@", [point pointDescription]);
        }
    } errorHandler:^(Fault *fault) {
        NSLog(@"Error: %@", fault.message);
    }];

    let geoQuery = BackendlessGeoQuery()
    geoQuery.geoPoint = GeoPoint(latitude: 32.555, longitude: -97.667)
    geoQuery.categories = ["geoservice_sample"]
    geoQuery.includemetadata = true
    geoQuery.radius = 270
    geoQuery.setUnits(units: Units.MILES.rawValue)
            
    Backendless.shared.geo.getPoints(geoQuery: geoQuery, responseHandler: { points in
        for point in points {
            print("GeoPoint - \(point.pointDescription())")
        }
    }, errorHandler: { fault in
        print("Error: \(fault.message ?? "")")
    })

    const Backendless = require('backendless')
    /*
     Or use `import Backendless from 'backendless'` for client side.
     If you don't use npm or yarn to install modules, you can add the following line
     <script src="//api.backendless.com/sdk/js/latest/backendless.min.js"></script>
     to your index.html file and use the global Backendless variable.
    */
    
    Backendless.initApp('YOUR_APP_ID', 'YOUR_JS_API_KEY')
    
    const searchPoints = () => {
      const query = new Backendless.GeoQuery()
    
      query.latitude = 32.555
      query.longitude = -97.667
      query.categories = ['geoservice_sample']
      query.includeMetadata = true
      query.radius = '270d'
      query.units = Backendless.Geo.UNITS.MILES
    
      return Backendless.Geo.find(query)
    }
    
    const onSuccess = points => {
      points.forEach(point => {
        console.log(`GeoPoint - ${JSON.stringify(point)}`)
      })
    }
    
    const onError = error => {
      console.error('Server reported an error: ', error.message)
      console.error('error code: ', error.code)
      console.error('http status: ', error.status)
    }
    
    Promise.resolve()
      .then(searchPoints)
      .then(onSuccess)
      .catch(onError)
    

    BackendlessGeoQuery geoQuery = BackendlessGeoQuery()
     ..latitude = 32.555
     ..longitude = -97.667
     ..addCategory("geoservice_sample")
     ..includeMeta = true
     ..radius = 270.0
     ..units = Units.MILES;
    
    Backendless.Geo.getPoints(query: geoQuery).then((geoPoints) {
     geoPoints.forEach((geoPoint) => print("GeoPoint - $geoPoint"));
    });


    The program output is:

    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}

    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, we 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 our testing:

    To run searches in radius in the Console:

    1. Login to Backendless Console, select your app and click the Geolocation icon.
    2. Select a geocategory where you would like to perform a search.
    3. Click the Map-driven navigation toggle located under the map.
    4. Click the Search in radius toggle.
    5. The map displays a circle that 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.