Package mosp :: Package gui :: Module playerChamplain
[hide private]
[frames] | no frames]

Source Code for Module mosp.gui.playerChamplain

  1  # -*- coding: utf-8 -*- 
  2  """A visual player for simulation output based on libchamplain and its python bindings""" 
  3   
  4  import champlain 
  5  import clutter 
  6  import cairo 
  7  import math 
  8  import gobject 
  9  import threading 
 10  import time 
 11   
 12  import select 
 13  import sys 
 14  import struct 
 15   
 16  sys.path.append("..")  
 17  from mosp.geo.utm import utm_to_latlong 
 18  from mosp.monitors import PipePlayerMonitor 
 19   
 20  __author__ = "F. Ludwig, P. Tute" 
 21  __copyright__ = "2010-2011, DCSec, Leibniz Universitaet Hannover, Germany" 
 22  __license__ = "GPLv3" 
 23  __deprecated__ = True 
 24  __status__ = "unmaintained" 
 25   
 26   
 27  COLORS = {0: [0.1,0.1,0.9,1.0], # blue 
 28            1: [0.9,0.1,0.1,1.0], # red 
 29            2: [0.1,0.9,0.1,1.0], # green 
 30            3: [0.5,0.0,0.5,1.0], # purple 
 31            4: [0.0,1.0,1.0,1.0], # aqua 
 32            5: [0.6,0.6,0.0,1.0], # olive 
 33            6: [0.5,0.5,0.5,1.0], # grey 
 34            7: [0.0,0.0,0.0,1.0]  # black 
 35            }                     #: blue, red, green, purple, aqua, olive, grey, black 
 36   
 37   
