#!/usr/bin/python # from ~/Desktop/downloads/PythonWeb.org/web/image/graph.py: # self.image=PIL.Image.new("RGB", size, bgColor) # self.draw=PIL.ImageDraw.Draw(self.image) # self.font = PIL.ImageFont.truetype(font,12) # look at ~/Desktop/downloads/schoolbell-m7.1/src/schooltool/rest/infofacets.py # just to see why it is called that, even though it only mucks with images # what does sysinfo.displaypixels() return? # portrun python import sys sys.path.append("/opt/local/lib/python2.4/site-packages/") import PIL import PIL.Image import PIL.ImageDraw import os imgbase = os.path.expanduser("~/symbian/BACKUP/current/Images/") # lifted from bcpathtrace.py: def old_to_new(val): if str(val)[-1] not in "NSEW": return float(val) newval = float(val[:-1])/100.0 if val[-1] in "SW": newval = -newval return newval def scan_where(): fields = {} for f in os.listdir(imgbase): if not f.endswith(".where"): continue imgpath = os.path.join(imgbase, f) if os.path.exists(imgpath.replace(".where",".bad")): continue bits = open(imgpath,"r").read() if bits.startswith("("): words=eval(bits) else: words=bits.split(" ") lat, lon = map(old_to_new,words[:2]) when, discard = os.path.splitext(f) fields[when] = (lat, lon) return fields class scaler: def __init__(self, insamp): self.inmin = insamp self.inmax = insamp self.outmin = None self.outmax = None def addval(self, v): self.inmin = min(self.inmin, v) self.inmax = max(self.inmax, v) def scale(self, v): inrange = self.inmax - self.inmin outrange = self.outmax - self.outmin return self.outmin + outrange *(v - self.inmin)/inrange def center(self): inrange = self.inmax - self.inmin return self.inmin + inrange/2 # modified from original to take the PIL.Image def make_scalers(points, c): order = points.keys() order.sort() samplat, samplon = points[order[0]] latscale = scaler(samplat) lonscale = scaler(samplon) for lat, lon in points.values(): latscale.addval(lat) lonscale.addval(lon) max_x,max_y = c.size latscale.outmin = 0 latscale.outmax = max_y lonscale.outmin = 0 lonscale.outmax = max_x return latscale, lonscale, order # unified aspect-preserving scalers are harder, because we *don't* # just want 1:1, we need full generality: # >>> math.cos(math.radians(57.417)) # 0.539 for Gothenburg, # 0.740 for Boston (42.3) # 0.511 for Stockholm (59.243) def find_days(points): days = {} for k in points.keys(): d,t = k.split("t") days[d] = days.get(d,0) + 1 daylist = days.keys() daylist.sort() # require 2 points for a day to count return [day for day in daylist if days[day] > 2] def points_of_day(points, day): subpoints = {} for k,v in points.items(): d,t = k.split("t") if d == day: # or say d.startswith(day) to handle prefix hours? subpoints[k] = v return subpoints def bothscale(point, latscale, lonscale): lat, lon = point return (latscale.scale(lat), lonscale.scale(lon)) def latlon_to_xy(point, latscale, lonscale): neglat, lon = bothscale(point, latscale, lonscale) return lon, latscale.outmax - neglat blue = (0,0,255) green = (0,255,0) red = (255,0,0) yellow = (255,255,0) if __name__ == "__main__": allpoints = scan_where() days = find_days(allpoints) # enumerate isn't in 2.2, but the mac side starts with 2.3... for dayno, thisday in enumerate(days): target_size = (192,204) # copy value from sysinfo.displaypixels() image = PIL.Image.new("RGB", target_size, 0) draw = PIL.ImageDraw.Draw(image) # what follows is lifted from bcpathtrace.render() max_x,max_y = target_size # or image.size... points = points_of_day(allpoints, thisday) latscale, lonscale, order = make_scalers(points, image) label = u"Day %s/%s: c %.4s,%.4s" % (dayno+1, len(days), latscale.center(),lonscale.center()) # ds.text( (0,max_y), label, yellow) draw.setink(yellow) textwidth, textheight = draw.textsize(label) draw.text( (0,max_y - textheight), label ) lastpoint = points[order.pop(0)] draw.setink(blue) draw.point(latlon_to_xy(lastpoint, latscale, lonscale) ) # width=4) # turns out that there's no equivalent to point(width) other than manually drawing a chord... # and PIL includes no docs on the args to chord, though guesses work ok... # lastd, lastt = order[0].split("t") for k in order: # sleep makes the rendering order visible, but we don't need that with a cursor # e32.ao_sleep(0.1) thispoint = points[k] # plot from lastpoint to thispoint, scaled by size draw.setink(green) draw.line( (latlon_to_xy(lastpoint, latscale, lonscale), latlon_to_xy(thispoint, latscale, lonscale)) ) lastpoint = thispoint image.save(open("/tmp/uda%s.jpg" % thisday, "w"), format="JPEG")