Analytical Feature Map#

Aim: generate raster-based representations of GPS trajectories by aggregating analytical features over a regular grid.

Importing Tracklib#

[1]:
# Import the Tracklib library
import tracklib as tkl
Code running in a no shapely environment

Loading a collection of tracks#

[2]:
tkl.ObsTime.setReadFormat("2D/2M/4Y 2h:2m:2s")

chemin = '/home/md_vandamme/tracklib/trajlib/reseau/data2/'
fmt = tkl.TrackFormat({"ext": 'CSV',
    "id_E": 1,
    "id_N": 0,
    "id_U": 3,
    "id_T": 2,
    "h": 1,
    "separator": ";",
    "srid": "ENU"})

collection = tkl.TrackSource(chemin, fmt)

total = len(collection)
print ('Number of tracks: ' + str(total))
Number of tracks: 8654

Zoom in on a small area around a lake#

We extracte tracks abiding by geometrical shape (a Rectangle) constraint are cut and returned in the next stage below:

[3]:
xMin = 657336
yMin = 6860189
xMax = 657890
yMax = 6860625

ll = tkl.ENUCoords(xMin, yMin)
ur = tkl.ENUCoords(xMax, yMax)
bbox = tkl.Rectangle(ll, ur)

constraintBBox = tkl.Constraint(shape = bbox, mode = tkl.MODE_INSIDE, type=tkl.TYPE_CUT_AND_SELECT)
lakeCollection = constraintBBox.select(collection)
print ('Number of tracks near the lake: ' + str(lakeCollection.size()))
lakeCollection.plot('g-')
Number of tracks near the lake: 8654
../_images/howto_SUM_AFMap_6_1.png

Crowd density Map#

The first step is to create a Raster, which defines the spatial framework of the analysis through its spatial extent and cell resolution. In this example, we build a raster with a 2-meter resolution, aligned on the bounding box of the trajectory collection and without any margin.

[4]:
margin = 0.05
resolution = (2, 2)

raster = tkl.Raster(bbox=lakeCollection.bbox(), resolution=resolution, margin=margin,
                align=tkl.BBOX_ALIGN_CENTER)

Once the raster has been created, Analytical Feature Maps (AFMaps) can be added. Each AFMap is associated with a single Analytical Feature (AF) (e.g. uid, speed, or altitude) and may contain one or several Bands, each computing a different statistic over the raster cells (e.g. CountBand, CountDistinctBand, MeanBand, MedianBand, DominantBand).

In this example, we compute a crowd density map by counting the number of distinct trajectories crossing each raster cell. The selected Analytical Feature is the trajectory identifier uid, and the statistic is computed using a CountDistinctBand.

[5]:
uidMap = raster.addAFMap("uid")
uidMap.addCountDistinct()
[5]:
<tracklib.core.raster.CountDistinctBand at 0x7591072b34f0>

Before rasterization, trajectories are spatially resampled at 1-meter intervals to ensure that every crossed cell is taken into account during the accumulation process.

[6]:
cpt = 1
for trace in lakeCollection:
    trace.uid = cpt
    trace.resample(1, mode=1)
    cpt += 1

The rasterization is then performed by accumulating the trajectory observations into the raster cells and computing the requested statistics.

[7]:
tkl.summarize(lakeCollection, raster)
print ('Raster created.')
Raster created.

The resulting grid can be retrieved from the corresponding AFMap and displayed.

[8]:
grid = raster.getAFMap('uid')['count_distinct']

grid.plot(cmap='jet')
../_images/howto_SUM_AFMap_16_0.png

Write frequency of trajectories grid to Ascii Raster file#

[9]:
raster.writeToAscFile(grid, '/home/md_vandamme/zone_lac_2m.asc')
print ('Grid written in file.')
Grid written in file.