├── README.md
├── images
├── putty1.png
├── putty2.png
├── wintask1.png
└── wintask2.png
├── sql
├── flights.sql
├── mlat_cleanup.sql
└── track_mlat_lookup.sql
├── webserver
├── ADSB.png
├── MLAT.png
├── Mode-S.png
├── config-example.php
├── destination.png
├── fasource.gif
├── flightimport.php
├── flights.php
├── functions.php
├── getTrackMlat.php
├── jquery.timeago.js
├── map.php
├── origin.png
├── search.php
└── style.css
└── windows
├── db_query.bat
├── db_query.vbs
└── dbquerycommands.txt
/README.md:
--------------------------------------------------------------------------------
1 | # VRS-flights-db
2 | Code to export Virtual Radar Server flight records and track logs to a MySQL database. This is the code used to power http://flights.hillhome.org.
3 | Also includes example pages written in PHP to display flight info.
4 |
5 | ##Prerequisites
6 | - VRS installed and running
7 | - VRS database writer plugin configured and enabled
8 | - A web server running PHP and MySQL. These instructions assume you will be using a Linux host, although you can use any OS.
9 | - PuTTY (including pageant and pscp) installed on your VRS machine
10 | - You will need to configure Pageant for key-based authentication to your web server using instructions such as http://johannesbrodwall.com/2011/06/15/howto-use-pageant-and-putty/
11 | - [phpMyAdmin](https://www.phpmyadmin.net) is very helpful for viewing your MySQL tables to ensure records are being populated correctly.
12 |
13 | ##Instructions
14 | Note: These instructions are not exhaustive. You will need to be handy with Windows, Linux, MySQL, etc. If you encounter issues, please log them here and I will update the documentation.
15 |
16 | ### Database schema
17 | You will need to create a database and two tables on your MySQL database host.
18 |
19 | ```
20 | mysql -u root
21 | $create database adsb;
22 | grant usage on *.* to vrsdbwriter@localhost identified by 'somepasswordhere';
23 | grant all privileges on adsb.* to vrsdbwriter@localhost;
24 | ```
25 |
26 | Now import the three .sql files in this repository:
27 | ```
28 | use adsb;
29 | source path/to/flights.sql
30 | source path/to/track_mlat_lookup.sql
31 | source path/to/mlat_cleanup.sql
32 | ```
33 |
34 | ###Install sqlite for Windows
35 | You will need to install the sqlite3.exe binary on your VRS host.
36 | - Grab the sqlite-tools-win32-x86 zip file from https://www.sqlite.org/download.html
37 | - Unzip and place sqlite3.exe in c:\sqlite
38 |
39 | ###Windows scripts
40 | Place the files from the windows directory of this repository in your c:\sqlite directory on the VRS host:
41 | - db_query.bat
42 | - db_query.vbs
43 | - dbquerycommands.txt
44 |
45 | Double check all the paths in these files, as your setup may differ.
46 |
47 | ###PHP scripts
48 | Place all the files from the webserver directory of this repository onto your web server in a flights directory under the web server's document root (example: /srv/www/htdocs/flights)
49 |
50 | You will need to edit the config-example.php file and fill in your database connection information and your VRS hostname and port, plus username and password if your setup is password protected. *Then rename the file to config.php.*
51 |
52 | Now login to your web server and edit the crontab as follows:
53 | ```
54 | crontab -e
55 | ```
56 | Enter the following line into the file - this will run the getTrackMlat.php file every minute.
57 | ```
58 | */1 * * * * /usr/bin/php /srv/www/htdocs/flights/getTrackMlat.php >/dev/null
59 | ```
60 | Save the file, and the new crontab will be installed. After a few minutes, you should observe rows being added to the track_mlat_lookup table in your database.
61 |
62 | ###PuTTY Setup on Windows
63 | First, configure Pageant for password-less authentication to your web server as discussed in the prereqs section.
64 | Next, create a PuTTY profile for your web server that will execute the flightimport.php file, as depicted in the following two images. Make sure you use the correct path to the php binary on your web server.
65 | 
66 | 
67 |
68 | Save the profile with the name flightimport.
69 |
70 | You will now need to use Windows Task Scheduler on your VRS host to run db_query.vbs every 5 minutes, as depicted in the following images.
71 |
72 | 
73 | 
74 |
75 | That should complete the setup. New flight records will be added to the flights table every 5 minutes, and the track log and MLAT flag will be merged in from the track_mlat_lookup table as part of the import process.
76 |
77 | ##Displaying Flight Data
78 | (Work in Progress)
79 |
80 | ###flights.php
81 | Displays a flight log with clickable links to the map page
82 |
83 | ###map.php
84 | Displays the route and full track log
85 | - Usage: http://webserver/flights/map.php?id=123456
86 | - Where 123456 is the flight's ID number from the database
87 |
88 | ###search.php
89 | Search the database based on flight/aircraft details
90 |
--------------------------------------------------------------------------------
/images/putty1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProHill/VRS-flights-db/e2967d226d0f2030bae8857e7a3c9853e39d53b0/images/putty1.png
--------------------------------------------------------------------------------
/images/putty2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProHill/VRS-flights-db/e2967d226d0f2030bae8857e7a3c9853e39d53b0/images/putty2.png
--------------------------------------------------------------------------------
/images/wintask1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProHill/VRS-flights-db/e2967d226d0f2030bae8857e7a3c9853e39d53b0/images/wintask1.png
--------------------------------------------------------------------------------
/images/wintask2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProHill/VRS-flights-db/e2967d226d0f2030bae8857e7a3c9853e39d53b0/images/wintask2.png
--------------------------------------------------------------------------------
/sql/flights.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS `flightstable` (
2 | `ID` int(11) NOT NULL,
3 | `ModeS` varchar(6) CHARACTER SET utf8 NOT NULL,
4 | `Country` varchar(24) CHARACTER SET utf8 DEFAULT NULL,
5 | `Registration` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
6 | `Operator` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
7 | `Callsign` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
8 | `ModelCode` varchar(10) CHARACTER SET utf8 DEFAULT NULL,
9 | `AircraftModel` varchar(40) CHARACTER SET utf8 DEFAULT NULL,
10 | `OperatorCode` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
11 | `FirstSeen` datetime NOT NULL,
12 | `FirstLatitude` double DEFAULT NULL,
13 | `FirstLongitude` double DEFAULT NULL,
14 | `FirstAltitude` int(11) DEFAULT NULL,
15 | `LastSeen` datetime NOT NULL,
16 | `LastLatitude` double DEFAULT NULL,
17 | `LastLongitude` double DEFAULT NULL,
18 | `LastAltitude` int(11) DEFAULT NULL,
19 | `NumPositionReports` int(11) DEFAULT NULL,
20 | `FromICAO` char(4) CHARACTER SET utf8 DEFAULT NULL,
21 | `FromIATA` char(3) CHARACTER SET utf8 DEFAULT NULL,
22 | `FromName` varchar(80) CHARACTER SET utf8 DEFAULT NULL,
23 | `FromLat` double DEFAULT NULL,
24 | `FromLong` double DEFAULT NULL,
25 | `FromLocation` varchar(80) CHARACTER SET utf8 DEFAULT NULL,
26 | `FromCountry` varchar(80) CHARACTER SET utf8 DEFAULT NULL,
27 | `ToICAO` char(4) CHARACTER SET utf8 DEFAULT NULL,
28 | `ToIATA` char(3) CHARACTER SET utf8 DEFAULT NULL,
29 | `ToName` varchar(80) CHARACTER SET utf8 DEFAULT NULL,
30 | `ToLat` double DEFAULT NULL,
31 | `ToLong` double DEFAULT NULL,
32 | `ToLocation` varchar(80) CHARACTER SET utf8 DEFAULT NULL,
33 | `ToCountry` varchar(80) CHARACTER SET utf8 DEFAULT NULL,
34 | `Interesting` tinyint(1) NOT NULL DEFAULT '0',
35 | `Mlat` tinyint(1) NOT NULL DEFAULT '0',
36 | `Track` varchar(60000) DEFAULT NULL,
37 | `Note` varchar(100) DEFAULT NULL
38 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
39 |
40 | --
41 | -- Indexes for dumped tables
42 | --
43 |
44 | --
45 | -- Indexes for table `flightsos`
46 | --
47 | ALTER TABLE `flightstable`
48 | ADD PRIMARY KEY (`ID`),
49 | ADD KEY `LastSeen` (`LastSeen`),
50 | ADD KEY `ModeS` (`ModeS`),
51 | ADD KEY `Registration` (`Registration`),
52 | ADD KEY `Operator` (`Operator`),
53 | ADD KEY `Callsign` (`Callsign`),
54 | ADD KEY `AircraftModel` (`AircraftModel`),
55 | ADD KEY `Interesting_Index` (`ModeS`,`Callsign`,`Interesting`,`LastSeen`) USING BTREE,
56 | ADD KEY `ModeS_LastSeen` (`ModeS`,`LastSeen`),
57 | ADD KEY `Interesting_ModeS` (`Interesting`,`ModeS`);
58 |
--------------------------------------------------------------------------------
/sql/mlat_cleanup.sql:
--------------------------------------------------------------------------------
1 | CREATE EVENT `Delete old MLAT lookup rows` ON SCHEDULE EVERY 1 HOUR STARTS NOW() ON COMPLETION PRESERVE ENABLE DO DELETE FROM `track_mlat_lookup` WHERE Timestamp < (NOW() - INTERVAL 24 HOUR);
2 |
--------------------------------------------------------------------------------
/sql/track_mlat_lookup.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS `track_mlat_lookup` (
2 | `Id` int(11) NOT NULL,
3 | `Icao` varchar(6) NOT NULL,
4 | `Callsign` varchar(20) DEFAULT NULL,
5 | `Registration` varchar(20) DEFAULT NULL,
6 | `Mlat` tinyint(1) NOT NULL,
7 | `Track` varchar(60000) DEFAULT NULL,
8 | `MultiTrack` tinyint(1) DEFAULT '0',
9 | `Timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
10 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
11 |
12 | --
13 | -- Indexes for dumped tables
14 | --
15 |
16 | --
17 | -- Indexes for table `mlat_lookupos`
18 | --
19 | ALTER TABLE `track_mlat_lookup`
20 | ADD PRIMARY KEY (`Id`),
21 | ADD KEY `Icao_Timestamp` (`Icao`,`Timestamp`);
--------------------------------------------------------------------------------
/webserver/ADSB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProHill/VRS-flights-db/e2967d226d0f2030bae8857e7a3c9853e39d53b0/webserver/ADSB.png
--------------------------------------------------------------------------------
/webserver/MLAT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProHill/VRS-flights-db/e2967d226d0f2030bae8857e7a3c9853e39d53b0/webserver/MLAT.png
--------------------------------------------------------------------------------
/webserver/Mode-S.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProHill/VRS-flights-db/e2967d226d0f2030bae8857e7a3c9853e39d53b0/webserver/Mode-S.png
--------------------------------------------------------------------------------
/webserver/config-example.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/webserver/destination.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProHill/VRS-flights-db/e2967d226d0f2030bae8857e7a3c9853e39d53b0/webserver/destination.png
--------------------------------------------------------------------------------
/webserver/fasource.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProHill/VRS-flights-db/e2967d226d0f2030bae8857e7a3c9853e39d53b0/webserver/fasource.gif
--------------------------------------------------------------------------------
/webserver/flightimport.php:
--------------------------------------------------------------------------------
1 | true,
15 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
16 | )
17 | );
18 | } catch (PDOException $e) {
19 | die("database connection failed: ".$e->getMessage());
20 | }
21 | $affectedRows = $pdo->exec("
22 | LOAD DATA LOCAL INFILE ".$pdo->quote($csvfile)." IGNORE INTO TABLE $flightsdatabasetable
23 | FIELDS TERMINATED BY ".$pdo->quote($fieldseparator)."
24 | ESCAPED BY ''
25 | LINES TERMINATED BY ".$pdo->quote($lineseparator));
26 |
27 | $date = date('m/d/Y h:i:s a');
28 | echo "Loaded a total of $affectedRows records from this csv file at $date\n";
29 |
30 | $stmt = "SELECT * FROM $flightsdatabasetable ORDER BY LastSeen DESC LIMIT " . $affectedRows;
31 |
32 | $conn = new mysqli($databasehost, $databaseusername, $databasepassword, $databasename);
33 |
34 | if ($conn->connect_error) {
35 | die("Connection failed: " . $conn->connect_error);
36 | }
37 |
38 | $result = $conn->query($stmt);
39 |
40 | //ob_start();
41 | if ($result->num_rows > 0) {
42 | while($row = $result->fetch_assoc()) {
43 | $ModeS = $row["ModeS"];
44 |
45 | // Check if the flight's positions are MLAT-derived
46 | // Also grab the flight's full track log, if there is one
47 | $mlat_stmt = 'SELECT Icao, Mlat, Track from ' . $lookup_table . ' WHERE Icao = "' . $ModeS . '" AND Timestamp >= NOW() - INTERVAL 2 HOUR ORDER BY Timestamp DESC LIMIT 1';
48 | $mlat_result = $conn->query($mlat_stmt);
49 | if ($mlat_result->num_rows > 0) {
50 | while ($mlat_row = $mlat_result->fetch_assoc()) {
51 |
52 | // Override MLAT flag to true if NumPositionReports is 0 but there is a track
53 | if (($row["NumPositionReports"] == 0) && (!empty($mlat_row["Track"]))) {
54 | $mlat_row["Mlat"] = 1;
55 | }
56 | // Add logic here to deal with multiple tracks in the Track field in the mlat_lookup table
57 | $Trackarray = explode('|', $mlat_row["Track"]);
58 | if (count($Trackarray) > 1) {
59 | $mlat_row["Track"] = str_replace("]|[", ",", $mlat_row["Track"]);
60 | }
61 | $mlat_update_stmt = 'UPDATE ' . $flightsdatabasetable . ' SET Mlat = ' . $mlat_row["Mlat"] . ', Track = "' . $mlat_row["Track"] . '" WHERE ModeS = "' . $mlat_row["Icao"] . '" AND LastSeen >= NOW() - INTERVAL 1 HOUR';
62 | $mlat_update_result = $conn->query($mlat_update_stmt);
63 | }
64 | }
65 | }
66 | }
67 | //ob_end_clean();
68 | $conn->close();
69 |
70 | ?>
--------------------------------------------------------------------------------
/webserver/flights.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |