Mobile Zone is brought to you in partnership with:

German has posted 19 posts at DZone. View Full User Profile

Geolocation with an MBaaS on Android

07.15.2013
| 3618 views |
  • submit to reddit
Having smart devices that are constantly aware of geographic positioning introduces many advantages but also new challenges for mobile application developers. Not only do developers find that data often needs to be efficiently stored with associated location data, but that it's also a requirement to do fast and accurate "geo-aware" queries to retrieve the right objects (eg. when refreshing a map view). In this article I will introduce the Geolocation feature that we've developed here at Kii to make your life easier when you're working with associated location data. Thanks to Geolocation, geo data becomes a first class citizen in our platform with the ability to support advanced geo queries.

Map marker

Actually, associating locations with your data and performing geo queries is easy. You just need to get familiar with two basic elements: GeoPoint and GeoQuery. A GeoPoint is basically a pair of latitude and longitude magnitudes that you can freely associate with a Kii object as its attribute. And a GeoQuery is what allows you to query for objects based on these GeoPoint attributes (eg. to issue queries like "which objects are in the given rectangular area?" (GeoBox clause) or "which objects are within a 10km radius of the given point?" (GeoDistance clause).

Let's create an example scenario to illustrate what you can do with Kii Geolocation (we'll provide a sample app around this soon). Imagine your app allows users to scan coupons that they can redeem later on specific stores. The app can store the location where the coupon was scanned and the location of the store where it was redeemed (both as GeoPoints). This information is then used by the app to display a map with locations where the user scanned and/or redeemed coupons.

The application screens looks more or less like this:

Kii Coupon Sample Mockup 


How can we store a Coupon object with location data? You can associate location data by just populating attributes with GeoPoints. For this this example we will associate two GeoPoint attributes to the Coupon: "viewedAt" and "redeemedAt":

KiiObject coupon = KiiUser.getCurrentUser().bucket("Coupons").object();
GeoPoint viewedAt = new GeoPoint(35.667983, 139.739356);
GeoPoint redeemedAt = new GeoPoint(34.342123, 139.335355);

// associate geo point with KiiObject
coupon.set("viewedAt", viewedAt);
coupon.set("redeemedAt", redeemedAt);
try {
  coupon.save();
} catch (IOException ioe) {
  // check fail reason
} catch (AppException ae) {
  // check fail reason.
}

When it's time to retrieve the GeoPoint attributes from an already populated object you'd simply do something like this:

// The fields "viewedAt" and "redeemedAt" have GeoPoint values
GeoPoint viewedAt = coupon.getGeoPoint("viewedAt");
GeoPoint redeemedAt = coupon.getGeoPoint("redeemedAt");
double viewedLat = viewedAt.getLatitude();
double viewedLon = viewedAt.getLongitude();

And now the best part: submitting geographic queries that are executed over objects on Kii Cloud. Let's stick to the proposed scenario and show a code snippet that answers the following query: "find all coupons that were viewed at a bounding box and redeemed at no more than 1 km of a specific store" (let's assume the bounding box is the current visible area of the map screen):

// Prepare the target bucket to be queried.
KiiBucket bucket = KiiUser.getCurrentUser().bucket("Coupons");
GeoPoint storeLocation = new GeoPoint(35.52105, 139.699402);

try {
  // Define GeoBox with NorthEast and SouthWest points.
  VisibleRegion vr = mMap.getProjection().getVisibleRegion();
  GeoPoint sw = new GeoPoint(
      vr.latLngBounds.southwest.latitude, 
      vr.latLngBounds.southwest.longitude);
  GeoPoint ne = new GeoPoint(
      vr.latLngBounds.northeast.latitude, 
      vr.latLngBounds.northeast.longitude);
  KiiClause clause1 = KiiClause.geoBox("viewedAt", ne, sw);
  KiiClause clause2 = KiiClause.geoDistance("redeemedAt", storeLocation, 1000);
  KiiQuery query = new KiiQuery(KiiClause.and(clause1, clause2));;

  // Execute GeoBox query.
  KiiQueryResult result = bucket.query(query);

  // Parsing the result will follow...

} catch (IOException ioe) {
  // check fail reason
} catch (AppException e) {
  // check fail reason.
}

As you can see, Kii GeoQuerys are smart enough to understand bounding boxes and distances to GeoPoints (with the ability to use multiple GeoPoints as part of queries). And what's really a plus here is that you can attach as many geo attributes as you want to your objects and have complex geo queries that rely on them (you're not limited to one associated GeoPoint per object!!).

You can get more detailed information about our Geolocation feature on our documentation.

Stay tuned for the iOS implementation of Geolocation (coming in the next few weeks...)

Published at DZone with permission of its author, German Viscuso.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)