This sample application demonstrates the clustering of spot objects on a map. Initially the spots are unclustered. When clicking the toggle button the objects are grouped together depending on their location. The number in the cluster object indicates the amount of objects clustered together. If you click on a cluster object a popover will open and show the list of all objects' tooltips. You can zoom in and out and see how the clustering changes depending on the zoom level. When you move the mouse over a cluster you can see the underlying area of the involved spots.

Add GeoMap control to view

We start placing a GeoMap control on the view with a spot aggregation. The properties of the spots are listed in json-file: index, geo location, tooltip and status. Status is defined as CustomData, which is a map with a key - value pair. The Spots aggregation needs a customProperties property which points to it.

XML View code

<vbm:GeoMap id='vbi' width="100%" height="100%"
   initialZoom='6' initialPosition="9.3;52;0">
   <vbm:vos>
      <vbm:Spots customProperties="{= ['status']}" items="{/spots}">
         <vbm:items>
            <vbm:Spot position='{A1}' tooltip='{A2}'
               type='Success'>
               <vbm:customData>
                  <core:CustomData key='status' value='{status}' />
               </vbm:customData>
            </vbm:Spot>
         </vbm:items>
      </vbm:Spots>
   </vbm:vos>
</vbm:GeoMap>
				

JSON View code

{
"spots": [
{"VB:ix":"0","A1":"9.22622;52.47909;0","A2": "LTL001001", "status":"good"},
{"VB:ix":"1","A1":"11.01954;53.38237;0","A2": "LTL001002", "status":"good"}
...
]
}
				

Add a Model and assign it to the view

Controller code

onInit: function() {
   this.oVBI = null;
   this.oCurrentClustering = null;
   var oController = this;
   var oModel = new sap.ui.model.json.JSONModel();
   oModel.setSizeLimit(99999);

   $.getJSON("media/clusterUnclustered.json", function(data) {
      oModel.setData(data);
      oController.oData = data;
   });
			
   this.getView().setModel(oModel);
   this.oVBI = this.getView().byId("vbi");
}
				

In function onInit we do some initialization for controller variables. Then we create a JSONModel, get the data from the json file and assign it to the view. The model will serve as data source for our spots. Note that we need to extend the size limit for the model because we specify more than 100 spot items.

Set and Remove Clustering

Controller code

onToggleCluster: function(e) {
   var bCluster = e.getParameter("pressed");

   if (bCluster) {
      if (!this.oCurrentClustering) {
         this.oCurrentClustering = new sap.ui.vbm.ClusterTree({
            rule: "status=good",
            click: this.onClickCluster.bind(this),
            vizTemplate: new sap.ui.vbm.Cluster({
               type: "Success",
               icon: 'sap-icon://shipping-status'
            })
         });
      }
      this.oVBI.addCluster(this.oCurrentClustering);
      e.getSource().setText("Cluster off");
   } else {
      this.oVBI.removeCluster(this.oCurrentClustering);
      e.getSource().setText("Cluster on");
   }

}
				
				

The function onToggleCluster turns the clustering mode on or off depending on the toggle button press state. The clustering aggregation object is created when it is called for the first time. In our sample we define a ClusterTree object. The rule defines which items will be clustered. The click event is bound to an onClickCluster method. The vizTemplate is the aggregation we use to define a control that serves as a visualization template for our cluster. In our sample we specify the Cluster control with the properties semantic type and an icon to show. Finally our GeoMap control adds or removes the clustering object.

Show Cluster Details

Controller code

onClickCluster: function( evt ){
   var oTarget = evt.getParameter("instance").getItem(); 
   var ident = evt.getParameter("instance").getKey();
   var type = sap.ui.vbm.ClusterInfoType.ContainedVOs;
   var info = this.oVBI.getInfoForCluster(ident, type);			
   var cluster = [];
   for (var j = 0; j < info.length; j++) {
      var spot = this.oVBI.getVoByInternalId(info[j]);
      if (spot) {
         cluster.push({name: spot.getTooltip()});
      }
   }
			
   var oClusterModel = new sap.ui.model.json.JSONModel();
   oClusterModel.setSizeLimit(99999);
   oClusterModel.setData({"cluster":cluster});
			
   var oPopover = new sap.m.Popover({
      title: "Cluster Details", 
      placement:"Right",
      content: new sap.m.List({
         items:{
            path: "/cluster",
            template: new sap.m.StandardListItem({
               title: '{name}',
               icon: 'sap-icon://shipping-status'
            })
         }
      })});
   oPopover.setModel(oClusterModel);
   ....
}
				

The function onClickCluster shows some detail information on a cluster object when it is clicked. To get this information we need to call method getInfoForCluster on our GeoMap control. First parameter identifies the cluster itself, second parameter specifies the type of information needed. The returned info is an array of internal IDs, and to get the spots out of them we use the method getVoByInternalId. The spots' tooltips are assembled in an array and set as data into a new model. We define a popover with a list of items to show it. The list gets a single list item element assigned to the items aggregation - acting as a template for the aggregation binding. The attribute 'title' of the template object are bound to model attribute 'name'.