From 3209f698306ab0cf22ef0fe31a722bad22214691 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Wed, 2 May 2012 16:43:12 +0100 Subject: building xml loader --- latLng.py | 23 +++++++ layers.py | 48 +++++++++++++++ testopen.pd | 3 + testreceive.pd | 4 ++ tomorrowtheground.py | 46 ++++++++++++-- tomorrowthegroundGUI/tomorrowthegroundGUI.pde | 2 +- ttg01.xml | 24 +++++--- x01.png | Bin 0 -> 206526 bytes x02.png | Bin 0 -> 206526 bytes x03.png | Bin 0 -> 206526 bytes xml2obj.py | 84 ++++++++++++++++++++++++++ 11 files changed, 219 insertions(+), 15 deletions(-) create mode 100644 latLng.py create mode 100644 layers.py create mode 100644 testopen.pd create mode 100644 testreceive.pd create mode 100644 x01.png create mode 100644 x02.png create mode 100644 x03.png create mode 100644 xml2obj.py 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); } } diff --git a/ttg01.xml b/ttg01.xml index 3a8f9e2..3b3daa0 100644 --- a/ttg01.xml +++ b/ttg01.xml @@ -1,11 +1,19 @@ - - - - - - - - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/x01.png b/x01.png new file mode 100644 index 0000000..4233f5f Binary files /dev/null and b/x01.png differ diff --git a/x02.png b/x02.png new file mode 100644 index 0000000..4233f5f Binary files /dev/null and b/x02.png differ diff --git a/x03.png b/x03.png new file mode 100644 index 0000000..4233f5f Binary files /dev/null and b/x03.png differ diff --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 -- cgit v1.2.3