Adding a script to generate a kml from the adsb state server. Also a kml file to periodically refresh the kml based on a network link.

This commit is contained in:
Phelps Williams 2014-11-05 17:49:28 -08:00 committed by Phelps Williams
parent 9dcb977bdc
commit 9f0eeb02f9
2 changed files with 149 additions and 0 deletions

22
apps/adsb.kml Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Folder>
<name>Network Links</name>
<visibility>1</visibility>
<open>0</open>
<description>Network link example</description>
<NetworkLink>
<name>Planes</name>
<visibility>1</visibility>
<open>0</open>
<description>Moar Planes</description>
<refreshVisibility>1</refreshVisibility>
<flyToView>0</flyToView>
<Link>
<href><![CDATA[http://localhost:8080]]></href>
<refreshMode>onInterval</refreshMode>
<refreshInterval>0.4</refreshInterval>
</Link>
</NetworkLink>
</Folder>
</kml>

127
apps/adsb_to_kml.py Executable file
View File

@ -0,0 +1,127 @@
#!/usr/bin/env python
from twisted.internet.protocol import Protocol, ReconnectingClientFactory
from twisted.internet import reactor, task
import struct
from datetime import datetime
import calendar
import time
class Echo(Protocol):
def __init__(self):
self.buf = ""
self.targets = {}
self.timeout = task.LoopingCall(self.cull)
self.timeout.start(30)
def dataReceived(self, data):
self.buf += data
self.process()
def process(self):
while len(self.buf) >= 40:
(icao, _type, ts, lat, lon, alt) = struct.unpack("!IIdddd", self.buf[:40])
self.buf = self.buf[40:]
if _type != 0x1:
continue
self.targets[icao] = (ts, lat, lon, alt)
def get_targets(self):
return self.targets
def cull(self):
"""
Periodically this should be called to dump targets which haven't been
heard from in a while.
"""
delete_icaos = []
for icao, met in self.targets.iteritems():
print met[0]
#if (calendar.timegm(datetime.utcnow().utctimetuple()) - met[0]) > 120:
if (time.time() - met[0]) > 120:
delete_icaos.append(icao)
for i in delete_icaos:
print "deleting", i
del self.targets[i]
class EchoClientFactory(ReconnectingClientFactory):
def __init__(self):
self.connected = False
def startedConnecting(self, connector):
print 'Started to connect.'
def buildProtocol(self, addr):
print 'Connected.'
self.connected = True
self.client = Echo()
return self.client
def is_connected(self):
return self.connected
def get_client(self):
return self.client
def clientConnectionLost(self, connector, reason):
self.connected = False
print 'Lost connection. Reason:', reason
self.retry(connector)
def clientConnectionFailed(self, connector, reason):
self.connected = False
print 'Connection failed. Reason:', reason
self.retry(connector)
from twisted.web import server, resource
from lxml import etree
from pykml.factory import KML_ElementMaker as KML
class Simple(resource.Resource):
def __init__(self, _factory):
self.factory = _factory
isLeaf = True
def render_GET(self, request):
if not self.factory.is_connected():
return
request.responseHeaders.setRawHeaders("content-type", ['application/vnd.google-earth.kml+xml'])
doc = KML.kml()
folder = KML.Folder(KML.name("planes"))
doc.append(folder)
targ = self.factory.get_client().get_targets()
for icao, met in targ.iteritems():
folder.append(
KML.Placemark(
KML.name('%x' % icao),
#KML.styleUrl("#pushpin"),
KML.Point(
KML.extrude(True),
KML.altitudeMode('relativeToGround'),
KML.coordinates('%f,%f,%f' % (met[2], met[1], met[3])),
),
),
)
return etree.tostring(etree.ElementTree(doc),pretty_print=True)
if __name__ == "__main__":
host = "localhost"
port = 1234
factory = EchoClientFactory()
reactor.connectTCP(host, port, factory)
site = server.Site(Simple(factory))
reactor.listenTCP(8080, site)
reactor.run()