Blog

How to Search for Geopoints in a Rectangular Area

by on September 1, 2019

In another article, we demonstrated sample code that shows how to search for Backendless geopoints in a radius. Now we will review the API for searching for geopoints in a rectangular area. The API is very similar to the one for search in radius, except the app must define the “view port” or the rectangular area on the map where the search must occur.

Consider the example below:

    BackendlessGeoQuery geoQuery = new BackendlessGeoQuery();
    geoQuery.setSearchRectangle(new double[]{49.615, -152.944, 25.648, -21.636});
    
    geoQuery.addCategory("geoservice_sample");
    geoQuery.setIncludeMeta(true);
    
    Backendless.Geo.getPoints(geoQuery, new AsyncCallback<List<GeoPoint>>() {
       @Override
       public void handleResponse(List<GeoPoint> 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.searchRectangle = doubleArrayOf(49.615, -152.944, 25.648, -21.636)
    
    geoQuery.addCategory("geoservice_sample")
    geoQuery.isIncludeMeta = true
    
    Backendless.Geo.getPoints(geoQuery, object : AsyncCallback<List<GeoPoint>> {
       override fun handleResponse(geoPoints: List<GeoPoint>) {
           for (geoPoint in geoPoints)
               Log.i(TAG, "GeoPoint - $geoPoint")
       }
    
       override fun handleFault(fault: BackendlessFault) {
           Log.e(TAG, fault.message)
       }
    })

    GeoPoint *nwPoint = [[GeoPoint alloc] initWithLatitude:49.615 longitude:-152.944];
    GeoPoint *sePoint = [[GeoPoint alloc] initWithLatitude:25.648 longitude:-21.636];
        
    BackendlessGeoQuery *geoQuery = [BackendlessGeoQuery new];
    geoQuery.rectangle = [[GeoQueryRectangle alloc] initWithNordWestPoint:nwPoint southEastPoint:sePoint];
    geoQuery.categories = @[@"geoservice_sample"];
    geoQuery.includemetadata = YES;
        
    [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 nwPoint = GeoPoint(latitude: 49.615, longitude: -152.944)
    let sePoint = GeoPoint(latitude: 25.648, longitude: -21.636)
            
    let geoQuery = BackendlessGeoQuery()
    geoQuery.rectangle = GeoQueryRectangle(nordWestPoint: nwPoint, southEastPoint: sePoint)
    geoQuery.categories = ["geoservice_sample"]
    geoQuery.includemetadata = true
            
    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.categories = ['geoservice_sample']
      query.includeMetadata = true
      query.searchRectangle = [49.615, -152.944, 25.648, -21.636]
    
      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()
      ..searchRectangle = Float64List.fromList([49.615, -152.944, 25.648, -21.636])
      ..categories = ["geoservice_sample"]
      ..includeMeta = true;
    
    Backendless.Geo.getPoints(query: geoQuery).then((geoPoints) {
      geoPoints.forEach((geoPoint) =^gt; print("GeoPoint - $geoPoint"));
    });

    Notice the code above sets the search rectangle as two pairs of coordinates. The first two numbers in the setSearchRectangle method are the latitude and longitude coordinates of the North-West corner of the search rectangle. The other two numbers are the coordinates of the South-East corner.

    Backendless Console makes it easy to identify the coordinates of the search rectangle and also provides a way to run a rectangle-based search for diagnostics purposes. To run a rectangle-based search in the Console:

    1. Login to Backendless Console, select your app and click the Geolocation icon.
    2. Select the geocategory for which you would like to perform the search.
    3. Click the Map-driven navigation toggle located under the map.
    4. As you pan and zoom the map, the Console runs rectangle-based geo point searches and displays the returned geo points on the map. Also, the map displays the coordinates of the North-West and South-East corners to make it easier for developers to replicate the same behavior in an API call.

    Leave a Reply