Compare commits
No commits in common. "main" and "natural_earth_maps" have entirely different histories.
main
...
natural_ea
22
.gitignore
vendored
22
.gitignore
vendored
|
@ -6,24 +6,4 @@
|
|||
.~
|
||||
thumbs.db
|
||||
|
||||
*.shp
|
||||
*.shp*
|
||||
*.shx*
|
||||
*.shx
|
||||
*.geojson
|
||||
|
||||
*.cpg
|
||||
*.dbf
|
||||
*.zip*
|
||||
*.prj
|
||||
*.xml
|
||||
*.html
|
||||
*.txt
|
||||
|
||||
airportnames
|
||||
mapnames
|
||||
|
||||
|
||||
viz1090
|
||||
|
||||
result
|
||||
viz1090
|
48
Aircraft.cpp
48
Aircraft.cpp
|
@ -1,47 +1,23 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "Aircraft.h"
|
||||
#include "AircraftLabel.h"
|
||||
|
||||
Aircraft::Aircraft(uint32_t addr) {
|
||||
this->addr = addr;
|
||||
prev_seen = 0;
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
cx = 0;
|
||||
cy = 0;
|
||||
|
||||
ox = 0;
|
||||
oy = 0;
|
||||
dox = 0;
|
||||
doy = 0;
|
||||
ddox = 0;
|
||||
ddoy = 0;
|
||||
|
||||
lon = 0;
|
||||
lat = 0;
|
||||
|
||||
label = NULL;
|
||||
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
51
Aircraft.h
51
Aircraft.h
|
@ -1,48 +1,15 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
|
||||
class AircraftLabel;
|
||||
|
||||
class Aircraft {
|
||||
public:
|
||||
uint32_t addr; // ICAO address
|
||||
char flight[16]; // Flight number
|
||||
unsigned char signalLevel[8]; // Last 8 Signal Amplitudes
|
||||
float messageRate;
|
||||
double messageRate;
|
||||
int altitude; // Altitude
|
||||
int speed; // Velocity
|
||||
int track; // Angle of flight
|
||||
|
@ -50,16 +17,13 @@ public:
|
|||
time_t seen; // Time at which the last packet was received
|
||||
time_t seenLatLon; // Time at which the last packet was received
|
||||
time_t prev_seen;
|
||||
float lat, lon; // Coordinated obtained from CPR encoded data
|
||||
double lat, lon; // Coordinated obtained from CPR encoded data
|
||||
|
||||
//history
|
||||
|
||||
std::vector <float> lonHistory, latHistory, headingHistory;
|
||||
std::vector <std::chrono::high_resolution_clock::time_point> timestampHistory;
|
||||
|
||||
|
||||
AircraftLabel *label;
|
||||
|
||||
// float oldLon[TRAIL_LENGTH];
|
||||
// float oldLat[TRAIL_LENGTH];
|
||||
// float oldHeading[TRAIL_LENGTH];
|
||||
|
@ -74,12 +38,9 @@ public:
|
|||
|
||||
//// label stuff -> should go to aircraft icon class
|
||||
|
||||
// int x, y, cx, cy;
|
||||
int x, y;
|
||||
// float w, h, target_w, target_h;
|
||||
// float ox, oy, dox, doy, ddox, ddoy;
|
||||
// float labelLevel;
|
||||
// float opacity, target_opacity;
|
||||
int x, y, cx, cy, w, h;
|
||||
float ox, oy, dox, doy, ddox, ddoy;
|
||||
float pressure;
|
||||
|
||||
/// methods
|
||||
|
||||
|
|
|
@ -1,538 +0,0 @@
|
|||
#include "AircraftLabel.h"
|
||||
#include "Aircraft.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "SDL2/SDL2_gfxPrimitives.h"
|
||||
|
||||
using fmilliseconds = std::chrono::duration<float, std::milli>;
|
||||
|
||||
static std::chrono::high_resolution_clock::time_point now() {
|
||||
return std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
static float elapsed(std::chrono::high_resolution_clock::time_point ref) {
|
||||
return (fmilliseconds {now() - ref}).count();
|
||||
}
|
||||
|
||||
static float sign(float x) {
|
||||
return (x > 0) - (x < 0);
|
||||
}
|
||||
|
||||
SDL_Rect AircraftLabel::getFullRect(int labelLevel) {
|
||||
SDL_Rect rect = {static_cast<int>(x),static_cast<int>(y),0,0};
|
||||
|
||||
SDL_Rect currentRect;
|
||||
|
||||
if(labelLevel < 2) {
|
||||
currentRect = speedLabel.getRect();
|
||||
|
||||
rect.w = std::max(rect.w,currentRect.w);
|
||||
rect.h += currentRect.h;
|
||||
}
|
||||
|
||||
if(labelLevel < 1) {
|
||||
currentRect = altitudeLabel.getRect();
|
||||
|
||||
rect.w = std::max(rect.w,currentRect.w);
|
||||
rect.h += currentRect.h;
|
||||
|
||||
currentRect = speedLabel.getRect();
|
||||
|
||||
rect.w = std::max(rect.w,currentRect.w);
|
||||
rect.h += currentRect.h;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
void AircraftLabel::update() {
|
||||
char flight[17] = "";
|
||||
snprintf(flight,17," %s", p->flight);
|
||||
|
||||
|
||||
std::string flightString = flight;
|
||||
flightString.erase(std::remove_if(flightString.begin(), flightString.end(), isspace), flightString.end());
|
||||
|
||||
flightLabel.setText(flightString);
|
||||
|
||||
char alt[10] = "";
|
||||
if (metric) {
|
||||
snprintf(alt,10," %dm", static_cast<int>(p->altitude / 3.2828));
|
||||
} else {
|
||||
snprintf(alt,10," %d'", p->altitude);
|
||||
}
|
||||
|
||||
altitudeLabel.setText(alt);
|
||||
|
||||
char speed[10] = "";
|
||||
if (metric) {
|
||||
snprintf(speed,10," %dkm/h", static_cast<int>(p->speed * 1.852));
|
||||
} else {
|
||||
snprintf(speed,10," %dmph", p->speed);
|
||||
}
|
||||
|
||||
speedLabel.setText(speed);
|
||||
}
|
||||
|
||||
void AircraftLabel::clearAcceleration() {
|
||||
ddx = 0;
|
||||
ddy = 0;
|
||||
}
|
||||
|
||||
float AircraftLabel::calculateDensity(Aircraft *check_p, int labelLevel) {
|
||||
float density_max = 0;
|
||||
|
||||
while(check_p) {
|
||||
if(check_p->addr == p->addr) {
|
||||
check_p = check_p->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!check_p->label) {
|
||||
check_p = check_p->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(check_p->label->x + check_p->label->w < 0) {
|
||||
check_p = check_p->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(check_p->label->y + check_p->label->h < 0) {
|
||||
check_p = check_p->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(check_p->label->x > screen_width) {
|
||||
check_p = check_p->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(check_p->label->y > screen_height) {
|
||||
check_p = check_p->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
SDL_Rect currentRect = getFullRect(labelLevel);
|
||||
|
||||
float width_proportion = (currentRect.w + check_p->label->w) / fabs(x - check_p->label->x);
|
||||
float height_proportion = (currentRect.h + check_p->label->h) / fabs(y - check_p->label->y);
|
||||
|
||||
float density = width_proportion * height_proportion;
|
||||
|
||||
if(density > density_max) {
|
||||
density_max = density;
|
||||
}
|
||||
|
||||
check_p = check_p -> next;
|
||||
}
|
||||
|
||||
return density_max;
|
||||
}
|
||||
|
||||
void AircraftLabel::calculateForces(Aircraft *check_p) {
|
||||
if(w == 0 || h == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Aircraft *head = check_p;
|
||||
|
||||
int p_left = x;
|
||||
int p_right = x + w;
|
||||
int p_top = y;
|
||||
int p_bottom = y + h;
|
||||
|
||||
|
||||
float boxmid_x = static_cast<float>(p_left + p_right) / 2.0f;
|
||||
float boxmid_y = static_cast<float>(p_top + p_bottom) / 2.0f;
|
||||
|
||||
float offset_x = boxmid_x - p->x;
|
||||
float offset_y = boxmid_y - p->y;
|
||||
|
||||
float target_length_x = attachment_dist + w / 2.0f;
|
||||
float target_length_y = attachment_dist + h / 2.0f;
|
||||
|
||||
// stay icon_dist away from own icon
|
||||
|
||||
ddx -= sign(offset_x) * attachment_force * (fabs(offset_x) - target_length_x);
|
||||
ddy -= sign(offset_y) * attachment_force * (fabs(offset_y) - target_length_y);
|
||||
|
||||
|
||||
// screen edge
|
||||
|
||||
if(p_left < edge_margin) {
|
||||
ddx += boundary_force * static_cast<float>(edge_margin - p_left);
|
||||
}
|
||||
|
||||
if(p_right > screen_width - edge_margin) {
|
||||
ddx += boundary_force * static_cast<float>(screen_width - edge_margin - p_right);
|
||||
}
|
||||
|
||||
if(p_top < edge_margin) {
|
||||
ddy += boundary_force * static_cast<float>(edge_margin - p_top);
|
||||
}
|
||||
|
||||
if(p_bottom > screen_height - edge_margin) {
|
||||
ddy += boundary_force * static_cast<float>(screen_height - edge_margin - p_bottom);
|
||||
}
|
||||
|
||||
|
||||
float all_x = 0;
|
||||
float all_y = 0;
|
||||
int count = 0;
|
||||
//check against other labels
|
||||
|
||||
while(check_p) {
|
||||
if(check_p->addr == p->addr) {
|
||||
check_p = check_p->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!check_p->label) {
|
||||
check_p = check_p->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
int check_left = check_p->label->x;
|
||||
int check_right = check_p->label->x + check_p->label->w;
|
||||
int check_top = check_p->label->y;
|
||||
int check_bottom = check_p->label->y + check_p->label->h;
|
||||
|
||||
float icon_x = static_cast<float>(check_p->x);
|
||||
float icon_y = static_cast<float>(check_p->y);
|
||||
|
||||
float checkboxmid_x = static_cast<float>(check_left + check_right) / 2.0f;
|
||||
float checkboxmid_y = static_cast<float>(check_top + check_bottom) / 2.0f;
|
||||
|
||||
float offset_x = boxmid_x - checkboxmid_x;
|
||||
float offset_y = boxmid_y - checkboxmid_y;
|
||||
|
||||
float target_length_x = label_dist + static_cast<float>(check_p->label->w + w) / 2.0f;
|
||||
float target_length_y = label_dist + static_cast<float>(check_p->label->h + h) / 2.0f;
|
||||
|
||||
float x_mag = std::max(0.0f,(target_length_x - fabs(offset_x)));
|
||||
float y_mag = std::max(0.0f,(target_length_y - fabs(offset_y)));
|
||||
|
||||
// stay at least label_dist away from other icons
|
||||
|
||||
if(x_mag > 0 && y_mag > 0) {
|
||||
ddx += sign(offset_x) * label_force * x_mag;
|
||||
ddy += sign(offset_y) * label_force * y_mag;
|
||||
}
|
||||
|
||||
// stay at least icon_dist away from other icons
|
||||
|
||||
offset_x = boxmid_x - check_p->x;
|
||||
offset_y = boxmid_y - check_p->y;
|
||||
|
||||
target_length_x = icon_dist + static_cast<float>(check_p->label->w) / 2.0f;
|
||||
target_length_y = icon_dist + static_cast<float>(check_p->label->h) / 2.0f;
|
||||
|
||||
x_mag = std::max(0.0f,(target_length_x - fabs(offset_x)));
|
||||
y_mag = std::max(0.0f,(target_length_y - fabs(offset_y)));
|
||||
|
||||
if(x_mag > 0 && y_mag > 0) {
|
||||
ddx += sign(offset_x) * icon_force * x_mag;
|
||||
ddy += sign(offset_y) * icon_force * y_mag;
|
||||
}
|
||||
|
||||
all_x += sign(boxmid_x - checkboxmid_x);
|
||||
all_y += sign(boxmid_y - checkboxmid_y);
|
||||
|
||||
count++;
|
||||
|
||||
check_p = check_p -> next;
|
||||
}
|
||||
|
||||
// move away from others
|
||||
ddx += density_force * all_x / count;
|
||||
ddy += density_force * all_y / count;
|
||||
|
||||
// char buff[100];
|
||||
// snprintf(buff, sizeof(buff), "%2.2f", labelLevel);
|
||||
// debugLabel.setText(buff);
|
||||
|
||||
float density_mult = 0.5f;
|
||||
float level_rate = 0.25f;
|
||||
|
||||
if(elapsed(lastLevelChange) > 1000.0) {
|
||||
if(labelLevel < 0.8f * density_mult * calculateDensity(head, labelLevel + 1)) {
|
||||
if(labelLevel <= 2) {
|
||||
labelLevel += level_rate;
|
||||
lastLevelChange = now();
|
||||
}
|
||||
} else if (labelLevel > 1.2f * density_mult * calculateDensity(head, labelLevel - 1)) {
|
||||
if(labelLevel >= 0) {
|
||||
labelLevel -= level_rate;
|
||||
lastLevelChange = now();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AircraftLabel::applyForces() {
|
||||
dx += ddx;
|
||||
dy += ddy;
|
||||
|
||||
dx *= damping_force;
|
||||
dy *= damping_force;
|
||||
|
||||
if(fabs(dx) > velocity_limit) {
|
||||
dx = sign(dx) * velocity_limit;
|
||||
}
|
||||
|
||||
if(fabs(dy) > velocity_limit) {
|
||||
dy = sign(dy) * velocity_limit;
|
||||
}
|
||||
|
||||
if(fabs(dx) < 0.01f) {
|
||||
dx = 0;
|
||||
}
|
||||
|
||||
if(fabs(dy) < 0.01f) {
|
||||
dy = 0;
|
||||
}
|
||||
|
||||
x += dx;
|
||||
y += dy;
|
||||
|
||||
if(isnan(x)) {
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if(isnan(y)) {
|
||||
y = 0;
|
||||
}
|
||||
|
||||
// x = p->cx + (int)round(p->ox);
|
||||
// y = p->cy + (int)round(p->oy);
|
||||
}
|
||||
|
||||
// SDL_Color signalToColor(int signal) {
|
||||
// SDL_Color planeColor;
|
||||
|
||||
// if(signal > 127) {
|
||||
// signal = 127;
|
||||
// }
|
||||
|
||||
// if(signal < 0) {
|
||||
// planeColor = setColor(96, 96, 96);
|
||||
// } else {
|
||||
// planeColor = setColor(parula[signal][0], parula[signal][1], parula[signal][2]);
|
||||
// }
|
||||
|
||||
// return planeColor;
|
||||
// }
|
||||
// void View::drawSignalMarks(Aircraft *p, int x, int y) {
|
||||
// unsigned char * pSig = p->signalLevel;
|
||||
// unsigned int signalAverage = (pSig[0] + pSig[1] + pSig[2] + pSig[3] +
|
||||
// pSig[4] + pSig[5] + pSig[6] + pSig[7] + 3) >> 3;
|
||||
|
||||
// SDL_Color barColor = signalToColor(signalAverage);
|
||||
|
||||
// Uint8 seenFade;
|
||||
|
||||
// if(elapsed(p->msSeen) < 1024) {
|
||||
// seenFade = (Uint8) (255.0 - elapsed(p->msSeen) / 4.0);
|
||||
|
||||
// circleRGBA(renderer, x + mapFontWidth, y - 5, 2 * screen_uiscale, barColor.r, barColor.g, barColor.b, seenFade);
|
||||
// }
|
||||
|
||||
// if(elapsed(p->msSeenLatLon) < 1024) {
|
||||
// seenFade = (Uint8) (255.0 - elapsed(p->msSeenLatLon) / 4.0);
|
||||
|
||||
// hlineRGBA(renderer, x + mapFontWidth + 5 * screen_uiscale, x + mapFontWidth + 9 * screen_uiscale, y - 5, barColor.r, barColor.g, barColor.b, seenFade);
|
||||
// vlineRGBA(renderer, x + mapFontWidth + 7 * screen_uiscale, y - 2 * screen_uiscale - 5, y + 2 * screen_uiscale - 5, barColor.r, barColor.g, barColor.b, seenFade);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) {
|
||||
if(x == 0 || y == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// char buff[100];
|
||||
// snprintf(buff, sizeof(buff), "%f %f", x, y);
|
||||
// debugLabel.setText(buff);
|
||||
|
||||
int totalWidth = 0;
|
||||
int totalHeight = 0;
|
||||
|
||||
// int margin = 4 * screen_uiscale;
|
||||
|
||||
int margin = 4;
|
||||
|
||||
SDL_Rect outRect;
|
||||
|
||||
if(opacity == 0 && labelLevel < 2) {
|
||||
target_opacity = 1.0f;
|
||||
}
|
||||
|
||||
if(opacity > 0 && labelLevel >= 2) {
|
||||
target_opacity = 0.0f;
|
||||
}
|
||||
|
||||
opacity += 0.25f * (target_opacity - opacity);
|
||||
|
||||
if(opacity < 0.05f) {
|
||||
opacity = 0;
|
||||
}
|
||||
|
||||
if(w != 0 && h != 0 && opacity > 0) {
|
||||
|
||||
SDL_Color drawColor = style.labelLineColor;
|
||||
|
||||
drawColor.a = static_cast<int>(255.0f * opacity);
|
||||
|
||||
if(selected) {
|
||||
drawColor = style.selectedColor;
|
||||
}
|
||||
|
||||
int tick = 4;
|
||||
|
||||
int anchor_x, anchor_y, exit_x, exit_y;
|
||||
|
||||
if(x + w / 2 > p->x) {
|
||||
anchor_x = x;
|
||||
} else {
|
||||
anchor_x = x + w;
|
||||
}
|
||||
|
||||
if(y + h / 2 > p->y) {
|
||||
anchor_y = y - margin;
|
||||
} else {
|
||||
anchor_y = y + h + margin;
|
||||
}
|
||||
|
||||
if(abs(anchor_x - p->x) > abs(anchor_y - p->y)) {
|
||||
exit_x = (anchor_x + p->x) / 2;
|
||||
exit_y = anchor_y;
|
||||
} else {
|
||||
exit_x = anchor_x;
|
||||
exit_y = (anchor_y + p->y) / 2;
|
||||
}
|
||||
|
||||
Sint16 vx[3] = {
|
||||
static_cast<Sint16>(p->x),
|
||||
static_cast<Sint16>(exit_x),
|
||||
static_cast<Sint16>(anchor_x)};
|
||||
|
||||
Sint16 vy[3] = {
|
||||
static_cast<Sint16>(p->y),
|
||||
static_cast<Sint16>(exit_y),
|
||||
static_cast<Sint16>(anchor_y)};
|
||||
|
||||
boxRGBA(renderer, x, y, x + w, y + h, style.labelBackground.r, style.labelBackground.g, style.labelBackground.b, drawColor.a);
|
||||
|
||||
// char buff[100];
|
||||
// snprintf(buff, sizeof(buff), "%d", drawColor.a);
|
||||
// debugLabel.setText(buff);
|
||||
|
||||
bezierRGBA(renderer, vx, vy, 3, 2, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
|
||||
//lineRGBA(renderer, x,y - margin, x + tick, y - margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
lineRGBA(renderer, x,y - margin, x + w, y - margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
lineRGBA(renderer, x,y - margin, x, y - margin + tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
|
||||
// lineRGBA(renderer, x + w, y - margin, x + w - tick, y - margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
lineRGBA(renderer, x + w, y - margin, x + w, y - margin + tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
|
||||
//lineRGBA(renderer, x, y + h + margin, x + tick, y + h + margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
lineRGBA(renderer, x, y + h + margin, x + w, y + h + margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
lineRGBA(renderer, x, y + h + margin, x, y + h + margin - tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
|
||||
// lineRGBA(renderer, x + w, y + h + margin,x + w - tick, y + h + margin, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
lineRGBA(renderer, x + w, y + h + margin,x + w, y + h + margin - tick, drawColor.r, drawColor.g, drawColor.b, drawColor.a);
|
||||
}
|
||||
|
||||
if(labelLevel < 2 || selected) {
|
||||
// drawSignalMarks(p, x, y);
|
||||
|
||||
SDL_Color drawColor = style.labelColor;
|
||||
drawColor.a = static_cast<int>(255.0f * opacity);
|
||||
|
||||
flightLabel.setColor(drawColor);
|
||||
flightLabel.setPosition(x,y);
|
||||
flightLabel.draw(renderer);
|
||||
// outRect = drawString(flight, x, y, mapBoldFont, drawColor);
|
||||
outRect = flightLabel.getRect();
|
||||
|
||||
totalWidth = std::max(totalWidth,outRect.w);
|
||||
totalHeight += outRect.h;
|
||||
|
||||
}
|
||||
|
||||
if(labelLevel < 1 || selected) {
|
||||
SDL_Color drawColor = style.subLabelColor;
|
||||
drawColor.a = static_cast<int>(255.0f * opacity);
|
||||
|
||||
altitudeLabel.setColor(drawColor);
|
||||
altitudeLabel.setPosition(x,y + totalHeight);
|
||||
altitudeLabel.draw(renderer);
|
||||
outRect = altitudeLabel.getRect();
|
||||
|
||||
totalWidth = std::max(totalWidth,outRect.w);
|
||||
totalHeight += outRect.h;
|
||||
|
||||
speedLabel.setColor(drawColor);
|
||||
speedLabel.setPosition(x,y + totalHeight);
|
||||
speedLabel.draw(renderer);
|
||||
outRect = speedLabel.getRect();
|
||||
|
||||
totalWidth = std::max(totalWidth,outRect.w);
|
||||
totalHeight += outRect.h;
|
||||
|
||||
}
|
||||
|
||||
debugLabel.setPosition(x,y + totalHeight);
|
||||
debugLabel.draw(renderer);
|
||||
|
||||
target_w = totalWidth;
|
||||
target_h = totalHeight;
|
||||
|
||||
w += 0.25f * (target_w - w);
|
||||
h += 0.25f * (target_h - h);
|
||||
|
||||
if(w < 0.05f) {
|
||||
w = 0;
|
||||
}
|
||||
|
||||
if(h < 0.05f) {
|
||||
h = 0;
|
||||
}
|
||||
}
|
||||
|
||||
AircraftLabel::AircraftLabel(Aircraft *p, bool metric, int screen_width, int screen_height, TTF_Font *font) {
|
||||
this->p = p;
|
||||
|
||||
this->metric = metric;
|
||||
|
||||
x = p->x;
|
||||
y = p->y + 20; //*screen_uiscale
|
||||
w = 0;
|
||||
h = 0;
|
||||
target_w = 0;
|
||||
target_h = 0;
|
||||
|
||||
opacity = 0;
|
||||
target_opacity = 0;
|
||||
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
ddx = 0;
|
||||
ddy = 0;
|
||||
|
||||
this->screen_width = screen_width;
|
||||
this->screen_height = screen_height;
|
||||
|
||||
labelLevel = 0;
|
||||
|
||||
flightLabel.setFont(font);
|
||||
altitudeLabel.setFont(font);
|
||||
speedLabel.setFont(font);
|
||||
debugLabel.setFont(font);
|
||||
|
||||
lastLevelChange = now();
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
|
||||
#include <string>
|
||||
#include "SDL2/SDL_ttf.h"
|
||||
#include <chrono>
|
||||
|
||||
#include "Label.h"
|
||||
#include "Style.h"
|
||||
|
||||
class Aircraft;
|
||||
|
||||
|
||||
class AircraftLabel {
|
||||
public:
|
||||
void update();
|
||||
void clearAcceleration();
|
||||
void calculateForces(Aircraft *check_p);
|
||||
void applyForces();
|
||||
|
||||
void draw(SDL_Renderer *renderer, bool selected);
|
||||
|
||||
AircraftLabel(Aircraft *p, bool metric, int screen_width, int screen_height, TTF_Font *font);
|
||||
|
||||
private:
|
||||
SDL_Rect getFullRect(int labelLevel);
|
||||
float calculateDensity(Aircraft *check_p, int labelLevel);
|
||||
|
||||
Aircraft *p;
|
||||
|
||||
Label flightLabel;
|
||||
Label altitudeLabel;
|
||||
Label speedLabel;
|
||||
Label debugLabel;
|
||||
|
||||
float labelLevel;
|
||||
|
||||
bool metric;
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float w;
|
||||
float h;
|
||||
|
||||
float target_w;
|
||||
float target_h;
|
||||
|
||||
float dx;
|
||||
float dy;
|
||||
float ddx;
|
||||
float ddy;
|
||||
|
||||
float opacity;
|
||||
float target_opacity;
|
||||
|
||||
float pressure;
|
||||
|
||||
int screen_width;
|
||||
int screen_height;
|
||||
|
||||
std::chrono::high_resolution_clock::time_point lastLevelChange;
|
||||
|
||||
///////////
|
||||
|
||||
float label_force = 0.001f;
|
||||
float label_dist = 2.0f;
|
||||
float density_force = 0.05f;
|
||||
float attachment_force = 0.0015f;
|
||||
float attachment_dist = 10.0f;
|
||||
float icon_force = 0.001f;
|
||||
float icon_dist = 15.0f;
|
||||
float boundary_force = 0.01f;
|
||||
float damping_force = 0.85f;
|
||||
float velocity_limit = 2.0f;
|
||||
float edge_margin = 15.0f;
|
||||
|
||||
Style style;
|
||||
};
|
|
@ -1,34 +1,3 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "AircraftList.h"
|
||||
|
||||
static std::chrono::high_resolution_clock::time_point now() {
|
||||
|
@ -53,14 +22,10 @@ void AircraftList::update(Modes *modes) {
|
|||
Aircraft *p = head;
|
||||
|
||||
while(p) {
|
||||
p->live = 0;
|
||||
p->live = 0;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
//debug
|
||||
//find(1)->live = 1;
|
||||
|
||||
|
||||
while(a) {
|
||||
|
||||
p = find(a->addr);
|
||||
|
@ -108,12 +73,6 @@ void AircraftList::update(Modes *modes) {
|
|||
if(p->lon == 0) {
|
||||
p->created = now();
|
||||
}
|
||||
|
||||
if(p->lon == a->lon && p->lat == a->lat) {
|
||||
a = a->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
p->lon = a->lon;
|
||||
p->lat = a->lat;
|
||||
|
||||
|
@ -148,10 +107,6 @@ void AircraftList::update(Modes *modes) {
|
|||
|
||||
AircraftList::AircraftList() {
|
||||
head = nullptr;
|
||||
|
||||
// //debug aircraft attached to mouse
|
||||
// head = new Aircraft(1);
|
||||
// memcpy(head->flight, "mouse", sizeof("mouse"));
|
||||
}
|
||||
|
||||
AircraftList::~AircraftList() {
|
||||
|
|
|
@ -1,34 +1,3 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "Aircraft.h"
|
||||
|
||||
#include "dump1090.h" //for Modes
|
||||
|
|
57
AppData.cpp
57
AppData.cpp
|
@ -1,34 +1,3 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "AppData.h"
|
||||
|
||||
//
|
||||
|
@ -62,20 +31,16 @@ void AppData::initialize() {
|
|||
|
||||
|
||||
void AppData::connect() {
|
||||
|
||||
if(connected) {
|
||||
return;
|
||||
c = (struct client *) malloc(sizeof(*c));
|
||||
while(1) {
|
||||
if ((fd = setupConnection(c)) == ANET_ERR) {
|
||||
fprintf(stderr, "Waiting on %s:%d\n", server, modes.net_input_beast_port);
|
||||
sleep(1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
c = (struct client *) malloc(sizeof(*c));
|
||||
|
||||
if ((fd = setupConnection(c)) == ANET_ERR) {
|
||||
fprintf(stderr, "Waiting on %s:%d\n", server, modes.net_input_beast_port);
|
||||
return;
|
||||
}
|
||||
|
||||
connected = true;
|
||||
fprintf(stderr, "Connected to %s:%d\n", server, modes.net_input_beast_port);
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,10 +51,6 @@ void AppData::disconnect() {
|
|||
|
||||
|
||||
void AppData::update() {
|
||||
if(!connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fd == ANET_ERR) || (recv(c->fd, pk_buf, sizeof(pk_buf), MSG_PEEK | MSG_DONTWAIT) == 0)) {
|
||||
free(c);
|
||||
usleep(1000000);
|
||||
|
@ -162,6 +123,4 @@ AppData::AppData(){
|
|||
|
||||
modes.interactive = 0;
|
||||
modes.quiet = 1;
|
||||
|
||||
connected = false;
|
||||
}
|
||||
|
|
32
AppData.h
32
AppData.h
|
@ -1,34 +1,3 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef APPDATA_H
|
||||
#define APPDATA_H
|
||||
|
||||
|
@ -45,7 +14,6 @@ class AppData {
|
|||
//
|
||||
|
||||
struct client *c;
|
||||
bool connected;
|
||||
int fd;
|
||||
char pk_buf[8];
|
||||
|
||||
|
|
31
Input.cpp
31
Input.cpp
|
@ -1,34 +1,3 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "Input.h"
|
||||
|
||||
static std::chrono::high_resolution_clock::time_point now() {
|
||||
|
|
31
Input.h
31
Input.h
|
@ -1,34 +1,3 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
|
|
70
Label.cpp
70
Label.cpp
|
@ -1,70 +0,0 @@
|
|||
#include "Label.h"
|
||||
#include <string>
|
||||
|
||||
void Label::draw(SDL_Renderer *renderer) {
|
||||
SDL_Rect rect = getRect();
|
||||
|
||||
if(rect.h == 0 || rect.w == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
SDL_RenderCopy(renderer, texture, NULL, &rect);
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
|
||||
void Label::makeSurface() {
|
||||
if(surface != NULL) {
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
|
||||
surface = TTF_RenderUTF8_Solid(font, text.c_str(), color);
|
||||
}
|
||||
|
||||
SDL_Rect Label::getRect() {
|
||||
SDL_Rect rect = {0,0,0,0};
|
||||
|
||||
if(!text.length()) {
|
||||
return rect;
|
||||
}
|
||||
|
||||
if(surface == NULL) {
|
||||
return rect;
|
||||
}
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.w = surface->w;
|
||||
rect.h = surface->h;
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
void Label::setText(std::string text) {
|
||||
this->text = text;
|
||||
makeSurface();
|
||||
}
|
||||
|
||||
void Label::setPosition(int x, int y) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
void Label::setFont(TTF_Font *font) {
|
||||
this->font = font;
|
||||
}
|
||||
|
||||
void Label::setColor(SDL_Color color) {
|
||||
this->color = color;
|
||||
}
|
||||
//
|
||||
Label::Label() {
|
||||
this->color = {255,255,255,255};
|
||||
surface = NULL;
|
||||
}
|
||||
|
||||
Label::~Label() {
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
|
||||
|
29
Label.h
29
Label.h
|
@ -1,29 +0,0 @@
|
|||
|
||||
#include "SDL2/SDL.h"
|
||||
#include "SDL2/SDL_ttf.h"
|
||||
#include <string>
|
||||
|
||||
class Label {
|
||||
public:
|
||||
void draw(SDL_Renderer *renderer);
|
||||
|
||||
void setText(std::string text);
|
||||
void setPosition(int x, int y);
|
||||
void setFont(TTF_Font *font);
|
||||
void setColor(SDL_Color color);
|
||||
|
||||
SDL_Rect getRect();
|
||||
|
||||
Label();
|
||||
~Label();
|
||||
|
||||
private:
|
||||
void makeSurface();
|
||||
|
||||
std::string text;
|
||||
int x;
|
||||
int y;
|
||||
TTF_Font *font;
|
||||
SDL_Color color;
|
||||
SDL_Surface *surface;
|
||||
};
|
17
Makefile
17
Makefile
|
@ -3,8 +3,8 @@
|
|||
# sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local
|
||||
#
|
||||
|
||||
CXXFLAGS=-O2 -std=c++11 -g
|
||||
LIBS= -lm -lSDL2 -lSDL2_ttf -lSDL2_gfx -g
|
||||
CXXFLAGS=-O2 -std=c++11
|
||||
LIBS= -lm -lSDL2 -lSDL2_ttf -lSDL2_gfx
|
||||
CXX=g++
|
||||
|
||||
all: viz1090
|
||||
|
@ -12,15 +12,8 @@ all: viz1090
|
|||
%.o: %.c %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(EXTRACFLAGS) -c $<
|
||||
|
||||
viz1090: viz1090.o AppData.o AircraftList.o Aircraft.o Label.o AircraftLabel.o anet.o interactive.o mode_ac.o mode_s.o net_io.o Input.o View.o Map.o parula.o monokai.o
|
||||
$(CXX) -o viz1090 viz1090.o AppData.o AircraftList.o Aircraft.o Label.o AircraftLabel.o anet.o interactive.o mode_ac.o mode_s.o net_io.o Input.o View.o Map.o parula.o monokai.o $(LIBS) $(LDFLAGS)
|
||||
viz1090: viz1090.o AppData.o AircraftList.o Aircraft.o anet.o interactive.o mode_ac.o mode_s.o net_io.o Input.o View.o Map.o parula.o monokai.o
|
||||
$(CXX) -o viz1090 viz1090.o AppData.o AircraftList.o Aircraft.o anet.o interactive.o mode_ac.o mode_s.o net_io.o Input.o View.o Map.o parula.o monokai.o $(LIBS) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f \
|
||||
airportdata.bin \
|
||||
airportnames \
|
||||
mapdata/* \
|
||||
mapdata.bin \
|
||||
mapnames \
|
||||
*.o \
|
||||
viz1090
|
||||
rm -f *.o viz1090
|
||||
|
|
260
Map.cpp
260
Map.cpp
|
@ -1,41 +1,6 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "Map.h"
|
||||
#include <stdio.h>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
bool Map::QTInsert(QuadTree *tree, Line *line, int depth) {
|
||||
|
||||
|
@ -189,197 +154,68 @@ std::vector<Line*> Map::getLines(float screen_lat_min, float screen_lat_max, flo
|
|||
Map::Map() {
|
||||
FILE *fileptr;
|
||||
|
||||
if((fileptr = fopen("mapdata.bin", "rb"))) {
|
||||
|
||||
if(!(fileptr = fopen("mapdata.bin", "rb"))) {
|
||||
printf("Couldn't read mapdata.bin\nDid you run getmap.sh?\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fseek(fileptr, 0, SEEK_END);
|
||||
mapPoints_count = ftell(fileptr) / sizeof(float);
|
||||
rewind(fileptr);
|
||||
fseek(fileptr, 0, SEEK_END);
|
||||
mapPoints_count = ftell(fileptr) / sizeof(float);
|
||||
rewind(fileptr);
|
||||
|
||||
mapPoints = (float *)malloc(mapPoints_count * sizeof(float));
|
||||
if(!fread(mapPoints, sizeof(float), mapPoints_count, fileptr)){
|
||||
printf("Map read error\n");
|
||||
exit(0);
|
||||
}
|
||||
mapPoints = (float *)malloc(mapPoints_count * sizeof(float));
|
||||
if(!fread(mapPoints, sizeof(float), mapPoints_count, fileptr)){
|
||||
printf("Read error\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fclose(fileptr);
|
||||
fclose(fileptr);
|
||||
|
||||
printf("Read %d map points.\n",mapPoints_count / 2);
|
||||
printf("Read %d map points.\n",mapPoints_count / 2);
|
||||
|
||||
// load quad tree
|
||||
// load quad tree
|
||||
|
||||
for(int i = 0; i < mapPoints_count; i+=2) {
|
||||
if(mapPoints[i] == 0)
|
||||
continue;
|
||||
for(int i = 0; i < mapPoints_count; i+=2) {
|
||||
if(mapPoints[i] == 0)
|
||||
continue;
|
||||
|
||||
if(mapPoints[i] < root.lon_min) {
|
||||
root.lon_min = mapPoints[i];
|
||||
} else if(mapPoints[i] > root.lon_max) {
|
||||
root.lon_max = mapPoints[i];
|
||||
}
|
||||
if(mapPoints[i] < root.lon_min) {
|
||||
root.lon_min = mapPoints[i];
|
||||
} else if(mapPoints[i] > root.lon_max) {
|
||||
root.lon_max = mapPoints[i];
|
||||
}
|
||||
|
||||
if(mapPoints[i+1] < root.lat_min) {
|
||||
root.lat_min = mapPoints[i+1];
|
||||
} else if(mapPoints[i+1] > root.lat_max) {
|
||||
root.lat_max = mapPoints[i+1];
|
||||
}
|
||||
}
|
||||
if(mapPoints[i+1] < root.lat_min) {
|
||||
root.lat_min = mapPoints[i+1];
|
||||
} else if(mapPoints[i+1] > root.lat_max) {
|
||||
root.lat_max = mapPoints[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
//printf("map bounds: %f %f %f %f\n",root.lon_min, root.lon_max, root.lat_min, root.lat_max);
|
||||
printf("map bounds: %f %f %f %f\n",root.lon_min, root.lon_max, root.lat_min, root.lat_max);
|
||||
|
||||
Point currentPoint;
|
||||
Point nextPoint;
|
||||
Point currentPoint;
|
||||
Point nextPoint;
|
||||
|
||||
for(int i = 0; i < mapPoints_count - 2; i+=2) {
|
||||
if(mapPoints[i] == 0)
|
||||
continue;
|
||||
if(mapPoints[i + 1] == 0)
|
||||
continue;
|
||||
if(mapPoints[i + 2] == 0)
|
||||
continue;
|
||||
if(mapPoints[i + 3] == 0)
|
||||
continue;
|
||||
currentPoint.lon = mapPoints[i];
|
||||
currentPoint.lat = mapPoints[i + 1];
|
||||
for(int i = 0; i < mapPoints_count - 2; i+=2) {
|
||||
if(mapPoints[i] == 0)
|
||||
continue;
|
||||
if(mapPoints[i + 1] == 0)
|
||||
continue;
|
||||
if(mapPoints[i + 2] == 0)
|
||||
continue;
|
||||
if(mapPoints[i + 3] == 0)
|
||||
continue;
|
||||
currentPoint.lon = mapPoints[i];
|
||||
currentPoint.lat = mapPoints[i + 1];
|
||||
|
||||
nextPoint.lon = mapPoints[i + 2];
|
||||
nextPoint.lat = mapPoints[i + 3];
|
||||
|
||||
// printf("inserting [%f %f] -> [%f %f]\n",currentPoint.lon,currentPoint.lat,nextPoint.lon,nextPoint.lat);
|
||||
|
||||
QTInsert(&root, new Line(currentPoint, nextPoint), 0);
|
||||
}
|
||||
} else {
|
||||
printf("No map file found\n");
|
||||
}
|
||||
//
|
||||
|
||||
|
||||
if((fileptr = fopen("airportdata.bin", "rb"))) {
|
||||
fseek(fileptr, 0, SEEK_END);
|
||||
airportPoints_count = ftell(fileptr) / sizeof(float);
|
||||
rewind(fileptr);
|
||||
|
||||
airportPoints = (float *)malloc(airportPoints_count * sizeof(float));
|
||||
if(!fread(airportPoints, sizeof(float), airportPoints_count, fileptr)){
|
||||
printf("Map read error\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fclose(fileptr);
|
||||
|
||||
printf("Read %d airport points.\n",airportPoints_count / 2);
|
||||
|
||||
// load quad tree
|
||||
|
||||
for(int i = 0; i < airportPoints_count; i+=2) {
|
||||
if(airportPoints[i] == 0)
|
||||
continue;
|
||||
|
||||
if(airportPoints[i] < airport_root.lon_min) {
|
||||
airport_root.lon_min = airportPoints[i];
|
||||
} else if(airportPoints[i] > airport_root.lon_max) {
|
||||
airport_root.lon_max = airportPoints[i];
|
||||
}
|
||||
|
||||
if(airportPoints[i+1] < airport_root.lat_min) {
|
||||
airport_root.lat_min = airportPoints[i+1];
|
||||
} else if(airportPoints[i+1] > airport_root.lat_max) {
|
||||
airport_root.lat_max = airportPoints[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
//printf("map bounds: %f %f %f %f\n",root.lon_min, root.lon_max, root.lat_min, root.lat_max);
|
||||
|
||||
Point currentPoint;
|
||||
Point nextPoint;
|
||||
|
||||
for(int i = 0; i < airportPoints_count - 2; i+=2) {
|
||||
if(airportPoints[i] == 0)
|
||||
continue;
|
||||
if(airportPoints[i + 1] == 0)
|
||||
continue;
|
||||
if(airportPoints[i + 2] == 0)
|
||||
continue;
|
||||
if(airportPoints[i + 3] == 0)
|
||||
continue;
|
||||
currentPoint.lon = airportPoints[i];
|
||||
currentPoint.lat = airportPoints[i + 1];
|
||||
|
||||
nextPoint.lon = airportPoints[i + 2];
|
||||
nextPoint.lat = airportPoints[i + 3];
|
||||
|
||||
//printf("inserting [%f %f] -> [%f %f]\n",currentPoint.lon,currentPoint.lat,nextPoint.lon,nextPoint.lat);
|
||||
|
||||
QTInsert(&airport_root, new Line(currentPoint, nextPoint), 0);
|
||||
}
|
||||
} else {
|
||||
printf("No airport file found\n");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
|
||||
std::string line;
|
||||
std::ifstream infile("mapnames");
|
||||
|
||||
|
||||
while (std::getline(infile, line))
|
||||
{
|
||||
float lon, lat;
|
||||
|
||||
std::istringstream iss(line);
|
||||
|
||||
iss >> lon;
|
||||
iss >> lat;
|
||||
|
||||
std::string assemble;
|
||||
|
||||
iss >> assemble;
|
||||
|
||||
for(std::string s; iss >> s; ) {
|
||||
assemble = assemble + " " + s;
|
||||
}
|
||||
|
||||
// std::cout << "[" << x << "," << y << "] " << assemble << "\n";
|
||||
MapLabel *label = new MapLabel(lon,lat,assemble);
|
||||
mapnames.push_back(label);
|
||||
}
|
||||
|
||||
std::cout << "Read " << mapnames.size() << " place names\n";
|
||||
|
||||
infile.close();
|
||||
|
||||
infile.open("airportnames");
|
||||
|
||||
|
||||
while (std::getline(infile, line))
|
||||
{
|
||||
float lon, lat;
|
||||
|
||||
std::istringstream iss(line);
|
||||
|
||||
iss >> lon;
|
||||
iss >> lat;
|
||||
|
||||
std::string assemble;
|
||||
|
||||
iss >> assemble;
|
||||
|
||||
for(std::string s; iss >> s; ) {
|
||||
assemble = assemble + " " + s;
|
||||
}
|
||||
|
||||
// std::cout << "[" << x << "," << y << "] " << assemble << "\n";
|
||||
MapLabel *label = new MapLabel(lon,lat,assemble);
|
||||
airportnames.push_back(label);
|
||||
}
|
||||
|
||||
std::cout << "Read " << airportnames.size() << " airport names\n";
|
||||
|
||||
infile.close();
|
||||
nextPoint.lon = mapPoints[i + 2];
|
||||
nextPoint.lat = mapPoints[i + 3];
|
||||
|
||||
// printf("inserting [%f %f] -> [%f %f]\n",currentPoint.lon,currentPoint.lat,nextPoint.lon,nextPoint.lat);
|
||||
|
||||
QTInsert(&root, new Line(currentPoint, nextPoint), 0);
|
||||
}
|
||||
|
||||
printf("done\n");
|
||||
}
|
||||
|
|
53
Map.h
53
Map.h
|
@ -1,56 +1,13 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef MAP_H
|
||||
#define MAP_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
typedef struct Point{
|
||||
float lat;
|
||||
float lon;
|
||||
} Point;
|
||||
|
||||
typedef struct MapLabel{
|
||||
Point location;
|
||||
std::string text;
|
||||
|
||||
MapLabel(float lon, float lat, std::string text) {
|
||||
this->location.lon = lon;
|
||||
this->location.lat = lat;
|
||||
this->text = text;
|
||||
}
|
||||
} MapLabel;
|
||||
|
||||
typedef struct Line{
|
||||
float lat_min;
|
||||
float lat_max;
|
||||
|
@ -119,22 +76,14 @@ class Map {
|
|||
|
||||
public:
|
||||
QuadTree root;
|
||||
QuadTree airport_root;
|
||||
|
||||
bool QTInsert(QuadTree *tree, Line *line, int depth);
|
||||
std::vector<Line*> getLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
|
||||
std::vector<Line*> getLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
|
||||
|
||||
std::vector<MapLabel*> mapnames;
|
||||
std::vector<MapLabel*> airportnames;
|
||||
|
||||
Map();
|
||||
|
||||
int mapPoints_count;
|
||||
float *mapPoints;
|
||||
|
||||
int airportPoints_count;
|
||||
float *airportPoints;
|
||||
|
||||
float *mapPoints;
|
||||
};
|
||||
#endif
|
78
README.md
78
README.md
|
@ -1,10 +1,9 @@
|
|||
# viz1090
|
||||
|
||||

|
||||
**This is work in progress**
|
||||
|
||||
**This is a work in progress**
|
||||
|
||||
There are some major fixes and cleanup that need to happen before a release:
|
||||
There are some major fixes and cleanup that need to happen before a relase:
|
||||
* Everything is a grab bag of C and C++, need to more consistently modernize
|
||||
* A full refactor, especially View.cpp, necessary for many of the new features below.
|
||||
* A working Android build, as this is the best way to run this on portable hardware.
|
||||
|
@ -27,52 +26,51 @@ Tested and working on Ubuntu 18.04, Raspbian Stretch / Buster, Windows Subsystem
|
|||
sudo apt-get install build-essential
|
||||
```
|
||||
|
||||
1. Install SDL and RTL-SDR libraries
|
||||
1. Install SDL and RTL-SDR libararies
|
||||
```
|
||||
sudo apt-get install libsdl2-dev libsdl2-ttf-dev libsdl2-gfx-dev librtlsdr-dev libgdal-dev
|
||||
sudo apt-get install libsdl2-dev libsdl2-ttf-dev libsdl2-gfx-dev librtlsdr-dev
|
||||
```
|
||||
|
||||
Note: On Raspbian the SDL2 package requires X to be running. See the Raspberry Pi section for notes on running from the terminal and other improvements.
|
||||
|
||||
2. Download and build viz1090
|
||||
2. Download and build spidr
|
||||
```
|
||||
cd ~
|
||||
git clone https://www.github.com/nmatsuda/viz1090
|
||||
cd viz1090
|
||||
git clone https://www.github.com/nmatsuda/spidr
|
||||
cd spidr
|
||||
make clean; make
|
||||
```
|
||||
|
||||
3. Download and process map data
|
||||
Grab a shapefile with your desired level of detail from https://www.naturalearthdata.com/downloads
|
||||
|
||||
[This](https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_1_states_provinces.zip) is a good place to start.
|
||||
|
||||
Unzip and copy the .shp and .shx files.
|
||||
|
||||
```
|
||||
sudo apt install python3 python3-pip
|
||||
pip3 install fiona tqdm shapely
|
||||
./getmap.sh
|
||||
pip3 install geopandas tqdm
|
||||
python3 mapconverter.py ne_10m_admin_1_states_provinces.shp
|
||||
```
|
||||
|
||||
This will produce files for map and airport geometry, with labels, that viz1090 reads. If any of these files don't exist then visualizer will show planes and trails without any geography.
|
||||
|
||||
The default parameters for mapconverter should render reasonably quickly on a Raspberry Pi 4. See the mapconverter section below for other options and more information about map sources.
|
||||
This will produce a file mapdata.bin that viz1090 reads. If the file doesn't exist then visualizer will show planes and trails without any geography.
|
||||
|
||||
The default parameters for mapconverter should render resonably quickly on a Raspberri Pi 4. See the mapconverter section below for other options.
|
||||
|
||||
|
||||
3. (Windows only)
|
||||
|
||||
As WSL does not have an X server built in, you will need to install a 3rd party X server, such as https://sourceforge.net/projects/vcxsrv/
|
||||
|
||||
* run Xlaunch from the start menu
|
||||
* Uncheck "Use Native openGL"
|
||||
* Add parameter ```-ac``` (WSL 2 only)
|
||||
* Open the Ubuntu WSL terminal
|
||||
* Specify the X display to use (WSL 1)
|
||||
```
|
||||
export DISPLAY=:0
|
||||
```
|
||||
* or for (WSL 2)
|
||||
```
|
||||
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
|
||||
```
|
||||
* Start viz1090 as described below.
|
||||
* run Xlaunch from the start menu
|
||||
* Uncheck "Use Native openGL"
|
||||
* Open the Ubuntu WSL terminal
|
||||
* Specify the X display to use
|
||||
```
|
||||
export DISPLAY=:0
|
||||
```
|
||||
* Start viz1090 as described below.
|
||||
|
||||
### RUNNING
|
||||
|
||||
|
@ -96,36 +94,11 @@ viz1090 will open an SDL window set to the resolution of your screen.
|
|||
| --port [port number] | Specify dump1090 server port |
|
||||
| --metric | Display metric units |
|
||||
| --lat | Specify your latitude in degrees |
|
||||
| --lon | Specify your longitude in degrees |
|
||||
| --lon | Specify your longitiude in degrees |
|
||||
| --screensize [width] [height] | Specify a resolution, otherwise use resolution of display |
|
||||
| --uiscale [scale] | Scale up UI elements by integer amounts for high resolution screen |
|
||||
| --fullscreen | Render fullscreen rather than in a window |
|
||||
|
||||
### MAPS
|
||||
|
||||
The best map data source I've found so far is https://www.naturalearthdata.com. This has a lot of useful GIS data, but not airport runways, which you can get from the FAA Aeronautical Data Delivery Service (https://adds-faa.opendata.arcgis.com/)
|
||||
|
||||
|
||||
I've been using these files:
|
||||
|
||||
* [Map geometry](https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_1_states_provinces.zip)
|
||||
* [Place names](https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_populated_places.zip)
|
||||
* [Airport IATA codes](https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_airports.zip)
|
||||
* [Airport runway geometry](https://opendata.arcgis.com/datasets/4d8fa46181aa470d809776c57a8ab1f6_0.zip)
|
||||
|
||||
The bash script getmap.sh will download (so long as the links don't break) and convert these. Alternatively, you can pass shapefiles and other arguments to mapconverter.py directly
|
||||
|
||||
### MAPCONVERTER.PY RUNTIME OPTIONS
|
||||
|
||||
| Argument | Description |
|
||||
| ----------------------------- | ----------- |
|
||||
| --mapfile | shapefile for main map |
|
||||
| --mapnames | shapefile for map place names |
|
||||
| --airportfile | shapefile for airport runway outlines |
|
||||
| --airportnames | shapefile for airport IATA names |
|
||||
| --minpop | minimum population to show place names for (defaults to 100000) |
|
||||
| --tolerance" | map simplification tolerance (defaults to 0.001, which works well on a Raspberry Pi 4 - smaller values will produce more detail but slow down the map refresh rate) |
|
||||
|
||||
### HARDWARE NOTES
|
||||
|
||||
This software was originally intended for Raspberry Pi devices, and it is currently optimized for the Raspberry Pi 4 with the following configuration:
|
||||
|
@ -143,7 +116,6 @@ This software was originally intended for Raspberry Pi devices, and it is curren
|
|||
* [Noelec Nano V3](https://www.nooelec.com/store/nesdr-nano-three.html)
|
||||
* Stratux V2 \*very low power but hard to find
|
||||
|
||||
If you want to print the case in the GIF shown above, you can [download it here](https://github.com/nmatsuda/viz1090_case).
|
||||
|
||||
If running as a front end only, with a separate dump1090 server, the best option is to use an Android phone, such as the Pixel 2, which significantly outperforms a Raspberry Pi 4.
|
||||
|
||||
|
|
94
Style.h
94
Style.h
|
@ -1,94 +0,0 @@
|
|||
#ifndef STYLE_H
|
||||
#define STYLE_H
|
||||
|
||||
#include "SDL2/SDL.h"
|
||||
|
||||
|
||||
//
|
||||
// This should go to a full theming class
|
||||
//
|
||||
typedef struct Style {
|
||||
SDL_Color backgroundColor;
|
||||
|
||||
SDL_Color selectedColor;
|
||||
SDL_Color planeColor;
|
||||
SDL_Color planeGoneColor;
|
||||
SDL_Color trailColor;
|
||||
|
||||
SDL_Color geoColor;
|
||||
SDL_Color airportColor;
|
||||
|
||||
SDL_Color labelColor;
|
||||
SDL_Color labelLineColor;
|
||||
SDL_Color subLabelColor;
|
||||
SDL_Color labelBackground;
|
||||
|
||||
SDL_Color scaleBarColor;
|
||||
SDL_Color buttonColor;
|
||||
SDL_Color buttonBackground;
|
||||
SDL_Color buttonOutline;
|
||||
|
||||
SDL_Color clickColor;
|
||||
|
||||
SDL_Color black;
|
||||
SDL_Color white;
|
||||
SDL_Color red;
|
||||
SDL_Color green;
|
||||
SDL_Color blue;
|
||||
|
||||
//
|
||||
// todo separate style stuff
|
||||
//
|
||||
|
||||
Style() {
|
||||
|
||||
SDL_Color pink = {249,38,114,255};
|
||||
|
||||
SDL_Color purple = {85, 0, 255,255};
|
||||
SDL_Color purple_dark = {33, 0, 122,255};
|
||||
|
||||
SDL_Color blue = {102,217,239,255};
|
||||
SDL_Color blue_dark = {102,217,239,255};
|
||||
|
||||
SDL_Color green = {0,255,234,255};
|
||||
SDL_Color green_dark = {24,100,110,255};
|
||||
|
||||
SDL_Color yellow = {216,255,0,255};
|
||||
SDL_Color yellow_dark = {90,133,50,255};
|
||||
|
||||
SDL_Color orange = {253,151,31,255};
|
||||
SDL_Color grey_light = {196,196,196,255};
|
||||
SDL_Color grey = {127,127,127,255};
|
||||
SDL_Color grey_dark = {64,64,64,255};
|
||||
|
||||
black = {0,0,0,255};
|
||||
white = {255,255,255,255};
|
||||
red = {255,0,0,255};
|
||||
green = {0,255,0,255};
|
||||
blue = {0,0,255,255};
|
||||
|
||||
|
||||
backgroundColor = black;
|
||||
|
||||
selectedColor = pink;
|
||||
planeColor = yellow;
|
||||
planeGoneColor = grey;
|
||||
trailColor = yellow_dark;
|
||||
|
||||
geoColor = purple_dark;
|
||||
airportColor = purple;
|
||||
|
||||
labelColor = white;
|
||||
labelLineColor = grey_dark;
|
||||
subLabelColor = grey;
|
||||
labelBackground = black;
|
||||
scaleBarColor = grey_light;
|
||||
buttonColor = grey_light;
|
||||
buttonBackground = black;
|
||||
buttonOutline = grey_light;
|
||||
|
||||
clickColor = grey;
|
||||
}
|
||||
} Style;
|
||||
|
||||
#endif
|
73
Text.cpp
73
Text.cpp
|
@ -1,73 +0,0 @@
|
|||
#include "SDL2/SDL2_gfxPrimitives.h"
|
||||
|
||||
#include "Text.h"
|
||||
|
||||
SDL_Rect Text::drawString(std::string text, int x, int y, TTF_Font *font, SDL_Color color)
|
||||
{
|
||||
SDL_Rect dest = {0,0,0,0};
|
||||
|
||||
if(!text.length()) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
SDL_Surface *surface;
|
||||
|
||||
surface = TTF_RenderUTF8_Solid(font, text.c_str(), color);
|
||||
|
||||
if (surface == NULL)
|
||||
{
|
||||
printf("Couldn't create String %s: %s\n", text.c_str(), SDL_GetError());
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
dest.x = x;
|
||||
dest.y = y;
|
||||
dest.w = surface->w;
|
||||
dest.h = surface->h;
|
||||
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
SDL_RenderCopy(renderer, texture, NULL, &dest);
|
||||
SDL_DestroyTexture(texture);
|
||||
SDL_FreeSurface(surface);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
SDL_Rect Text::drawStringBG(std::string text, int x, int y, TTF_Font *font, SDL_Color color, SDL_Color bgColor) {
|
||||
SDL_Rect dest = {0,0,0,0};
|
||||
|
||||
if(!text.length()) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
SDL_Surface *surface;
|
||||
|
||||
surface = TTF_RenderUTF8_Shaded(font, text.c_str(), color, bgColor);
|
||||
|
||||
if (surface == NULL)
|
||||
{
|
||||
printf("Couldn't create String %s: %s\n", text.c_str(), SDL_GetError());
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
dest.x = x;
|
||||
dest.y = y;
|
||||
dest.w = surface->w;
|
||||
dest.h = surface->h;
|
||||
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||
SDL_RenderCopy(renderer, texture, NULL, &dest);
|
||||
SDL_DestroyTexture(texture);
|
||||
SDL_FreeSurface(surface);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
// check if text has changed and surface exists
|
||||
// redraw existing surface
|
||||
// or make new surface
|
||||
// for BG, draw bg size of surface
|
||||
// draw surface
|
70
View.h
70
View.h
|
@ -1,52 +1,21 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef VIEW_H
|
||||
#define VIEW_H
|
||||
|
||||
#include "AppData.h"
|
||||
#include "Map.h"
|
||||
#include "Style.h"
|
||||
#include "SDL2/SDL.h"
|
||||
#include "SDL2/SDL_ttf.h"
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
|
||||
//defs - should all move to config file setup
|
||||
#define ROUND_RADIUS 3 //radius of text box corners
|
||||
|
||||
#define CENTEROFFSET .5 //vertical offset for middle of screen
|
||||
|
||||
#define TRAIL_LENGTH 120
|
||||
#define TRAIL_TTL 240.0
|
||||
#define DISPLAY_ACTIVE 30.0
|
||||
#define DISPLAY_ACTIVE 30
|
||||
#define TRAIL_TTL_STEP 2
|
||||
|
||||
#define MIN_MAP_FEATURE 2
|
||||
|
@ -58,6 +27,27 @@
|
|||
#define LATLONMULT 111.195 // 6371.0 * M_PI / 180.0
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// This should go to a full theming class
|
||||
//
|
||||
typedef struct Style {
|
||||
SDL_Color backgroundColor;
|
||||
|
||||
SDL_Color selectedColor;
|
||||
SDL_Color planeColor;
|
||||
SDL_Color planeGoneColor;
|
||||
|
||||
SDL_Color mapInnerColor;
|
||||
SDL_Color mapOuterColor;
|
||||
SDL_Color scaleBarColor;
|
||||
|
||||
SDL_Color buttonColor;
|
||||
} Style;
|
||||
|
||||
|
||||
|
||||
class View {
|
||||
|
||||
private:
|
||||
|
@ -81,8 +71,8 @@ class View {
|
|||
|
||||
TTF_Font* loadFont(const char *name, int size);
|
||||
void closeFont(TTF_Font *font);
|
||||
SDL_Rect drawString(std::string text, int x, int y, TTF_Font *font, SDL_Color color);
|
||||
SDL_Rect drawStringBG(std::string text, int x, int y, TTF_Font *font, SDL_Color color, SDL_Color bgColor);
|
||||
void drawString(std::string text, int x, int y, TTF_Font *font, SDL_Color color);
|
||||
void drawStringBG(std::string text, int x, int y, TTF_Font *font, SDL_Color color, SDL_Color bgColor);
|
||||
void drawStatusBox(int *left, int *top, std::string label, std::string message, SDL_Color color);
|
||||
void drawStatus();
|
||||
|
||||
|
@ -101,13 +91,13 @@ class View {
|
|||
void drawPlaneIcon(int x, int y, float heading, SDL_Color planeColor);
|
||||
void drawTrails(int left, int top, int right, int bottom);
|
||||
void drawScaleBars();
|
||||
void drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max, SDL_Color color);
|
||||
void drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
|
||||
void drawLines(int left, int top, int right, int bottom, int bailTime);
|
||||
void drawPlaceNames();
|
||||
void drawGeography();
|
||||
void drawSignalMarks(Aircraft *p, int x, int y);
|
||||
void drawPlaneText(Aircraft *p);
|
||||
float resolveLabelConflicts();
|
||||
void drawSelectedAircraftText(Aircraft *p);
|
||||
void resolveLabelConflicts();
|
||||
void drawPlanes();
|
||||
void animateCenterAbsolute(float x, float y);
|
||||
void moveCenterAbsolute(float x, float y);
|
||||
|
@ -130,8 +120,6 @@ class View {
|
|||
////////////////
|
||||
bool metric;
|
||||
|
||||
bool fps;
|
||||
|
||||
float maxDist;
|
||||
float currentMaxDist;
|
||||
|
||||
|
|
61
flake.lock
61
flake.lock
|
@ -1,61 +0,0 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1739758141,
|
||||
"narHash": "sha256-uq6A2L7o1/tR6VfmYhZWoVAwb3gTy7j4Jx30MIrH0rE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c618e28f70257593de75a7044438efc1c1fc0791",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
50
flake.nix
50
flake.nix
|
@ -1,50 +0,0 @@
|
|||
{
|
||||
# TODO desc
|
||||
description = "viz1090";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (system: let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
};
|
||||
in rec
|
||||
{
|
||||
# Nix formatter, run using `$ nix fmt`
|
||||
formatter = pkgs.alejandra;
|
||||
|
||||
# Exports the package
|
||||
# Build with `$ nix build`
|
||||
packages.viz1090 = pkgs.callPackage ./nix/viz1090.nix {inherit self system;};
|
||||
packages.viz1090-mapdata = pkgs.callPackage ./nix/viz1090-mapdata.nix {};
|
||||
packages.default = packages.viz1090;
|
||||
|
||||
# Creates a shell with the necessary dependencies
|
||||
# Enter using `$ nix develop`
|
||||
devShell = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
rtl-sdr-librtlsdr
|
||||
SDL2
|
||||
SDL2_ttf
|
||||
SDL2_gfx
|
||||
gdal
|
||||
python3
|
||||
python312Packages.pip
|
||||
python312Packages.shapely
|
||||
python312Packages.fiona
|
||||
python312Packages.tqdm
|
||||
unzip
|
||||
python312Packages.requests
|
||||
git
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
25
getmap.sh
25
getmap.sh
|
@ -1,24 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
mkdir -p mapdata
|
||||
pushd mapdata > /dev/null
|
||||
|
||||
wget --no-verbose https://naciscdn.org/naturalearth/10m/cultural/ne_10m_admin_1_states_provinces.zip
|
||||
wget --no-verbose https://naciscdn.org/naturalearth/10m/cultural/ne_10m_populated_places.zip
|
||||
wget --no-verbose https://naciscdn.org/naturalearth/10m/cultural/ne_10m_airports.zip
|
||||
|
||||
#this may not be up to date
|
||||
wget --no-verbose https://opendata.arcgis.com/datasets/4d8fa46181aa470d809776c57a8ab1f6_0.zip
|
||||
|
||||
for file in *.zip; do
|
||||
unzip -o "${file}"
|
||||
rm "${file}"
|
||||
done
|
||||
|
||||
popd > /dev/null
|
||||
|
||||
python3 mapconverter.py \
|
||||
--mapfile mapdata/ne_10m_admin_1_states_provinces.shp \
|
||||
--mapnames mapdata/ne_10m_populated_places.shp \
|
||||
--airportfile mapdata/Runways.shp \
|
||||
--airportnames mapdata/ne_10m_airports.shp
|
||||
wget https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_1_states_provinces.zip
|
||||
unzip ne_10m_admin_1_states_provinces.zip
|
||||
python3 mapconverter.py ne_10m_admin_1_states_provinces.shp
|
||||
|
|
64
mapconverter-cartopy.py
Normal file
64
mapconverter-cartopy.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
import cartopy.io.shapereader as shpreader
|
||||
import numpy as np
|
||||
from tqdm import tqdm
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
#from urllib.request import urlopen
|
||||
import requests
|
||||
import argparse
|
||||
import os
|
||||
|
||||
def convertLinestring(linestring):
|
||||
outlist = []
|
||||
|
||||
pointx = linestring.coords.xy[0]
|
||||
pointy = linestring.coords.xy[1]
|
||||
|
||||
for j in range(len(pointx)):
|
||||
outlist.extend([float(pointx[j]),float(pointy[j])])
|
||||
|
||||
outlist.extend([0,0])
|
||||
return outlist
|
||||
|
||||
def extractLines(shapefile, tolerance):
|
||||
print("Extracting map lines")
|
||||
outlist = []
|
||||
|
||||
for i in tqdm(range(len(shapefile))):
|
||||
|
||||
simplified = shapefile[i].geometry.simplify(tolerance, preserve_topology=False)
|
||||
|
||||
if(simplified.geom_type == "LineString"):
|
||||
outlist.extend(convertLinestring(simplified))
|
||||
|
||||
elif(simplified.geom_type == "MultiPolygon" or simplified.geom_type == "Polygon"):
|
||||
|
||||
if(simplified.boundary.geom_type == "MultiLineString"):
|
||||
for boundary in simplified.boundary:
|
||||
outlist.extend(convertLinestring(boundary))
|
||||
else:
|
||||
outlist.extend(convertLinestring(simplified.boundary))
|
||||
|
||||
else:
|
||||
print("Unsupported type: " + simplified.geom_type)
|
||||
|
||||
|
||||
|
||||
return outlist
|
||||
|
||||
parser = argparse.ArgumentParser(description='viz1090 Natural Earth Data Map Converter')
|
||||
parser.add_argument("--tolerance", default=0.001, type=float, help="map simplification tolerance")
|
||||
parser.add_argument("--scale", default="10m", choices=["10m","50m","110m"], type=str, help="map file scale")
|
||||
parser.add_argument("mapfile", type=str, help="shapefile to load (e.g., from https://www.naturalearthdata.com/downloads/")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
shapefile = list(shpreader.Reader(args.mapfile).records())
|
||||
|
||||
outlist = extractLines(shapefile, args.tolerance)
|
||||
|
||||
bin_file = open("mapdata.bin", "wb")
|
||||
np.asarray(outlist).astype(np.single).tofile(bin_file)
|
||||
bin_file.close()
|
||||
|
||||
print("Wrote %d points" % (len(outlist) / 2))
|
107
mapconverter.py
107
mapconverter.py
|
@ -1,5 +1,4 @@
|
|||
import fiona
|
||||
from shapely.geometry import shape
|
||||
import geopandas
|
||||
import numpy as np
|
||||
from tqdm import tqdm
|
||||
import zipfile
|
||||
|
@ -24,110 +23,40 @@ def convertLinestring(linestring):
|
|||
def extractLines(shapefile, tolerance):
|
||||
print("Extracting map lines")
|
||||
outlist = []
|
||||
simplified = shapefile['geometry'].simplify(tolerance, preserve_topology=False)
|
||||
|
||||
for i in tqdm(range(len(shapefile))):
|
||||
|
||||
if(tolerance > 0):
|
||||
simplified = shape(shapefile[i]['geometry']).simplify(tolerance, preserve_topology=False)
|
||||
else:
|
||||
simplified =shape(shapefile[i]['geometry'])
|
||||
|
||||
if(simplified.geom_type == "LineString"):
|
||||
outlist.extend(convertLinestring(simplified))
|
||||
for i in tqdm(range(len(simplified))):
|
||||
if(simplified[i].geom_type == "LineString"):
|
||||
outlist.extend(convertLinestring(simplified[i]))
|
||||
|
||||
elif(simplified.geom_type == "MultiPolygon" or simplified.geom_type == "Polygon"):
|
||||
elif(simplified[i].geom_type == "MultiPolygon" or simplified[i].geom_type == "Polygon"):
|
||||
|
||||
if(simplified.boundary.geom_type == "MultiLineString"):
|
||||
for boundary in simplified.boundary.geoms:
|
||||
if(simplified[i].boundary.geom_type == "MultiLineString"):
|
||||
for boundary in simplified[i].boundary:
|
||||
outlist.extend(convertLinestring(boundary))
|
||||
else:
|
||||
outlist.extend(convertLinestring(simplified.boundary))
|
||||
outlist.extend(convertLinestring(simplified[i].boundary))
|
||||
|
||||
else:
|
||||
print("Unsupported type: " + simplified.geom_type)
|
||||
print("Unsupported type: " + simplified[i].geom_type)
|
||||
|
||||
|
||||
|
||||
return outlist
|
||||
|
||||
parser = argparse.ArgumentParser(description='viz1090 Natural Earth Data Map Converter')
|
||||
parser.add_argument("--mapfile", type=str, help="shapefile for main map")
|
||||
parser.add_argument("--mapnames", type=str, help="shapefile for map place names")
|
||||
parser.add_argument("--airportfile", type=str, help="shapefile for airport runway outlines")
|
||||
parser.add_argument("--airportnames", type=str, help="shapefile for airport IATA names")
|
||||
parser.add_argument("--minpop", default=100000, type=int, help="map simplification tolerance")
|
||||
parser.add_argument("--tolerance", default=0.001, type=float, help="map simplification tolerance")
|
||||
parser.add_argument("--scale", default="10m", choices=["10m","50m","110m"], type=str, help="map file scale")
|
||||
parser.add_argument("mapfile", type=str, help="shapefile to load (e.g., from https://www.naturalearthdata.com/downloads/")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# mapfile
|
||||
if args.mapfile is not None:
|
||||
shapefile = fiona.open(args.mapfile)
|
||||
shapefile = geopandas.read_file(args.mapfile)
|
||||
|
||||
outlist = extractLines(shapefile, args.tolerance)
|
||||
outlist = extractLines(shapefile, args.tolerance)
|
||||
|
||||
bin_file = open("mapdata.bin", "wb")
|
||||
np.asarray(outlist).astype(np.single).tofile(bin_file)
|
||||
bin_file.close()
|
||||
|
||||
print("Wrote %d points" % (len(outlist) / 2))
|
||||
|
||||
# mapnames
|
||||
bin_file = open("mapnames", "w")
|
||||
|
||||
if args.mapnames is not None:
|
||||
shapefile = fiona.open(args.mapnames)
|
||||
|
||||
count = 0
|
||||
|
||||
for i in tqdm(range(len(shapefile))):
|
||||
|
||||
xcoord = shapefile[i]['geometry']['coordinates'][0]
|
||||
ycoord = shapefile[i]['geometry']['coordinates'][1]
|
||||
pop = shapefile[i]['properties']['POP_MIN']
|
||||
name = shapefile[i]['properties']['NAME']
|
||||
|
||||
if pop > args.minpop:
|
||||
outstring = "{0} {1} {2}\n".format(xcoord, ycoord, name)
|
||||
bin_file.write(outstring)
|
||||
count = count + 1
|
||||
|
||||
bin_file.close()
|
||||
|
||||
print("Wrote %d place names" % count)
|
||||
|
||||
#airportfile
|
||||
if args.airportfile is not None:
|
||||
shapefile = fiona.open(args.airportfile)
|
||||
|
||||
outlist = extractLines(shapefile, 0)
|
||||
|
||||
bin_file = open("airportdata.bin", "wb")
|
||||
np.asarray(outlist).astype(np.single).tofile(bin_file)
|
||||
bin_file.close()
|
||||
|
||||
print("Wrote %d points" % (len(outlist) / 2))
|
||||
|
||||
|
||||
#airportnames
|
||||
if args.airportnames is not None:
|
||||
bin_file = open("airportnames", "w")
|
||||
|
||||
shapefile = fiona.open(args.airportnames)
|
||||
|
||||
count = 0
|
||||
|
||||
for i in tqdm(range(len(shapefile))):
|
||||
|
||||
xcoord = shapefile[i]['geometry']['coordinates'][0]
|
||||
ycoord = shapefile[i]['geometry']['coordinates'][1]
|
||||
name = shapefile[i]['properties']['iata_code']
|
||||
|
||||
outstring = "{0} {1} {2}\n".format(xcoord, ycoord, name)
|
||||
bin_file.write(outstring)
|
||||
count = count + 1
|
||||
|
||||
bin_file.close()
|
||||
|
||||
print("Wrote %d airport names" % count)
|
||||
bin_file = open("mapdata.bin", "wb")
|
||||
np.asarray(outlist).astype(np.single).tofile(bin_file)
|
||||
bin_file.close()
|
||||
|
||||
print("Wrote %d points" % (len(outlist) / 2))
|
BIN
ne_10m_coastline.shp
Normal file
BIN
ne_10m_coastline.shp
Normal file
Binary file not shown.
BIN
ne_10m_coastline.shx
Normal file
BIN
ne_10m_coastline.shx
Normal file
Binary file not shown.
|
@ -1,69 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
stdenv,
|
||||
fetchFromGitea,
|
||||
}: let
|
||||
runways = fetchTarball {
|
||||
url = "https://opendata.arcgis.com/datasets/4d8fa46181aa470d809776c57a8ab1f6_0.zip";
|
||||
sha256 = "sha256:1ivwx8glk8yk68nmqz467yzvlb3l66l1s3ibmd9p41wz737lmz88";
|
||||
};
|
||||
provinces = fetchTarball {
|
||||
url = "https://naciscdn.org/naturalearth/10m/cultural/ne_10m_admin_1_states_provinces.zip";
|
||||
sha256 = "sha256:06ai02b8rfsfzpa0gq4nsg29lxvwy4zvjw44099hc78vr7dkfsdp";
|
||||
};
|
||||
places = fetchTarball {
|
||||
url = "https://naciscdn.org/naturalearth/10m/cultural/ne_10m_populated_places.zip";
|
||||
sha256 = "sha256:1dhh569520f02yml1m5zp2znjv85cqbccl4nvpmigynxd37kid3j";
|
||||
};
|
||||
airports = fetchTarball {
|
||||
url = "https://naciscdn.org/naturalearth/10m/cultural/ne_10m_airports.zip";
|
||||
sha256 = "sha256:0893zg63ygr2l2d1wpyigls1syfkryjlygvnbbjikpqk5i5cwr56";
|
||||
};
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "viz1090-mapdata";
|
||||
version = "0.1.0";
|
||||
|
||||
src = fetchFromGitea {
|
||||
domain = "git.vulpecula.zone";
|
||||
owner = "tasiaiso";
|
||||
repo = pname;
|
||||
rev = "d1f53019b22a9e605506bed90fcffcdc5f7e6186";
|
||||
hash = "sha256-gtv0u7o+5fqVgA0CHDWdZr0h9A1Nbky1+okHvSv1cVU=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
python3
|
||||
python312Packages.pip
|
||||
python312Packages.shapely
|
||||
python312Packages.fiona
|
||||
python312Packages.tqdm
|
||||
python312Packages.requests
|
||||
];
|
||||
|
||||
buildPhase = ''
|
||||
mkdir -p mapdata
|
||||
|
||||
cp ${runways}/* mapdata
|
||||
cp ${provinces}/* mapdata
|
||||
cp ${places}/* mapdata
|
||||
cp ${airports}/* mapdata
|
||||
# ls -al mapdata
|
||||
|
||||
python3 mapconverter.py \
|
||||
--mapfile mapdata/ne_10m_admin_1_states_provinces.shp \
|
||||
--mapnames mapdata/ne_10m_populated_places.shp \
|
||||
--airportfile mapdata/Runways.shp \
|
||||
--airportnames mapdata/ne_10m_airports.shp
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
|
||||
cp airportdata.bin $out
|
||||
cp airportnames $out
|
||||
cp mapdata.bin $out
|
||||
cp mapnames $out
|
||||
'';
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
stdenv,
|
||||
fetchFromGitea,
|
||||
self,
|
||||
system,
|
||||
}: let
|
||||
viz1090-mapdata = self.packages.${system}.viz1090-mapdata;
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "viz1090";
|
||||
version = "0.1.0";
|
||||
|
||||
src = fetchFromGitea {
|
||||
domain = "git.vulpecula.zone";
|
||||
owner = "tasiaiso";
|
||||
repo = pname;
|
||||
rev = "1922324b40f84fd449cec3fbfdade8aa33597bf6";
|
||||
hash = "sha256-bPVFKbGtPXOitzzHb3yJ6XW3fRh8PF/7kfP7EJkJX3c=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
rtl-sdr-librtlsdr
|
||||
SDL2
|
||||
SDL2_ttf
|
||||
SDL2_gfx
|
||||
gdal
|
||||
git
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
viz1090-mapdata
|
||||
];
|
||||
|
||||
buildPhase = ''
|
||||
echo "diff --git a/Makefile b/Makefile
|
||||
index 5e60779..d5b30ab 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -3,7 +3,7 @@
|
||||
# sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local
|
||||
#
|
||||
|
||||
-CXXFLAGS=-O2 -std=c++11 -g
|
||||
+CXXFLAGS=-O2 -std=c++11 -g -I ${pkgs.SDL2.dev}/include/SDL2/
|
||||
LIBS= -lm -lSDL2 -lSDL2_ttf -lSDL2_gfx -g
|
||||
CXX=g++
|
||||
|
||||
diff --git a/Map.cpp b/Map.cpp
|
||||
index cd798ec..c5736bd 100644
|
||||
--- a/Map.cpp
|
||||
+++ b/Map.cpp
|
||||
@@ -189,7 +189,7 @@ std::vector<Line*> Map::getLines(float screen_lat_min, float screen_lat_max, flo
|
||||
Map::Map() {
|
||||
FILE *fileptr;
|
||||
|
||||
- if((fileptr = fopen(\"mapdata.bin\", \"rb\"))) {
|
||||
+ if((fileptr = fopen(\"${viz1090-mapdata}/mapdata.bin\", \"rb\"))) {
|
||||
|
||||
|
||||
fseek(fileptr, 0, SEEK_END);
|
||||
@@ -255,7 +255,7 @@ Map::Map() {
|
||||
//
|
||||
|
||||
|
||||
- if((fileptr = fopen(\"airportdata.bin\", \"rb\"))) {
|
||||
+ if((fileptr = fopen(\"${viz1090-mapdata}/airportdata.bin\", \"rb\"))) {
|
||||
fseek(fileptr, 0, SEEK_END);
|
||||
airportPoints_count = ftell(fileptr) / sizeof(float);
|
||||
rewind(fileptr);
|
||||
@@ -350,7 +350,7 @@ Map::Map() {
|
||||
|
||||
infile.close();
|
||||
|
||||
- infile.open(\"airportnames\");
|
||||
+ infile.open(\"${viz1090-mapdata}/airportnames\");
|
||||
|
||||
|
||||
while (std::getline(infile, line))
|
||||
|
||||
" | git apply -
|
||||
|
||||
cat Map.cpp | grep mapdata
|
||||
|
||||
make -j $NIX_BUILD_CORES
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp -v viz1090 $out/bin
|
||||
'';
|
||||
}
|
234
view1090.bak
Normal file
234
view1090.bak
Normal file
|
@ -0,0 +1,234 @@
|
|||
// view1090, a Mode S messages viewer for dump1090 devices.
|
||||
//
|
||||
// Copyright (C) 2014 by Malcolm Robb <Support@ATTAvionics.com>
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "view1090.h"
|
||||
#include "structs.h"
|
||||
#include "AircraftData.h"
|
||||
|
||||
int go = 1;
|
||||
|
||||
|
||||
AppData appData;
|
||||
Style style;
|
||||
|
||||
//
|
||||
// ============================= Utility functions ==========================
|
||||
//
|
||||
void sigintHandler(int dummy) {
|
||||
NOTUSED(dummy);
|
||||
signal(SIGINT, SIG_DFL); // reset signal handler - bit extra safety
|
||||
AircraftData.modes.exit = 1; // Signal to threads that we are done
|
||||
}
|
||||
|
||||
//
|
||||
//=========================================================================
|
||||
//
|
||||
|
||||
// Set up data connection
|
||||
int setupConnection(struct client *c) {
|
||||
int fd;
|
||||
|
||||
// Try to connect to the selected ip address and port. We only support *ONE* input connection which we initiate.here.
|
||||
if ((fd = anetTcpConnect(AircraftData.modes.aneterr, View1090.net_input_beast_ipaddr, AircraftData.modes.net_input_beast_port)) != ANET_ERR) {
|
||||
anetNonBlock(AircraftData.modes.aneterr, fd);
|
||||
//
|
||||
// Setup a service callback client structure for a beast binary input (from dump1090)
|
||||
// This is a bit dodgy under Windows. The fd parameter is a handle to the internet
|
||||
// socket on which we are receiving data. Under Linux, these seem to start at 0 and
|
||||
// count upwards. However, Windows uses "HANDLES" and these don't nececeriy start at 0.
|
||||
// dump1090 limits fd to values less than 1024, and then uses the fd parameter to
|
||||
// index into an array of clients. This is ok-ish if handles are allocated up from 0.
|
||||
// However, there is no gaurantee that Windows will behave like this, and if Windows
|
||||
// allocates a handle greater than 1024, then dump1090 won't like it. On my test machine,
|
||||
// the first Windows handle is usually in the 0x54 (84 decimal) region.
|
||||
|
||||
c->next = NULL;
|
||||
c->buflen = 0;
|
||||
c->fd =
|
||||
c->service =
|
||||
AircraftData.modes.bis = fd;
|
||||
AircraftData.modes.clients = c;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
//
|
||||
// ================================ Main ====================================
|
||||
//
|
||||
void showHelp(void) {
|
||||
printf(
|
||||
"-----------------------------------------------------------------------------\n"
|
||||
"| view1090 dump1090 Viewer Ver : "MODES_DUMP1090_VERSION " |\n"
|
||||
"-----------------------------------------------------------------------------\n"
|
||||
"--server <IPv4/hosname> TCP Beast output listen IPv4 (default: 127.0.0.1)\n"
|
||||
"--port <port> TCP Beast output listen port (default: 30005)\n"
|
||||
"--lat <latitude> Reference/receiver latitide for surface posn (opt)\n"
|
||||
"--lon <longitude> Reference/receiver longitude for surface posn (opt)\n"
|
||||
"--metric Use metric units (meters, km/h, ...)\n"
|
||||
"--help Show this help\n"
|
||||
"--uiscale <factor> UI global scaling (default: 1)\n"
|
||||
"--screensize <width> <height> Set frame buffer resolution (default: screen resolution)\n"
|
||||
"--fullscreen Start fullscreen\n"
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void showCopyright(void) {
|
||||
uint64_t llTime = time(NULL) + 1;
|
||||
|
||||
printf(
|
||||
"-----------------------------------------------------------------------------\n"
|
||||
"| view1090 ModeS Viewer Ver : " MODES_DUMP1090_VERSION " |\n"
|
||||
"-----------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
" Copyright (C) 2012 by Salvatore Sanfilippo <antirez@gmail.com>\n"
|
||||
" Copyright (C) 2014 by Malcolm Robb <support@attavionics.com>\n"
|
||||
" Copyright (C) 2020 by Nathan Matsuda <info@nathanmatsuda.com>\n"
|
||||
"\n"
|
||||
" All rights reserved.\n"
|
||||
"\n"
|
||||
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
|
||||
" ""AS IS"" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
|
||||
" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
|
||||
" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
|
||||
" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
|
||||
" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
|
||||
" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
|
||||
" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
|
||||
" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
|
||||
" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
|
||||
" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||
"\n"
|
||||
" For further details refer to <https://github.com/MalcolmRobb/dump1090>\n"
|
||||
"\n"
|
||||
);
|
||||
|
||||
// delay for 1 second to give the user a chance to read the copyright
|
||||
while (llTime >= time(NULL)) {}
|
||||
}
|
||||
#endif
|
||||
//
|
||||
//=========================================================================
|
||||
//
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int j, fd;
|
||||
struct client *c;
|
||||
char pk_buf[8];
|
||||
|
||||
AircraftData aircraftData;
|
||||
|
||||
signal(SIGINT, sigintHandler); // Define Ctrl/C handler (exit program)
|
||||
|
||||
|
||||
aircraftData.initialize();
|
||||
|
||||
// Parse the command line options
|
||||
for (j = 1; j < argc; j++) {
|
||||
int more = ((j + 1) < argc); // There are more arguments
|
||||
|
||||
if (!strcmp(argv[j],"--net-bo-port") && more) {
|
||||
AircraftData.modes.net_input_beast_port = atoi(argv[++j]);
|
||||
} else if (!strcmp(argv[j],"--port") && more) {
|
||||
AircraftData.modes.net_input_beast_port = atoi(argv[++j]);
|
||||
} else if (!strcmp(argv[j],"--net-bo-ipaddr") && more) {
|
||||
strcpy(View1090.net_input_beast_ipaddr, argv[++j]);
|
||||
} else if (!strcmp(argv[j],"--server") && more) {
|
||||
strcpy(View1090.net_input_beast_ipaddr, argv[++j]);
|
||||
} else if (!strcmp(argv[j],"--lat") && more) {
|
||||
AircraftData.modes.fUserLat = atof(argv[++j]);
|
||||
appData.centerLat = AircraftData.modes.fUserLat;
|
||||
} else if (!strcmp(argv[j],"--lon") && more) {
|
||||
AircraftData.modes.fUserLon = atof(argv[++j]);
|
||||
appData.centerLon = AircraftData.modes.fUserLon;
|
||||
} else if (!strcmp(argv[j],"--metric")) {
|
||||
AircraftData.modes.metric = 1;
|
||||
} else if (!strcmp(argv[j],"--fullscreen")) {
|
||||
appData.fullscreen = 1;
|
||||
} else if (!strcmp(argv[j],"--uiscale") && more) {
|
||||
appData.screen_uiscale = atoi(argv[++j]);
|
||||
} else if (!strcmp(argv[j],"--screensize") && more) {
|
||||
appData.screen_width = atoi(argv[++j]);
|
||||
appData.screen_height = atoi(argv[++j]);
|
||||
} else if (!strcmp(argv[j],"--help")) {
|
||||
showHelp();
|
||||
exit(0);
|
||||
} else {
|
||||
fprintf(stderr, "Unknown or not enough arguments for option '%s'.\n\n", argv[j]);
|
||||
showHelp();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to connect to the selected ip address and port. We only support *ONE* input connection which we initiate.here.
|
||||
c = (struct client *) malloc(sizeof(*c));
|
||||
while(1) {
|
||||
if ((fd = setupConnection(c)) == ANET_ERR) {
|
||||
fprintf(stderr, "Waiting on %s:%d\n", View1090.net_input_beast_ipaddr, AircraftData.modes.net_input_beast_port);
|
||||
sleep(1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int go;
|
||||
|
||||
|
||||
init("sdl1090");
|
||||
|
||||
atexit(cleanup);
|
||||
|
||||
go = 1;
|
||||
|
||||
while (go == 1)
|
||||
{
|
||||
getInput();
|
||||
|
||||
interactiveRemoveStaleAircrafts();
|
||||
draw();
|
||||
if ((fd == ANET_ERR) || (recv(c->fd, pk_buf, sizeof(pk_buf), MSG_PEEK | MSG_DONTWAIT) == 0)) {
|
||||
free(c);
|
||||
usleep(1000000);
|
||||
c = (struct client *) malloc(sizeof(*c));
|
||||
fd = setupConnection(c);
|
||||
continue;
|
||||
}
|
||||
modesReadFromClient(c,"",decodeBinMessage);
|
||||
//usleep(10000);
|
||||
}
|
||||
|
||||
// The user has stopped us, so close any socket we opened
|
||||
if (fd != ANET_ERR)
|
||||
{close(fd);}
|
||||
|
||||
return (0);
|
||||
}
|
||||
//
|
||||
//=========================================================================
|
||||
//
|
149
view1090.dsp
Normal file
149
view1090.dsp
Normal file
|
@ -0,0 +1,149 @@
|
|||
# Microsoft Developer Studio Project File - Name="view1090" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=view1090 - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "view1090.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "view1090.mak" CFG="view1090 - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "view1090 - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "view1090 - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "view1090 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I ".\pthreads\." /I ".\rtlsdr\." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /machine:I386
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "view1090 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I ".\pthreads\." /I ".\rtlsdr\." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "view1090 - Win32 Release"
|
||||
# Name "view1090 - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\anet.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\interactive.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mode_ac.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mode_s.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\net_io.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\view1090.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dump1090.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\view1090.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\winstubs.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# Begin Group "Library Files"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\pthreads\pthreadVC2.lib
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rtlsdr\rtlsdr.lib
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
35
viz1090.cpp
35
viz1090.cpp
|
@ -1,8 +1,8 @@
|
|||
// viz1090, a vizualizer for dump1090 ADSB output
|
||||
// Adapted from:
|
||||
// view1090, a Mode S messages viewer for dump1090 devices.
|
||||
//
|
||||
// Copyright (C) 2014 by Malcolm Robb <Support@ATTAvionics.com>
|
||||
//
|
||||
// Copyright (C) 2020, Nathan Matsuda <info@nathanmatsuda.com>
|
||||
// Copyright (C) 2014, Malcolm Robb <Support@ATTAvionics.com>
|
||||
// Copyright (C) 2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,17 +48,16 @@ void showHelp(void) {
|
|||
"-----------------------------------------------------------------------------\n"
|
||||
"| viz1090 ADSB Viewer Ver : 0.1 |\n"
|
||||
"-----------------------------------------------------------------------------\n"
|
||||
"--fps Show current framerate\n"
|
||||
"--fullscreen Start fullscreen\n"
|
||||
"--help Show this help\n"
|
||||
"--lat <latitude> Latitude in degrees\n"
|
||||
"--lon <longitude> Longitude in degrees\n"
|
||||
"--metric Use metric units\n"
|
||||
"--port <port> TCP Beast output listen port (default: 30005)\n"
|
||||
"--server <IPv4/hosname> TCP Beast output listen IPv4 (default: 127.0.0.1)\n"
|
||||
"--screensize <width> <height> Set frame buffer resolution (default: screen resolution)\n"
|
||||
"--screenindex <i> Set the index of the display to use (default: 0)\n"
|
||||
"--uiscale <factor> UI global scaling (default: 1)\n"
|
||||
"--server <IPv4/hosname> TCP Beast output listen IPv4 (default: 127.0.0.1)\n"
|
||||
"--port <port> TCP Beast output listen port (default: 30005)\n"
|
||||
"--lat <latitude> Latitide in degrees\n"
|
||||
"--lon <longitude> Longitude in degrees\n"
|
||||
"--metric Use metric units\n"
|
||||
"--help Show this help\n"
|
||||
"--uiscale <factor> UI global scaling (default: 1)\n"
|
||||
"--screensize <width> <height> Set frame buffer resolution (default: screen resolution)\n"
|
||||
"--screenindex <i> Set the index of the display to use (default: 0)\n"
|
||||
"--fullscreen Start fullscreen\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -95,8 +94,6 @@ int main(int argc, char **argv) {
|
|||
view.centerLon = appData.modes.fUserLon;
|
||||
} else if (!strcmp(argv[j],"--metric")) {
|
||||
view.metric = 1;
|
||||
} else if (!strcmp(argv[j],"--fps")) {
|
||||
view.fps = 1;
|
||||
} else if (!strcmp(argv[j],"--fullscreen")) {
|
||||
view.fullscreen = 1;
|
||||
} else if (!strcmp(argv[j],"--screenindex")) {
|
||||
|
@ -117,7 +114,10 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
int go;
|
||||
|
||||
appData.connect();
|
||||
|
||||
|
||||
view.SDL_init();
|
||||
view.font_init();
|
||||
|
||||
|
@ -125,7 +125,6 @@ int main(int argc, char **argv) {
|
|||
|
||||
while (go == 1)
|
||||
{
|
||||
appData.connect();
|
||||
input.getInput();
|
||||
appData.update();
|
||||
view.draw();
|
||||
|
|
111
winstubs.h
Normal file
111
winstubs.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
// dump1090, a Mode S messages decoder for RTLSDR devices.
|
||||
//
|
||||
// Copyright (C) 2014 by Malcolm Robb <support@attavionics.com>
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// This file provides basic Windows implementation of Linux specific functions
|
||||
// used in the dump1090 project. This allows dump1090 to be compiled and debugged
|
||||
// using Microsoft Visual C++ 6.0
|
||||
//
|
||||
// Note that not all functions actually provide equivalent functionality to their
|
||||
// Linux equivalents. They are simply stubs to allow the project to compile.
|
||||
//
|
||||
#ifndef __WINSTUBS_H
|
||||
#define __WINSTUBS_H
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <basetsd.h>
|
||||
|
||||
typedef UCHAR uint8_t;
|
||||
typedef USHORT uint16_t;
|
||||
typedef UINT32 uint32_t;
|
||||
typedef UINT64 uint64_t;
|
||||
typedef UINT32 mode_t;
|
||||
typedef long ssize_t;
|
||||
typedef int socklen_t;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define M_PI 3.14159265358979323846
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Functions not included in the MSVC maths library. This will do for our use.
|
||||
_inline double round(double d) {return floor(d + 0.5);}
|
||||
_inline double trunc(double d) {return (d>0) ? floor(d):ceil(d) ;}
|
||||
|
||||
//usleep works in microseconds, and isn't supported in Windows. This will do for our use.
|
||||
_inline void usleep(UINT32 ulSleep) {Sleep(ulSleep/1000);}
|
||||
_inline uint64_t strtoll(const char *p, void *e, UINT32 base) {return _atoi64(p);}
|
||||
_inline int inet_aton(const char * cp, DWORD * ulAddr) { *ulAddr = inet_addr(cp); return (INADDR_NONE != *ulAddr);}
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
|
||||
|
||||
_inline void cls() {
|
||||
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
COORD coord = {0, 0};
|
||||
DWORD count;
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
GetConsoleScreenBufferInfo(hStdOut, &csbi);
|
||||
|
||||
FillConsoleOutputCharacter(hStdOut, ' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
|
||||
|
||||
SetConsoleCursorPosition(hStdOut, coord);
|
||||
}
|
||||
|
||||
_inline int gettimeofday(struct timeval *tv, struct timezone *tz) {
|
||||
SYSTEMTIME stSystemTime;
|
||||
GetLocalTime(&stSystemTime);
|
||||
|
||||
tv->tv_sec = stSystemTime.wSecond + (60 * (stSystemTime.wMinute + (60 * stSystemTime.wHour)));
|
||||
tv->tv_usec = stSystemTime.wMilliseconds * 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define STDIN_FILENO 0
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __WINSTUBS_H
|
Loading…
Reference in a new issue