import os
imgbase = u"E:\\Images"
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 mark_bad(when):
open(os.path.join(imgbase, "%s.bad" % when),"w").close()
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
import key_codes
import e32
lock=e32.Ao_lock()
running=1
def quit():
global running,lock
running=0
lock.signal()
def refresh():
# just wakes up, doesn't do anything directly
global lock
lock.signal()
import appuifw
appuifw.app.screen='full'
appuifw.app.exit_key_handler=quit
import graphics
c=appuifw.Canvas()
appuifw.app.body=c
c.bind(key_codes.EKey9,refresh)
def nextday():
global dayno, pointno
dayno += 1
if dayno >= len(days):
dayno = 0
pointno = 0
render()
def prevday():
global dayno, pointno
dayno -= 1
if dayno < 0:
dayno = len(days)-1
pointno = 0
render()
def nextpoint():
global pointno
pointno += 1
render()
def prevpoint():
global pointno
pointno -= 1
render()
# really need a "point" data type...
def pointstep(pt1, pt2, nsteps):
pt1_x, pt1_y = pt1
pt2_x, pt2_y = pt2
return ((pt2_x - pt1_x)/nsteps, (pt2_y - pt1_y)/nsteps)
def addpoints(pt, dpt):
pt_x, pt_y = pt
dpt_x, dpt_y = dpt
return (pt_x + dpt_x, pt_y + dpt_y)
def animate_boxes(start_point, latscale, lonscale, steps):
# ds.rectangle ( (pt1, pt2), color)
# assume corners, so we just have to do 2 of them
end_1 = (latscale.inmax, lonscale.inmin) # upper left
end_2 = (latscale.inmin, lonscale.inmax) # lower right
step_1 = pointstep(start_point, end_1, steps)
step_2 = pointstep(start_point, end_2, steps)
run_1 = start_point
run_2 = start_point
for _ in range(steps):
run_1 = addpoints(run_1, step_1)
run_2 = addpoints(run_2, step_2)
# print (latlon_to_xy(run_1, latscale, lonscale), latlon_to_xy(run_2, latscale, lonscale))
# print yellow
#rectx1, recty1 = latlon_to_xy(run_1, latscale, lonscale)
#rectx2, recty2 = latlon_to_xy(run_2, latscale, lonscale)
#ds.rectangle( ((rect, ), yellow, width=3)
ds.rectangle( (latlon_to_xy(run_1, latscale, lonscale), latlon_to_xy(run_2, latscale, lonscale)), yellow, width=3)
e32.ao_sleep(0.1)
ds.rectangle( (latlon_to_xy(run_1, latscale, lonscale), latlon_to_xy(run_2, latscale, lonscale)), 0, width=3)
# ds.line( (latlon_to_xy(run_1, latscale, lonscale), latlon_to_xy(run_2, latscale, lonscale)), green, width=3)
def viewpicture():
# dayno + pointno...
print dayno, pointno
# lifted from render():
points = points_of_day(allpoints, days[dayno])
latscale, lonscale, order = make_scalers(points)
dkey = order[pointno]
imgpath = os.path.join(imgbase, dkey + ".jpg")
lat, lon = points[dkey]
# animation!
print lat, lon
animate_boxes((lat, lon), latscale, lonscale, 5) # steps
# now open the picture
appuifw.Content_handler(refresh).open(imgpath)
def badpicture():
# dayno + pointno...
print dayno, pointno
# lifted from render():
points = points_of_day(allpoints, days[dayno])
latscale, lonscale, order = make_scalers(points)
dkey = order[pointno]
del allpoints[dkey]
mark_bad(dkey)
render()
c.bind(key_codes.EKeyLeftArrow, prevday)
c.bind(key_codes.EKeyRightArrow, nextday)
c.bind(key_codes.EKeyDownArrow, nextpoint)
c.bind(key_codes.EKeyUpArrow, prevpoint)
c.bind(key_codes.EKeyDevice3, viewpicture)
c.bind(key_codes.EKeyStar, badpicture)
ds=graphics.Draw(c)
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
def make_scalers(points):
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
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 find_hours(points):
# days = {}
# for k in points.keys():
# d,t = k.split("t")
# dd = d + "t" + t[:2]
# days[dd] = days.get(dd,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
allpoints = scan_where()
days = find_days(allpoints)
#hours = find_hours(allpoints)
dayno = 0
pointno = 0 # point within day
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)
def render():
ds.clear(0)
max_x,max_y = c.size
points = points_of_day(allpoints, days[dayno])
latscale, lonscale, order = make_scalers(points)
# note that %.3g doesn't truncate at all, though that may be documented
label = u"Day %s/%s: c %.4s,%.4s" % (dayno+1, len(days),
latscale.center(),lonscale.center())
ds.text( (0,max_y), label, yellow)
# do this here instead of in prevpoint/nextpoint because they don't know our bounds
global pointno
if pointno >= len(order):
pointno = len(order) - 1
if pointno < 0:
pointno = 0
pointkey = order[pointno]
lastpoint = points[order.pop(0)]
if pointno == 0:
ds.point(latlon_to_xy(lastpoint, latscale, lonscale), yellow, width=4)
else:
ds.point(latlon_to_xy(lastpoint, latscale, lonscale), blue, width=4)
# 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
ds.line((latlon_to_xy(lastpoint, latscale, lonscale), latlon_to_xy(thispoint, latscale, lonscale)), green)
lastpoint = thispoint
if k == pointkey:
# cursor
ds.point(latlon_to_xy(thispoint, latscale, lonscale), yellow, width=4)
# d,t = k.split("t")
# if d != lastd:
# ds.point(latlon_to_xy(lastpoint, latscale, lonscale), yellow, width=2)
# lastd = d
# what about pictures?
# keep an "nth" point, use up-down to select
# click to show, just "open" it? or imgviewer render it?
# add "delete this point" too, make a .bad file?
while running:
e32.ao_sleep(0.5)
render()
lock.wait()