Skip to content

GeoPoint Clustering

Geo point search in a category, radius or a rectangular area may return too many geo points within close geographic proximity from each other. This might be difficult to view and process in a client application. To address this problem, Backendless supports the * geo clustering* feature. A geo cluster is a group of several geo points located close to each other. The two screenshots below demonstrate the advantages of clustering: the picture on the top displays search results in the Backendless Console with clustering turned off and the one on the bottom displays search results as clusters when clustering has been enabled:

Geo Points View:

clustering-points.zoom50

Clusters and Points View:

clustering-clusters.zoom50

Backendless creates clusters by splitting the map into a grid of squares. Geo points which belong to a square are placed into the same cluster. When a square contains only one point, it remains non-clustered.

Testing Geo Clustering in Backendless Console

The Geolocation page displays non-clustered geo points by default. To see how geoclustering works and test geoclustering search results:

  1. Log in to Backendless Console, select an application and click the Geolocation icon.
  2. Click the Map-driven navigation toggle. The toggle changes how the geo points are loaded from the backend. In the map-driven mode console loads the geo points for the visible area of the map.
  3. Click the Geo Clustering toggle to enable clustering.
  4. Console reloads geo points and clusters for the current viewport of the map and displays the results. A cluster is visualized as a blue marker on the map with a number indicating how many geo points it represents.
    geofence-screen7.zoom50

Geo clustering is also available with the "Search in Radius" option, which searches for geo points in a circular area. To enable this functionality, click the Search in radius toggle:

geofence-screen8.zoom50

If you want to see the geo points in a cluster, zoom in the map or double-click a cluster's marker. Zooming the map in too much (when using the clustering along with the search in radius) may result that the search radius will be much bigger than the visible part of the map on the screen. In this case, zoom out so you can adjust the circle position and/or radius.

Clicking a cluster's marker will reveal the coordinates and combined metadata of all geopoints in the cluster.

geofence-screen9.zoom50

Retrieving Clustered Geo Points

Geo point clustering can be requested by setting clustering parameters in BackendlessGeoQuery, which is used in the calls to retrieve geo points from a category, radius or rectangular area.

public void setClusteringParams(double westLongitude, 
                                double eastLongitude, 
                                int mapWidth, 
                                int clusterGridSize )  

// same as above, but uses the default clusterGridSize of 100
public void setClusteringParams(double westLongitude, 
                                double eastLongitude, 
                                int mapWidth ).

where:

  • westLongitude - the longitude of any point on the western boundary of the map in degrees.
  • eastLongitude - the longitude of any point on the eastern boundary of the map in degrees. | Argument                | Description | | --- | --- | | mapWidth | the size of the viewing area of the map in pixels. | | clusterGridSize | the size in pixels of the grid's squares used to group points into clusters. The default value is 100 pixels |

Example

Once the clustering parameters are set, the geo point search API will return clustered geo points. The return value is a collection of GeoCluster and/or GeoPoint objects. Instances of the latter may be returned when a geo point does not have any neighboring points within the grid's square it belongs to. The GeoCluster class extends from GeoPoint and supports all the inherited properties: latitude, longitude, categories and metadata. Additionally, geo cluster has its own property representing the number of points the cluster consists of. Since a GeoCluster object an instance of the GeoPoint class, the processing of search responses may look like this:

int mapWidth = 500;
double westLongitude = 23.123;
double eastLongitude = -80.238;

BackendlessGeoQuery geoQuery = new BackendlessGeoQuery();
geoQuery.addCategory( "geoservice_sample" );
geoQuery.initClustering( westLongitude, eastLongitude, mapWidth );
List<GeoPoint> points = Backendless.Geo.getPoints( geoQuery );

Iterator<GeoPoint> iterator=points.iterator();

while( iterator.hasNext() )
{
    GeoPoint geoPointOrCluster =iterator.next();

    if( geoPointOrCluster instanceof GeoCluster )
    {
        GeoCluster geoCluster = (GeoCluster) geoPointOrCluster;
        Log.i( "MYAPP", "Number of points in the cluster: " + geoCluster.getTotalPoints() );
    }
    else
    {
        Log.i( "MYAPP", "Loaded geo point" );
    }

    Log.i( "MYAPP", "latitude - " + geoPointOrCluster.getLatitude() + 
                    ", longitude - " + geoPointOrCluster.getLongitude() );
}

Loading Geo Points from a Cluster

With the geo clustering feature enabled, you may need to reveal the geo points gathered in a cluster. In the Backendless Console, you can click the cluster to reveal its details as described above. By using the calls described below, you will be able to reveal the geo points in a cluster via API.

Blocking API

List<GeoPoint> Backendless.Geo.loadGeoPoints( GeoCluster geoCluster )

Non-Blocking API

Backendless.Geo.loadGeoPoints( final GeoCluster geoCluster, 
                               final AsyncCallback<List<GeoPoint>> responder )

Return Value

A collection of GeoPoint objects that are included into a cluster.