diff --git a/www/index.html b/www/index.html
index 1871bb42e97a5d7cc71ffaefddd7d5c77625ea73..d092bd6b3d0dc8c947acefeeaf28d4e6e389bdd2 100644
--- a/www/index.html
+++ b/www/index.html
@@ -200,6 +200,10 @@
 
   <!-- Map plugin -->
   <script src="dist/dist_js/plugins/map/js/plugin.js"></script>
+  <script src="dist/dist_js/plugins/map/js/services.js"></script>
+  <script src="dist/dist_js/plugins/map/js/services/data-services.js"></script>
+  <script src="dist/dist_js/plugins/map/js/controllers/wot-controllers.js"></script>
+  <script src="dist/dist_js/plugins/map/js/controllers/network-controllers.js"></script>
 
   <!-- RML9 plugin -->
   <!--<script src="dist/dist_js/plugins/rml9/plugin-01-add_button.js"></script>-->
diff --git a/www/plugins/es/templates/registry/edit_record.html b/www/plugins/es/templates/registry/edit_record.html
index be055364d8b0086db3de68cf67c2b376ddd015bc..be56da1680c00e2d7be289ffd86befb84f01385d 100644
--- a/www/plugins/es/templates/registry/edit_record.html
+++ b/www/plugins/es/templates/registry/edit_record.html
@@ -103,7 +103,7 @@
                     <input type="text" placeholder="{{'REGISTRY.EDIT.RECORD_ADDRESS_HELP'|translate}}" ng-model="formData.address">
                   </label>
                   <button class="button button-small button-positive" ng-click="localize()" ng-if="location.enable">
-                    <i class="icon ion-pinpoint"></i>
+                    <i class="icon ion-android-locate"></i>
                   </button>
                 </div>
               </div>
diff --git a/www/plugins/es/templates/user/edit_profile.html b/www/plugins/es/templates/user/edit_profile.html
index 72e4cb4c7edd622b7403d313e2b39eda34101d0f..a6a1923108b9a3bb9644eedf0296e72a272dbbbc 100644
--- a/www/plugins/es/templates/user/edit_profile.html
+++ b/www/plugins/es/templates/user/edit_profile.html
@@ -158,7 +158,7 @@
                      ng-click="localizeByCity()">
                   </a>
 
-                  <a class="button button-stable button-small-padding icon ion-pinpoint"
+                  <a class="button button-stable button-small-padding icon ion-android-locate"
                      title="{{'PROFILE.BTN_GEOLOC_ME'|translate}}"
                      ng-click="localizeMe()">
                   </a>
diff --git a/www/plugins/map/i18n/locale-fr-FR.json b/www/plugins/map/i18n/locale-fr-FR.json
index 52c1f83cffe8bb89b7403c92e4523b9ae8c13a92..abaa0335c2f14f9e649f245972ee2bfce622093e 100644
--- a/www/plugins/map/i18n/locale-fr-FR.json
+++ b/www/plugins/map/i18n/locale-fr-FR.json
@@ -13,6 +13,9 @@
           "WALLET": "Non-membres"
         }
       }
+    },
+    "ERROR": {
+      "LOCALIZE_ME_FAILED": "Echec de la récupération de votre position"
     }
   }
 }
