Noise model#
To create noise simulation on a track, we use the same method describes in Create realistic synthetic track Notebook and dont l’approche is described in [Ripley (2009)] and also employed in [Ménéroux (2022)].
This tutorial is going to illustrate of the noise model on a 30-meter-radius continuous circle, on a piecewise linear building and on a path with a length of approximately 300 meters. Covariance scope is increasing from 0.1 (white noise process) to 500 m (global translation), for a same amplitude level of 5 meters.
To generate noise simulation in tracklib, you need to create a kernel with a scope and then apply the noise method to a track by configure the amplitude:
kernel = tkl.GaussianKernel(50)
amplitude = 2
noised_track = track.noise(amplitude, kernel)
References:
[Ripley (2009)] - Ripley, B.D., 2009. Stochastic simulation. vol. 316. Hoboken, NJ: John Wiley & Sons.
[Ménéroux (2022)] - Méneroux, Y., Maidaneh Abdi, I., Le Guilcher, A., & Olteanu-Raimond, A. M. (2022). Is the radial distance really a distance? An analysis of its properties and interest for the matching of polygon features. International Journal of Geographical Information Science, 37(2), 438–475. https://doi.org/10.1080/13658816.2022.2123487
As usual, let’s start by defining our environment#
The first task is only useful for the online notebook and import the local tracklib code source. It’s not necessary if tracklib is installed from PyPI.
[1]:
import matplotlib.pyplot as plt
import os.path
import sys
#-------------------------------------------------------
# Import de tracklib
module_path = os.path.abspath(os.path.join('../../..'))
if module_path not in sys.path:
sys.path.append(module_path)
import tracklib as tkl
The following two imports are necessary for the tutorial:
[2]:
import math
import matplotlib.pyplot as plt
from random import random, randint
Loading a building, a circle and a path#
[3]:
# The bui
param = tkl.TrackFormat({'ext': 'WKT', 'id_wkt': 0, 'separator': ',', 'header': 1})
batis = tkl.TrackReader.readFromFile("../../../data/radial/bati_bdtopo.wkt", param)
#bati1 = batis[234]
bati = batis[305]
plt.figure(figsize=(5, 5))
plt.plot(bati.getX(), bati.getY(), color="royalblue", linestyle='-')
plt.xticks([])
plt.yticks([])
[3]:
([], [])

[4]:
def x_t(t):
return 10*math.cos(2*math.pi*t)
def y_t(t):
return 10*math.sin(2*math.pi*t)
plt.figure(figsize=(5, 5))
circle = tkl.generate(x_t, y_t, dt=5)
tkl.resample(circle, 0.1, 1, 1)
if not ((circle.getX()[-1] == circle.getX()[0]) and (circle.getY()[-1] == circle.getY()[0])):
circle.addObs(circle[0])
circle.plot('r-')
plt.xticks([]); plt.yticks([]) ; plt.xlabel(''); plt.ylabel(''); plt.title('')
Generated track from 24/04/2025 02:45:54 to 24/04/2025 03:45:54 [719 pts, 62.74m]
[4]:
Text(0.5, 1.0, '')

[5]:
tkl.seed(14380247)
sentier = tkl.generate(0.20)
plt.figure(figsize=(5, 5))
plt.plot(sentier.getX(), sentier.getY(), color="darkorange", linestyle='-')
plt.xticks([]); plt.yticks([]) ; plt.xlabel(''); plt.ylabel(''); plt.title('')
Generated track from 20/07/2046 04:48:07 to 20/07/2046 05:48:07 [100 pts, 147.76m]
[5]:
Text(0.5, 1.0, '')

Generate noise#
[6]:
tkl.seed(123)
amp = 5
N = 5
SCOPES = [0.1, 1, 5, 10, 500]
plt.figure(figsize=(3*N, 2*N))
for i in range(N):
kernel = tkl.GaussianKernel(SCOPES[i])
b2 = bati.noise(amp, kernel, cycle=True, force=True)
if not ((b2.getX()[-1] == b2.getX()[0]) and (b2.getY()[-1] == b2.getY()[0])):
b2.addObs(b2[0])
ax = plt.subplot2grid((3, N), (0,i))
ax.set_title('covariance scope:' + str(SCOPES[i]))
ax.plot(bati.getX(), bati.getY(), color="royalblue", linestyle='--')
ax.plot(b2.getX(), b2.getY(), color="limegreen", linestyle='-')
ax.set_xticks([])
ax.set_yticks([])
for i in range(N):
kernel = tkl.GaussianKernel(SCOPES[i])
b2 = circle.noise(amp, kernel, cycle=True, force=True)
if not ((b2.getX()[-1] == b2.getX()[0]) and (b2.getY()[-1] == b2.getY()[0])):
b2.addObs(b2[0])
ax = plt.subplot2grid((3, N), (1,i))
ax.set_title('covariance scope:' + str(SCOPES[i]))
ax.plot(circle.getX(), circle.getY(), color="royalblue", linestyle='--')
ax.plot(b2.getX(), b2.getY(), color="deeppink", linestyle='-')
ax.set_xticks([])
ax.set_yticks([])
for i in range(N):
kernel = tkl.GaussianKernel(SCOPES[i])
b2 = sentier.noise(amp, kernel, cycle=True, force=True)
#if not ((b2.getX()[-1] == b2.getX()[0]) and (b2.getY()[-1] == b2.getY()[0])):
# b2.addObs(b2[0])
ax = plt.subplot2grid((3, N), (2,i))
ax.set_title('covariance scope:' + str(SCOPES[i]))
ax.plot(sentier.getX(), sentier.getY(), color="royalblue", linestyle='--')
ax.plot(b2.getX(), b2.getY(), color="darkorange", linestyle='-')
ax.set_xticks([])
ax.set_yticks([])
/usr/lib/python3/dist-packages/matplotlib/cbook/__init__.py:1298: ComplexWarning: Casting complex values to real discards the imaginary part
return np.asarray(x, float)

[ ]: