adsb2kml 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bffdcf414c8bf8c95a2ae2df02a1655a7cc97654
4
+ data.tar.gz: e19ad042804dff14d00725cbbaac9773a737428a
5
+ SHA512:
6
+ metadata.gz: 35e13e17080a5a7eec0b666bbce7972d614afca5f3b79dafb1e16aa17123dfa24ff711c53743555a9e7fd199cd00515192db0b55f8fa0d918e36c5453eb47c4b
7
+ data.tar.gz: 312e3a10e7b7b99f4b9310e0eb76d42ba4af3e13587147c2c964914c1c2a24a0872c50db99ff16733c330b533b67f10c4f142a7a93125b3e507cfd54c1fdc1dc
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014, Aaron Herting "qwertos" <aaron@herting.cc>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ #adsb2kml
2
+
3
+ This is a library to make it easy to view [ADS-B](http://en.wikipedia.org/wiki/Automatic_dependent_surveillance-broadcast)
4
+ traffic in [Google Earth](http://earth.google.com).
5
+
6
+ It was originaly used as part of a presentation at [Imagine RIT](http://www.rit.edu/imagine/) where the data
7
+ was merged with [APRS](http://en.wikipedia.org/wiki/Automatic_Packet_Reporting_System)
8
+ traffic from [aprs.fi](http://aprs.fi).
9
+
10
+ ##Using repository code
11
+
12
+ When using the code cloned from the git repository, two basic implementations are included.
13
+
14
+ `cons_fe.rb` is a basic console front end that looks very similar to the interactive view of dump1090.
15
+
16
+ `sin_fe.rb` uses sinatra to provide the KML file to Google Earth. This KML file gets regenerated every time
17
+ the server gets a new request.
18
+
19
+ In either case, a dump1090 server must be availible and serving SBS1 format data (any server providing this
20
+ data should work but has only been tested with dump1090). The provided `config.rb.example` file can be copied
21
+ to `config.rb` and edited to set the hostname and port number of the server providing this data.
22
+
23
+ Also, after 120 seconds (2 minutes) of not hearing any packets from a plane, the plane will be removed from
24
+ the list of planes.
25
+
26
+ ###sin_fe.rb specific info
27
+
28
+ The plane clipart is a modified version of the image that was found [here](http://openclipart.org/detail/16400/boing-plane-icon-by-sabrog),
29
+ and is in the public domian. You can set your own by changing the file `public/plane_icon.png`. What ever you
30
+ put there, you should set the top of the image to be the front of the plane. This allows the heading
31
+ to be properly viewed in Google Earth.
32
+
33
+ When sinatra is running, the "dynamic KML" can be found at the location `/adsb.kml`.
34
+
35
+
36
+ ##Dependencies
37
+
38
+ + [rtl_sdr](http://sdr.osmocom.org/trac/wiki/rtl-sdr)
39
+ + [dump1090](https://github.com/antirez/dump1090)
40
+ + Gems
41
+ + [sinatra](http://sinatrarb.com)
42
+ + [ruby_kml](https://github.com/schleyfox/ruby_kml)
43
+
44
+ *NOTE: This project does add some files to the module created by ruby_kml.*
45
+
46
+
47
+
@@ -0,0 +1,17 @@
1
+
2
+ require 'ruby_kml'
3
+
4
+ require_relative "ruby_kml/label_style.rb"
5
+
6
+ require_relative "adsb2kml/listener.rb"
7
+ require_relative "adsb2kml/database.rb"
8
+ require_relative "adsb2kml/airplane.rb"
9
+
10
+ module ADSB
11
+
12
+ $MESSAGE_FORMAT = /^(?<type>(MSG|STA|ID|AIR|SEL|CLK)),(?<subtype>(1|2|3|4|5|6|7|8)?),(?<session_id>\d*),(?<aircraft_id>\d*),(?<address>\h{6}),(?<flight_id>\d*),\w*,\w*,\w*,\w*,(?<callsign>(\w|\s)*),(?<altitude>\d*),(?<speed>\d*),(?<track>\d*),(?<latitude>(-?\d{1,3}\.\d{5})?),(?<longitude>(-?\d{1,3}\.\d{5})?),(?<vert_rate>-?\d*),(?<squawk>\d*),(?<alert>\d*),(?<emergency>\d*),(?<ident>\d*),(?<ground>\d*)$/
13
+
14
+ $STRING_FORMAT = "%10s %10s %10s %10s %10s %10s %10s %10s\n"
15
+
16
+
17
+ end
@@ -0,0 +1,89 @@
1
+ require 'ruby_kml'
2
+
3
+
4
+ module ADSB
5
+ class Airplane
6
+
7
+ @@info = [
8
+ :latitude,
9
+ :longitude,
10
+ :last_heard,
11
+ :speed,
12
+ :vert_rate,
13
+ :track,
14
+ :altitude
15
+ ]
16
+
17
+ @@info.each do |x|
18
+ attr_accessor x
19
+ end
20
+
21
+ attr_reader :address
22
+
23
+ def info
24
+ return @@info
25
+ end
26
+
27
+ def initialize address
28
+ @address = address
29
+ @altitude = "0"
30
+ end
31
+
32
+ def merge_with airplane
33
+ if airplane.address != @address then
34
+ return false
35
+ end
36
+
37
+
38
+ @@info.each do |x|
39
+ if ! airplane.send(x).empty? then
40
+ send( x.to_s + "=" , airplane.send(x) )
41
+ end
42
+ end
43
+
44
+ return true
45
+ end
46
+
47
+ def placemark
48
+ to_return = KML::Placemark.new(
49
+ :name => @address,
50
+ :geometry => KML::Point.new(
51
+ :coordinates => {
52
+ :lat => @latitude,
53
+ :lng => @longitude,
54
+ :alt => @altitude
55
+ }
56
+ ),
57
+ :style_url => "#" + @address + "_style"
58
+ )
59
+
60
+ return to_return
61
+ end
62
+
63
+ def icon url
64
+ to_return = KML::Style.new(
65
+ :id => @address + "_style",
66
+ :icon_style => KML::IconStyle.new(
67
+ :heading => @track,
68
+ :icon => KML::Icon.new(
69
+ :href => url
70
+ ),
71
+ :scale => 1.4
72
+ ),
73
+ :label_style => KML::LabelStyle.new(
74
+ :scale => 0.4
75
+ )
76
+ )
77
+ end
78
+
79
+ def to_cons
80
+ return sprintf $STRING_FORMAT, @address, @latitude, @longitude, @altitude, @speed, @last_heard, time_diff, @track
81
+ end
82
+
83
+ def time_diff
84
+ return Time.now.to_i - @last_heard.to_i
85
+ end
86
+
87
+ end
88
+ end
89
+
@@ -0,0 +1,86 @@
1
+
2
+ require 'ruby_kml'
3
+
4
+ module ADSB
5
+ class Database
6
+ attr_accessor :icon_url
7
+
8
+ def initialize name = "ADSB"
9
+ @name = name
10
+ @airplanes = {}
11
+ @icon_url = "/plane_icon.png"
12
+ end
13
+
14
+
15
+ def update airplane
16
+ if ( @airplanes.has_key? airplane.address ) then
17
+ @airplanes[airplane.address].merge_with airplane
18
+ else
19
+ @airplanes[airplane.address] = airplane
20
+ end
21
+ end
22
+
23
+ def update_t airplane
24
+ Thread.new do
25
+ update airplane
26
+ end
27
+ end
28
+
29
+
30
+ def to_kml
31
+ kml = KMLFile.new
32
+ folder = KML::Folder.new( :name => @name )
33
+
34
+ @airplanes.each do |address, airplane|
35
+ folder.features << airplane.icon(@icon_url)
36
+ folder.features << airplane.placemark
37
+ end
38
+
39
+ kml.objects << folder
40
+
41
+ return kml
42
+ end
43
+
44
+ def to_cons
45
+ to_return = sprintf $STRING_FORMAT, "Address", "Latitude", "Longitude", "Altitude", "Speed", "Last Heard", "Time Diff", "Track"
46
+
47
+ @airplanes.each do |address, air|
48
+ to_return += air.to_cons
49
+ end
50
+
51
+ return to_return
52
+
53
+ end
54
+
55
+
56
+ def expire_after time = 120
57
+ @time_expire = time
58
+ spawn_thread :watch_expire
59
+ end
60
+
61
+ private
62
+ def spawn_thread sym
63
+ Thread.new do
64
+ loop do
65
+ send sym
66
+ end
67
+ end
68
+ end
69
+
70
+ def watch_expire
71
+ expired = []
72
+ @airplanes.each do |addr, air|
73
+ if air.time_diff >= @time_expire then
74
+ expired.push addr
75
+ end
76
+ end
77
+
78
+ expired.each do |exp|
79
+ @airplanes.delete exp
80
+ end
81
+
82
+ sleep 10
83
+ end
84
+ end
85
+ end
86
+
@@ -0,0 +1,71 @@
1
+ require 'socket'
2
+
3
+
4
+ module ADSB
5
+ class Listener
6
+
7
+ def initialize hostname, port, database
8
+ @hostname = hostname
9
+ @port = port
10
+ @database = database
11
+
12
+ @cons_sock = TCPSocket.new hostname, port
13
+
14
+ @lt = spawn_thread :listener
15
+ end
16
+
17
+ private
18
+ def spawn_thread sym
19
+ Thread.new do
20
+ loop do
21
+ send sym
22
+ end
23
+ end
24
+ end
25
+
26
+ def listener
27
+ begin
28
+ line = @cons_sock.gets
29
+ rescue
30
+ puts "error"
31
+ end
32
+ line.strip!
33
+
34
+ match = nil
35
+ begin
36
+ if ! ( match = $MESSAGE_FORMAT.match line ) then
37
+ puts "no match"
38
+ puts line
39
+ return
40
+ end
41
+ rescue
42
+ puts "error2"
43
+ end
44
+
45
+
46
+ temp_airplane = Airplane.new match[:address]
47
+
48
+ temp_airplane.last_heard = Time.now.to_i.to_s
49
+
50
+
51
+ temp_airplane.info.each do |sym|
52
+ begin
53
+ if sym == :last_heard then
54
+ next
55
+ end
56
+
57
+ temp_airplane.send( sym.to_s + "=", match[sym])
58
+ rescue
59
+ puts "error " + sym.to_s
60
+ end
61
+ end
62
+
63
+
64
+
65
+
66
+ @database.update_t( temp_airplane )
67
+ end
68
+ end
69
+ end
70
+
71
+
@@ -0,0 +1,16 @@
1
+
2
+
3
+ module KML
4
+ class LabelStyle < ColorStyle
5
+
6
+ attr_accessor :scale
7
+
8
+ def render(xm=Builder::XmlMarkup.new(:indent => 2) )
9
+ xm.LabelStyle {
10
+ super
11
+ xm.scale(scale) unless scale.nil?
12
+ }
13
+ end
14
+ end
15
+ end
16
+
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adsb2kml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Herting 'qwertos'
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ruby_kml
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.1'
20
+ - - '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 0.1.7
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '0.1'
30
+ - - '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 0.1.7
33
+ description: A library to convert SBS1 messages to KML
34
+ email: aaron@herting.cc
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - LICENSE.MIT
40
+ - README.md
41
+ - lib/adsb2kml.rb
42
+ - lib/adsb2kml/airplane.rb
43
+ - lib/adsb2kml/database.rb
44
+ - lib/adsb2kml/listener.rb
45
+ - lib/ruby_kml/label_style.rb
46
+ homepage: https://github.com/qwertos/adsb2kml
47
+ licenses:
48
+ - MIT
49
+ metadata: {}
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubyforge_project:
66
+ rubygems_version: 2.2.2
67
+ signing_key:
68
+ specification_version: 4
69
+ summary: A library to convert SBS1 messages to KML
70
+ test_files: []