Skip to main content
`Ctrl`+`K`

# Summarize GPS information

This functionality of tracklib reduce the full dataset of GPS traces into a regular grid of summarized features. In each cell, n aggregated features (such as mean and standard deviation of speeds, number of traces, most frequent bearing …) are computed to produce a set of raster maps, which may be seen as a single image with n channels.

These process has been used in works presented in (1).

Figure 1 : Workflow presented in (1) to produce raster images (5 meter-resolution grid)

Reference:(1) - Y. Méneroux and al. Convolutional Neural Network for Traffic Signal Inference based on GPS Traces. Proceedings of Spatial big data and machine learning in GIScience Workshop’18, August 28-31, 2018, Melbourne, Australia. GIScience.

## Import de la librairie tracklib

Il faut importer tracklib si la librairie n’est pas dans le python path

    [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 du jeu de traces

The dataset comprises a set of 11862 GPS traces, located in Mitaka city (16 km2), suburbs of Tokyo (Japan).

    [2]:

    from tracklib.io.TrackReader import TrackReader as reader
    from tracklib.core.ObsTime import ObsTime

    PATH = '/home/marie-dominique/PROJET/FINI/MITAKA/DATA/mitaka/complet'
    ObsTime.setReadFormat("4Y-2M-2D 2h:2m:2s")
    collection = reader.readFromCsv(path=PATH, id_E=2, id_N=3, id_T=1)
    print ('Number of tracks: ' + str(collection.size()))

    Number of tracks: 11872

## Sélection des traces sur une zone restreinte de type Rectangle

    [3]:

    import matplotlib.pyplot as plt

    from tracklib.core.TrackCollection import TrackCollection
    from tracklib.core.Track import Track
    from tracklib.core.ObsCoords import ENUCoords
    import tracklib.algo.Geometrics as Geometrics
    from tracklib.algo.Selection import Constraint
    from tracklib.algo.Selection import TYPE_CUT_AND_SELECT, MODE_INSIDE

    Xmin = 370250
    Xmax = 371250
    Ymin = 3949050
    Ymax = 3950050

    ll = ENUCoords(Xmin, Ymin)
    ur = ENUCoords(Xmax, Ymax)
    bbox = Geometrics.Rectangle(ll, ur)

    constraintBBox = Constraint(shape = bbox, mode = MODE_INSIDE, type=TYPE_CUT_AND_SELECT)
    selections = constraintBBox.select(collection)
    print ('Number of tracks: ' + str(selections.size()))

    for track in selections:
        if track.size() < 10:
            selections.removeTrack(track)
    selections.plot('k')

    plt.xlim((Xmin, Xmax))
    plt.ylim((Ymin, Ymax))
    plt.show()

    print ('Number of tracks: ' + str(selections.size()))
    collection = selections

    Number of tracks: 3850

    Number of tracks: 3804

## Raster de la moyenne des vitesses et de l’orientation de la plus fréquente par cellule

Les AF seront calculées si elles n’ont pas encore été créées

Les scripts des deux AF qu’on prend existent déjà dans la librairie, sinon il aurait fallu les écrire

    [4]:

    from tracklib.algo import (Analytics, Summarising)

    # On crée l'AF speed
    collection.addAnalyticalFeature(Analytics.speed)

    af_algos = [Analytics.speed, Analytics.orientation]
    cell_operators = [Summarising.co_avg, Summarising.co_dominant]

    marge = 0
    resolution = (5, 5)
    raster = Summarising.summarize(collection, af_algos, cell_operators, resolution, marge)

## Conversion des indicateurs en 8-bit grayscale

Feature values are converted on a 8-bit grayscale.

    [5]:

    # the mean of speeds is distributed between 16 and 255
    band1 = raster.getRasterBand('speed#co_avg')
    for i in range(band1.nrow):
        for j in range(band1.ncol):
            val = band1.grid[i][j]
            if val != band1.getNoDataValue():
                if val > 25:
                    band1.grid[i][j] = 10
                else:
                    band1.grid[i][j] = 100 - val/25*90

    # The dominance of orientations is discretized in 8 eight values
    band2 = raster.getRasterBand('orientation#co_dominant')
    for i in range(band2.nrow):
        for j in range(band2.ncol):
            val = band2.grid[i][j]
            if val != band2.getNoDataValue():
                if val == 1:
                    band2.grid[i][j] = 156
                elif val == 2:
                    band2.grid[i][j] = 218
                elif val == 3:
                    band2.grid[i][j] = 249
                elif val == 4:
                    band2.grid[i][j] = 187
                elif val == 5:
                    band2.grid[i][j] = 125
                elif val == 6:
                    band2.grid[i][j] = 63
                elif val == 7:
                    band2.grid[i][j] = 32
                elif val == 8:
                    band2.grid[i][j] = 94
                else:
                    band2.grid[i][j] = 0

## Affichage

    [6]:

    fig = plt.figure(figsize=(16, 8))

    ax1 = fig.add_subplot(121)
    band1.plotAsImage(axe=ax1, figure=fig, novaluecolor='teal')

    ax2 = fig.add_subplot(122)
    band2.plotAsImage(ax2, figure=fig, novaluecolor='teal')