diff --git a/www/index.html b/www/index.html
index 3ba552d6ae6bc873ac73138cf68a2a82ab4d238d..451caedeff0a2d9e9f7b7af0760c8606bb2689a7 100644
--- a/www/index.html
+++ b/www/index.html
@@ -193,7 +193,6 @@
   <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/wot-services.js"></script>
-  <script src="dist/dist_js/plugins/map/js/services/network-services.js"></script>
   <script src="dist/dist_js/plugins/map/js/services/utils-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>
diff --git a/www/js/config.js b/www/js/config.js
index 4ce3354a20d2cbc411f7075cee86cba0a28dff16..a2ed9f897604529e0c18bb2c9bc23c5afa7ffbab 100644
--- a/www/js/config.js
+++ b/www/js/config.js
@@ -55,7 +55,9 @@ angular.module("cesium.config", [])
 				"txReceived": true,
 				"certSent": true,
 				"certReceived": true
-			}
+			},
+      "defaultCountry": "France",
+      "googleApiKey": "AIzaSyBSMd4vSr3P6TV8WI-trqio9z0Qpr1hKVk"
 		}
 	},
 	"version": "0.15.0",
@@ -63,4 +65,4 @@ angular.module("cesium.config", [])
 	"newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug"
 })
 
-;
\ No newline at end of file
+;
diff --git a/www/plugins/es/i18n/locale-en-GB.json b/www/plugins/es/i18n/locale-en-GB.json
index a8fcc0de4aa904f23dba696fe7e58458434bd086..5dfa7831a239ed1d98dbb661c2d060d060b5e3d3 100644
--- a/www/plugins/es/i18n/locale-en-GB.json
+++ b/www/plugins/es/i18n/locale-en-GB.json
@@ -361,12 +361,17 @@
       "RESIZE_HELP": "<b>Re-crop the image</b> if necessary. A click on the image allows to move it. Click on the area at the bottom left to zoom in.",
       "RESULT_HELP": "<b>Here is the result</b> as seen on your profile:"
     },
+    "MODAL_LOCATIONS": {
+      "TITLE": "Validation de l'adresse",
+      "RESULT_DIVIDER": "Résultat(s) pour <b>{{address}}</b> :"
+    },
     "ERROR": {
       "LOAD_PROFILE_FAILED": "Could not load user profile.",
       "SAVE_PROFILE_FAILED": "Saving profile failed",
       "INVALID_SOCIAL_NETWORK_FORMAT": "Invalid format: please fill a valid Internet address.<br/><br/>Examples :<ul><li>- A Facebook page (https://www.facebook.com/user)</li><li>- A web page (http://www.domain.com)</li><li>- An email address (joe@dalton.com)</li></ul>",
       "IMAGE_RESIZE_FAILED": "Error while resizing picture",
-      "GEO_LOCATION_FAILED": "Unable to retrieve your current position"
+      "GEO_LOCATION_FAILED": "Unable to retrieve your current position",
+      "ADDRESS_LOCATION_FAILED": "Unable to retrieve the address position"
     },
     "INFO": {
       "PROFILE_SAVED": "Profile saved"
diff --git a/www/plugins/es/i18n/locale-en.json b/www/plugins/es/i18n/locale-en.json
index a8fcc0de4aa904f23dba696fe7e58458434bd086..5dfa7831a239ed1d98dbb661c2d060d060b5e3d3 100644
--- a/www/plugins/es/i18n/locale-en.json
+++ b/www/plugins/es/i18n/locale-en.json
@@ -361,12 +361,17 @@
       "RESIZE_HELP": "<b>Re-crop the image</b> if necessary. A click on the image allows to move it. Click on the area at the bottom left to zoom in.",
       "RESULT_HELP": "<b>Here is the result</b> as seen on your profile:"
     },
+    "MODAL_LOCATIONS": {
+      "TITLE": "Validation de l'adresse",
+      "RESULT_DIVIDER": "Résultat(s) pour <b>{{address}}</b> :"
+    },
     "ERROR": {
       "LOAD_PROFILE_FAILED": "Could not load user profile.",
       "SAVE_PROFILE_FAILED": "Saving profile failed",
       "INVALID_SOCIAL_NETWORK_FORMAT": "Invalid format: please fill a valid Internet address.<br/><br/>Examples :<ul><li>- A Facebook page (https://www.facebook.com/user)</li><li>- A web page (http://www.domain.com)</li><li>- An email address (joe@dalton.com)</li></ul>",
       "IMAGE_RESIZE_FAILED": "Error while resizing picture",
-      "GEO_LOCATION_FAILED": "Unable to retrieve your current position"
+      "GEO_LOCATION_FAILED": "Unable to retrieve your current position",
+      "ADDRESS_LOCATION_FAILED": "Unable to retrieve the address position"
     },
     "INFO": {
       "PROFILE_SAVED": "Profile saved"
diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json
index c4d28a409385d340d557e18d636847f3cc0092fd..0181266c1329187bf18cfd2265344fe9e03301af 100644
--- a/www/plugins/es/i18n/locale-fr-FR.json
+++ b/www/plugins/es/i18n/locale-fr-FR.json
@@ -402,12 +402,17 @@
       "RESIZE_HELP": "<b>Recadrez l'image</b>, si besoin. Un clic maintenu sur l'image permet de la déplacer. Cliquez sur la zone en bas à gauche pour zoomer.",
       "RESULT_HELP": "<b>Voici le résultat</b> tel que visible sur votre profil :"
     },
+    "MODAL_LOCATIONS": {
+      "TITLE": "Validation de l'addresse",
+      "RESULT_DIVIDER": "Résultat(s) pour <b>{{address}}</b> :"
+    },
     "ERROR": {
       "LOAD_PROFILE_FAILED": "Erreur de chargement du profil utilisateur.",
       "SAVE_PROFILE_FAILED": "Erreur lors de la sauvegarde",
       "INVALID_SOCIAL_NETWORK_FORMAT": "Format non pris en compte : veuillez indiquer une adresse valide.<br/><br/>Exemples :<ul><li>- Une page Facebook (https://www.facebook.com/user)</li><li>- Une page web (http://www.monsite.fr)</li><li>- Une adresse email (joe@dalton.com)</li></ul>",
       "IMAGE_RESIZE_FAILED": "Erreur lors du redimensionnement de l'image",
-      "GEO_LOCATION_FAILED": "Impossible de récupérer votre position actuelle"
+      "GEO_LOCATION_FAILED": "Impossible de récupérer votre position actuelle",
+      "ADDRESS_LOCATION_FAILED": "Impossible de récupérer la position à partir de l'adresse"
     },
     "INFO": {
       "PROFILE_SAVED": "Profil sauvegardé"
diff --git a/www/plugins/es/js/controllers/common-controllers.js b/www/plugins/es/js/controllers/common-controllers.js
index ed6aa01af5c0525d465a7443cfff44a98c1d7a1c..6ec8300080c03fa238d580422a590b4a17e8501c 100644
--- a/www/plugins/es/js/controllers/common-controllers.js
+++ b/www/plugins/es/js/controllers/common-controllers.js
@@ -80,6 +80,9 @@ function ESCategoryModalController($scope, UIUtils, $timeout, parameters) {
   $scope.categories = [];
   this.searchText = '';
 
+  // modal title
+  this.title = parameters && parameters.title;
+
   $scope.afterLoad = function(result) {
     $scope.categories = result;
     $scope.allCategories = result;
@@ -118,6 +121,7 @@ function ESCategoryModalController($scope, UIUtils, $timeout, parameters) {
     });
   }
 
+
 }
 
 
