Tying It All Together

Finally, Listing 1-10 shows the combined code to analyze and plot all GPS files in directory data.

Listing 1-10. Script gps.py from pylab import * import csv, os

# constant definitions STANDING_KMH =10.0 SPEEDING_KMH =50.0 NMI = 1852.0 D2R = pi/180.0

Reads a CSV file and returns it as a list of rows

data.append(row) return data def process_gps_data(data):

Processes GPS data, NMEA 0183 format.

Returns a tuple of arrays: latitude, longitude, velocity [km/h], time [sec] and number of satellites.

for row in data:

num_sats.append(float(row[3])) elif row[0] == '\$GPRMC':

t_seconds.append(float(row[l][0:2])*3600 + \ float(row[l][2:4])*60+float(row[l][4:6])) latitude.append(float(row[3][0:2]) + \

float(row[3][2:])/60.0) longitude.append((float(row[5][0:3]) + \

float(row[5][3:])/60.0)) velocity.append(float(row[7])*NMI/1000.0)

return (array(latitude), array(longitude), \

array(velocity), array(t_seconds), array(num_sats))

# read every data file, filter, and plot the data for root, dirs, files in os.walk('../data'): for filename in files:

# create full file name including path cur_file = os.path.join(root, filename) if filename.endswith('csv'):

continue

# only files with the .csv extension from here on

# process GPS data

# translate spherical coordinates to Cartesian py = (lat-min(lat))*NMI*60.0

# find out when standing, speeding, or cruising Istand = find(v < STANDING_KMH)

Ispeed = find(v > SPEEDING_KMH)

Icruise = find((v >= STANDING_KMH) & (v <= SPEEDING_KMH))

# left side, GPS location graph figure()

# longitude values go from right to left,

# we want increasing values from left to right gca().axes.invert_xaxis()

plot(px, py, 'b', label=' Cruising', linewidth=3) plot(px[Istand], py[Istand], 'sg', label=' Standing') plot(px[Ispeed], py[Ispeed], 'or', label=' Speeding!')

# add direction of travel for i in range(o, len(v), len(v)/10-l): text(px[i], py[i], "ยป>", \

rotation = arctan2(py[i+l]-py[i], \ -(px[i+l]-px[i]))/D2R, ha='center')

# legends and labels title(filename[:-4]) legend(loc='upper left') xlabel('east-west (meters)') ylabel('south-north (meters)')

# top-right corner, speed graph subplot(2, 2, 2)

# set the start time as t[o]; convert to minutes t = (t-t[0])/60.0

# plot the standing and speeding threshold lines plot([t[0], t[-l]], [STANDING_KMH, STANDING_KMH], '-g') text(t[0], STANDING_KMH, \

" Standing threshold: "+str(STANDING_KMH)) plot([t[0], t[-l]], [SPEEDING_KMH, SPEEDING_KMH], '-r') text(t[0], SPEEDING_KMH, \

" Speeding threshold: "+str(SPEEDING_KMH)) grid()

# legend and labels title('Velocity')

xlabel('Time from start of file (minutes)') ylabel('Speed (Km/H)')

# right-side corner, statistics data subplot(2, 2, 4)

# remove the frame and x-/y-axes. we want a clean slate axis('off')

# generate an array of strings to be printed Total_distance = float(sum(sqrt(diff(px)**2+diff(py)**2)) \

/lOOO.O) Stand_time = len(Istand)/60.0 Cruise_time = len(Icruise)/60.0 Speed_time = len(Ispeed)/60.0 Stand_per = 100*len(Istand)/len(v) Cruise_per = 100*len(Icruise)/len(v) Speed_per = 100*len(Ispeed)/len(v) stats=['Statistics', \ '%s' % filename, \

'Total driving time: %.lf minutes:' % (len(v)/60.0), \

'Total distance traveled: %.lf Km' % Total_distance ]

# display statistics information for index, stat_line in enumerate(reversed(stats)): text(o, index, stat_line, va='bottom')

# draw a line below the "Statistics" text plot([index-.2, index-.2])

# set axis properly so all the text is displayed axis([0, 1, -1, len(stats)])

Figure 1-5 shows the final results.

Figure 1-5. Output ofgps.py on some GPS data