Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- # Copyright 2010 Nick Foster
- #
- # This file is part of gr-air-modes
- #
- # gr-air-modes is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 3, or (at your option)
- # any later version.
- #
- # gr-air-modes is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with gr-air-modes; see the file COPYING. If not, write to
- # the Free Software Foundation, Inc., 51 Franklin Street,
- # Boston, MA 02110-1301, USA.
- #
- import sqlite3
- import string, math, threading, time
- import subprocess #g0hww - for xastir hack
- class modes_kml(threading.Thread):
- def __init__(self, dbfile, filename, localpos, timeout=5):
- threading.Thread.__init__(self)
- self._filename = filename
- self._dbfile = dbfile
- self.my_coords = localpos
- self._timeout = timeout
- self.done = False
- self.setDaemon(1)
- self.start()
- def run(self):
- while self.done is False:
- self.output()
- time.sleep(self._timeout)
- self.done = True
- def output(self):
- self._db = sqlite3.connect(self._dbfile)
- kmlstr = self.genkml()
- if kmlstr is not None:
- f = open(self._filename, 'w')
- f.write(kmlstr)
- f.close()
- self._db.close()
- def draw_circle(self, center, rng):
- retstr = ""
- steps=30
- #so we're going to do this by computing a bearing angle based on the steps, and then compute the coordinate of a line extended from the center point to that range.
- [center_lat, center_lon] = center
- esquared = (1/298.257223563)*(2-(1/298.257223563))
- earth_radius_mi = 3963.19059
- #here we figure out the circumference of the latitude ring
- #which tells us how wide one line of longitude is at our latitude
- lat_circ = earth_radius_mi * math.cos(center_lat)
- #the circumference of the longitude ring will be equal to the circumference of the earth
- lat_rad = math.radians(center_lat)
- lon_rad = math.radians(center_lon)
- tmp0 = rng / earth_radius_mi
- for i in range(0, steps+1):
- bearing = i*(2*math.pi/steps) #in radians
- lat_out = math.degrees(math.asin(math.sin(lat_rad)*math.cos(tmp0) + math.cos(lat_rad)*math.sin(tmp0)*math.cos(bearing)))
- lon_out = center_lon + math.degrees(math.atan2(math.sin(bearing)*math.sin(tmp0)*math.cos(lat_rad), math.cos(tmp0)-math.sin(lat_rad)*math.sin(math.radians(lat_out))))
- retstr += " %.8f, %.8f, 0" % (lon_out, lat_out,)
- retstr = string.lstrip(retstr)
- return retstr
- def genkml(self):
- '''
- #first let's draw the static content
- retstr="""<?xml version="1.0" encoding="UTF-8"?>\n<kml xmlns="http://www.opengis.net/kml/2.2">\n<Document>\n\t<Style id="airplane">\n\t\t<IconStyle>\n\t\t\t<Icon><href>airports.png</href></Icon>\n\t\t</IconStyle>\n\t</Style>\n\t<Style id="rangering">\n\t<LineStyle>\n\t\t<color>9f4f4faf</color>\n\t\t<width>2</width>\n\t</LineStyle>\n\t</Style>\n\t<Style id="track">\n\t<LineStyle>\n\t\t<color>5fff8f8f</color>\n\t\t<width>4</width>\n\t</LineStyle>\n\t</Style>"""
- retstr += """\t<Folder>\n\t\t<name>Range rings</name>\n\t\t<open>0</open>"""
- for rng in [100, 200, 300]:
- retstr += """\n\t\t<Placemark>\n\t\t\t<name>%inm</name>\n\t\t\t<styleUrl>#rangering</styleUrl>\n\t\t\t<LinearRing>\n\t\t\t\t<coordinates>%s</coordinates>\n\t\t\t</LinearRing>\n\t\t</Placemark>""" % (rng, self.draw_circle(self.my_coords, rng),)
- retstr += """\t</Folder>\n\t<Folder>\n\t\t<name>Aircraft locations</name>\n\t\t<open>0</open>"""
- '''
- #read the database and add KML
- q = "select distinct icao from positions where seen > datetime('now', '-10 second')" # g0hww reduced time window to 10 second
- c = self._db.cursor()
- # g0hhw, we get errors saying that the database is locked, so try doing something about it :)
- try:
- c.execute(q)
- except:
- print "modes_kml.genkml() - Exception caught when attempting to initially access database, will try again later"
- return
- icaolist = c.fetchall()
- #now we have a list icaolist of all ICAOs seen in the last 1 minutes # g0hww 1 minute
- for icao in icaolist:
- #print "ICAO: %x" % icao
- q = "select * from positions where icao=%i and seen > datetime('now', '-2 hour') ORDER BY seen DESC" % icao
- try:
- c.execute(q)
- except:
- print "modes_kml.genkml() - Exception caught when attempting to subsequently access database, will try again later"
- return
- track = c.fetchall()
- #print "Track length: %i" % len(track)
- if len(track) != 0:
- lat = track[0][3]
- if lat is None: lat = 0
- lon = track[0][4]
- if lon is None: lon = 0
- alt = track[0][2]
- if alt is None: alt = 0
- metric_alt = alt * 0.3048 #google earth takes meters, the commie bastards
- trackstr = ""
- for pos in track:
- trackstr += " %f, %f, %f" % (pos[4], pos[3], pos[2]*0.3048)
- trackstr = string.lstrip(trackstr)
- else:
- alt = 0
- metric_alt = 0
- lat = 0
- lon = 0
- trackstr = str("")
- #now get metadata
- q = "select ident from ident where icao=%i" % icao
- try:
- c.execute(q)
- except:
- print "modes_kml.genkml() - Exception caught when attempting to penultimately access database, will try again later"
- return
- r = c.fetchall()
- if len(r) != 0:
- ident = r[0][0]
- else: ident=""
- #if ident is None: ident = ""
- #get most recent speed/heading/vertical
- q = "select seen, speed, heading, vertical from vectors where icao=%i order by seen desc limit 1" % icao
- try:
- c.execute(q)
- except:
- print "modes_kml.genkml() - Exception caught when attempting to finally access database, will try again later"
- return
- r = c.fetchall()
- if len(r) != 0:
- seen = r[0][0]
- speed = r[0][1]
- heading = r[0][2]
- vertical = r[0][3]
- else:
- seen = 0
- speed = 0
- heading = 0
- vertical = 0
- # G0HWW - hack for a xastir feed in an aprs format.
- # we're gonna use the xastir udp client so we don't need a socket, we just need to create a string, and invoke the udp client binary.
- # We want to send
- # Track ID as the source callsign. We can't use the flight ID, as we might not know it and we don't want
- # The command will be something like this:
- # xastir_udp_client localhost 2023 G0HWW 11141 "4ca61d>ADS-B:=5223.25N/00035.00E^001/150/A=001234ADS-B Test"
- utility="/usr/local/bin/xastir_udp_client"
- server="localhost"
- port="2023"
- mycall = "MYCALL"
- mypass="MYPASS"
- net="ADS-B"
- # set up the track info
- actrack=icao[0]
- latdm = '{0:02d}{1:05.2f}{2}'.format(abs(int(lat)), (abs(lat)-abs(int(lat))) * 60, 'S' if (lat<0) else 'N')
- longdm = '{0:03d}{1:05.2f}{2}'.format(abs(int(lon)), (abs(lon)-abs(int(lon))) * 60, 'W' if (lon<0) else 'E')
- #consruct the message payload string
- payload = '{0:X}>{1}:={2}/{3}^{4:03.0f}/{5:03.0f}/A={6:06.0f}{7}{8}'.format(actrack,net,latdm,longdm,heading,speed,alt,ident,'')
- cmd = '{0} {1} {2} {3} {4} "{5}"'.format(utility,server,port,mycall,mypass,payload)
- print cmd
- subprocess.call(cmd, shell=True)
- # end G0HWW hack for Xastir
- #now generate some KML
- #retstr+= "\n\t\t<Placemark>\n\t\t\t<name>%s</name>\n\t\t\t<styleUrl>#airplane</styleUrl>\n\t\t\t<description>\n\t\t\t\t<![CDATA[Altitude: %s<br/>Heading: %i<br/>Speed: %i<br/>Vertical speed: %i<br/>ICAO: %x<br/>Last seen: %s]]>\n\t\t\t</description>\n\t\t\t<Point>\n\t\t\t\t<altitudeMode>absolute</altitudeMode>\n\t\t\t\t<extrude>1</extrude>\n\t\t\t\t<coordinates>%s,%s,%i</coordinates>\n\t\t\t</Point>\n\t\t</Placemark>" % (ident, alt, heading, speed, vertical, icao[0], seen, lon, lat, metric_alt, )
- #retstr+= "\n\t\t<Placemark>\n\t\t\t<styleUrl>#track</styleUrl>\n\t\t\t<LineString>\n\t\t\t\t<extrude>0</extrude>\n\t\t\t\t<altitudeMode>absolute</altitudeMode>\n\t\t\t\t<coordinates>%s</coordinates>\n\t\t\t</LineString>\n\t\t</Placemark>" % (trackstr,)
- #retstr+= '\n\t</Folder>\n</Document>\n</kml>'
- retstr = None
- return retstr
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement