CRM and CX Blogs by SAP
Stay up-to-date on the latest developments and product news about intelligent customer experience and CRM technologies through blog posts from SAP experts.
cancel
Showing results for 
Search instead for 
Did you mean: 
921


 

Requirement:


Integrate the AutoNavi Map with C4C so that Chinese customer can use map function.

 


AMap UI component integration


We get the requirement that to create a zoom/in out buttons on the map to control the zoom level for the AutoNavi Map instead of the tool bar.



So we need to import another module provided by AutoNavi Map which is named 'AMap UI', this module has 2 version : async version & sync version, before this backlog , our map is using the async version, so we need to use the async version's AMap UI.

previous codes:












AutoNaviMapApi.initialize = function(sApiKey) {

   if (!AutoNaviMapApi.isInitialized()) {

      window._AMapInitCallBack = sap.client.mashup.rt.map.AutoNaviMapApi._onApiInitializedCallback;

      var sUri = "https://webapi.amap.com/maps?v=1.3";

      if (sApiKey) {

         sUri += "&key=" + sApiKey + "&callback=_AMapInitCallBack";

      }


      if (!$("script[src*='webapi.amap.com/maps']").length) {

         jQuery.sap.includeScript(sUri);

      else {

         var iIntervalId = setInterval(function() {

            this._pollForInitialized(iIntervalId);

         }.bind(this), 500);

      }

   }

};






Actually the method 'jQuery.sap.includeScript(sUri)' is also a async method, and from below document, we should call initAMapUI() in the callback of the init map. But the initAMapUI() has some issue will cause the event '

apiInitialized' not called , then the map will not rendered.(the event 'apiInitialized' is triggered by method '_onApiInitializedCallback()').












1

2

3

4

5

6

7

8

9

10

11

12

13


/**

 * @private Method gets called when external maps API is initialized

 */

AutoNaviMapApi._onApiInitializedCallback = function() {


   // checks if event emitter was created for interested parties

   if (AutoNaviMapApi._oEventEmitter) {

      // emit event "apiInitialized" and destroy event emitter since API is initialized now

      AutoNaviMapApi._oEventEmitter.emit("apiInitialized").destroy();

      delete AutoNaviMapApi._oEventEmitter;

   }


};








refer to : http://lbs.amap.com/api/javascript-api/guide/amap-ui/intro/#import

Due to above issue , we have changed the map API & map UI API to sync version, and they will be initialized in method 'initialize', and we will call the callback after both API initialized ,also we have replace the sap standard (jQuery.sap.includeScript(sUri))method to the JQuery's method.












1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42


AutoNaviMapApi.initialize = function(sApiKey) {


   var that = this;

   //changed by joey.yang02@sap.com

   //Since we need to use AMapUI API , but the async version cannot support it correctly, so I just change the API to synchronized version

   //if the AutoNavi Map API is not initialized, we need to init it

   if (!AutoNaviMapApi.isInitialized() || !AutoNaviMapApi.isUIInitialized()) {


      var sUri = "https://webapi.amap.com/maps?v=1.3";

      if (sApiKey) {

         sUri += "&key=" + sApiKey;

      }


      if (!$("script[src*='webapi.amap.com/maps']").length) {


         $.getScript(sUri, function() {

            //after the AutoNavi Map API initialized,  we need to init the AMap UI API


            if (!AutoNaviMapApi.isUIInitialized()) {

               var sUirForUI = "https://webapi.amap.com/ui/1.0/main.js";


               if (!$("script[src*='webapi.amap.com/ui']").length) {


                  $.getScript(sUirForUI, function() {


                     //after the Map API and AMapUI API both initialized, need to call the callback method to render the map.

                     if (AutoNaviMapApi.isInitialized() && AutoNaviMapApi.isUIInitialized()) {

                        that._onApiInitializedCallback();

                     }

                  });

               }

            }

         });

      }

   }

   //if Map API and AMapUI API both initialized, need to call the callback method to render the map.


   if (AutoNaviMapApi.isInitialized() && AutoNaviMapApi.isUIInitialized()) {

      this._onApiInitializedCallback();

   }


};






Then we can use it in the codes:





Please note that the 'AMapUI.loadUI' is async process.

The Custom Component for AutoNavi Map


The requirement is to all some buttons on the map to impl the specific function, so we need to create some custom component which is provided by AutoNavi Map to impl these buttons.



AutoNavi Map has provide us a custom component to impl them, below is a sample to create a map setting button.












1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64


/**

 * @function to create map setting control for map setting button(AutoNavi Map)

 * @returns { the control of the map setting button}

 * @private

 */


_createMapSettingsControl: function() {


   var that = this;


   AMap.settingControl = function() {};


   AMap.settingControl.prototype = {


      addTo: function(map, dom) {

         dom.appendChild(this._getHtmlDom(map));

      },


      _getHtmlDom: function(map) {


         this.map = map;

         var oMapSettingsCtrl = document.createElement('div');


         oMapSettingsCtrl.style.right = '12px';

         oMapSettingsCtrl.style.bottom = '20px';

         oMapSettingsCtrl.style.height = '32px';

         oMapSettingsCtrl.style.position = 'absolute';

         oMapSettingsCtrl.style.boxShadow = '0px 1px 2px #d8d8d8';

         var controlUI = document.createElement('div');

         oMapSettingsCtrl.appendChild(controlUI);

         controlUI.id = "AMap-map-map-settings" + that.sId;

         if (!that._oMapSettingsBtn) {

            that._oMapSettingsBtn = new sap.m.Button({

               icon: "sap-icon://action-settings",

               press: function() {

                  that._openSettingsPopover();

               }

            }).addStyleClass("sapClientMCustomMapCtrls").addStyleClass("sapAutoNaviButton");

         }


         AMap.event.addListener(that._oMap, 'complete'function() {

            if (that._oMapSettingsBtn) {

               that._oMapSettingsBtn.placeAt(controlUI);

            }

         });


         that._aObjects2Destroy.push(that._oMapSettingsBtn);

         return oMapSettingsCtrl;

      }

   };


   if (this._oMap) {

      this._oMap.plugin(["AMap.settingControl"], function() {

         var oMapSettingsCtrl = new AMap.settingControl();

         if (!that.oSettingControl) {

            that._oMap.addControl(oMapSettingsCtrl);

            //after control created, we need to set this control to the object which is to belong to that so that we can remove it later

            that.oSettingControl = oMapSettingsCtrl;

            //push it to the destroy list

            that._aObjects2Destroy.push(that.oSettingControl);

         }

      });

   }

},






please note that the method 'addTo' & '_getHtmlDom' are AutoNavi's standard, we should follow it to create custom control on the map. and this method is async process.

Layers for AutoNavi Map


The requirement is to let the radio button control the map style,



The first step is to create layers on the map:












1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27


/**

 * @private

 * @function create layers on AutoNavi Map

 */

_createLayersForAutoNavi: function() {


   //create a Satellite layer for AutoNaviMap

   var satelliteLayerSettings = {

      detectRetina: true,

      zIndex: 2

   };


   var satelliteLayer = new AMap.TileLayer.Satellite(satelliteLayerSettings);

   satelliteLayer.setMap(this._oMap);

   satelliteLayer.hide();



   //create road net layer for autoNaviMap

   var roadNetLayerSettings = {

      detectRetina: true,

      zIndex: 3

   };


   var roadNetLayer = new AMap.TileLayer.RoadNet(roadNetLayerSettings);

   roadNetLayer.setMap(this._oMap);

   roadNetLayer.hide();

}






The AutoNavi Map has provide a method to get all layers , after you get all layers , you can control them to show or hide.












1

2

3

4

5

6

7

8

9

10

11

12

13

14

15


//get all layers for current map

var layers = this._oMap.getLayers();

//variable to define the satellite layer //variable to define the roadNet layer

var satelliteLayer, roadNetLayer;


for (var i = 0; i < layers.length; i++) {


   if (layers[i].CLASS_NAME === "AMap.TileLayer.Satellite") {

      satelliteLayer = layers[i];

   }

   if (layers[i].CLASS_NAME === "AMap.TileLayer.RoadNet") {

      roadNetLayer = layers[i];

   }


}






Destroy controls after the map destroyed.


We have created a batch of controls on the map , so after the map destroyed , we should destroy them.

The first step is to create a list to carry them:



Then after you created every control , you should push it into the list:



Then destroy it in the method 'destroy':











/**

 * @public Destroys instance and releases all resources.

 */

destroy: function() {


   if(this._innerMapContainerDiv) {

      this._innerMapContainerDiv.remove();

      this._innerMapContainerDiv = null;

   }

   if(this._oMap) {

      AMap.event.clearInstanceListeners(this._oMap);

   }

   deletethis._oMap;

   deletethis._oLocationPinHalo;

   deletethis._oMapSettingsBtn;

   deletethis._oSettingsPO;

   deletethis.oSettingControl;


   deletethis.oSearchNearControl;

   deletethis.oSearchAreaControl;

   deletethis.oLocatemeBtn;

   deletethis.oLocateMeCtrl;

   this._aObjects2Destroy.push(this.oClientStorage);

   deletethis.oClientStorage;

   this.oDefaultSettings = null;

   deletethis.oDefaultSettings;

   this._aObjects2Destroy.push(sap.ui.getCore().getUIArea("AMap-map-map-settings"));

   this._aObjects2Destroy.push(sap.ui.getCore().getUIArea("AMap-map-locate-me"));


   if(this.isSearchEnabled) {

      deletethis._SearchNearByBtn;

      deletethis._SearchAreaBtn;

      this._aObjects2Destroy.push(sap.ui.getCore().getUIArea("AMap-map-search-nearby"));

      this._aObjects2Destroy.push(sap.ui.getCore().getUIArea("AMap-map-search-area"));

   }

   deletethis.isSearchEnabled;

   Util.destroyObjects(this._aObjects2Destroy);

   Map.prototype.destroy.apply(this);


},





 

In case you have more question when developing the AutoNavi Map or when you are using this feature, you can raise your question below and I'll answer it if I can.