38 -class AnimatedMarker(champlain.Marker) :
39 """The AnimatedMarker extends the champlain.Marker"""
40 - def __init__(self, color=0, markersize=10) :
41 """Init the AnimatedMarker.""" 42 champlain.Marker.__init__(self) 43 self.markersize = markersize 44 self.color = -1 45 self.texture = None 46 self.change_color(color)
47
48 - def change_color(self, color):
49 """Change AnimatedMarker's color.""" 50 if self.color != color: 51 self.color = color 52 if self.texture: 53 #print 'remove texture' 54 self.remove(self.texture) 55 56 self.texture = clutter.CairoTexture(self.markersize, self.markersize) 57 cr = self.texture.cairo_create() 58 cr.arc(self.markersize / 2.0, self.markersize / 2.0, self.markersize / 2.0, 59 0, 2 * math.pi) 60 cr.set_source_rgba(*COLORS[self.color]) 61 cr.fill() 62 self.add(self.texture)
63 64
65 -class Player(object):
66 """The visual player based on libchamplain and its python bindings.""" 67
68 - def __init__(self, width=640, height=480, init_zoom=14, markersize=10):
69 """Inits the Player.""" 70 super(Player, self).__init__() 71 self.screensize=(width, height) #: size of screen/app: width and height as tuple 72 self.init_zoom = init_zoom #: inital zoom factor of map 73 self.markersize = markersize #: size of moving markers
74
75 - def update(self):
76 """On update, get new marker positions, update colors, ...""" 77 try: 78 s = select.select([sys.stdin], [], [], 0.0) 79 except IOError: 80 print 'assuming end of simulation' 81 return 82 while s[0]: 83 type = sys.stdin.read(1) 84 if type == '\x00': 85 data = sys.stdin.read(PipePlayerMonitor.FORMAT_LEN) 86 color, id, x, y = struct.unpack(PipePlayerMonitor.FORMAT, data) 87 coords = utm_to_latlong(x, y, self.zone) 88 self.markers[id].set_position(coords[1], coords[0]) 89 self.markers[id].change_color(color) 90 # print id, t, x, y 91 # print coords 92 elif type == '\x01': 93 t = struct.unpack('I', sys.stdin.read(4))[0] 94 self.date.set_text(str(t)) 95 t %= 24000 96 op = None 97 if 4000 <= t <= 8000: 98 op = 120 - (t - 4000.0) / 4000 * 120 99 if 16000 <= t <= 20000: 100 op = (t - 16000.0) / 4000 * 120 101 102 if not op is None: 103 self.night.set_opacity(int(op)) 104 105 s = select.select([sys.stdin], [], [], 0.0) 106 107 s = select.select([sys.stdin], [], [], 0.0) 108 109 # TODO 110 # self.night.set_opacity(self.night.get_opacity() + 1) 111 gobject.timeout_add(50, self.update)
112
113 - def key_press(self, stage, event):
114 """Handle key presses.""" 115 if event.keyval == clutter.keysyms.q: 116 #if the user pressed "q" quit the demo 117 clutter.main_quit() 118 if event.keyval in (clutter.keysyms.plus, clutter.keysyms.o): 119 #if the user pressed "+" zoom in 120 self.actor.zoom_in() 121 if event.keyval in (clutter.keysyms.minus, clutter.keysyms.i): 122 #if the user pressed "-" zoom out 123 self.actor.zoom_out() 124 elif event.keyval == clutter.keysyms.a: 125 #if the user pressed "a" turn people into ants. OMG! 126 for marker in self.markers: 127 marker.toggle_ant() 128 print event.keyval
129
130 - def resize_actor(self, stage, box, flags):
131 """On resize resize also this ...""" 132 self.actor.set_size(int(stage.get_width()), int(stage.get_height())) 133 self.night.set_size(int(stage.get_width()), int(stage.get_height()))
134
135 - def main(self):
136 """The window, stage, marker init and so on ...""" 137 global markers 138 gobject.threads_init() 139 clutter.init() 140 stage = clutter.Stage(default=True) 141 self.actor = champlain.View() 142 layer = champlain.Layer() 143 144 stage.connect("button-press-event", self.button_pressed) 145 stage.connect("key-press-event", self.key_press) 146 147 stage.set_user_resizable(True) 148 stage.connect("allocation-changed", self.resize_actor) 149 150 self.markers = [] 151 self.num_marker = int(sys.stdin.readline()) 152 self.minlat = float(sys.stdin.readline()) 153 self.minlon = float(sys.stdin.readline()) 154 self.maxlat = float(sys.stdin.readline()) 155 self.maxlon = float(sys.stdin.readline()) 156 self.zone = int(sys.stdin.readline()) 157 print 'showing %i marker' % self.num_marker 158 for i in xrange(self.num_marker): 159 marker = AnimatedMarker(markersize=self.markersize) 160 # marker.set_position(*POSITION) 161 layer.add(marker) 162 self.markers.append(marker) 163 164 bbox = champlain.Polygon() 165 bbox.append_point(self.minlat, self.minlon) 166 bbox.append_point(self.minlat, self.maxlon) 167 bbox.append_point(self.maxlat, self.maxlon) 168 bbox.append_point(self.maxlat, self.minlon) 169 bbox.set_stroke_width(1.0); 170 bbox.set_property("closed-path", True) 171 bbox.set_property("mark-points", True) 172 bbox.set_property("stroke-color", clutter.Color(red=64,green=64,blue=64,alpha=128)) 173 self.actor.add_polygon(bbox) 174 175 self.POSITION = [ self.minlat+((self.maxlat-self.minlat)/2), self.minlon+(self.maxlon-self.minlon)/2] 176 177 stage.set_size(*self.screensize) 178 self.actor.set_size(*self.screensize) 179 stage.add(self.actor) 180 181 layer.show() 182 self.actor.add_layer(layer) 183 184 # Finish initialising the map view 185 self.actor.set_property("zoom-level", self.init_zoom) 186 self.actor.set_property("scroll-mode", champlain.SCROLL_MODE_KINETIC) 187 self.actor.center_on(*self.POSITION) 188 189 self.night = clutter.Rectangle(clutter.Color(0, 0, 50)) 190 self.night.set_size(*self.screensize) 191 self.night.set_opacity(120) 192 self.night.show() 193 194 if not '-n' in sys.argv: 195 stage.add(self.night) 196 197 self.date = clutter.Text() 198 self.date.set_text("Hello World") 199 stage.add(self.date) 200 201 stage.show() 202 203 gobject.timeout_add(200, self.update) 204 205 clutter.main()
206
207 - def button_pressed(self, stage, event):
208 """On button_pressed print coordinates to console.""" 209 print self.actor.get_coords_from_event(event)
210 211 212 if __name__ == '__main__': 213 p = Player(width=800, height=600, init_zoom=15, markersize=10) 214 p.main() 215