source: subversion/applications/routing/pyroute/gui.py @ 5306

Last change on this file since 5306 was 5306, checked in by ojw, 12 years ago

Example of routing in the GUI (fixed nodes for now)

  • Property svn:executable set to *
File size: 4.2 KB
Line 
1#!/usr/bin/env python
2import pygtk
3pygtk.require('2.0')
4import gobject
5import gtk
6import sys
7from gtk import gdk
8from loadOsm import *
9from route import *
10import cairo
11
12def update(mapWidget):
13  return(True)
14
15class Projection:
16  def __init__(self):
17    pass
18  def setView(self,x,y,w,h):
19    self.w = w / 2
20    self.h = h / 2
21    self.xc = x + self.w
22    self.yc = y + self.h
23  def recentre(self,lat,lon,scale):
24    self.lat = lat
25    self.lon = lon
26    self.scale = scale  # TODO: scale and scaleCosLat
27  def nudge(self,dx,dy,scale):
28    self.lat = self.lat + dy * scale * self.scale
29    self.lon = self.lon + dx * scale * self.scale
30  def ll2xy(self,lat,lon):
31    px = (lon - self.lon) / self.scale
32    py = (lat - self.lat) / self.scale
33    x = self.xc + self.w * px
34    y = self.yc - self.h * py
35    return(x,y)
36  def xy2ll(self,x,y):
37    pass
38   
39class MapWidget(gtk.Widget):
40  __gsignals__ = { \
41    'realize': 'override',
42    'expose-event' : 'override',
43    'size-allocate': 'override',
44    'size-request': 'override'}
45  def __init__(self, osmDataFile):
46    gtk.Widget.__init__(self)
47    self.draw_gc = None
48    self.timer = gobject.timeout_add(200, update, self)
49    self.data = LoadOsm(osmDataFile)
50    self.projection = Projection()
51    self.projection.recentre(51.524,-0.129, 0.02)
52    self.router = Router(self.data)
53    result, self.route = self.router.doRoute(107318,107999)
54    print "Done routing, result: %s" % result
55   
56  def move(self,dx,dy):
57    self.projection.nudge(-dx,dy,1.0/self.rect.width)
58    self.window.invalidate_rect((0,0,self.rect.width,self.rect.height),False)
59  def nodeXY(self,node):
60    node = self.data.nodes[node]
61    return(self.projection.ll2xy(node[0], node[1]))
62  def draw(self, cr):
63    # Just nodes:
64    cr.set_source_rgb(0.0, 0.0, 0.0)
65    cr.set_line_cap(cairo.LINE_CAP_ROUND)
66    for k,v in self.data.nodes.items():
67      x,y = self.projection.ll2xy(v[0],v[1])
68      cr.move_to(x,y)
69      cr.line_to(x,y)
70      cr.stroke()
71   
72    if(len(self.route) > 1):
73      x,y = self.nodeXY(self.route[0])
74      cr.move_to(x,y)
75      for i in self.route:
76        x,y = self.nodeXY(i)
77        cr.line_to(x,y)
78      cr.stroke()
79     
80  def do_realize(self):
81    self.set_flags(self.flags() | gtk.REALIZED)
82    self.window = gdk.Window( \
83      self.get_parent_window(),
84      width = self.allocation.width,
85      height = self.allocation.height,
86      window_type = gdk.WINDOW_CHILD,
87      wclass = gdk.INPUT_OUTPUT,
88      event_mask = self.get_events() | gdk.EXPOSURE_MASK)
89    self.window.set_user_data(self)
90    self.style.attach(self.window)
91    self.style.set_background(self.window, gtk.STATE_NORMAL)
92    self.window.move_resize(*self.allocation)
93  def do_size_request(self, allocation):
94    pass
95  def do_size_allocate(self, allocation):
96    self.allocation = allocation
97    if self.flags() & gtk.REALIZED:
98      self.window.move_resize(*allocation)
99  def _expose_cairo(self, event, cr):
100    self.rect = self.allocation
101    self.projection.setView( \
102      self.rect.x, 
103      self.rect.y, 
104      self.rect.width, 
105      self.rect.height)
106    self.draw(cr)
107  def do_expose_event(self, event):
108    self.chain(event)
109    cr = self.window.cairo_create()
110    return self._expose_cairo(event, cr)
111
112class GuiBase:
113  """Wrapper class for a GUI interface"""
114  def __init__(self, osmDataFile):
115    # Create the window
116    win = gtk.Window()
117    win.set_title('map')
118    win.connect('delete-event', gtk.main_quit)
119    win.resize(600,800)
120    win.move(50, gtk.gdk.screen_height() - 850)
121   
122    # Events
123    event_box = gtk.EventBox()
124    event_box.connect("button_press_event", lambda w,e: self.pressed(e))
125    event_box.connect("button_release_event", lambda w,e: self.released(e))
126    event_box.connect("motion_notify_event", lambda w,e: self.moved(e))
127    win.add(event_box)
128   
129    # Create the map
130    self.mapWidget = MapWidget(osmDataFile)
131    event_box.add(self.mapWidget)
132   
133    # Finalise the window
134    win.show_all()
135    gtk.main()
136   
137  def pressed(self, event):
138    self.dragx = event.x
139    self.dragy = event.y
140  def released(self, event):
141    pass
142  def moved(self, event):
143    """Drag-handler"""
144    self.mapWidget.move(event.x - self.dragx, event.y - self.dragy)
145    self.dragx = event.x
146    self.dragy = event.y
147
148if __name__ == "__main__":
149  program = GuiBase(sys.argv[1])
Note: See TracBrowser for help on using the repository browser.