Location tracking is a common feature in many applications, and in this tutorial, we'll explore how to create a simple location tracker using the OpenLayers library. OpenLayers is a powerful open-source JavaScript library for displaying maps on the web.
Prerequisites
Before we begin, ensure you have a basic understanding of HTML, JavaScript, and web development. Also, ensure that you have a code editor of your choice installed and Nodejs.
Setting Up the Project
Let's start by creating the basic structure of our project. Create the following files in your project directory and initialize npm
in your project directory
index.html
index.js
style.css
mkdir locator && cd locator
npm init -y
touch index.html index.js style.css
We'll install the required dependencies, OpenLayers, vite and idb.
OpenLayers is an open-source JavaScript library used to create interactive web maps. It's like a toolkit for developers to easily build powerful map applications without complex server-side setup.
npm install ol
Vite is a modern frontend build tool designed to provide a faster and leaner development experience for building web applications
npm install -D vite
This should do it for the project set-up. Let's start coding!
Layout and Styling
Add the code below to your index.html
file.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Locator</title>
<link href="./style.css" rel="stylesheet" />
</head>
<body>
<!-- Map container and locate button -->
<div id="map"></div>
<button id="locate" title="Locate">
<i class="fas fa-location-arrow"></i>
</button>
<!-- Include the OpenLayers library and index.js -->
<script type="module" crossorigin src="./index.js"></script>
</body>
</html>
The <div id="map"></div>
is a container for the map. This is where the OpenLayers map will be displayed.
The <button>
with ID "locate" serves as a button to trigger the location-tracking functionality. It contains an <i>
tag with the class "fas fa-location-arrow" to display a location arrow icon. It's a violation to trigger location tracking without a user gesture.
The final <script>
tag imports the main JavaScript file (./index.js
). The type="module"
attribute indicates that this script is an ECMAScript module.
Add the following code to your style.css
file.
@import url("./node_modules/ol/ol.css");
@import url("https://use.fontawesome.com/releases/v5.0.13/css/all.css");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
width: 100%;
scroll-behavior: smooth;
}
#map {
height: 100%;
width: 100%;
}
button {
background-color: #000;
position: absolute;
bottom: 20px;
right: 20px;
padding: 18px;
border: none;
border-radius: 100%;
color: aliceblue;
}
Creating the OpenLayers Map
In this step, we'll be adding the logic for adding the map to or web page.
Initialize OpenLayers
Open the index.js
file and the code below.
import { Map, View, Feature } from "ol";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { transform } from "ol/proj";
import { OSM, Vector as VectorSource } from "ol/source";
import { Point, LineString } from "ol/geom";
/**
* @type {Map}
*/
let map;
/**
* @type {View}
*/
let view;
let coordinates = [];
/**
* @type {VectorLayer}
*/
let markerLayer;
const init = () => {
view = new View({
center: [0, 0],
zoom: 2,
});
map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
})
],
view: view,
});
document.getElementById("locate").addEventListener("click", (e) => {
e.preventDefault();
locate();
});
};
const addMarker = (coord) => {
if (coordinates.length < 2 || !markerLayer) {
markerLayer = new VectorLayer({
source: new VectorSource({
features: [
new Feature({
geometry: new Point(coord),
}),
],
}),
});
map.addLayer(markerLayer);
} else {
markerLayer.getSource().clear();
markerLayer.getSource().addFeature(
new Feature({
geometry: new Point(coord),
})
);
markerLayer.getSource().addFeature(
new Feature({
geometry: new LineString(coordinates),
})
);
}
view.animate({
duration: 2000,
center: coord,
zoom: 18,
});
}
const locate = () => {
if (navigator.geolocation) {
navigator.geolocation.watchPosition(
(position) => {
let { latitude, longitude } = position.coords;
const coords = transform(
[longitude, latitude],
"EPSG:4326",
"EPSG:3857"
);
coordinates.push(coords);
addMarker(coordinates[coordinates.length - 1]);
},
console.error,
{
enableHighAccuracy: true,
maximumAge: 5,
}
);
}
};
window.onload = init;
In this code block, we create OpenLayers View
with an initial centre and zoom level. The Map
is then instantiated with a target element - map
, layers (in this case, an OpenStreetMap layer), and the defined view.
The addMarker
function is responsible for adding markers to the map based on the user's location. It also handles the creation of a line connecting consecutive markers to visualize the movement: If there are fewer than two coordinates or if the marker layer hasn't been initialized yet, if true, it creates a new marker layer and adds a point feature to it. Otherwise, it updates the existing marker layer with the latest point and a line feature connecting the points.
The locate
function utilizes the Geolocation API to continuously watch for the user's position. When a new position is obtained, it transforms the coordinates and updates the marker on the map using the addMarker
function.
Running the project
In your terminal type the command below to start the dev server.
npm run dev
This will run the app on port 5173 - Vite's default port. Navigate to https://localhost:5173 to view the app.
Congratulations! You've successfully built a simple location tracker using OpenLayers. In this tutorial, we explored how to set up a basic project structure, create an interactive map, and implement location tracking. In the next series, we'll be handling offline support and analysis using indexedDB
Feel free to expand on this project by adding additional features or customizing the user interface. Happy coding!
Link to the Github repository <https://github.com/bryanbill/locator\>