Location

Kinvey allows you to express the location of entities, including users, as longitude and latitude points on the coordinate system. Based on this, you can run proximity queries to find the closest restaurants, shops, or friends to a given location.

Location queries are only possible when the data store is in Network mode. Location queries in Cache or Sync mode return an error.

Storing Locations

For an entity to have an associated location, it needs an ArrayList parameter mapped to @Key("_geoloc").

For example, the code below adds a geocoord property to the Event class.

public class EventEntity extends GenericJson {

    @Key
    private String name;
    @Key
    private String address;
    @Key("_geoloc")
    private ArrayList<Double> geocoord;
    @Key
    private String date;
    @Key
    private KinveyMetadata meta; // Kinvey metadata, OPTIONAL

}

Note that the contents of the geocoord ArrayList in the example above have to be in the form [Longitude, Latitude].

Queries

Query supports special location operators that work on the _geoloc property

  • nearSphere
  • withinBox
  • withinPolygon

Here's an example of using some queries in an app:

Geolocation queries currently working only with NETWORK store type;

// This code assumes that you have a class with a name property,
// an address property and a geocoord property.  To properly enable
// geo queries, makes sure to map the "geocoord" property to 
// _geoloc 

event1.name = "Holiday Party At The Office";
event1.address = "1 Main St, Cambridge, MA";
event1.geocoord = Arrays.asList(new Double[]{-71.083934, 42.362474});

event2.name = "Pat's Birthday";
event2.address = "1 Broadway, Cambridge, MA";
event2.geocoord = Arrays.asList(new Double[]{-71.085438, 42.362688});

event3.name = "Happy Hour";
event3.address = "711 Atlantic Ave, Boston, MA";
event3.geocoord = Arrays.asList(new Double[]{-71.056416, 42.351018});


// Find all entities within a sphere centered at latutude 41, Longitude -71
Query q1 = new Query();
q1.nearSphere("_geoloc", 41, -71);


// Find all entites within .5 miles of the sphere centered at [42.35, -71.05]
Query q2 = new Query();
q2.nearSphere("_geoloc", 42.35, -71.05, 0.5);


// Find all entities "Within" the box that goes from
// point1 ([-70, 44]) to point2 ([-72, 42])
Query q3 = new Query();
q3.withinBox("_geoloc", 44, -70, 42, -72);


// Get our events collection, assuming your class is called event
DataStore<EventEntity> dataStore =
    DataStore<EventEntity>.Collection(
                "events",
                EventEntity.class,
                StoreType.NETWORK,
                client);


// Fetch the first group of entities
events.find(q1, new KinveyListCallback<EventEntity>() {

    public void onFailure(Throwable t) {
         Log.d(TAG, "Error fetching event data: " + t.getMessage());
     }

    public void onSuccess(List<EventEntity> eventEntities) {
         Log.d(TAG, "Retrieved " + eventEntities.size() + " events");
    }
});

// Fetch the second group of entities
events.get(q2, new KinveyListCallback<EventEntity>() {

    public void onFailure(Throwable t) {
         Log.d(TAG, "Error fetching event data: " + t.getMessage());
     }

    public void onSuccess(List<EventEntity> eventEntities) {
         Log.d(TAG, "Retrieved " + eventEntities.size() + " events");
    }
}); 
// Fetch the third group of entities
events.get(q3, new KinveyListCallback<EventEntity>() {

    public void onFailure(Throwable t) {
         Log.d(TAG, "Error fetching event data: " + t.getMessage());
     }

    public void onSuccess(List<EventEntity> eventEntities) {
         Log.d(TAG, "Retrieved " + eventEntities.size() + " events");
    }
});