Switchbacks identification#
References: - Plazanet, Corinne Margote, 2001. Modeling Geometry for Linear Feature Generalization.
Un point d’inflexion est un point où la courbe change de convexité.
Un virage est délimité par deux points d’inflexion. Le virage est constitué des points de la trace entre ses deux points limites.
Les lacets sont des séries de virage, fusion des virages successifs. Ils sont paramétrés suivant un nombre minimal de virage et une distance maximale entre les sommets de deux virages consécutifs.
Import de la librairie tracklib#
[1]:
# -*- coding: utf-8 -*-
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)
Chargement de la trace + interpolation spatiale#
[5]:
from tracklib.io.TrackReader import TrackReader
import tracklib.algo.Interpolation as interpolation
import tracklib.plot.Plot as Plot
csvpath = '../../../data/lacet/ecrins.csv'
tracks = TrackReader.readFromWkt(csvpath, 0, 1, 2, ",", 1, "ENUCoords", None, True)
trace = tracks["903959","%"][0]
trace.resample(5, interpolation.MODE_SPATIAL)
#traceE = trace.extract(405, 1217)
#traceE = trace.extract(405, 850)
traceE = trace.copy()
plt.figure(figsize = (8,8))
traceE.plot(append = True, sym='g-', label='original extract track 3')
[5]:
<AxesSubplot: xlabel='E (m)', ylabel='N (m)'>

Lissage gaussien de la trace#
[6]:
from tracklib.core.Kernel import GaussianKernel
from tracklib.core.Operator import Operator
kernel = GaussianKernel(3)
# On fait une copie pour jouer
traceEBis = traceE.copy()
# Calcul
traceEBis.operate(Operator.FILTER, "x", kernel, "x_filtered")
traceEBis.operate(Operator.FILTER, "y", kernel, "y_filtered")
traceEBis.operate("x=x_filtered")
traceEBis.operate("y=y_filtered")
# Dessin
plt.figure(figsize = (8,8))
traceEBis.plot(append = True, sym='g-', label='original extracted track')
traceE.plot(append = True, sym='b-', label='smoothed extracted track')
plt.legend()
[6]:
<matplotlib.legend.Legend at 0x7f9df5454eb0>

Compute inflection points#
[8]:
import tracklib.algo.Cinematics as Cinematics
import tracklib.core.Utils as utils
# On repart du lissage
traceE = traceEBis
# Calcul
Cinematics.inflection(traceE)
# Dessin
COLS = utils.getColorMap((220, 220, 220), (255, 0, 0))
plt.figure(figsize = (7, 7))
traceE.plot(type='POINT', af_name='inflection', append = True,
cmap = COLS, pointsize=10)
[8]:
<AxesSubplot: xlabel='E (m)', ylabel='N (m)'>

Détection des sommets#
[9]:
# On repart du lissage
traceE = traceEBis
# Calcul
Cinematics.setVertexAF(traceE)
# Dessin
COLS = utils.getColorMap((220, 220, 220), (0, 0, 255))
plt.figure(figsize = (7,7))
traceE.plot(type='POINT', af_name='vertex', append = True, cmap = COLS, pointsize=20)
[9]:
<AxesSubplot: xlabel='E (m)', ylabel='N (m)'>

Construction des virages#
[10]:
# On repart du lissage
traceE = traceEBis
# Calcul
from numpy import pi
BE = Cinematics.setBendAsAF(traceE, 75*pi/180)
# Dessin
COLS = utils.getColorMap((200, 200, 200), (0, 0, 255))
plt.figure(figsize = (7, 7))
traceE.plot(type='POINT', af_name='bend', append = True, cmap = COLS)
[10]:
<AxesSubplot: xlabel='E (m)', ylabel='N (m)'>

Construction des lacets#
Il faut choisir 2 paramètres: * distance maximum entre deux sommets pour qu’ils appartiennent a une même suite * nombre de virages minimum pour constituer une série de virages
[18]:
# Calcul
Cinematics.setSwitchbacksAsAF(traceE, 20, 50)
# Dessin
COLS = utils.getColorMap((200, 200, 200), (0, 0, 255))
plt.figure(figsize = (8,8))
traceE.plot(type='POINT', af_name='switchbacks', append = True, cmap = COLS)
[18]:
<AxesSubplot: xlabel='E (m)', ylabel='N (m)'>

[ ]: