Skip to content

Relations with Geo Points

Backendless Geo Service manages application's geo location data and provides APIs to work with Geo points. Backendless supports integration between data objects managed by Data Service and geo points for the scenarios when a logical connection between the two entity types must exist in an application. For instance, in a taxi ordering application a data object may represent a taxi car, while a geo point represents its location on the map. Linking the two entity types together provides great benefits such as retrieving both objects at once and managing as a consistent, cohesive object hierarchy.

The Data-to-Geo integration is implemented through object relations. Data table schema may declare a table column with a special data type - "GeoPoint Relationship". As a result, the data objects in the table may contain a reference to one or more GeoPoints. When a data object with a related GeoPoint is saved, Backendless persists information about both the data object and the geo point in the corresponding persistent systems and sets up the relationship. Likewise, when a data object is retrieved by using the API, any related geo points can be retrieved using the same principle for loading data relations. The data-to-geo relation is bidirectional, it means a geo point may reference a data object in its metadata. You can learn more about it in the Relations with Data Objects section of the Geolocation documentation.

The relationship between a data object and a geo point (or a collection of) can be established by using either the "code first" or the "schema first" approaches. With the former, the relationship is determined by the data structure persisted with the API. If a data object references a GeoPoint (or a collection of) in one of its properties, Backendless interprets it as a relation and, as a result, will create a relation column in the data table schema. With the latter ("schema first") approach, application developer can declare a relationship in the data table schema first. In either one of these approaches, once a relationship is declared, data objects and geo points may be linked together by using the Backendless console as well.

This chapter consists of the following sections:

Declaring a Data-to-Geo Relationship in Table Schema

Linking a Data Object with Geo Points

Update/Delete Relations

Deleting Relation Column in Table Schema

Establishing Relations with Geo Points via API

Declaring a Data-to-Geo Relationship in Table Schema

To declare a relationship in a data table schema:

  1. Select a table where a relation column should be declared.
  2. Click the Schema menu.
  3. Click the New button. Enter a name for the new column in the Name field. This column will represent a data-to-geo relationship.
  4. Select the Geopoint Relationship option from the Type drop-down list.
    geo-point-relationship-type

  5. Select the constraints and/or cardinality of the relation from the corresponding drop-down menus.

    Constraints:
    There are two available constraints: "Not Null (Required)" and "Unique Value". The former (NN) establishes the column as required. It means when a new object is created or an existing one is updated, server will be expecting a value for the column. The latter constraint (UQ) will enforce a rule that the column must contain a unique value, thus no two objects will be able to contain the same GeoPoint.

    Cardinality:
    The one-to-one relation means that a table's object can be linked with only one geo point, while the one-to-many relation means that a table's object can be linked with multiple geo points.
    location-column

  6. Click the CREATE button to save the changes.

Linking a Data Object with Geo Points

Once a data-to-geo relationship column is declared, data objects from the table can be linked to geo point(s) as described below:

  1. Click the name of the table containing an object you want to link with a geo point.
  2. Table columns representing the data-to-geo relationships are identified as "GEOPOINT relationship" in the header row. The cardinality of the relation is visualized as one red line for the one-to-one relations and three red lines for the one-to-many relations:
    geopoint-column.zoom70
  3. To create a relationship between an object and a geopoint, click the plus icon next in the cell for a GEOPOINT column.
    plus-icon-for-geopoint.zoom70
  4. The Set Related GeoPoint pop-up window will display the list of the geo points. Use the Geo Category drop-down list to select a geo category from which the points should be displayed. Additionally, you can use the search bar to locate a geopoint by its metadata:
    geopoint-search.zoom80
  5. If you declared a one-to-one relation for a table the object belongs to, you will be able to link this object with only one geo point (by the means of a radio button). If it is a one-to-many relationship, the interface uses check boxes, which allow for multiple selection. Click a radio-button or select check-boxes next to the geo points which you want to link with the data object.
  6. Click the ADD RELATION button to save the changes.

Once a relation is established, it is shown in the data browser as a hyperlink. The hyperlink for the one-to-one relations displays the coordinates of the related geo point. For the one-to-many relations the link says "multiple Geopoints". In both cases, the link opens the Geolocation screen of the console which displays the related geo point(s). Additionally, the link has a mouse-over preview for the related geopoints:

geopoint-preview

Update/Delete Relations

To update a data-to-geo relation, use the same plus icon that opened the popup to create a geopoint relation. The popup tracks the selection changes and allows update or deletion of the relation.

Deleting Relation Column in Table Schema

A data-to-geo relationship can be removed at the schema level. When a relationship column is removed, the "links" between the corresponding data objects and geopoints are deleted, however, it does not remove the objects themselves.

To delete a relationship definition between a data table and the geo points:

  1. Click the name of the table which contains a "GeoPoint relationship" column you need to remove.
  2. Click the Schema menu
  3. Click the check-box next to the column you need to delete.
  4. Click the Delete menu.
    delete-geopoint-relation-column