diff --git a/www/plugins/map/js/controllers/network-controllers.js b/www/plugins/map/js/controllers/network-controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..e11eda775168e9b6c5dc56693336b4a1c1655d8f
--- /dev/null
+++ b/www/plugins/map/js/controllers/network-controllers.js
@@ -0,0 +1,4 @@
+
+angular.module('cesium.map.network.controllers', ['cesium.services', 'cesium.map.services'])
+
+;
diff --git a/www/plugins/map/js/controllers/wot-controllers.js b/www/plugins/map/js/controllers/wot-controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..b00b50b70936ea87c6e64210411f8af987bb92a6
--- /dev/null
+++ b/www/plugins/map/js/controllers/wot-controllers.js
@@ -0,0 +1,320 @@
+
+angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.services'])
+
+  .config(function($stateProvider, PluginServiceProvider, csConfig) {
+    'ngInject';
+
+    var enable = csConfig.plugins && csConfig.plugins.es;
+    if (enable) {
+
+      PluginServiceProvider
+
+      // Extension de la vue d'une identité: ajout d'un bouton
+        .extendState('app.wot_lookup', {
+          points: {
+            'filter-buttons': {
+              templateUrl: "plugins/map/templates/wot/lookup_extend.html"
+            }
+          }
+        });
+
+      // [NEW] Ajout d'une nouvelle page #/app/wot/map
+      $stateProvider
+        .state('app.view_wot_map', {
+          url: "/wot/map?lat&lng&zoom",
+          views: {
+            'menuContent': {
+              templateUrl: "plugins/map/templates/wot/view_map.html",
+              controller: 'MapWotViewCtrl'
+            }
+          }
+        });
+    }
+
+    L.AwesomeMarkers.Icon.prototype.options.prefix = 'ion';
+  })
+
+  // [NEW] Manage events from the page #/app/wot/map
+  .controller('MapWotViewCtrl', function($scope, $q, $translate, $state, $filter, $templateCache, $timeout, $ionicHistory,
+                                         esGeo, UIUtils, MapData, leafletData) {
+    'ngInject';
+
+    var constants = {
+      FRANCE: {
+        lat: 47.35, lng: 5.65, zoom: 6
+      },
+      ICONS: {
+        member: {
+          type: 'awesomeMarker',
+          icon: 'person',
+          markerColor: 'blue'
+        },
+        wallet: {
+          type: 'awesomeMarker',
+          icon: 'key',
+          markerColor: 'lightgray'
+        },
+        group: {
+          type: 'awesomeMarker',
+          icon: 'person-stalker',
+          markerColor: 'green'
+        },
+        registry: {
+          type: 'awesomeMarker',
+          icon: 'person-stalker', // TODO
+          markerColor: 'green' // TODO
+        }
+      }
+    };
+    constants.DEFAULT_CENTER = constants.FRANCE;
+    var
+      markersSearchLayer,
+      searchControl;
+
+    $scope.init = false;
+    $scope.loading = true;
+    $scope.mapId = 'map-wot-' + $scope.$id;
+    $scope.map = {
+      center: angular.copy(constants.DEFAULT_CENTER),
+      defaults: {
+        scrollWheelZoom: true
+      },
+      layers: {
+        baselayers: {
+          openStreetMap: {
+            name: 'OpenStreetMap',
+            type: 'xyz',
+            url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
+          }
+        },
+        overlays: {
+          member: {
+            type: 'group',
+            name: '',
+            visible: true
+          },
+          wallet: {
+            type: 'group',
+            name: '',
+            visible: true
+          }
+        }
+      },
+      legend: {},
+      controls: {
+        custom: []
+      }
+    };
+
+    $scope.init = function() {
+      if ($scope.initialized) return $q.when(); // init only once
+
+      return $translate(['MAP.WOT.VIEW.LEGEND.MEMBER', 'MAP.WOT.VIEW.LEGEND.WALLET', 'MAP.WOT.VIEW.SEARCH_DOTS', 'COMMON.SEARCH_NO_RESULT'])
+        .then(function(translations){
+
+          // Set layers overlays
+          $scope.map.layers.overlays.member.name=translations['MAP.WOT.VIEW.LEGEND.MEMBER'];
+          $scope.map.layers.overlays.wallet.name=translations['MAP.WOT.VIEW.LEGEND.WALLET'];
+
+          // Create a  hidden layer, to hold search markers
+          markersSearchLayer = L.layerGroup({visible: false});
+
+          // Add search control
+          searchControl = L.control.search({
+            layer: markersSearchLayer,
+            initial: false,
+            marker: false,
+            propertyName: 'title',
+            position: 'topleft',
+            zoom: 13,
+            buildTip: function(text, val) {
+              var marker = val.layer.options;
+              var title = marker.name != marker.uid ? marker.name +' ' : '';
+              if (marker.type == 'member') {
+                return '<a href="#" class="'+marker.type+'">'+title+'<span class="positive"><i class="icon ion-person"></i> '+marker.uid+'</span></a>';
+              }
+              else {
+                return '<a href="#" class="'+marker.type+'">'+title+'<span class="gray"><i class="icon ion-key"></i> '+marker.shortPubkey+'</span></a>';
+              }
+
+              return '<a href="#" class="'+marker.type+'">'+title+'</a>';
+            },
+            textPlaceholder: translations['MAP.WOT.VIEW.SEARCH_DOTS'],
+            textErr: translations['COMMON.SEARCH_NO_RESULT'],
+            markerLocation: true
+          });
+
+          $scope.initialized = true;
+        });
+    };
+
+    // [NEW] When opening the view
+    $scope.enter = function(e, state) {
+      if ($scope.loading) {
+        console.log("[map] Opening the view... (first time)");
+
+        // remember state, to be able to refresh location
+        $scope.stateName = state && state.stateName;
+        $scope.stateParams = angular.copy(state && state.stateParams||{});
+
+        // Read state params
+        var center;
+        if (state.stateParams) {
+          if (state.stateParams.lat) {
+            center = {};
+            center.lat = parseFloat(state.stateParams.lat);
+          }
+          if (state.stateParams.lng) {
+            center = center || {};
+            center.lng = parseFloat(state.stateParams.lng);
+          }
+          if (state.stateParams.zoom) {
+            center = center || {};
+            center.zoom = parseFloat(state.stateParams.zoom);
+          }
+          if (center) {
+            center = angular.merge({}, constants.DEFAULT_CENTER, center);
+          }
+        }
+
+        // Init map
+        return $scope.init()
+          .then(function() {
+            // Load data
+            return $scope.load(center);
+          });
+      }
+    };
+    $scope.$on('$ionicView.enter', $scope.enter);
+
+    // Load markers data
+    $scope.load = function(center) {
+      $scope.loading = true;
+
+      // removeIf(no-device)
+      UIUtils.loading.show();
+      // endRemoveIf(no-device)
+
+      return MapData.load()
+        .then(function(res) {
+          if (!res || !res.length) {
+            $scope.loading = false;
+            return;
+          }
+
+          var formatPubkey = $filter('formatPubkey');
+          var markerTemplate = $templateCache.get('plugins/map/templates/wot/popup_marker.html');
+
+          // Sort with member first
+          res = _.sortBy(res, function(hit) {
+            var score = 0;
+            score += (!hit.uid) ? 100 : 0;
+            return -score;
+          });
+
+          var markers = res.reduce(function(res, hit) {
+            var type = hit.uid ? 'member' : 'wallet';
+            var shortPubkey = formatPubkey(hit.issuer);
+            var marker = {
+              layer: type,
+              icon: constants.ICONS[type],
+              title: hit.title + ' | ' + shortPubkey,
+              lat: hit.geoPoint.lat,
+              lng: hit.geoPoint.lon,
+              getMessageScope: function() {
+                var scope = $scope.$new();
+                scope.hit = hit;
+                return scope;
+              },
+              focus: false,
+              message: markerTemplate
+            };
+            res[hit.issuer] = marker;
+
+            // Create a search marker (will be hide)
+            var searchText = hit.title + ((hit.uid && hit.uid != hit.title) ? (' | ' + hit.uid) : '') + ' | ' + shortPubkey;
+            var searchMarker = angular.merge({
+              type: type,
+              opacity: 0,
+              icon: L.divIcon({
+                className: type + ' ng-hide',
+                iconSize: L.point(0, 0)
+              })
+            }, {title: searchText, shortPubkey: shortPubkey, uid: hit.uid, name: hit.title});
+            markersSearchLayer.addLayer(new L.Marker({
+                lat: hit.geoPoint.lat,
+                lng: hit.geoPoint.lon
+              },
+              searchMarker));
+            return res;
+          }, {});
+
+          $scope.map.markers = markers;
+
+
+          leafletData.getMap($scope.mapId).then(function(map) {
+            // Add search control to map
+            searchControl.addTo(map);
+
+            // Add center to me control to map
+            L.easyButton('icon ion-android-locate', function(btn, map){
+              $scope.localizeMe();
+            }).addTo(map);
+
+            var needCenterUpdate = center && !angular.equals($scope.map.center, center);
+            if (needCenterUpdate) {
+              //angular.merge($scope.map.center, center);
+              $timeout(function() {
+                map.invalidateSize();
+                map._resetView(center, center.zoom, true);
+              }, 300);
+            }
+            $scope.loading = false;
+            UIUtils.loading.hide();
+          });
+        });
+    };
+
+    // Update the browser location, to be able to refresh the page
+    $scope.updateLocation = function() {
+
+      $ionicHistory.nextViewOptions({
+        disableAnimate: true,
+        disableBack: true,
+        historyRoot: false
+      });
+
+      $scope.stateParams = $scope.stateParams || {};
+      $scope.stateParams.lat = ($scope.map.center.lat != constants.DEFAULT_CENTER.lat) ? $scope.map.center.lat : undefined;
+      $scope.stateParams.lng = ($scope.map.center.lng != constants.DEFAULT_CENTER.lng) ? $scope.map.center.lng : undefined;
+      $scope.stateParams.zoom = ($scope.map.center.zoom != constants.DEFAULT_CENTER.zoom) ? $scope.map.center.zoom : undefined;
+
+      $state.go($scope.stateName, $scope.stateParams, {
+        reload: false,
+        inherit: true,
+        notify: false}
+      );
+    };
+
+    $scope.localizeMe = function() {
+      return esGeo.point.current()
+        .then(function(res) {
+          $scope.map.center = {
+            lat: res.lat,
+            lng: res.lon,
+            zoom: 14
+          };
+        })
+        .catch(UIUtils.onError('MAP.ERROR.LOCALIZE_ME_FAILED'));
+    };
+
+    // removeIf(device)
+    $scope.onMapCenterChanged = function() {
+      if (!$scope.loading) {
+        $timeout($scope.updateLocation, 500);
+      }
+    };
+    $scope.$watch('map.center', $scope.onMapCenterChanged, true);
+    // endRemoveIf(device)
+
+  });
diff --git a/www/plugins/map/js/plugin.js b/www/plugins/map/js/plugin.js
index eff1f326346a223ed9796ed070b1c4296b26be6b..883264e378c0a561072d2ad930c57821185362bf 100644
--- a/www/plugins/map/js/plugin.js
+++ b/www/plugins/map/js/plugin.js
@@ -1,383 +1,18 @@
 
