adsb2kml 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.MIT +21 -0
- data/README.md +47 -0
- data/lib/adsb2kml.rb +17 -0
- data/lib/adsb2kml/airplane.rb +89 -0
- data/lib/adsb2kml/database.rb +86 -0
- data/lib/adsb2kml/listener.rb +71 -0
- data/lib/ruby_kml/label_style.rb +16 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -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
|
data/LICENSE.MIT
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
+
|
data/lib/adsb2kml.rb
ADDED
@@ -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
|
+
|
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: []
|