Establishing Relations with Geo Points via API

Creating a relationship between a data object and a geo point (or a collection of) uses the same API as saving a data object with a related entity. In the case of data-to-geo relations, the related entity is a geopoint or a collection of geopoints. Consider the example that below saves a data object with a related geopoint. The geopoint is also persisted in the Geo Service:

The example below demonstrates how to link a taxi (a data object) with its location (geo point). First, declare the TaxiCabclass:

The Map-based approach does not require you defining classes for the objects stored in Backendless. Instead your code can use java.util.Map to to store and retrieve objects in/from Backendless.

public class TaxiCab
{
  public String carmake;
  public String carmodel;
  public GeoPoint location;
  public List<GeoPoint> previousDropOffs;

  public String getCarmake()
  {
    return carmake;
  }

  public void setCarmake( String carmake )
  {
    this.carmake = carmake;
  }

  public String getCarmodel()
  {
    return carmodel;
  }

  public void setCarmodel( String carmodel )
  {
    this.carmodel = carmodel;
  }

  public GeoPoint getLocation()
  {
    return location;
  }

  public void setLocation( GeoPoint location )
  {
    this.location = location;
  }

  public List<GeoPoint> getPreviousDropOffs()
  {
    return previousDropOffs;
  }

  public void setPreviousDropOffs( List<GeoPoint> previousDropOffs )
  {
    this.previousDropOffs = previousDropOffs;
  }
}

To set one-to-one or one-to-many relations:

Important

The code uses synchronous API - when executing on Android, make sure to run it on a non-UI thread, or change the code to use the asynchronous API.

GeoPoint point = new GeoPoint();
point.setLatitude( 40.7148 );
point.setLongitude( -74.0059 );
point.addCategory( "taxi" );
point.addMetadata( "service_area", "NYC" );
point = Backendless.Geo.savePoint( point );

List<GeoPoint> previousDropOffs = new ArrayList<GeoPoint>();

GeoPoint dropOff1 = new GeoPoint( 40.757977, -73.98557 );
dropOff1.addMetadata( "name", "Times Square" );
dropOff1.addCategory( "DropOffs" );
dropOff1 = Backendless.Geo.savePoint( dropOff1 );
previousDropOffs.add( dropOff1 );

GeoPoint dropOff2 = new GeoPoint( 40.748379, -73.985565 );
dropOff2.addMetadata( "name", "Empire State Building" );
dropOff2.addCategory( "DropOffs" );
dropOff2 = Backendless.Geo.savePoint( dropOff2 );
previousDropOffs.add( dropOff2 );

Map taxi = new HashMap();
taxi.put( "carmake", "Toyota" );
taxi.put( "carmodel", "Prius" );
taxi = Backendless.Data.of( "TaxiCab" ).save( taxi );

ArrayList<GeoPoint> location = new ArrayList<GeoPoint>();
location.add( point );
// create a one to one relation
Backendless.Data.of( "TaxiCab" ).setRelation( taxi, "location:GeoPoint:1", location );

// link several points to data object
Backendless.Data.of( "TaxiCab" ).setRelation( taxi, "previousDropOffs:GeoPoint:n", previousDropOffs );
GeoPoint point = new GeoPoint();
point.setLatitude( 40.7148 );
point.setLongitude( -74.0059 );
point.addCategory( "taxi" );
point.addMetadata( "service_area", "NYC" );
point = Backendless.Geo.savePoint( point );

List<GeoPoint> previousDropOffs = new ArrayList<GeoPoint>();

GeoPoint dropOff1 = new GeoPoint( 40.757977, -73.98557 );
dropOff1.addMetadata( "name", "Times Square" );
dropOff1.addCategory( "DropOffs" );
dropOff1 = Backendless.Geo.savePoint( dropOff1 );
previousDropOffs.add( dropOff1 );

GeoPoint dropOff2 = new GeoPoint( 40.748379, -73.985565 );
dropOff2.addMetadata( "name", "Empire State Building" );
dropOff2.addCategory( "DropOffs" );
dropOff2 = Backendless.Geo.savePoint( dropOff2 );
previousDropOffs.add( dropOff2 );

TaxiCab taxi = new TaxiCab();
taxi.carmake = "Toyota";
taxi.carmodel = "Prius";
taxi = Backendless.Data.of( TaxiCab.class ).save( taxi );

ArrayList<GeoPoint> location = new ArrayList<GeoPoint>();
location.add( point );
// create a one to one relation between the data object and a geopoint
Backendless.Data.of( TaxiCab.class ).setRelation( taxi, "location:GeoPoint:1", location );

// link several points to data object
Backendless.Data.of( TaxiCab.class ).setRelation( taxi, "previousDropOffs:GeoPoint:n", previousDropOffs );

After you run the code, you will see the following data object and geopoints created in the application:

Data object:

taxi-data-object.zoom70

Geopoints:

taxi-geo-points.zoom70