diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts
index 1236e15251075416efffbc06a4b6155d883411b7..dacea3736f58a0e90ab0a296d2f5ecaf540e490e 100644
--- a/src/app/map/services/map.service.ts
+++ b/src/app/map/services/map.service.ts
@@ -21,7 +21,10 @@ export class MapService {
   private _map: mapboxgl.Map;
   private url: string;
   selectedBaseLayer;
+
   metadata: Metadata;
+  uriWFS: IMetadataLink;
+
   eventPopupAdded = false;
   minimap: Minimap;
   mapIsConstructed: boolean = false;
@@ -29,9 +32,12 @@ export class MapService {
 
   // Map
   featureColor: string = '#1d92ff';
-  featureColorHalo: string = 'rgba(29, 146, 255, 0.3)';
+  featureHoverColor: string = '#235b8f';
   featureHighlightedColor: string = '#F72F2F'; // Tomato color
 
+  hoveredFeatureId: string;
+  highlightedFeatureId: string;
+
   // This is used to remeber what is the previous dataset that the map displayed.
   // The reason is to know if we need to display the same map settings (for example the user went to another
   // tab), or if we display with default settings (if the user changed the dataset and go to the map).
@@ -62,6 +68,8 @@ export class MapService {
 
   createMap(url: string, baseLayer: any, addControls: boolean, options?: mapboxgl.MapboxOptions): mapboxgl.Map {
     this.metadata = this._datasetDetailService.datasetMetadata;
+    this.uriWFS = this.metadata.link.find((e) => { return e.service === linkFormats.wfs; });
+
     // Reset to false in ordre to set event listener
     this.eventPopupAdded = false;
     // Re-initialize panel state
@@ -78,6 +86,7 @@ export class MapService {
 
     // Subscribe to the error observable and send a notification
     this._errorSubscription = errorObservable.subscribe((v) => {
+      console.log(v);
       this._notificationService.notify(
         new Notification({
           message: notificationMessages.geosource.mapError,
@@ -125,8 +134,7 @@ export class MapService {
   // - if WFS exists but data > 100 000, or if WFS no exist: we display the WMS layer
   addLayers() {
     // Check if the metadata has WFS data format.
-    const uriWFS = this.metadata.link.find((e) => { return e.service === linkFormats.wfs; });
-    if (uriWFS && this._datasetDetailService.datasetDataNumber < 100000) {
+    if (this.uriWFS && this._datasetDetailService.datasetDataNumber < 100000) {
       this._currentLayerType = linkFormats.wfs;
       this.getWFSFeatures(
         this.metadata,
@@ -170,213 +178,258 @@ export class MapService {
   // - Create the WFS layers from this source
   // - if the features are 'Point' type, create clustering layers
   addWFSLayer() {
+    console.log(this.metadata);
+    const url = 'https://download.recette.data.grandlyon.com/mvt/grandlyon?LAYERS' +
+      `=${this.uriWFS.name}&map.imagetype=mvt&tilemode=gmap&tile={x}+{y}+{z}&mode=tile`;
+    console.log(url);
+    // this._map.addSource('wfs-clustered-points', {
+    //   type: 'geojson',
+    //   tiles: url,
+    //   cluster: true,
+    //   clusterMaxZoom: 13, // Max zoom to cluster points on
+    //   clusterRadius: 45, // Radius of each cluster when clustering points (defaults to 50)
+    // });
+
     this._map.addSource('wfs-clustered-points', {
-      type: 'geojson',
-      data: this.geojson,
-      cluster: true,
-      clusterMaxZoom: 13, // Max zoom to cluster points on
-      clusterRadius: 45, // Radius of each cluster when clustering points (defaults to 50)
+      type: 'vector',
+      tiles: [url],
     });
 
+    // this._map.addSource('wfs-polygon', {
+    //   type: 'geojson',
+    //   data: this.geojson,
+    // });
+
     this._map.addSource('wfs-polygon', {
-      type: 'geojson',
-      data: this.geojson,
+      type: 'vector',
+      tiles: [url],
     });
 
     // Add the layers for 'Point' features (clustered and unclustered layers)
     // Create steps to display different circle size and colors depending the count
-    this._map.addLayer({
-      id: 'point-features',
-      type: 'circle',
-      source: 'wfs-clustered-points',
-      paint: {
-        // Use step expressions (https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-step)
-        // with three steps to implement three types of circles:
-        //   * 20px circles when point count is less than 20
-        //   * 30px circles when point count is between 20 and 50
-        //   * 40px circles when point count is greater than or equal to 50
-        'circle-color': this.featureColor,
-        'circle-radius': [
-          'step',
-          ['get', 'point_count'],
-          20, // 20px
-          20, // les than 20 features
-          30, // 30px
-          50, // until - more 50 features
-          40, // 40px
-        ],
-        'circle-stroke-width': [
-          'step',
-          ['get', 'point_count'],
-          4, // 4px
-          20, // les than 20 features
-          6, // 6px
-          50, // until - more 50 features
-          11, // 11px
-        ],
-        'circle-stroke-color': this.featureColorHalo,
-      },
-      filter: ['has', 'point_count'],
-    });
+    if (false) {
+      this._map.addLayer({
+        id: 'point-features',
+        type: 'circle',
+        source: 'wfs-clustered-points',
+        paint: {
+          // Use step expressions (https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-step)
+          // with three steps to implement three types of circles:
+          //   * 20px circles when point count is less than 20
+          //   * 30px circles when point count is between 20 and 50
+          //   * 40px circles when point count is greater than or equal to 50
+          'circle-color': this.featureColor,
+          'circle-radius': [
+            'step',
+            ['get', 'point_count'],
+            20, // 20px
+            20, // les than 20 features
+            30, // 30px
+            50, // until - more 50 features
+            40, // 40px
+          ],
+          'circle-stroke-width': [
+            'step',
+            ['get', 'point_count'],
+            4, // 4px
+            20, // les than 20 features
+            6, // 6px
+            50, // until - more 50 features
+            11, // 11px
+          ],
+          'circle-stroke-color': this.featureHoverColor,
+        },
+        filter: ['has', 'point_count'],
+      });
+    }
 
     // Add the cluster count layer (the number inside the circle)
-    this._map.addLayer({
-      id: 'cluster-count',
-      type: 'symbol',
-      source: 'wfs-clustered-points',
-      filter: ['has', 'point_count'],
-      layout: {
-        'text-field': '{point_count_abbreviated}',
-        'text-size': 14,
-        'text-font': ['Noto Sans Bold'],
-      },
-      paint: {
-        'text-color': 'white',
-      },
-    });
+    if (false) {
+      this._map.addLayer({
+        id: 'cluster-count',
+        type: 'symbol',
+        source: 'wfs-clustered-points',
+        filter: ['has', 'point_count'],
+        layout: {
+          'text-field': '{point_count_abbreviated}',
+          'text-size': 14,
+          'text-font': ['Noto Sans Bold'],
+        },
+        paint: {
+          'text-color': 'white',
+        },
+      });
+    }
 
     // For 'Polygon' feature highlighted
-    this._map.addLayer({
-      id: 'polygon-features-highlight',
-      type: 'fill',
-      layout: {
-        visibility: 'none',
-      },
-      source: 'wfs-polygon',
-      paint: {
-        'fill-color': this.featureHighlightedColor,
-        'fill-opacity': 0.4,
-      },
-      filter: ['==', '$type', 'Polygon'],
-    });
-
+    if (false) { // TODO Remove
+      this._map.addLayer({
+        id: 'polygon-features-highlight',
+        type: 'fill',
+        layout: {
+          visibility: 'none',
+        },
+        source: 'wfs-polygon',
+        paint: {
+          'fill-color': this.featureHighlightedColor,
+          'fill-opacity': 0.4,
+        },
+        filter: ['==', '$type', 'Polygon'],
+      });
+    }
     // For 'Polygon' and 'MultiPolygon' features, one layer is enough (no cluster)
     this._map.addLayer(
       {
         id: 'polygon-features',
         type: 'fill',
         source: 'wfs-polygon',
+        'source-layer': this.uriWFS.name,
         paint: {
           'fill-color': this.featureColor,
           'fill-opacity': 0.4,
         },
         filter: ['match', ['geometry-type'], ['Polygon', 'MultiPolygon'], true, false],
-      },
-      'polygon-features-highlight',
-    );
+      });
 
     // For 'LineString' feature selected highlight
-    this._map.addLayer({
-      id: 'line-features-highlight',
-      type: 'line',
-      source: 'wfs-polygon',
-      layout: {
-        'line-cap': 'round',
-        'line-join': 'round',
-        visibility: 'none',
-      },
-      paint: {
-        'line-color': this.featureHighlightedColor,
-        'line-width': 3,
-        'line-opacity': 0.8,
-      },
-    });
-
-    // For 'LineString' and 'MultiLineString features, one layer is enough (no cluster)
-    this._map.addLayer(
-      {
-        id: 'line-features',
+    if (0) { // TODO Remove
+      this._map.addLayer({
+        id: 'line-features-highlight',
         type: 'line',
         source: 'wfs-polygon',
         layout: {
           'line-cap': 'round',
           'line-join': 'round',
+          visibility: 'none',
         },
         paint: {
-          'line-color': this.featureColor,
+          'line-color': this.featureHighlightedColor,
           'line-width': 3,
           'line-opacity': 0.8,
         },
-        filter: ['match', ['geometry-type'], ['LineString', 'MultiLineString'], true, false],
-      },
-      'line-features-highlight',
-    );
-
-    this._map.loadImage('./assets/img/marker_blue_active.png', (error, image) => {
-      if (error) throw error;
-      this._map.addImage('marker-active', image);
-
-      this._map.loadImage('./assets/img/marker_blue_hover.png', (error, image) => {
-        if (error) throw error;
-        this._map.addImage('marker-hover', image);
-        // Add layer + style for the unclustered points highlighted
-        this._map.addLayer(
-          {
-            id: 'unclustered-point-highlighted',
-            type: 'symbol',
-            source: 'wfs-clustered-points',
-            filter: ['!has', 'point_count'],
-            layout: {
-              'icon-image': 'marker-active',
-              'icon-size': 0.5,
-              'icon-anchor': 'bottom',
-              'icon-allow-overlap': true,
-              visibility: 'none',
-            },
+      });
+    }
+
+    // For 'LineString' and 'MultiLineString features, one layer is enough (no cluster)
+    if (false) { // TODO Remove
+      this._map.addLayer(
+        {
+          id: 'line-features',
+          type: 'line',
+          source: 'wfs-polygon',
+          'source-layer': this.uriWFS.name,
+          layout: {
+            'line-cap': 'round',
+            'line-join': 'round',
           },
-        );
+          paint: {
+            'line-color': this.featureColor,
+            'line-width': 3,
+            'line-opacity': 0.8,
+          },
+          filter: ['match', ['geometry-type'], ['LineString', 'MultiLineString'], true, false],
+        },
+        'line-features-highlight',
+      );
+    }
 
-        this._map.loadImage('./assets/img/marker_blue_normal.png', (error, image) => {
-          if (error) throw error;
-          this._map.addImage('marker', image);
-          // Add layer + style for the unclustered points
-          this._map.addLayer(
-            {
-              id: 'unclustered-point',
-              type: 'symbol',
+    // Add layer + style for the unclustered points highlighted
+    // this._map.addLayer(
+    //   {
+    //     id: 'unclustered-point-highlighted',
+    //     type: 'circle',
+    //     source: 'wfs-clustered-points',
+    //     'source-layer': this.uriWFS.name,
+    //     filter: ['==', 'id', ''],
+    //     layout: {
+    //       visibility: 'none',
+    //     },
+    //     paint: {
+    //       'circle-radius': {
+    //         base: 1.75,
+    //         stops: [[12, 2], [22, 180]],
+    //       },
+    //       'circle-color': this.featureHighlightedColor,
+    //     },
+    //   });
+
+    // Add layer + style for the unclustered points
+
+    this._map.addLayer(
+      {
+        id: 'unclustered-point',
+        type: 'circle',
+        source: 'wfs-clustered-points',
+        'source-layer': this.uriWFS.name,
+        filter: ['match', ['geometry-type'], ['Point'], true, false],
+        paint: {
+          'circle-radius': {
+            base: 1.75,
+            stops: [[12, 2], [22, 180]],
+          },
+          'circle-stroke-width': {
+            base: 0.3,
+            stops: [[12, 0.6], [22, 2]],
+          },
+          'circle-stroke-color': 'white',
+          'circle-stroke-opacity': 0.7,
+          'circle-color': ['case',
+            ['boolean', ['feature-state', 'hover'], false],
+            this.featureHoverColor,
+            ['boolean', ['feature-state', 'highlight'], false],
+            this.featureHighlightedColor,
+            this.featureColor,
+          ],
+        },
+      });
+
+    if (!this.eventPopupAdded) {
+      // Change the cursor to a pointer when the mouse is over the unclustered-point layer.
+      this._map.on('mousemove', 'unclustered-point', (e) => {
+        if (e.features.length > 0) {
+          this._map.getCanvas().style.cursor = 'pointer';
+          if (this.hoveredFeatureId) {
+            this._map.setFeatureState({
               source: 'wfs-clustered-points',
-              filter: ['!has', 'point_count'],
-              layout: {
-                'icon-image': 'marker',
-                'icon-size': 0.5,
-                'icon-anchor': 'bottom',
-                'icon-allow-overlap': true,
-              },
+              sourceLayer: this.uriWFS.name,
+              id: this.hoveredFeatureId,
             },
-            'unclustered-point-highlighted',
-          );
+              // tslint:disable-next-line:align
+              { hover: false });
+          }
 
-          this._map.addLayer(
-            {
-              id: 'unclustered-point-hover',
-              type: 'symbol',
+          this.hoveredFeatureId = e.features[0].id;
+
+          // Display hover state only if not already highlighted
+          const state = this._map.getFeatureState({
+            source: 'wfs-clustered-points',
+            sourceLayer: this.uriWFS.name,
+            id: this.hoveredFeatureId,
+          });
+          if (!state.highlight) {
+            this._map.setFeatureState({
               source: 'wfs-clustered-points',
-              filter: ['==', '_featureId', ''],
-              layout: {
-                'icon-image': 'marker-hover',
-                'icon-size': 0.5,
-                'icon-anchor': 'bottom',
-                'icon-allow-overlap': true,
-                visibility: 'none',
-              },
+              sourceLayer: this.uriWFS.name,
+              id: this.hoveredFeatureId,
             },
-          );
-        });
+              // tslint:disable-next-line:align
+              { hover: true });
+          }
+        }
       });
-    });
 
-    if (!this.eventPopupAdded) {
-      // Change the cursor to a pointer when the mouse is over the unclustered-point layer.
-      this._map.on('mouseenter', 'unclustered-point', (e) => {
-        this._map.getCanvas().style.cursor = 'pointer';
-        const hoveredFeature = e.features[0].properties._featureId;
-        this._map.setFilter('unclustered-point-hover', ['==', '_featureId', hoveredFeature]);
-        this._map.setLayoutProperty('unclustered-point-hover', 'visibility', 'visible');
-      }).on('mouseleave', 'unclustered-point', () => {
-        this._map.getCanvas().style.cursor = '';
-        this._map.setFilter('unclustered-point-hover', ['==', '_featureId', '']);
-        this._map.setLayoutProperty('unclustered-point-hover', 'visibility', 'none');
+      this._map.on('mouseleave', 'unclustered-point', (e) => {
+        if (this.hoveredFeatureId) {
+          this._map.getCanvas().style.cursor = '';
+          this._map.setFeatureState({
+            source: 'wfs-clustered-points',
+            sourceLayer: this.uriWFS.name,
+            id: this.hoveredFeatureId,
+            // tslint:disable-next-line:align
+          }, { hover: false });
+        }
 
+        this.hoveredFeatureId = null;
       });
 
       this._map.on('mouseenter', 'polygon-features', () => {
@@ -397,27 +450,54 @@ export class MapService {
         this.closePanel();
       });
 
-      this.addClickEventOnLayer('unclustered-point', 'unclustered-point-highlighted');
-      this.addClickEventOnLayer('polygon-features', 'polygon-features-highlight');
-      this.addClickEventOnLayer('line-features', 'line-features-highlight');
+      this.addClickEventOnLayer('unclustered-point', this.uriWFS.name);
+      // this.addClickEventOnLayer('polygon-features', 'polygon-features-highlight');
+      // if (this._map.getLayer('line-features-highlight')) {
+      //   this.addClickEventOnLayer('line-features', 'line-features-highlight');
+      // }
 
       this.eventPopupAdded = true;
     }
 
   }
 
-  addClickEventOnLayer(layer, highlightedLayer) {
+  addClickEventOnLayer(layer, layerName) {
     this._map.on('click', layer, (e) => {
-      this.selectedFeature = e.features[0].properties._featureId;
-      this._map.setFilter(highlightedLayer, ['==', ['get', '_featureId'], this.selectedFeature]);
-      this._map.setLayoutProperty(highlightedLayer, 'visibility', 'visible');
+      this.selectedFeature = e.features[0].id;
+
+      // Reset the hover and highglithed state for the current and previous feature
+      this._map.setFeatureState({
+        source: 'wfs-clustered-points',
+        sourceLayer: layerName,
+        id: this.hoveredFeatureId,
+      },
+        // tslint:disable-next-line:align
+        { hover: false });
+      this._map.setFeatureState({
+        source: 'wfs-clustered-points',
+        sourceLayer: layerName,
+        id: this.highlightedFeatureId,
+      },
+        // tslint:disable-next-line:align
+        { highlight: false });
+
+      // Set highlited style for the current feature
+      this.highlightedFeatureId = this.selectedFeature;
+      this._map.setFeatureState({
+        source: 'wfs-clustered-points',
+        sourceLayer: layerName,
+        id: this.highlightedFeatureId,
+      },
+        // tslint:disable-next-line:align
+        { highlight: true });
 
+      const feature = e.features[0];
       this.handleMapPosition(e.point.x, e.lngLat, () => {
-        const feature = this.geojson.features.find(f => f.properties._featureId === this.selectedFeature);
+
         const featureCloned = cloneDeep(feature);
 
         // Remove the generated id from the properties to be displayed
-        delete featureCloned.properties._featureId;
+        delete featureCloned.id;
         this._panelState.next({ state: true, properties: featureCloned.properties });
       });
     });
@@ -631,16 +711,15 @@ export class MapService {
   }
 
   closePanel() {
+    // Remove the highlighted style for the feature
+    this._map.setFeatureState({
+      source: 'wfs-clustered-points',
+      sourceLayer: this.uriWFS.name,
+      id: this.highlightedFeatureId,
+    },
+      // tslint:disable-next-line:align
+      { highlight: false });
     this.selectedFeature = null;
-    if (this._map.getLayer('polygon-features-highlight')) {
-      this._map.setLayoutProperty('polygon-features-highlight', 'visibility', 'none');
-    }
-    if (this._map.getLayer('line-features-highlight')) {
-      this._map.setLayoutProperty('line-features-highlight', 'visibility', 'none');
-    }
-    if (this._map.getLayer('unclustered-point-highlighted')) {
-      this._map.setLayoutProperty('unclustered-point-highlighted', 'visibility', 'none');
-    }
     this._panelState.next({ state: false });
   }
 
diff --git a/src/i18n/traductions.fr.ts b/src/i18n/traductions.fr.ts
index 0e2a004003e21c62b14148422a4ecc3706fe904e..a9491b3adfb659666a4d5db46e831cd2c0192aad 100644
--- a/src/i18n/traductions.fr.ts
+++ b/src/i18n/traductions.fr.ts
@@ -22,7 +22,7 @@ export const notificationMessages = {
     getDatasetById: 'Impossible de charger le dataset',
     getAutocomplete: 'Impossible de récupérer le resultat de l\'autocompletion',
     getSuggestion: 'Impossible de récupérer le resultat de la suggestion',
-    mapError: 'Une erreur c\'est produite avec la carte',
+    mapError: 'Une erreur s\'est produite avec la carte',
     getDatasetChildren: 'Impossible de récupérer les enfants du jeu de données',
     getDatasetParentInfo: 'Impossible de récupérer les informations du jeu de données parent',
     getDatasetData: 'Impossible de récupérer la donnée du jeu de données',