diff --git a/www/plugins/es/js/controllers/profile-controllers.js b/www/plugins/es/js/controllers/profile-controllers.js
index 67a9d396836a0ef960f133acb880ebb13497f42c..0e53ff8c06e46de1e27f07632c7e3fe4ec1dc317 100644
--- a/www/plugins/es/js/controllers/profile-controllers.js
+++ b/www/plugins/es/js/controllers/profile-controllers.js
@@ -25,9 +25,12 @@ angular.module('cesium.es.profile.controllers', ['cesium.es.services'])
 ;
 
 function ESViewEditProfileController($scope, $rootScope, $q, $timeout, $state, $focus, $translate, $ionicHistory,
-                           UIUtils, esHttp, esProfile, esGeo, ModalUtils, Device) {
+                           csConfig, UIUtils, esHttp, esProfile, esGeo, ModalUtils, Device) {
   'ngInject';
 
+  // The default country used for address localisation
+  var defaultCountry = csConfig.plugins && csConfig.plugins.es && csConfig.plugins.es.defaultCountry;
+
   $scope.loading = true;
   $scope.dirty = false;
   $scope.walletData = null;
@@ -313,27 +316,32 @@ function ESViewEditProfileController($scope, $rootScope, $q, $timeout, $state, $
 
   $scope.localizeByAddress = function() {
 
-    return $scope.searchPositions()
+    return UIUtils.loading.show()
+      .then($scope.searchPositions)
       .then(function(res) {
+        UIUtils.loading.hide();
+
         if (!res) return; // no result, or city value just changed
         if (res.length == 1) {
           return res[0];
         }
 
         return ModalUtils.show('plugins/es/templates/common/modal_category.html', 'ESCategoryModalCtrl as ctrl',
-          {categories : res},
+          {
+            categories : res,
+            title: 'PROFILE.MODAL_LOCATIONS.TITLE'
+          },
           {focusFirstInput: true}
         );
       })
-      .then(function(position) {
-        if (position && position.lat && position.lon) {
+      .then(function(res) {
+        if (res && res.lat && res.lon) {
           $scope.formData.geoPoint = $scope.formData.geoPoint || {};
-          $scope.formData.geoPoint.lat =  parseFloat(position.lat);
-          $scope.formData.geoPoint.lon =  parseFloat(position.lon);
-
-          //$scope.dirty = true; // not need ??
+          $scope.formData.geoPoint.lat =  parseFloat(res.lat);
+          $scope.formData.geoPoint.lon =  parseFloat(res.lon);
         }
-      });
+      })
+      .catch(UIUtils.onError('PROFILE.ERROR.ADDRESS_LOCATION_FAILED'));
   };
 
   $scope.searchPositions = function(query) {
@@ -346,7 +354,8 @@ function ESViewEditProfileController($scope, $rootScope, $q, $timeout, $state, $
 
       var cityPart = $scope.formData.city.split(',');
       var city = cityPart[0];
-      var country = cityPart.length > 1 ? cityPart[1].trim() : undefined;
+
+      var country = cityPart.length > 1 ? cityPart[1].trim() : defaultCountry;
       var street = $scope.formData.address ? angular.copy($scope.formData.address.trim()) : undefined;
       if (street) {
         // Search with AND without street
@@ -373,23 +382,24 @@ function ESViewEditProfileController($scope, $rootScope, $q, $timeout, $state, $
       }
     }
 
+    var queryString = (query.street ? query.street + ', ' : '') +
+      query.city +
+      (query.country ? ', ' + query.country : '')
     // Execute the given query
-    return esGeo.point.searchByAddress(query)
+    return $q.all([
+      $translate('PROFILE.MODAL_LOCATIONS.RESULT_DIVIDER', {address: queryString}),
+      esGeo.point.searchByAddress(query)
+    ])
       .then(function(res) {
+        var dividerText = res[0];
+        res = res[1];
         if (!res) return $q.when(); // no result
 
         // Ask user to choose
-        var index = 0;
-        var parent = {name: 'Résultat pour <b>' +
-          (query.street ? query.street + ', ' : '') +
-          query.city +
-          (query.country ? ', ' + query.country : '')  +
-        '</b>', id: 0};
+        var parent = {name: dividerText};
         var hits = res.reduce(function(res, hit){
-          index++;
           if (hit.class == 'waterway') return res;
           return res.concat({
-            id: index,
             name: hit.display_name,
             parent: parent,
             lat: hit.lat,
diff --git a/www/plugins/es/js/services/geo-services.js b/www/plugins/es/js/services/geo-services.js
index e05efc3570a8c9388d5ac65adaefd2168886d62a..b92660f9a9feb6d33d480ed34527afe1d7f3305e 100644
--- a/www/plugins/es/js/services/geo-services.js
+++ b/www/plugins/es/js/services/geo-services.js
@@ -10,27 +10,61 @@ angular.module('cesium.es.geo.services', ['cesium.services', 'cesium.es.http.ser
 
   })
 
-  .factory('esGeo', function($q, csHttp) {
+  .factory('esGeo', function($q, csConfig, csHttp) {
     'ngInject';
 
     var
       that = this;
 
     that.raw = {
-      searchByString: csHttp.get('nominatim.openstreetmap.org', 80, '/search.php?format=json&q=:query'),
-      searchByQuery: csHttp.get('nominatim.openstreetmap.org', 80, '/search.php?format=json'),
+      osm: {
+        searchByString: csHttp.get('nominatim.openstreetmap.org', 443, '/search.php?format=json&q=:query'),
+        searchByQuery: csHttp.get('nominatim.openstreetmap.org', 443, '/search.php?format=json')
+      },
+      google: {
+        search: csHttp.get('maps.google.com', 443, '/maps/api/geocode/json')
+      },
       searchByIP: csHttp.get('freegeoip.net', 80, '/json/:ip')
     };
 
-    function searchPositionByString(queryString) {
+    function _fallbackSearchPositionByString(err, address) {
+
+      console.debug('[ES] [geo] Search position failed on [OSM]. Trying [google] service');
+      var apiKey = csConfig.plugins && csConfig.plugins.es && csConfig.plugins.googleApiKey;
+
+      return that.raw.google.search({address: address, key: apiKey})
+        .then(function(res) {
+          if (!res || !res.results || !res.results.length) return;
+          return res.results.reduce(function(res, hit) {
+            return res.concat({
+              display_name: hit.address_components && hit.address_components.reduce(function(res, address){
+                return address.long_name ? res.concat(address.long_name) : res;
+              }, []).join(', '),
+              lat: hit.geometry && hit.geometry.location && hit.geometry.location.lat,
+              lon: hit.geometry && hit.geometry.location && hit.geometry.location.lng
+            });
+          }, []);
+        })
+        .catch(function() {
+          console.debug('[ES] [geo] Search position failed on [google] service');
+          throw err; // throw first error (OMS error)
+        });
+    }
+
+    function searchPositionByString(address) {
 
       var now = new Date();
-      console.debug('[ES] [geo] Searching position by string query [{0}]...'.format(queryString));
+      console.debug('[ES] [geo] Searching position by string query [{0}]...'.format(address));
 
-      return that.raw.searchByString({query: queryString})
+      return that.raw.osm.searchByString({query: address})
         .then(function(res) {
           console.debug('[ES] [geo] Found {0} address position(s) in {0}ms'.format(res && res.length || 0, new Date().getTime() - now.getTime()));
           return res;
+        })
+
+        // Fallback service
+        .catch(function(err) {
+          return _fallbackSearchPositionByString(err, address);
         });
     }
 
@@ -41,10 +75,16 @@ angular.module('cesium.es.geo.services', ['cesium.services', 'cesium.es.http.ser
       var now = new Date();
       console.debug('[ES] [geo] Searching position by query...', query);
 
-      return that.raw.searchByQuery(query)
+      return that.raw.osm.searchByQuery(query)
         .then(function(res) {
           console.debug('[ES] [geo] Found {0} address position(s) in {0}ms'.format(res && res.length || 0, new Date().getTime() - now.getTime()), res);
           return res;
+        })
+
+        // Fallback service
+        .catch(function(err) {
+          var address = (query.street ? query.street +', ' : '') + query.city +  (query.country ? ', '+ query.country : '');
+          return _fallbackSearchPositionByString(err, address);
         });
     }
 
diff --git a/www/plugins/es/templates/common/modal_category.html b/www/plugins/es/templates/common/modal_category.html
index bda21a8fafba0cde86b07a2c7b8e4e84dc104e0a..82045784b3688061562676674fc5bea0984c20bf 100644
--- a/www/plugins/es/templates/common/modal_category.html
+++ b/www/plugins/es/templates/common/modal_category.html
@@ -1,7 +1,7 @@
 <ion-modal-view>
   <ion-header-bar class="bar-positive">
       <button class="button button-clear" ng-click="closeModal()" translate>COMMON.BTN_CANCEL</button>
-      <h1 class="title" translate>COMMON.CATEGORIES</h1>
+      <h1 class="title" >{{ (ctrl.title || 'COMMON.CATEGORIES') | translate}}</h1>
   </ion-header-bar>
 
   <ion-content class="categoryModal">
diff --git a/www/plugins/es/templates/user/edit_profile.html b/www/plugins/es/templates/user/edit_profile.html
index 0dc08b5e514741c84ef84541a82d213ea83cfe5a..7fc1f170b2c79b9ce6dcdafa903f043f5b4e9622 100644
--- a/www/plugins/es/templates/user/edit_profile.html
+++ b/www/plugins/es/templates/user/edit_profile.html
@@ -142,7 +142,7 @@
                 </label>
               </div>
 
-              <div class="col no-padding">
+              <div class="col col-40 no-padding">
                 <div class="item no-padding text-center">
                   <span class="input-label"></span>
 
diff --git a/www/plugins/map/i18n/locale-en-GB.json b/www/plugins/map/i18n/locale-en-GB.json
index 4d23c5c79d9b9f615c470459e2bdf36963304c18..e25af76ebab057bb6e322c5da639aac80405d7db 100644
--- a/www/plugins/map/i18n/locale-en-GB.json
+++ b/www/plugins/map/i18n/locale-en-GB.json
@@ -26,6 +26,7 @@
         "TITLE": "Members map",
         "LAYER": {
           "MEMBER": "Members",
+          "PENDING": "Pending registrations",
           "WALLET": "Simple wallets"
         }
       }
diff --git a/www/plugins/map/i18n/locale-en.json b/www/plugins/map/i18n/locale-en.json
index 4d23c5c79d9b9f615c470459e2bdf36963304c18..e25af76ebab057bb6e322c5da639aac80405d7db 100644
--- a/www/plugins/map/i18n/locale-en.json
+++ b/www/plugins/map/i18n/locale-en.json
@@ -26,6 +26,7 @@
         "TITLE": "Members map",
         "LAYER": {
           "MEMBER": "Members",
+          "PENDING": "Pending registrations",
           "WALLET": "Simple wallets"
         }
       }
diff --git a/www/plugins/map/i18n/locale-fr-FR.json b/www/plugins/map/i18n/locale-fr-FR.json
index 4083d3d55a1b7e8b927536b7d1ca142f734a052f..7433568d28fcb7c6fb910477e32ebe39f5986320 100644
--- a/www/plugins/map/i18n/locale-fr-FR.json
+++ b/www/plugins/map/i18n/locale-fr-FR.json
@@ -24,9 +24,9 @@
       },
       "VIEW": {
         "TITLE": "Carte des membres",
-        "SEARCH_DOTS": "Rechercher...",
         "LAYER": {
           "MEMBER": "Membres",
+          "PENDING": "Inscriptions en attente",
           "WALLET": "Simples portefeuilles"
         }
       }
diff --git a/www/plugins/map/js/controllers/network-controllers.js b/www/plugins/map/js/controllers/network-controllers.js
index f511a09b4f1547710694af497e49a43381af82ab..a6b8b21f47a6a3bfb6df774f99eef5a02c1e9805 100644
--- a/www/plugins/map/js/controllers/network-controllers.js
+++ b/www/plugins/map/js/controllers/network-controllers.js
@@ -215,9 +215,9 @@ angular.module('cesium.map.network.controllers', ['cesium.services', 'cesium.map
             // Create a search marker (will be hide)
             var searchServer = peer.dns || peer.server;
             var searchText = searchServer +
-              (peer.uid ? (' | ' + peer.name||peer.uid) : '') +
+              (peer.uid ? (' | ' + (peer.name||peer.uid)) : '') +
               ' | ' + formatPubkey(peer.pubkey);
-            var searchIp;;
+            var searchIp;
             if (bma.ipv4 && !(peer.dns || peer.server).startsWith(bma.ipv4)) {
               searchIp = bma.ipv4;
               searchText += ' | ' + bma.ipv4;
diff --git a/www/plugins/map/js/controllers/wot-controllers.js b/www/plugins/map/js/controllers/wot-controllers.js
index a5dc55dd1b69aeb8c7f396e16087f20d29651b83..89c69ba62f73536039958fb00db7f7e9127a1a44 100644
--- a/www/plugins/map/js/controllers/wot-controllers.js
+++ b/www/plugins/map/js/controllers/wot-controllers.js
@@ -47,6 +47,12 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser
             icon: 'person',
             markerColor: 'blue'
         },
+        pending: {
+          type: 'awesomeMarker',
+          icon: 'clock',
+          markerColor: 'lightgreen',
+          iconColor: 'gray'
+        },
         wallet: {
           type: 'awesomeMarker',
             icon: 'key',
@@ -69,14 +75,19 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser
     $scope.map = MapUtils.map({
       layers: {
         overlays: {
-          wallet: {
+          member: {
             type: 'group',
-            name: 'MAP.WOT.VIEW.LAYER.WALLET',
+            name: 'MAP.WOT.VIEW.LAYER.MEMBER',
             visible: true
           },
-          member: {
+          pending: {
             type: 'group',
-            name: 'MAP.WOT.VIEW.LAYER.MEMBER',
+            name: 'MAP.WOT.VIEW.LAYER.PENDING',
+            visible: true
+          },
+          wallet: {
+            type: 'group',
+            name: 'MAP.WOT.VIEW.LAYER.WALLET',
             visible: true
           }
         }
@@ -163,13 +174,13 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser
              });*/
 
             _.forEach(res, function (hit) {
-              var type = hit.uid ? 'member' : 'wallet';
-              var shortPubkey = formatPubkey(hit.issuer);
+              var type = hit.pending ? 'pending' : (hit.uid ? 'member' : 'wallet');
+              var shortPubkey = formatPubkey(hit.pubkey);
               var marker = {
                 layer: type,
                 icon: icons[type],
-                opacity: 0.8,
-                title: hit.title + ' | ' + shortPubkey,
+                opacity: hit.uid ? 1 : 0.7,
+                title: hit.name + ' | ' + shortPubkey,
                 lat: hit.geoPoint.lat,
                 lng: hit.geoPoint.lon,
                 getMessageScope: function () {
@@ -180,11 +191,11 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser
                 focus: false,
                 message: markerTemplate
               };
-              var id = hit.uid ? (hit.uid + ':' + hit.issuer) : hit.issuer;
+              var id = hit.uid ? (hit.uid + ':' + hit.pubkey) : hit.pubkey;
               $scope.map.markers[id] = marker;
 
               // Create a search marker (will be hide)
-              var searchText = hit.title + ((hit.uid && hit.uid != hit.title) ? (' | ' + hit.uid) : '') + ' | ' + shortPubkey;
+              var searchText = hit.name + ((hit.uid && hit.uid != hit.name) ? (' | ' + hit.uid) : '') + ' | ' + shortPubkey;
               var searchMarker = angular.merge({
                 type: type,
                 opacity: 0,
@@ -192,7 +203,7 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser
                   className: type + ' ng-hide',
                   iconSize: L.point(0, 0)
                 })
-              }, {title: searchText, issuer: hit.issuer, uid: hit.uid, name: hit.title});
+              }, {title: searchText, pubkey: hit.pubkey, uid: hit.uid, name: hit.name, pending: hit.pending});
               markersSearchLayer.addLayer(new L.Marker({
                   lat: hit.geoPoint.lat,
                   lng: hit.geoPoint.lon
diff --git a/www/plugins/map/js/services.js b/www/plugins/map/js/services.js
index 02aec430c30330b0372f5f5479769c44041d0482..5e8cad2b4b4d9f97f239ba43ac83ba14dc8e50c0 100644
--- a/www/plugins/map/js/services.js
+++ b/www/plugins/map/js/services.js
@@ -2,7 +2,6 @@
 angular.module('cesium.map.services', [
     // Services
     'cesium.map.wot.services',
-    'cesium.map.network.services',
     'cesium.map.utils.services'
   ])
 ;
diff --git a/www/plugins/map/js/services/network-services.js b/www/plugins/map/js/services/network-services.js
deleted file mode 100644
index 5b48ba35a88b2e5a3de7dc16c664191d278c417d..0000000000000000000000000000000000000000
--- a/www/plugins/map/js/services/network-services.js
+++ /dev/null
@@ -1,60 +0,0 @@
-
-angular.module('cesium.map.network.services', ['cesium.services'])
-
-.factory('mapNetwork', function(csHttp, esHttp, csNetwork) {
-  'ngInject';
-
-  var
-    that = this,
-    constants = {
-      DEFAULT_LOAD_SIZE: 1000
-    },
-    fields = {
-      profile: ["issuer", "title", "description", "geoPoint"]
-    };
-
-  that.raw = {
-
-  };
-
-  function load(options) {
-
-    csNetwork.start()
-    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/utils-services.js b/www/plugins/map/js/services/utils-services.js
index 1e19a0c8b2756888faf2ef9f670e081317cf0e46..406a1ce1afa6d9290d823e9f6ead3aa7fece5559 100644
--- a/www/plugins/map/js/services/utils-services.js
+++ b/www/plugins/map/js/services/utils-services.js
@@ -1,10 +1,13 @@
 
 angular.module('cesium.map.utils.services', ['cesium.services', 'ui-leaflet'])
 
-.factory('MapUtils', function($timeout, $q, $translate, leafletData, csSettings, esGeo, UIUtils, leafletHelpers) {
+.factory('MapUtils', function($timeout, $q, $translate, leafletData, csConfig, csSettings, esGeo, UIUtils, leafletHelpers) {
   'ngInject';
 
-  var constants = {
+
+  var
+    googleApiKey = csConfig.plugins && csConfig.plugins.es && csConfig.plugins.es.googleApiKey;
+    constants = {
     locations: {
       FRANCE: {
         lat: 46.5588603, lng: 4.229736328124999, zoom: 6
@@ -22,10 +25,25 @@ angular.module('cesium.map.utils.services', ['cesium.services', 'ui-leaflet'])
       },
       layers: {
         baselayers: {
-          openStreetMap: {
+          osm: {
             name: 'OpenStreetMap',
             type: 'xyz',
-            url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
+            url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
+            layerOptions: {
+              subdomains: ["a", "b", "c"],
+              attribution: "&copy; <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>",
+              continuousWorld: true
+            }
+          },
+          cycle: {
+            name: "Google map",
+            type: "xyz",
+            url: 'http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}&key='+googleApiKey,
+            layerOptions: {
+              subdomains: ['mt0','mt1','mt2','mt3'],
+              attribution: "&copy; <a href=\"http://google.com/copyright\">Google</a>",
+              continuousWorld: true
+            }
           }
         }
       },
diff --git a/www/plugins/map/js/services/wot-services.js b/www/plugins/map/js/services/wot-services.js
index 264099f25eba85ede15d2af25368cbe333e61e66..1e97a6d753dcef9213fb43fd837e61568c3a2297 100644
--- a/www/plugins/map/js/services/wot-services.js
+++ b/www/plugins/map/js/services/wot-services.js
@@ -1,7 +1,7 @@
 
 angular.module('cesium.map.wot.services', ['cesium.services'])
 
-.factory('mapWot', function(csHttp, esHttp, csWot) {
+.factory('mapWot', function($q, csHttp, esHttp, csWot, BMA) {
   'ngInject';
 
   var
@@ -10,7 +10,7 @@ angular.module('cesium.map.wot.services', ['cesium.services'])
       DEFAULT_LOAD_SIZE: 1000
     },
     fields = {
-      profile: ["issuer", "title", "description", "geoPoint"]
+      profile: ["title", "geoPoint", "avatar._content_type"]
     };
 
   that.raw = {
@@ -43,15 +43,51 @@ angular.module('cesium.map.wot.services', ['cesium.services'])
       _source: fields.profile
     };
 
-    return that.raw.profile.postSearch(request)
+    return $q.all([
+        that.raw.profile.postSearch(request),
+        BMA.wot.member.uids(),
+        BMA.wot.member.pending()
+          .then(function(res) {
+            return (res.memberships && res.memberships.length) ? res.memberships : [];
+          })
+      ])
       .then(function(res) {
+        var uids = res[1];
+        var memberships = res[2];
+        var res = res[0];
         if (!res.hits || !res.hits.total) return [];
 
-        var commaRegexp = new RegExp('[,]');
+        // Transform pending MS into a map by pubkey
+        memberships = memberships.reduce(function(res, ms){
+          if (ms.membership == 'IN' && !uids[ms.pubkey]) {
+            var idty = {
+              uid: ms.uid,
+              pubkey: ms.pubkey,
+              block: ms.blockNumber,
+              blockHash: ms.blockHash,
+              pending: true
+            };
+            var otherIdtySamePubkey = res[ms.pubkey];
+            if (otherIdtySamePubkey && idty.block > otherIdtySamePubkey.block) {
+              return res; // skip
+            }
+            res[idty.pubkey] = idty;
+          }
+          return res;
+        }, {});
+
 
+        // Transform profile hits
+        var commaRegexp = new RegExp('[,]');
         res = res.hits.hits.reduce(function(res, hit) {
-          var item = hit._source;
+          var pubkey =  hit._id;
+
+          var uid = uids[pubkey];
+          var item = uid && {uid: uid} || memberships[pubkey] || {};
+          item.pubkey = pubkey;
 
+          // Set geo point
+          item.geoPoint = hit._source.geoPoint;
           if (!item.geoPoint || !item.geoPoint.lat || !item.geoPoint.lon) return res;
 
           // Convert lat/lon to float (if need)
@@ -62,13 +98,25 @@ angular.module('cesium.map.wot.services', ['cesium.services'])
             item.geoPoint.lon = parseFloat(item.geoPoint.lon.replace(commaRegexp, '.'));
           }
 
+          // Avatar
+          item.avatar = esHttp.image.fromHit(hit, 'avatar');
+
+          // Name
+          item.name = hit._source.title;
+          // Avoid too long name (workaround for #308)
+          if (item.name && item.name.length > 30) {
+            item.name = item.name.substr(0, 27) + '...';
+          }
+          console.log(item);
+
           return res.concat(item);
         }, []);
 
-        return csWot.extendAll(res, 'issuer');
+        return csWot.extendAll(res, 'pubkey');
       });
   }
 
+
   return {
     load: load
   };
diff --git a/www/plugins/map/templates/wot/item_search_tooltip.html b/www/plugins/map/templates/wot/item_search_tooltip.html
index 94800b3bd049d43fcca4a7fb6f236e0397b85c07..88e9dcf2fb158d9d832d525e710687f346558290 100644
--- a/www/plugins/map/templates/wot/item_search_tooltip.html
+++ b/www/plugins/map/templates/wot/item_search_tooltip.html
@@ -1,7 +1,8 @@
 <a href="#" class="{{type}}">
+  <i class="{{pending ? 'ion-clock': ''}}"></i>
   {{name != uid ? name +' ' : ''}}
   <span class="{{uid ? 'positive' : 'gray'}}">
-    <i class="icon {{uid ? 'ion-person' : 'ion-key'}}"></i>
-    {{uid ? uid : (issuer|formatPubkey) }}
+    <i class="{{uid ? 'ion-person' : 'ion-key'}}"></i>
+    {{uid ? uid : (pubkey|formatPubkey) }}
   </span>
 </a>
diff --git a/www/plugins/map/templates/wot/popup_marker.html b/www/plugins/map/templates/wot/popup_marker.html
index 7e31eecb1861814fa30689a0b2f244ba0867f726..9145a95e47b26ab907fe652d3fc97bf732bb066b 100644
--- a/www/plugins/map/templates/wot/popup_marker.html
+++ b/www/plugins/map/templates/wot/popup_marker.html
@@ -1,10 +1,11 @@
-<div class="item no-border no-padding" ng-class="::{'item-avatar': hit.avatar}">
-  <img ng-if="::hit.avatar" class="avatar" ng-src="{{::hit.avatar.src}}">
+<div class="item no-border no-padding item-avatar" ng-class="::{'item-avatar': hit.avatar}">
+  <img ng-if="::hit.avatar" class="item-image avatar" ng-src="{{::hit.avatar.src}}">
+  <i ng-if="::!hit.avatar" class="item-image icon " ng-class="::{'ion-person': hit.uid, 'ion-card': !hit.uid}"></i>
   <div class="item-content item-avatar-left-padding padding-top">
-    <h2 class="dark"><a ui-sref="app.wot_identity({pubkey: hit.issuer, uid: hit.uid})">{{::hit.title}}</a></h2>
+    <h2 class="dark"><a ui-sref="app.wot_identity({pubkey: hit.pubkey, uid: hit.uid})">{{::hit.name}}</a></h2>
     <h4>
       <span ng-if="::hit.uid" class="positive">
-        <i class="icon ion-person"></i>
+        <b class="ion-person"></b>
         {{::hit.uid}}
       </span>
       <span class="assertive" ng-if="!hit.uid">
@@ -12,7 +13,7 @@
       </span>
     </h4>
     <h4>
-      <span class="gray" title="{{::hit.issuer}}"><i class="icon ion-key"></i> {{::hit.issuer|formatPubkey}}</span>
+      <span class="gray" title="{{::hit.pubkey}}"><b class="ion-key"></b> {{::hit.pubkey|formatPubkey}}</span>
     </h4>
   </div>
 </div>