diff options
| author | Tim Redfern <tim@eclectronics.org> | 2012-05-02 16:43:12 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2012-05-02 16:43:12 +0100 |
| commit | 3209f698306ab0cf22ef0fe31a722bad22214691 (patch) | |
| tree | f81c7a0d1e2825bcfb6997554fa2ccc3aeef4cee | |
| parent | be1dd58124b3b4e1ad7a9eeabfb421d246b6ad1b (diff) | |
building xml loader
| -rw-r--r-- | latLng.py | 23 | ||||
| -rw-r--r-- | layers.py | 48 | ||||
| -rw-r--r-- | testopen.pd | 3 | ||||
| -rw-r--r-- | testreceive.pd | 4 | ||||
| -rwxr-xr-x | tomorrowtheground.py | 46 | ||||
| -rw-r--r-- | tomorrowthegroundGUI/tomorrowthegroundGUI.pde | 2 | ||||
| -rw-r--r-- | ttg01.xml | 24 | ||||
| -rw-r--r-- | x01.png | bin | 0 -> 206526 bytes | |||
| -rw-r--r-- | x02.png | bin | 0 -> 206526 bytes | |||
| -rw-r--r-- | x03.png | bin | 0 -> 206526 bytes | |||
| -rw-r--r-- | xml2obj.py | 84 |
11 files changed, 219 insertions, 15 deletions
diff --git a/latLng.py b/latLng.py new file mode 100644 index 0000000..f567371 --- /dev/null +++ b/latLng.py @@ -0,0 +1,23 @@ +class latLng: + def __init__(self,lat=0.0,lng=0.0): + self.lat=lat + self.lng=lng + def parse(self,string): + n=string.split(",") + try: + self.lat=float(n[0]) + except: + self.lat=0.0 + try: + self.lng=float(n[1]) + except: + self.lng=0.0 + def __eq__(self,pos): + ret=False + if isinstance(pos,latLng): + if self.lat==pos.lat: + if self.lng==pos.lng: + ret=True + return ret + def __ne__(self,pos): + return not self==pos
\ No newline at end of file diff --git a/layers.py b/layers.py new file mode 100644 index 0000000..38aeba4 --- /dev/null +++ b/layers.py @@ -0,0 +1,48 @@ +from PIL import Image +from latLng import latLng + +class layer: + """a generic GPS image layer""" + tl=latLng() + br=latLng() + pixel=latLng() + def __init__(self,file,ll1,ll2): + try: + self.image=Image.open(file) + except: + print "gps layer: failed to open", file + try: + self.tl.parse(ll1) + self.br.parse(ll2) + self.pixsize=latLng(abs(self.tl.lat-self.br.lat)/self.image.size[1],abs(self.tl.lng-self.br.lng)/self.image.size[0]) + except: + print "gps layer: failed to parse", file + def findpixel(self,pos): + return latLng(int((pos.lng-self.tl.lng)/self.pixsize.lng),int((pos.lat-self.br.lat)/self.pixsize.lat)) + def checkcoord(self,pos): + p=self.findpixel(pos) + if p!=self.pixel: + self.pixel=p + return self.setcoord(p) + else: + return None + def setcoord(self,pos): + return str(1.0) + +class trigger(): + """a generic trigger - + id can be anything - + i.e. a string or an integer""" + def __init__(self,id,command,param): + self.id=id + self.command=(command,param) + def check(self,id): + if id==self.id: + return command + else: + return None + +class indexlayer(layer): + triggers=[] + def setcoord(self,pos): + return str(1)
\ No newline at end of file diff --git a/testopen.pd b/testopen.pd new file mode 100644 index 0000000..a8cb8ee --- /dev/null +++ b/testopen.pd @@ -0,0 +1,3 @@ +#N canvas 256 226 450 300 10; +#X msg 59 113 \; pd open testreceive.pd /home/tim/workspace/tomorrowtheground/ +; diff --git a/testreceive.pd b/testreceive.pd new file mode 100644 index 0000000..c375170 --- /dev/null +++ b/testreceive.pd @@ -0,0 +1,4 @@ +#N canvas 796 273 450 300 10; +#X obj 126 54 netreceive 5401 1; +#X obj 126 96 print udp; +#X connect 0 0 1 0; diff --git a/tomorrowtheground.py b/tomorrowtheground.py index 7b68b12..2ffdf7e 100755 --- a/tomorrowtheground.py +++ b/tomorrowtheground.py @@ -1,11 +1,45 @@ #!/usr/bin/python #UDP listener +from latLng import * +from layers import * +from xml2obj import * + +doc=xml2obj(open("ttg01.xml")) +gpslayers=[] +for i in doc.gps.index: + #should catch invalid xml + g=indexlayer(i.file,i.ll1,i.ll2) + for t in i.trigger: + g.triggers.append(trigger(int(t.id),t.command,t.param)) + gpslayers.append(g) + import socket -UDP_IP="127.0.0.1" -UDP_PORT=5204 -sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) -sock.bind( (UDP_IP,UDP_PORT) ) + +GUI_IP="127.0.0.1" +GUI_PORT=5400 +insock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) +insock.bind( (GUI_IP,GUI_PORT) ) +insock.settimeout(0.01) +PD_IP="127.0.0.1" +PD_PORT=5401 +outsock = socket.socket( socket.AF_INET,socket.SOCK_DGRAM ) + +pos=latLng() +posChanged=False + while True: - data, addr = sock.recvfrom( 1024 ) - print "received message:", data
\ No newline at end of file + data="" + try: + data, addr = insock.recvfrom(128) + pos.parse(data) + posChanged=True + except: + nothing=None + if posChanged: + print "received message:", data + for layer in gpslayers: + r=layer.checkcoord(pos) + if layer.checkcoord!=None: + outsock.sendto( r, (PD_IP, PD_PORT) ) +
\ No newline at end of file diff --git a/tomorrowthegroundGUI/tomorrowthegroundGUI.pde b/tomorrowthegroundGUI/tomorrowthegroundGUI.pde index b784b99..0fe919e 100644 --- a/tomorrowthegroundGUI/tomorrowthegroundGUI.pde +++ b/tomorrowthegroundGUI/tomorrowthegroundGUI.pde @@ -36,6 +36,6 @@ void mouseDragged() y=mouseY; float fx=((float)mouseX)/width; float fy=((float)mouseY)/height; - udp.send(((fx*fw)+lng1)+","+((fy*fh)+lat2)+"\n","127.0.0.1",5204); + udp.send(((fy*fh)+lat2)+","+((fx*fw)+lng1)+"\n","127.0.0.1",5400); } } @@ -1,11 +1,19 @@ <?xml version="1.0" encoding="UTF-8" ?> <tomorrowtheground> - <gpsmapper file="x01.gif"> - <triggerlayer> - </triggerlayer> - <scalarlayer> - </scalarlayer> - </gpsmapper> - <bluetooth freq="10"> - </bluetooth> + <gps> + <index file="x01.png" ll1="51.050608,3.724698" ll2="51.046878,3.732852"> + <trigger id="01" command="play" param="b01.wav"> + </trigger> + <trigger id="02" command="play" param="b02.wav"> + </trigger> + </index> + <scale file="x02.png" ll1="51.050608,3.724698" ll2="51.046878,3.732852" freq="1.0" command="cc01"> + </scale> + <scale file="x03.png" ll1="51.050608,3.724698" ll2="51.046878,3.732852" freq="1.0" command="cc02"> + </scale> + </gps> + <bt freq="10"> + <trigger id="00:11:95:00:1A:CF" command="play" param="i01.wav"> + </trigger> + </bt> </tomorrowtheground>
\ No newline at end of file Binary files differBinary files differBinary files differdiff --git a/xml2obj.py b/xml2obj.py new file mode 100644 index 0000000..5668ec8 --- /dev/null +++ b/xml2obj.py @@ -0,0 +1,84 @@ +import re +import xml.sax.handler + +def xml2obj(src): + """ + A simple function to converts XML data into native Python object. + """ + + non_id_char = re.compile('[^_0-9a-zA-Z]') + def _name_mangle(name): + return non_id_char.sub('_', name) + + class DataNode(object): + def __init__(self): + self._attrs = {} # XML attributes and child elements + self.data = None # child text data + def __len__(self): + # treat single element as a list of 1 + return 1 + def __getitem__(self, key): + if isinstance(key, basestring): + return self._attrs.get(key,None) + else: + return [self][key] + def __contains__(self, name): + return self._attrs.has_key(name) + def __nonzero__(self): + return bool(self._attrs or self.data) + def __getattr__(self, name): + if name.startswith('__'): + # need to do this for Python special methods??? + raise AttributeError(name) + return self._attrs.get(name,None) + def _add_xml_attr(self, name, value): + if name in self._attrs: + # multiple attribute of the same name are represented by a list + children = self._attrs[name] + if not isinstance(children, list): + children = [children] + self._attrs[name] = children + children.append(value) + else: + self._attrs[name] = value + def __str__(self): + return self.data or '' + def __repr__(self): + items = sorted(self._attrs.items()) + if self.data: + items.append(('data', self.data)) + return u'{%s}' % ', '.join([u'%s:%s' % (k,repr(v)) for k,v in items]) + + class TreeBuilder(xml.sax.handler.ContentHandler): + def __init__(self): + self.stack = [] + self.root = DataNode() + self.current = self.root + self.text_parts = [] + def startElement(self, name, attrs): + self.stack.append((self.current, self.text_parts)) + self.current = DataNode() + self.text_parts = [] + # xml attributes --> python attributes + for k, v in attrs.items(): + self.current._add_xml_attr(_name_mangle(k), v) + def endElement(self, name): + text = ''.join(self.text_parts).strip() + if text: + self.current.data = text + if self.current._attrs: + obj = self.current + else: + # a text only node is simply represented by the string + obj = text or '' + self.current, self.text_parts = self.stack.pop() + self.current._add_xml_attr(_name_mangle(name), obj) + def characters(self, content): + self.text_parts.append(content) + + builder = TreeBuilder() + if isinstance(src,basestring): + xml.sax.parseString(src, builder) + else: + xml.sax.parse(src, builder) + return builder.root._attrs.values()[0]
\ No newline at end of file |
