Table of Contents

Display current location on a Map with Geolocation API

vue-typescript-pinia-googlemaps

Tutorial on how to display the users current location on a google map, using HTML5 and more.

Tags: Vue 3, Typescript, Google Maps JS, Vector Maps, Geolocation API

Time to read: 10 min

Prerequisites

  • Familiarity with the command line
  • Install Node.js version 16.0 or higher
  • Google Maps JS API key and a MapID of type Vector / Javascript. Read how to get it here

Setup project

We will focus on using the Geolocation API and getting current location. So to save us some time we will begin from a scaffold application.

Run below commands in the command line to get the scaffold app.

mkdir geolocation-map-app && cd geolocation-map-app
npx degit crunchwrap89/map-app-scaffold
npm i
npm run dev

Now you can visit http://127.0.0.1:5000/

For the map to work fully you must add a .env file that holds the apikey and mapid in the same way as shown in the .env.example file.

Add composable for using geolocation API

Now to use the geolocation API we will add a composable.

Create a new file: src/composables/useGeolocation.ts

add the following code to the file:

import { ref } from 'vue';
import type { Ref } from 'vue';
export function useGeolocation() {
  const enableHighAccuracy = true,
    maximumAge = 30000,
    timeout = 27000;
  const locatedAt: Ref<number | null> = ref(null);
  const error = ref<GeolocationPositionError | null>(null);
  const coords: Ref<GeolocationPosition['coords']> = ref({
    accuracy: 0,
    latitude: Infinity,
    longitude: Infinity,
    altitude: null,
    altitudeAccuracy: null,
    heading: null,
    speed: null,
  });
  let watcher: number;
  function updatePosition(position: GeolocationPosition) {
    locatedAt.value = position.timestamp;
    coords.value = position.coords;
    error.value = null;
  }
  function initWatch() {
    if (!navigator.geolocation) {
      error.value = {
        message: 'geolocation api not available',
      } as GeolocationPositionError;
    } else {
      watcher = navigator.geolocation.watchPosition(updatePosition, (err) => (error.value = err), {
        enableHighAccuracy,
        maximumAge,
        timeout,
      });
    }
  }
  function stopWatch() {
    navigator.geolocation.clearWatch(watcher);
  }
  return { initWatch, coords, locatedAt, error, stopWatch };
}

Initialize watch function to get lat/lng

Now to automatically get the users position when the user moves, and show the position with a marker, add the following code.

<script setup lang="ts">
import { initMap } from "@/utils/mapUtils";
import { tilesLoaded } from "@/utils/mapUtils";
import { useGeolocation } from "@/composables/useGeolocation";
import { onMounted, onBeforeUnmount, watchEffect } from "vue";
const map = await initMap("map-mount");
await tilesLoaded(map);
const { initWatch, coords, error, stopWatch } = useGeolocation();
let marker: google.maps.Marker | null;
onMounted(() => {
  marker = new google.maps.Marker({
    position: {lat: 0, lng: 0},
    map,
    title: "My current Position",
  });
  initWatch();
  watchEffect(() => {
    if(marker) {
        marker.setPosition({lat: coords.value.latitude, lng: coords.value.longitude});
        console.log("updated")
    }
  });
});
onBeforeUnmount(() => {
  stopWatch();
});
</script>
<template>
    <div class="coords">
       current lat:  {{ coords.latitude }}
       current lng: {{ coords.longitude }}
    </div>
</template>
<style scoped>
.coords {
    position: absolute;
    z-index: 999;
    left: 50%;
    bottom: 50%;
}
</style>

Run app

Run the application with

npm run dev

Now when the component is mounted, it will init the watch functionality from the geolocation API, which will prompt a question for the user if they accept to share their current location.

When they accept it, the users lat/lng will be displayed on the screen and the marker will automatically be moved to the users current location.

Did you like this tutorial?

You can support me, so that i can continue to make more tutorials like this one.

buy-me-a-coffee