Saturday, January 31, 2009

GPS and skiing

With the winter weather I'm unable to feed my GPS and cycling obsession. The good news is I've found a new obsession: OpenPisteMap. This is part of the OpenStreetMap project.

The idea is to map out ski resorts. I've been using JohnJohn to collect tracks of my recent ski trips. The results have been a bit mixed. One problem I've run into is that many ski hills are north facing, which means the GPS satellites tend to be below the horizon, giving a poor fix at times.

However, I am collecting some reasonable tracks. Below is some data from a trip to Mt Tremblant earlier this week. By plotting altitude, speed and direction (with matplotlib) you can get a reasonable feel for what is going on: I go downhill faster than uphill, you can see some lifts are faster than others etc etc.

Next job is to load the data into JOSM and see if I can create some sort of map.

Monday, January 26, 2009


A bit late, but here is a pic of me toasting Obama last week.

The T-shirt is one I had made with an image I'd created myself and it has a hidden message.

To see the message, here is the raw image.

Obama's inauguration brought back memories of Tony Blair being elected in the UK, which was a happy day for me for other reasons. People were optimistic about change, but it didn't quite turn out like that.

The image was created thanks to the Python Imaging Library and a few lines of code (see below).

I tried using the GIMP, but I'm afraid I don't use it often enough to be able to do anything non-trivial faster than I can write PIL code.

import optparse
import Image

import ImageFont
import ImageDraw

def get_weight(xoff, yoff, width, height, image):

total = 0
count = 0
for x in range(width):
for y in range(height):
total += image.getpixel((xoff+x, yoff+y))
count += 1

if count == 0: count = 1
return int(round(total/count))

def get_rgb(xoff, yoff, width, height, image):

rr = gg = bb = 0
count = 0
for x in range(width):
for y in range(height):
r, g, b = image.getpixel((xoff+x, yoff+y))

rr += r
gg += g
bb += b
count += 1

if count == 0: count = 1

return int(round(rr/count)), int(round(gg/count)), int(round(bb/count))

def make_image(options):

obama =

options.width, options.height = obama.size
scale = options.scale
options.width *= scale
options.height *= scale

image ='RGB', (options.width, options.height))

print obama.getpixel((10,10))

text = options.text

font = ImageFont.truetype("/home/me/.fonts/arial.ttf", options.font)

draw = ImageDraw.Draw(image)
width, height = font.getsize(options.text)

xpos = ypos = height

offset = 0
total_offset = 0
red, green, blue =,,

while ypos < options.height:
while xpos < options.width:

for char in options.text[offset:]:
wchar, hchar = font.getsize(char)
if opts.rgb:
rgb = get_rgb(xpos/scale, ypos/scale, 1 + (wchar/scale), 1 + (hchar/scale), obama)
draw.text((xpos, ypos), char, font=font, fill=rgb)
weight = get_weight(xpos/scale, ypos/scale, 1 + (wchar/scale), 1 + (hchar/scale), obama)
draw.text((xpos, ypos), char, font=font, fill=(int(weight*red), int(weight*green), int(weight*blue)))
xpos += wchar

offset = 0
ypos += height
xpos = height
total_offset += options.offset
offset = total_offset % len(options.text)'blair.png', 'w'))

def get_parser():
""" Get an option parser.
parser = optparse.OptionParser()

parser.add_option('--width', type='int', default=426)
parser.add_option('--height', type='int', default=640)
parser.add_option('--scale', type='int', default=2)
parser.add_option('--offset', type='int', default=15)
parser.add_option('--font', type='int', default=9)
parser.add_option('--obama', default='obamagrey.png')

parser.add_option('--red', type='float', default=1.0)
parser.add_option('--green', type='float', default=1.0)
parser.add_option('--blue', type='float', default=1.0)

parser.add_option('--rgb', action='store_true')

parser.add_option('--text', default="Please don't do a Tony Blair ")

return parser

if __name__ == '__main__':

parser = get_parser()

opts, args = parser.parse_args()