This sample application demonstrates a possible data drilldown or refinement. The sample implements two options in parallel:
FeatureCollection
element, which allows the use of GeoJSON data as input. We use two different GeoJSON source files,
one providing the country border, and the second providing county borders.
The GeoJSON files provide only the geometry data. In order to interact with the objects defined in the GeoJSON we need to add Feature
elements
to the FeatureCollection
. Feature
work as active overlays on the GeoJSON objects allowing to change colors and to interact with them
by handling event. The match between Feature
elements and GeoJSON objects is done by ID. In our sample is the either the ISO country code or the
ISO county code.
<GeoMap id="VBIDrillDown" width="100%" height="100%" centerPosition="10.298404;50.829142" zoomlevel="4" zoomChanged="onZoomChanged" />
We start placing a plain GeoMap
control on the view without any aggregation. Important is the assignment of the
handler function onZoomChanged
to the map event zoomChanged
. This will allow us to react on zoom changes.
onInit : function () { var oModel = new sap.ui.model.json.JSONModel(); oModel.setData( this.oData ); this.getView().setModel(oModel); this.oVBI = this.getView().byId("VBIDrillDown"); this.addFeatureCollection(0); }, addFeatureCollection : function ( currentDetailLevel ) { this.FCRef = new sap.ui.vbm.FeatureCollection( { srcURL: (!currentDetailLevel) ? "media/L0_DE.json" : "media/L1_DE.json", click : this.onClickFC.bind(this), items: { path: "/Features", template: new sap.ui.vbm.Feature({ color: '{color}', tooltip:'{tooltip}', featureId : '{id}' }) } }); this.oVBI.addFeatureCollection(this.FCRef); }
In function onInit
we create a JSONModel
, give it some data and assign it to the view.
The model will serve as data source for our Feature
overlays. Thus we need actually two models, one for
the country level and one for the county level. Since we either show the country or the county level, we do not use
two models in this sample, but exchange the data of the model. Therefore we define two data objects, oData
and oDataDetail
in the controller.
As last initilization step we call function addFeatureCollection
. In this function we create a FeatureCollection
instance, with either the country (L0) or county (L1) GeoJSON as source depending on function parameter currentDetailLevel
.
We add event handler onClickFC
to react on click events of the feature collection. We use the bind function to srt the scope of
the handler function to the controller instance.
Finally we add a Feature
template for the items
aggregation, bound to the model. Depending on the actual data given to the model,
we will get Feature
instances for the country or counties.
onClickFC : function (e) { var id = e.getParameter("featureId"); var FeatureIds = [id]; var datas = this.FCRef.getFeaturesInfo(FeatureIds); var bbs = [datas[id].BBox]; this.oVBI.zoomToAreas(bbs, 0.95); }
With the click event we receive the ID of the clicked feature as parameter. We can use the getFeaturesInfo
function of the FeatureCollection
to retrieve additional information for that ID. One information is are the
coordinates for the bounding box of that feature. We use this bounding box coordinates as input for GeoMap
function
zoomToAreas
in order to focus the map display on that area. The second parameter of this function allows the add
some margin to the visible map section.
onZoomChanged : function (e) { var oVBI = this.oVBI; if(oVBI) { var switchZoomLevel = 5; var zl = e.getParameter( "zoomLevel" ); var oModel = this.getView().getModel(); if(oVBI.getFeatureCollections().length > 0) { if (zl > switchZoomLevel && this.currentDetailLevel === 0){ oModel.setData( this.oDataDetail ); this.currentDetailLevel = 1; } else if (zl <= switchZoomLevel && this.currentDetailLevel === 1){ oModel.setData( this.oData ); this.currentDetailLevel = 0; } oVBI.removeFeatureCollection(this.FCRef); this.addFeatureCollection(this.currentDetailLevel); } } }
From the event zoomChanged
we receive the new zoom level as parameter zoomLevel
. We compare
the new zoom level with our pre-defined switchZoomLevel
.
Is the new zoom level greater than the switch value
and the currentDetailLevel
is still zero we remove the current FeatureCollection
instance from the
GeoMap
control by calling function removeFeatureCollection
. Than we create a new feature collection for
detail level 1 and set also the model data to this.oDataDetail
.
Is the new zoom level less or equal the switch value
and the currentDetailLevel
is 1 we remove the FeatureCollection
instance from the
GeoMap
control, create a new feature collection for
detail level 0, and set also the model data back to this.oData
.