Tracking and Analyzing My Location Data

A picture of the author, Jakob Maier
Jakob Maier
Nov 30, 2022

Table of Contents


I enjoy exploring the city I live in (vienna) by walking it's streets. However, I have noticed a tendency to always walk the same routes. Especially when I am not actively going somewhere my mind seems to always choose the same old routes, which is of course not what I want. The solution that I have come up with is to record my location data and render something like a heatmap of my location history. This way I would have a clear visualisitaion of the routes I have traveled often and where I haven't gone at all.

Since I would like to be in control of my data as much as possible the obvious choice is to host the solution myself. Essentially, I would need two parts, some kind of app that records the data and a server that receives it and creates the visualization.


Owntracks is a open source app, available for both Android and IOS. It does exactly what I need: record gps data and send it to a server. Owntracks supports two formats, MQTT and HTTP. HTTP is espcecially usefull, since it allows me two code up a server in minutes that can receive the JSON data POST'ed from the app.


I decided to implement my server app in Node.js and Express with a Sqlite database as the persistance layer.

First, I created a database schema:

    tid TEXT NOT NULL,                -- tracker id, identifies the device
    lat REAL NOT NULL,                -- latitude
    lon REAL NOT NULL,                -- longitude
    tst INTEGER NOT NULL UNIQUE       -- timestamp, only one datapoint per tst allowed

Here we receive the POST'ed data and save it to Sqlite3:

// Save location data in database.'*', async (req, res, next) => {
  try {
    const data = req.body;

    // we only care about 'location' messages
    if (data && data._type === "location") {      
      const sql = `INSERT INTO locations (lat, lon, tst, tid) VALUES (?, ?, ?, ?)`; 
      await run(sql, [, data.lon, data.tst, data.tid]);
    // Owntracks expects an empty json array as reponse.
    return res.status(200).json([]);
  } catch (err) {
    // Owntracks sometimes repeats messages. Already saved timestamp/location
    // tuples shall be ignored.
    if (err.code == "SQLITE_CONSTRAINT") {
      return res.status(200).json([]);
    } else {
      return res.status(400).send("something went wrong");

You can find the full sourcecode here.


Now that we have collected all this data I would like to analyze it. It would be interested to have a kind of heatmap, preferably interactive, to show where I spend most of my time. Fortunatly for me, there is already heatmap.js, a leaflet overlay for generating something like this.

So I quickly add a endpoint for getting the location data from the database and voila:


↑ back to top

© 2023 Jakob Maier
kontakt & impressum