-angular.module('cesium.map.plugin', ['cesium.services'])
-
-  .config(function($stateProvider, PluginServiceProvider, csConfig) {
+angular.module('cesium.map.plugin', [
+    // Services
+    'cesium.map.services',
+    // Controllers
+    'cesium.map.wot.controllers',
+    'cesium.map.network.controllers'
+  ])
+
+  // Configure plugin
+  .config(function() {
     'ngInject';
 
-    var enable = csConfig.plugins && csConfig.plugins.es;
-    if (enable) {
-
-      PluginServiceProvider
-
-        // Extension de la vue d'une identité: ajout d'un bouton
-        .extendState('app.wot_lookup', {
-          points: {
-            'filter-buttons': {
-              templateUrl: "plugins/map/templates/wot/lookup_extend.html"
-            }
-          }
-        });
-
-      // [NEW] Ajout d'une nouvelle page #/app/wot/map
-      $stateProvider
-        .state('app.view_wot_map', {
-          url: "/wot/map?lat&lng&zoom",
-          views: {
-            'menuContent': {
-              templateUrl: "plugins/map/templates/wot/map.html",
-              controller: 'MapWotViewCtrl'
-            }
-          }
-        });
-    }
-
+    // Define icon prefix for AwesomeMarker (a Leaflet plugin)
     L.AwesomeMarkers.Icon.prototype.options.prefix = 'ion';
-  })
-
-  // [NEW] Manage events from the page #/app/wot/map
-  .controller('MapWotViewCtrl', function($scope, $q, $translate, $state, $filter, $templateCache, $timeout, $ionicHistory,
-                                         esGeo, UIUtils, MapData, leafletData) {
-    'ngInject';
-
-    var constants = {
-      FRANCE: {
-        lat: 47.35, lng: 5.65, zoom: 6
-      }
-    };
-    constants.DEFAULT_CENTER = constants.FRANCE;
-
-    $scope.loading = true;
-    $scope.mapId = 'map-wot-' + $scope.$id;
-    $scope.map = {
-      center: angular.copy(constants.DEFAULT_CENTER),
-      defaults: {
-        scrollWheelZoom: true
-      },
-      layers: {
-        baselayers: {
-          openStreetMap: {
-            name: 'OpenStreetMap',
-              type: 'xyz',
-              url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
-          }
-        },
-        overlays: {
-          member: {
-            type: 'group',
-            name: '',
-            visible: true
-          },
-          wallet: {
-            type: 'group',
-            name: '',
-            visible: true
-          }
-        }
-      },
-      legend: {}
-    };
-
-    var icons = {
-      member: {
-        type: 'awesomeMarker',
-        icon: 'person',
-        markerColor: 'blue'
-      },
-      wallet: {
-        type: 'awesomeMarker',
-        icon: 'key',
-        markerColor: 'lightgray'
-      },
-      group: {
-        type: 'awesomeMarker',
-        icon: 'person-stalker',
-        markerColor: 'green'
-      },
-      registry: {
-        type: 'awesomeMarker',
-        icon: 'person-stalker', // TODO
-        markerColor: 'green' // TODO
-      }
-    };
-
-    var markersLayer = L.layerGroup({
-      visible: false
-    });
-
-    //$scope.$on()
-    //$scope.map.controls.custom.push(searchControl);
-
-    // [NEW] When opening the view
-    $scope.$on('$ionicView.enter', function(e, state) {
-
-      if ($scope.loading) {
-        console.log("[map] Opening the view... (first time)");
-
-        // remember state, to be able to refresh location
-        $scope.stateName = state && state.stateName;
-        $scope.stateParams = angular.copy(state && state.stateParams||{});
-
-        var center;
-        if (state.stateParams) {
-          if (state.stateParams.lat) {
-            center = {};
-            center.lat = parseFloat(state.stateParams.lat);
-          }
-          if (state.stateParams.lng) {
-            center = center || {};
-            center.lng = parseFloat(state.stateParams.lng);
-          }
-          if (state.stateParams.zoom) {
-            center = center || {};
-            center.zoom = parseFloat(state.stateParams.zoom);
-          }
-          if (center) {
-            center = angular.merge({}, constants.DEFAULT_CENTER, center);
-          }
-        }
-
-        $scope.load(center);
-      }
-      else {
-        console.log("[map] Opening the view... NOT the first time !");
-      }
-    });
-
-    $scope.load = function(center) {
-      $scope.loading = true;
-
-      // removeIf(no-device)
-      UIUtils.loading.show();
-      // endRemoveIf(no-device)
-
-      $q.all([
-        $translate(['MAP.WOT.VIEW.LEGEND.MEMBER', 'MAP.WOT.VIEW.LEGEND.WALLET', 'MAP.WOT.VIEW.SEARCH_DOTS', 'COMMON.SEARCH_NO_RESULT']),
-        MapData.load()
-      ])
-      .then(function(res) {
-        var translations = res[0];
-        res = res[1];
-        if (!res || !res.length) return;
-
-        var overlaysNames = {
-          member: translations['MAP.WOT.VIEW.LEGEND.MEMBER'],
-          wallet: translations['MAP.WOT.VIEW.LEGEND.WALLET']
-        };
-
-        $scope.map.layers.overlays.member.name=overlaysNames.member;
-        $scope.map.layers.overlays.wallet.name=overlaysNames.wallet;
-
-        var formatPubkey = $filter('formatPubkey');
-        var markerTemplate = $templateCache.get('plugins/map/templates/wot/popup_marker.html');
-
-        // Sort with member first
-        res = _.sortBy(res, function(hit) {
-          var score = 0;
-          score += (!hit.uid) ? 100 : 0;
-          return -score;
-        });
-
-        var markers = res.reduce(function(res, hit) {
-          var type = hit.uid ? 'member' : 'wallet';
-          var shortPubkey = formatPubkey(hit.issuer);
-          var marker = {
-            layer: type,
-            icon: icons[type],
-            title: hit.title + ' | ' + shortPubkey,
-            lat: hit.geoPoint.lat,
-            lng: hit.geoPoint.lon,
-            getMessageScope: function() {
-              var scope = $scope.$new();
-              scope.hit = hit;
-              return scope;
-            },
-            focus: false,
-            message: markerTemplate
-          };
-          res[hit.issuer] = marker;
-
-          // Create a search marker (will be hide)
-          var searchText = hit.title + ((hit.uid && hit.uid != hit.title) ? (' | ' + hit.uid) : '') + ' | ' + shortPubkey;
-          var searchMarker = angular.merge({
-              type: type,
-              opacity: 0,
-              icon: L.divIcon({
-                className: type + ' ng-hide',
-                iconSize: L.point(0, 0)
-              })
-            }, {title: searchText, shortPubkey: shortPubkey, uid: hit.uid, name: hit.title});
-          markersLayer.addLayer(new L.Marker({
-              lat: hit.geoPoint.lat,
-              lng: hit.geoPoint.lon
-            },
-            searchMarker));
-          return res;
-        }, {});
-
-        $scope.map.markers = markers;
-
-
-        leafletData.getMap(/*$scope.mapId*/).then(function(map) {
-          // Control: search
-          L.control.search({
-            layer: markersLayer,
-            initial: false,
-            marker: false,
-            propertyName: 'title',
-            position: 'topleft',
-            zoom: 13,
-            buildTip: function(text, val) {
-              var marker = val.layer.options;
-              var title = marker.name != marker.uid ? marker.name +' ' : '';
-              if (marker.type == 'member') {
-                return '<a href="#" class="'+marker.type+'">'+title+'<span class="positive"><i class="icon ion-person"></i> '+marker.uid+'</span></a>';
-              }
-              else {
-                return '<a href="#" class="'+marker.type+'">'+title+'<span class="gray"><i class="icon ion-key"></i> '+marker.shortPubkey+'</span></a>';
-              }
-
-              return '<a href="#" class="'+marker.type+'">'+title+'</a>';
-            },
-            textPlaceholder: translations['MAP.WOT.VIEW.SEARCH_DOTS'],
-            textErr: translations['COMMON.SEARCH_NO_RESULT'],
-            markerLocation: true
-          }).addTo(map);
-
-          L.easyButton('<i class="icon ion-ios-location"></i>', function(btn, map){
-            return esGeo.point.current()
-              .then(function(res) {
-                console.log(res);
-                $scope.map.center = {
-                  lat: res.lat,
-                  lng: res.lon,
-                  zoom: 14
-                };
-              });
-          }).addTo(map);
-
-          var needCenterUpdate = center && !angular.equals($scope.map.center, center);
-          if (needCenterUpdate) {
-            //angular.merge($scope.map.center, center);
-            $timeout(function() {
-              map.invalidateSize();
-              map._resetView(center, center.zoom, true);
-            }, 300);
-          }
-          $scope.loading = false;
-          UIUtils.loading.hide();
-        });
-      });
-    };
-
-    $scope.updateLocation = function() {
-      $ionicHistory.nextViewOptions({
-        disableAnimate: true,
-        disableBack: true,
-        historyRoot: false
-      });
-
-      $scope.stateParams = $scope.stateParams || {};
-      $scope.stateParams.lat = ($scope.map.center.lat != constants.DEFAULT_CENTER.lat) ? $scope.map.center.lat : undefined;
-      $scope.stateParams.lng = ($scope.map.center.lng != constants.DEFAULT_CENTER.lng) ? $scope.map.center.lng : undefined;
-      $scope.stateParams.zoom = ($scope.map.center.zoom != constants.DEFAULT_CENTER.zoom) ? $scope.map.center.zoom : undefined;
-
-      $state.go($scope.stateName, $scope.stateParams, {
-        reload: false,
-        inherit: true,
-        notify: false}
-      );
-    };
-
-    $scope.centerMe = function() {
-      $scope.map.center.autoDiscover = true;
-      /*esGeo.point.current()
-        .then(function() {
-
-        })*/
-    };
-
-    $scope.onMapCenterChanged = function() {
-      if (!$scope.loading) {
-        $timeout($scope.updateLocation, 500);
-      }
-    };
-    $scope.$watch('map.center', $scope.onMapCenterChanged, true);
-
-  })
-
-  // [NEW] Manage events from the page #/app/wot/map
-  .factory('MapData', function(csHttp, esHttp, csWot) {
-    'ngInject';
-
-    var
-      that = this,
-      constants = {
-        DEFAULT_LOAD_SIZE: 1000
-      },
-      fields = {
-        profile: ["issuer", "title", "description", "geoPoint"]
-      };
-
-    that.raw = {
-      profile: {
-        postSearch: esHttp.post('/user/profile/_search')
-      }
-    };
-
-    function createFilterQuery(options) {
-      var query = {
-        bool: {
-          must: [
-            {exists: {field: "geoPoint"}}
-          ]
-        }
-      };
-
-      return query;
-    }
-
-    function load(options) {
-      options = options || {};
-      options.from = options.from || 0;
-      options.size = options.size || constants.DEFAULT_LOAD_SIZE;
-
-      var request = {
-        query: createFilterQuery(options),
-        from: options.from,
-        size: options.size,
-        _source: fields.profile
-      };
-
-      return that.raw.profile.postSearch(request)
-        .then(function(res) {
-          if (!res.hits || !res.hits.total) return [];
-
-          var commaRegexp = new RegExp('[,]');
-
-          res = res.hits.hits.reduce(function(res, hit) {
-            var item = hit._source;
-
-            if (!item.geoPoint || !item.geoPoint.lat || !item.geoPoint.lon) return res;
-
-            // Convert lat/lon to float (if need)
-            if (item.geoPoint.lat && typeof item.geoPoint.lat === 'string') {
-              item.geoPoint.lat = parseFloat(item.geoPoint.lat.replace(commaRegexp, '.'));
-            }
-            if (item.geoPoint.lon && typeof item.geoPoint.lon === 'string') {
-              item.geoPoint.lon = parseFloat(item.geoPoint.lon.replace(commaRegexp, '.'));
-            }
-
-            return res.concat(item);
-          }, []);
-
-          return csWot.extendAll(res, 'issuer');
-        });
-    }
-
-    return {
-      load: load
-    };
-
   });
 
 
diff --git a/www/plugins/map/js/services.js b/www/plugins/map/js/services.js
new file mode 100644
index 0000000000000000000000000000000000000000..5b355e871c168400f4fe979a61fb0e851daaf677
--- /dev/null
+++ b/www/plugins/map/js/services.js
@@ -0,0 +1,6 @@
+
+angular.module('cesium.map.services', [
+    // Services
+    'cesium.map.data.services'
+  ])
+;
diff --git a/www/plugins/map/js/services/data-services.js b/www/plugins/map/js/services/data-services.js
new file mode 100644
index 0000000000000000000000000000000000000000..12802e21906eb36b28a272351b993237e2c03555
--- /dev/null
+++ b/www/plugins/map/js/services/data-services.js
@@ -0,0 +1,77 @@
+
+angular.module('cesium.map.data.services', ['cesium.services'])
+
+// [NEW] Manage events from the page #/app/wot/map
+.factory('MapData', function(csHttp, esHttp, csWot) {
+  'ngInject';
+
+  var
+    that = this,
+    constants = {
+      DEFAULT_LOAD_SIZE: 1000
+    },
+    fields = {
+      profile: ["issuer", "title", "description", "geoPoint"]
+    };
+
+  that.raw = {
+    profile: {
+      postSearch: esHttp.post('/user/profile/_search')
+    }
+  };
+
+  function createFilterQuery(options) {
+    var query = {
+      bool: {
+        must: [
+          {exists: {field: "geoPoint"}}
+        ]
+      }
+    };
+
+    return query;
+  }
+
+  function load(options) {
+    options = options || {};
+    options.from = options.from || 0;
+    options.size = options.size || constants.DEFAULT_LOAD_SIZE;
+
+    var request = {
+      query: createFilterQuery(options),
+      from: options.from,
+      size: options.size,
+      _source: fields.profile
+    };
+
+    return that.raw.profile.postSearch(request)
+      .then(function(res) {
+        if (!res.hits || !res.hits.total) return [];
+
+        var commaRegexp = new RegExp('[,]');
+
+        res = res.hits.hits.reduce(function(res, hit) {
+          var item = hit._source;
+
+          if (!item.geoPoint || !item.geoPoint.lat || !item.geoPoint.lon) return res;
+
+          // Convert lat/lon to float (if need)
+          if (item.geoPoint.lat && typeof item.geoPoint.lat === 'string') {
+            item.geoPoint.lat = parseFloat(item.geoPoint.lat.replace(commaRegexp, '.'));
+          }
+          if (item.geoPoint.lon && typeof item.geoPoint.lon === 'string') {
+            item.geoPoint.lon = parseFloat(item.geoPoint.lon.replace(commaRegexp, '.'));
+          }
+
+          return res.concat(item);
+        }, []);
+
+        return csWot.extendAll(res, 'issuer');
+      });
+  }
+
+  return {
+    load: load
+  };
+
+});
diff --git a/www/plugins/map/templates/wot/map.html b/www/plugins/map/templates/wot/view_map.html
similarity index 93%
rename from www/plugins/map/templates/wot/map.html
rename to www/plugins/map/templates/wot/view_map.html
index b6d45e4221c82855b238674838703956b1e04ccd..13769ef9224eccf56321a092ec9743a877464a3c 100644
--- a/www/plugins/map/templates/wot/map.html
+++ b/www/plugins/map/templates/wot/view_map.html
@@ -8,7 +8,7 @@
   </ion-nav-buttons>
 
   <ion-content data-tap-disabled="true">
-    <leaflet
+    <leaflet id="{{mapId}}"
              height="100%"
              center="map.center"
              markers="map.markers"