summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2012-05-02 16:43:12 +0100
committerTim Redfern <tim@eclectronics.org>2012-05-02 16:43:12 +0100
commit3209f698306ab0cf22ef0fe31a722bad22214691 (patch)
treef81c7a0d1e2825bcfb6997554fa2ccc3aeef4cee
parentbe1dd58124b3b4e1ad7a9eeabfb421d246b6ad1b (diff)
building xml loader
-rw-r--r--latLng.py23
-rw-r--r--layers.py48
-rw-r--r--testopen.pd3
-rw-r--r--testreceive.pd4
-rwxr-xr-xtomorrowtheground.py46
-rw-r--r--tomorrowthegroundGUI/tomorrowthegroundGUI.pde2
-rw-r--r--ttg01.xml24
-rw-r--r--x01.pngbin0 -> 206526 bytes
-rw-r--r--x02.pngbin0 -> 206526 bytes
-rw-r--r--x03.pngbin0 -> 206526 bytes
-rw-r--r--xml2obj.py84
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);
}
}
diff --git a/ttg01.xml b/ttg01.xml
index 3a8f9e2..3b3daa0 100644
--- a/ttg01.xml
+++ b/ttg01.xml
@@ -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
diff --git a/x01.png b/x01.png
new file mode 100644
index 0000000..4233f5f
--- /dev/null
+++ b/x01.png
Binary files differ
diff --git a/x02.png b/x02.png
new file mode 100644
index 0000000..4233f5f
--- /dev/null
+++ b/x02.png
Binary files differ
diff --git a/x03.png b/x03.png
new file mode 100644
index 0000000..4233f5f
--- /dev/null
+++ b/x03.png
Binary files 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