# Measuring Sinuosity of Walking Paths using QGIS?

I'm currently working on a project that examines the movement of consumers through different kinds of retail spaces in Central Asia – namely, bazaars versus supermarkets. I've equipped dozens of shoppers with GPS trackers that record their movements throughout these different retail spaces, and I'm now working on analyzing the resulting data.

I'm primarily interested in comparing overall walking distances and walking speeds – easy enough. But I've also noticed bazaar paths are highly irregular, with shoppers weaving this way and that through the crowded stalls, whereas the supermarket tracks are highly straight, efficient, and consistent between shoppers. So, I'd like to quantify the sinuosity or efficiency of these walking paths – i.e., how frequently the shoppers turn and/or backtrack.

I'm not sure how to approach this analysis – much less accomplish it in QGIS.

Should I define this "spatial efficiency" index as the ratio of overall distance traveled to overall degrees of rotation, or something?

Or should I use the simple river sinuosity calculation (direct distance vs. curvilinear length) – and if so, how should I determine the critical waypoints?

• I'd start with just a simple ratio (direct distance vs. actual distance walked) and see how informative that is. If you want to note when their direction changed -- that might actually be fairly difficult to figure out with GPS points from walking, given the typical errors I've seen in such paths, but you can script something to evaluate how many times their bearing changes more than 2-4°. – Erica Feb 26 '15 at 18:19
• Not sure in QGis, but in ArcGIS if after converting to line there are self-crossing lines, those form a branch where the polyline splits into multiple parts (typically 4 parts where two non-overlapping line segments fully cross each other). So a parts count may be a useful value to store in a field and to consider that count in your path evaluations. The more frequently they crossed their own path, the less efficiely they navigated the space (although that behavior could actually be purposefully done to shop around before making decisions to buy). – Richard Fairhurst Feb 26 '15 at 19:57

This will not solve all your issues, but its a good start. This script in python 2 works with a csv file with three fields: id, latitude, longitude. You can also add time field and implement the codes for calculate the average speed. It calculates absolute distance walked(diference between last and first point), also calculates the sum of distance to all points, and how many times walked to north, south, east and west. The algorithm is very simple but you can improve it.

import csv
from math import sqrt

class CSVFile:
csvfile=''
def values(self):
matrix= []
for i in self.csvfile:
matrix.append( [ float(i[0]), float(i[1]), float(i[2])] )
return(matrix)

class Distance:
def total_walked(self, matrix):
distX = 0.
distY = 0.
x_ant = 0.
y_ant = 0.
## if walked north or south, east or west this is relative,
## if analyzed move is in south hemisphere for example, the
## walked_south will be walked_north and vice-versa becouse
## south latitude coordinates are negative.
## if the moves cross equatorial line these values will be worthless.
walked_east = 0
walked_west = 0
walked_north = 0
walked_south = 0
for i in matrix:
if(x_ant != 0):
if (i[2]-x_ant > 0):
distX= distX + (i[2] - x_ant)
walked_east= walked_east + 1
if(i[2] -x_ant < 0 ):
distX= distX - (i[2] - x_ant)
walked_west = walked_west + 1
x_ant = i[2]
if (y_ant != 0):
if (i[1] - y_ant > 0):
distY = distY+ (i[1] - y_ant)
walked_north = walked_north + 1
if(i[1] - y_ant < 0 ):
distY = distY - (i[1] - y_ant)
walked_south = walked_south + 1
y_ant = i[1]
print "Walked Norte %s times" % walked_north
print "Walked South %s times" % walked_south
print "Walked East %s times" % walked_east
print "Walked West %s times" % walked_west
print "Total distance X walked: %.2f" % distX
print "Total distance Y walked: %.2f" % distY
print "Total distance: %.2f" % sqrt(pow(distX,2)+ pow(distY,2))

def total_distance(self, matrix):
num = len(matrix)-1
distanceY = matrix[num][1] - matrix[0][1]
distanceX = matrix[num][2] - matrix[0][2]
print "Absolute Distance Y: %s" % distanceY
print "Absolute Distance X: %s" % distanceX
print "Total Absolute Distance: %s" % sqrt(pow(distanceX,2)+ pow(distanceY,2))

matrix = []
delimiter = ','
print "Type path of csv file:"
path = raw_input()
csv_file = CSVFile()
csv_file.openCSV(path, delimiter)
matrix = csv_file.values()
calculum = Distance()
calculum.total_walked(matrix)
calculum.total_distance(matrix)