diff --git a/src/components/Map/EditingToolbar.vue b/src/components/Map/EditingToolbar.vue
index 97c86db1a01faad1f264161aaa6288167a6b7d62..33c86323c46c203d1fb6e3550130a6479a1e0d99 100644
--- a/src/components/Map/EditingToolbar.vue
+++ b/src/components/Map/EditingToolbar.vue
@@ -117,8 +117,9 @@ export default {
 
 .editionToolbar{
   position: absolute;
-  // each button have .5em space between, zoom buttons are 60px high and full screen button is 34px high
-  top: calc(2em + 60px + 34px + 28px);
+  // each button have (more or less depends on borders) .5em space between
+  // zoom buttons are 60px high, geolocation and full screen button is 34px high with borders
+  top: calc(2em + 60px + 34px + 64px);
   right: 6px;
   border: 2px solid rgba(0,0,0,.2);
   border-radius: 4px;
diff --git a/src/components/Map/Geocoder.vue b/src/components/Map/Geocoder.vue
index d4644cb993d52fcc035444d3103c01755aec27d8..028a6a7598288ccff9789868afffb60e819dd73b 100644
--- a/src/components/Map/Geocoder.vue
+++ b/src/components/Map/Geocoder.vue
@@ -143,8 +143,9 @@ export default {
 .geocoder-container {
   position: absolute;
   right: 0.5em;
-  // each button have .5em space between, zoom buttons are 60px high and full screen button is 34px high
-  top: calc(1.5em + 60px + 34px);
+  // each button have (more or less depends on borders) .5em space between
+  // zoom buttons are 60px high, geolocation and full screen button is 34px high with borders
+  top: calc(1.6em + 60px + 34px + 34px);
   pointer-events: auto;
   z-index: 1000;
   border: 2px solid rgba(0,0,0,.2);
diff --git a/src/components/Map/Geolocation.vue b/src/components/Map/Geolocation.vue
new file mode 100644
index 0000000000000000000000000000000000000000..cc83f8c98773273d69827886517ef40b739ad711
--- /dev/null
+++ b/src/components/Map/Geolocation.vue
@@ -0,0 +1,66 @@
+<template>
+  <div class="geolocation-container">
+    <button
+      :class="['button-geolocation', { tracking }]"
+      @click.prevent="toggleTracking"
+    >
+      <i class="crosshairs icon" />
+    </button>
+  </div>
+</template>
+
+<script>
+
+import mapService from '@/services/map-service';
+
+export default {
+  name: 'Geolocation',
+
+  data() {
+    return {
+      tracking: false,
+    };
+  },
+
+  methods: {
+    toggleTracking() {
+      this.tracking = !this.tracking;
+      mapService.toggleGeolocation(this.tracking);
+    },
+  }
+};
+</script>
+
+<style>
+div.geolocation-container {
+  position: absolute;
+  right: 6px;
+  z-index: 1000;
+  border: 2px solid rgba(0,0,0,.2);
+  background-clip: padding-box;
+  padding: 0;
+  border-radius: 4px;
+}
+button.button-geolocation {
+  border: none;
+  padding: 0;
+  margin: 0;
+  text-align: center;
+  background-color: #fff;
+  color: rgb(39, 39, 39);
+  width: 30px;
+  height: 30px;
+  font: 700 18px Lucida Console,Monaco,monospace;
+  border-radius: 4px;
+  line-height: 1.15;
+  cursor: pointer;
+}
+button.button-geolocation.tracking {
+  background-color: rgba(255, 145, 0, 0.904);
+  color: #fff;
+}
+button.button-geolocation i {
+  margin: 0;
+  vertical-align: top; /* strangely top is the only value that center at middle */
+}
+</style>
diff --git a/src/services/map-service.js b/src/services/map-service.js
index 5aefb5eada744855a97794e1990b04a83609d493..01d6cd8b01a9f6c1a6f8a5e22a57458e701bcf28 100644
--- a/src/services/map-service.js
+++ b/src/services/map-service.js
@@ -2,7 +2,7 @@ import TileWMS from 'ol/source/TileWMS';
 import { View, Map } from 'ol';
 import { ScaleLine, Zoom, Attribution, FullScreen } from 'ol/control';
 import TileLayer from 'ol/layer/Tile';
-import { transform, transformExtent } from 'ol/proj.js';
+import { transform, transformExtent, fromLonLat } from 'ol/proj.js';
 import { defaults } from 'ol/interaction';
 import XYZ from 'ol/source/XYZ';
 import VectorTileLayer from 'ol/layer/VectorTile';
@@ -16,8 +16,10 @@ import {
 import { asArray } from 'ol/color';
 import VectorSource from 'ol/source/Vector';
 import VectorLayer from 'ol/layer/Vector';
-import { fromLonLat } from 'ol/proj.js';
 import OverlayPositioning from 'ol/OverlayPositioning';
+import Geolocation from 'ol/Geolocation.js';
+import Feature from 'ol/Feature.js';
+import Point from 'ol/geom/Point.js';
 
 import axios from '@/axios-client.js';
 import router from '@/router';
@@ -26,6 +28,19 @@ import { statusChoices } from '@/utils';
 
 let dictLayersToMap = {};
 
+const geolocationStyle = new Style({
+  image: new Circle({
+    radius: 6,
+    fill: new Fill({
+      color: '#3399CC',
+    }),
+    stroke: new Stroke({
+      color: '#fff',
+      width: 2,
+    }),
+  }),
+});
+
 const mapService = {
   layers: [],
 
@@ -39,6 +54,9 @@ const mapService = {
 
   queryParams: {},
 
+  geolocation: undefined,
+
+  geolocationSource: null,
 
   getMap() {
     return this.map;
@@ -58,6 +76,7 @@ const mapService = {
       zoom,
       zoomControl = true,
       fullScreenControl = false,
+      geolocationControl = false,
       interactions = { doubleClickZoom: false, mouseWheelZoom: false, dragPan: true },
       controls = [
         new Attribution({ collapsible: false }),
@@ -92,6 +111,10 @@ const mapService = {
     if (zoomControl) {
       this.map.addControl(new Zoom({ zoomInTipLabel: 'Zoomer', zoomOutTipLabel: 'Dézoomer' }));
     }
+    if (geolocationControl) {
+      this.initGeolocation();
+    }
+
     this.map.once('rendercomplete', () => {
       this.map.updateSize();
     });
@@ -120,6 +143,68 @@ const mapService = {
     return this.map;
   },
 
+  initGeolocation() {
+    this.geolocation = new Geolocation({
+      // enableHighAccuracy must be set to true to have the heading value.
+      trackingOptions: {
+        enableHighAccuracy: true,
+      },
+      projection: this.map.getView().getProjection(),
+    });
+    
+    // handle this.geolocation error.
+    this.geolocation.on('error', (error) =>  {
+      console.error(error.message);
+    });
+    
+    /* const accuracyFeature = new Feature();
+    this.geolocation.on('change:accuracyGeometry', () => {
+      accuracyFeature.setGeometry(this.geolocation.getAccuracyGeometry());
+    }); */
+    
+    const positionFeature = new Feature();
+    positionFeature.setStyle( geolocationStyle );
+    
+    this.geolocation.on('change:position', () => {
+      const coordinates = this.geolocation.getPosition();
+      positionFeature.setGeometry(coordinates ? new Point(coordinates) : null);
+      if (coordinates) {
+        this.map.getView().animate(
+          { zoom: 16 },
+          { center: coordinates },
+          { duration: 1000 }
+        );
+      }
+    });
+
+    this.geolocationSource = new VectorSource({
+      features: [positionFeature],
+      //features: [accuracyFeature, positionFeature],
+    });    
+    new VectorLayer({
+      map: this.map,
+      source: this.geolocationSource,
+    });
+  },
+
+  displayGeolocationPoint(isVisible) {
+    let features = this.geolocationSource.getFeatures();
+    if (!features) return;
+    const hiddenStyle = new Style(); // hide the feature
+    for (let i = 0; i < features.length; i++) {
+      features[i].setStyle(isVisible ? geolocationStyle : hiddenStyle);
+    }
+  },
+
+
+  toggleGeolocation(isTracking) {
+    if (this.geolocation) {
+      this.geolocation.setTracking(isTracking);
+      if (this.geolocationSource) {
+        this.displayGeolocationPoint(isTracking);
+      } 
+    }
+  },
 
   addRouterToPopup({ featureId, featureTypeSlug, index }) {
 
diff --git a/src/store/modules/map.store.js b/src/store/modules/map.store.js
index f20bf643ccc8804c7f2dd6b794d5860b875991a4..8421ef3663ce34023d5df7498f797a598fc15681 100644
--- a/src/store/modules/map.store.js
+++ b/src/store/modules/map.store.js
@@ -111,7 +111,8 @@ const map = {
         maxZoom: options.maxZoom || rootState.projects.project.map_max_zoom_level,
         controls: options.controls,
         zoomControl: options.zoomControl,
-        interactions : { doubleClickZoom :false, mouseWheelZoom:true, dragPan:true }
+        interactions : { doubleClickZoom :false, mouseWheelZoom:true, dragPan:true },
+        geolocationControl: true,
       });
       const map = { ...mapService.getMap() };
       commit('SET_MAP', map);
diff --git a/src/views/Feature/FeatureDetail.vue b/src/views/Feature/FeatureDetail.vue
index a233e1b1a1a11dd45c70cf04b127de01efd05505..991bc5e11c69cbfc82cf830f1848ee455bcd71d8 100644
--- a/src/views/Feature/FeatureDetail.vue
+++ b/src/views/Feature/FeatureDetail.vue
@@ -42,6 +42,7 @@
                 v-if="basemaps && map"
                 ref="sidebar"
               />
+              <Geolocation />
             </div>
             <div
               id="popup"
@@ -182,6 +183,7 @@ import FeatureTable from '@/components/Feature/Detail/FeatureTable';
 import FeatureAttachements from '@/components/Feature/Detail/FeatureAttachements';
 import FeatureComments from '@/components/Feature/Detail/FeatureComments';
 import SidebarLayers from '@/components/Map/SidebarLayers';
+import Geolocation from '@/components/Map/Geolocation';
 
 import { buffer } from 'ol/extent';
 
@@ -194,6 +196,7 @@ export default {
     FeatureAttachements,
     FeatureComments,
     SidebarLayers,
+    Geolocation,
   },
 
   beforeRouteUpdate (to, from, next) {
@@ -482,7 +485,8 @@ export default {
             mouseWheelZoom: true,
             dragPan: true
           },
-          fullScreenControl: true
+          fullScreenControl: true,
+          geolocationControl: true,
         });
 
         // Update link to feature list with map zoom and center
@@ -600,6 +604,12 @@ export default {
   min-height: 250px;
   border: 1px solid grey;
 }
+div.geolocation-container {
+  /* each button have (more or less depends on borders) .5em space between */
+  /* zoom buttons are 60px high, geolocation and full screen button is 34px high with borders */
+  top: calc(1.3em + 60px + 34px);
+}
+
 .prewrap {
   white-space: pre-wrap;
 }
diff --git a/src/views/Feature/FeatureEdit.vue b/src/views/Feature/FeatureEdit.vue
index b156f07c8c517d5e4be302348d403d5d274c56fd..92b6004a2ae1bdd0f694c28041505002b4b70a39 100644
--- a/src/views/Feature/FeatureEdit.vue
+++ b/src/views/Feature/FeatureEdit.vue
@@ -15,8 +15,6 @@
 
     <form
       id="form-feature-edit"
-      action=""
-      method="post"
       enctype="multipart/form-data"
       class="ui form"
     >
@@ -252,6 +250,7 @@
             ref="map"
           >
             <SidebarLayers v-if="basemaps && map" />
+            <Geolocation />
             <Geocoder />
             <EditingToolbar
               v-if="isEditable"
@@ -375,6 +374,7 @@ import Dropdown from '@/components/Dropdown.vue';
 import SidebarLayers from '@/components/Map/SidebarLayers';
 import EditingToolbar from '@/components/Map/EditingToolbar';
 import Geocoder from '@/components/Map/Geocoder';
+import Geolocation from '@/components/Map/Geolocation';
 import featureAPI from '@/services/feature-api';
 
 import mapService from '@/services/map-service';
@@ -384,7 +384,6 @@ import axios from '@/axios-client.js';
 import { GeoJSON } from 'ol/format';
 
 
-
 export default {
   name: 'FeatureEdit',
 
@@ -394,6 +393,7 @@ export default {
     Dropdown,
     SidebarLayers,
     Geocoder,
+    Geolocation,
     EditingToolbar,
     FeatureExtraForm,
   },
@@ -970,7 +970,8 @@ export default {
         mapDefaultViewZoom,
         maxZoom: this.project.map_max_zoom_level,
         interactions : { doubleClickZoom :false, mouseWheelZoom:true, dragPan:true },
-        fullScreenControl: true
+        fullScreenControl: true,
+        geolocationControl: true,
       });
       const currentFeatureId = this.$route.params.slug_signal;
       const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}v2/features/?feature_type__slug=${this.$route.params.slug_type_signal}&project__slug=${this.$route.params.slug}&output=geojson`;
@@ -1035,6 +1036,13 @@ export default {
   width: 100%;
   border: 1px solid grey;
 }
+
+
+div.geolocation-container {
+  /* each button have .5em space between, zoom buttons are 60px high and full screen button is 34px high */
+  top: calc(1.3em + 60px + 34px);
+}
+  
 #get-geom-from-image-file {
   margin-bottom: 5px;
 }
diff --git a/src/views/Project/FeaturesListAndMap.vue b/src/views/Project/FeaturesListAndMap.vue
index 7d57794ee88151a3aa4258f6aa22793074a7918f..8bf9e85e87657ace651ff0952826c55b9cd4d0d0 100644
--- a/src/views/Project/FeaturesListAndMap.vue
+++ b/src/views/Project/FeaturesListAndMap.vue
@@ -26,6 +26,7 @@
             v-if="basemaps && map"
             ref="sidebar"
           />
+          <Geolocation />
           <Geocoder />
         </div>
         <div 
@@ -106,8 +107,9 @@ import Geocoder from '@/components/Map/Geocoder';
 import featureAPI from '@/services/feature-api';
 
 import FeaturesListAndMapFilters from '@/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters';
-import SidebarLayers from '@/components/Map/SidebarLayers';
 import FeatureListTable from '@/components/Project/FeaturesListAndMap/FeatureListTable';
+import SidebarLayers from '@/components/Map/SidebarLayers';
+import Geolocation from '@/components/Map/Geolocation';
 
 const initialPagination = {
   currentPage: 1,
@@ -123,6 +125,7 @@ export default {
     FeaturesListAndMapFilters,
     SidebarLayers,
     Geocoder,
+    Geolocation,
     FeatureListTable,
   },
 
@@ -332,7 +335,8 @@ export default {
         mapDefaultViewZoom,
         maxZoom: this.project.map_max_zoom_level,
         interactions : { doubleClickZoom :false, mouseWheelZoom:true, dragPan:true },
-        fullScreenControl: true
+        fullScreenControl: true,
+        geolocationControl: true,
       });
 
       document.addEventListener('change-layers-order', (event) => {
@@ -545,6 +549,11 @@ export default {
     z-index: 1;
   }
 }
+div.geolocation-container {
+  // each button have (more or less depends on borders) .5em space between
+  // zoom buttons are 60px high, geolocation and full screen button is 34px high with borders
+  top: calc(1.3em + 60px + 34px);
+}
 
 @media screen and (max-width: 767px) {
   #project-features {
diff --git a/src/views/Project/ProjectDetail.vue b/src/views/Project/ProjectDetail.vue
index 91aed08946787587bbfd699e5935b4fa6da0a643..ccbb87732b5e42f2e4799def93f2c1f67106a205 100644
--- a/src/views/Project/ProjectDetail.vue
+++ b/src/views/Project/ProjectDetail.vue
@@ -39,6 +39,7 @@
                 v-if="basemaps && map && !projectInfoLoading"
                 ref="sidebar"
               />
+              <Geolocation />
               <div
                 id="popup"
                 class="ol-popup"
@@ -127,6 +128,7 @@ import ProjectLastComments from '@/components/Project/Detail/ProjectLastComments
 import ProjectParameters from '@/components/Project/Detail/ProjectParameters';
 import ProjectModal from '@/components/Project/Detail/ProjectModal';
 import SidebarLayers from '@/components/Map/SidebarLayers';
+import Geolocation from '@/components/Map/Geolocation';
 
 export default {
   name: 'ProjectDetail',
@@ -139,6 +141,7 @@ export default {
     ProjectParameters,
     ProjectModal,
     SidebarLayers,
+    Geolocation,
   },
 
   filters: {
@@ -483,4 +486,9 @@ export default {
     margin-top: 0.5em;
   }
 }
+
+div.geolocation-container {
+  /* each button have .5em space between, zoom buttons are 60px high and full screen button is 34px high */
+  top: calc(1.1em + 60px);
+}
 </style>