working runway drawing and airport names with conversion
This commit is contained in:
parent
ab1dce1d15
commit
80e776d470
26
AppData.cpp
26
AppData.cpp
|
@ -62,16 +62,20 @@ void AppData::initialize() {
|
||||||
|
|
||||||
|
|
||||||
void AppData::connect() {
|
void AppData::connect() {
|
||||||
c = (struct client *) malloc(sizeof(*c));
|
|
||||||
while(1) {
|
if(connected) {
|
||||||
if ((fd = setupConnection(c)) == ANET_ERR) {
|
return;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,6 +86,10 @@ void AppData::disconnect() {
|
||||||
|
|
||||||
|
|
||||||
void AppData::update() {
|
void AppData::update() {
|
||||||
|
if(!connected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((fd == ANET_ERR) || (recv(c->fd, pk_buf, sizeof(pk_buf), MSG_PEEK | MSG_DONTWAIT) == 0)) {
|
if ((fd == ANET_ERR) || (recv(c->fd, pk_buf, sizeof(pk_buf), MSG_PEEK | MSG_DONTWAIT) == 0)) {
|
||||||
free(c);
|
free(c);
|
||||||
usleep(1000000);
|
usleep(1000000);
|
||||||
|
@ -154,4 +162,6 @@ AppData::AppData(){
|
||||||
|
|
||||||
modes.interactive = 0;
|
modes.interactive = 0;
|
||||||
modes.quiet = 1;
|
modes.quiet = 1;
|
||||||
|
|
||||||
|
connected = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ class AppData {
|
||||||
//
|
//
|
||||||
|
|
||||||
struct client *c;
|
struct client *c;
|
||||||
|
bool connected;
|
||||||
int fd;
|
int fd;
|
||||||
char pk_buf[8];
|
char pk_buf[8];
|
||||||
|
|
||||||
|
|
106
Map.cpp
106
Map.cpp
|
@ -189,10 +189,8 @@ std::vector<Line*> Map::getLines(float screen_lat_min, float screen_lat_max, flo
|
||||||
Map::Map() {
|
Map::Map() {
|
||||||
FILE *fileptr;
|
FILE *fileptr;
|
||||||
|
|
||||||
if(!(fileptr = fopen("mapdata.bin", "rb"))) {
|
if((fileptr = fopen("mapdata.bin", "rb"))) {
|
||||||
printf("No map file found\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(fileptr, 0, SEEK_END);
|
fseek(fileptr, 0, SEEK_END);
|
||||||
mapPoints_count = ftell(fileptr) / sizeof(float);
|
mapPoints_count = ftell(fileptr) / sizeof(float);
|
||||||
|
@ -251,8 +249,75 @@ Map::Map() {
|
||||||
|
|
||||||
QTInsert(&root, new Line(currentPoint, nextPoint), 0);
|
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::string line;
|
||||||
|
@ -283,5 +348,38 @@ Map::Map() {
|
||||||
|
|
||||||
std::cout << "Read " << mapnames.size() << " place names\n";
|
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";
|
||||||
|
Label *label = new Label(lon,lat,assemble);
|
||||||
|
airportnames.push_back(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Read " << airportnames.size() << " airport names\n";
|
||||||
|
|
||||||
|
infile.close();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
printf("done\n");
|
printf("done\n");
|
||||||
}
|
}
|
||||||
|
|
6
Map.h
6
Map.h
|
@ -119,16 +119,22 @@ class Map {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QuadTree root;
|
QuadTree root;
|
||||||
|
QuadTree airport_root;
|
||||||
|
|
||||||
bool QTInsert(QuadTree *tree, Line *line, int depth);
|
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*> 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<Line*> getLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
|
||||||
|
|
||||||
std::vector<Label*> mapnames;
|
std::vector<Label*> mapnames;
|
||||||
|
std::vector<Label*> airportnames;
|
||||||
|
|
||||||
Map();
|
Map();
|
||||||
|
|
||||||
int mapPoints_count;
|
int mapPoints_count;
|
||||||
float *mapPoints;
|
float *mapPoints;
|
||||||
|
|
||||||
|
int airportPoints_count;
|
||||||
|
float *airportPoints;
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
44
View.cpp
44
View.cpp
|
@ -647,12 +647,14 @@ void View::drawLines(int left, int top, int right, int bottom, int bailTime) {
|
||||||
latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, left, top);
|
latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, left, top);
|
||||||
latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, right, bottom);
|
latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, right, bottom);
|
||||||
|
|
||||||
drawLinesRecursive(&(map.root), screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
|
drawLinesRecursive(&(map.root), screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max, style.mapInnerColor);
|
||||||
|
|
||||||
|
drawLinesRecursive(&(map.airport_root), screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max, orange);
|
||||||
|
|
||||||
drawTrails(left, top, right, bottom);
|
drawTrails(left, top, right, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) {
|
void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max, SDL_Color color) {
|
||||||
if(tree == NULL) {
|
if(tree == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -665,13 +667,13 @@ void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawLinesRecursive(tree->nw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
|
drawLinesRecursive(tree->nw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max, color);
|
||||||
|
|
||||||
drawLinesRecursive(tree->sw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
|
drawLinesRecursive(tree->sw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max, color);
|
||||||
|
|
||||||
drawLinesRecursive(tree->ne, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
|
drawLinesRecursive(tree->ne, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max, color);
|
||||||
|
|
||||||
drawLinesRecursive(tree->se, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
|
drawLinesRecursive(tree->se, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max, color);
|
||||||
|
|
||||||
std::vector<Line*>::iterator currentLine;
|
std::vector<Line*>::iterator currentLine;
|
||||||
|
|
||||||
|
@ -695,7 +697,7 @@ void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
lineRGBA(renderer, x1, y1, x2, y2, style.mapInnerColor.r, style.mapInnerColor.g, style.mapInnerColor.b, 255);
|
lineRGBA(renderer, x1, y1, x2, y2, color.r, color.g, color.b, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
// //Debug quadtree
|
// //Debug quadtree
|
||||||
|
@ -742,6 +744,20 @@ void View::drawPlaceNames() {
|
||||||
|
|
||||||
drawString((*label)->text, x, y, mapFont, grey);
|
drawString((*label)->text, x, y, mapFont, grey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(std::vector<Label*>::iterator label = map.airportnames.begin(); label != map.airportnames.end(); ++label) {
|
||||||
|
float dx, dy;
|
||||||
|
int x,y;
|
||||||
|
|
||||||
|
pxFromLonLat(&dx, &dy, (*label)->location.lon, (*label)->location.lat);
|
||||||
|
screenCoords(&x, &y, dx, dy);
|
||||||
|
|
||||||
|
if(outOfBounds(x,y)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawString((*label)->text, x, y, listFont, red);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::drawGeography() {
|
void View::drawGeography() {
|
||||||
|
@ -1202,6 +1218,13 @@ void View::drawPlanes() {
|
||||||
|
|
||||||
while(p) {
|
while(p) {
|
||||||
if (p->lon && p->lat) {
|
if (p->lon && p->lat) {
|
||||||
|
|
||||||
|
// if lon lat argments were not provided, start by snapping to the first plane we see
|
||||||
|
if(centerLon == 0 && centerLat == 0) {
|
||||||
|
mapTargetLon = p->lon;
|
||||||
|
mapTargetLat = p->lat;
|
||||||
|
}
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
float dx, dy;
|
float dx, dy;
|
||||||
|
@ -1256,6 +1279,10 @@ void View::drawPlanes() {
|
||||||
drawPlaneOffMap(x, y, &(p->cx), &(p->cy), planeColor);
|
drawPlaneOffMap(x, y, &(p->cx), &(p->cy), planeColor);
|
||||||
} else {
|
} else {
|
||||||
drawPlaneIcon(usex, usey, p->track, planeColor);
|
drawPlaneIcon(usex, usey, p->track, planeColor);
|
||||||
|
|
||||||
|
p->x += usex - p->cx;
|
||||||
|
p->y += usey - p->cy;
|
||||||
|
|
||||||
p->cx = usex;
|
p->cx = usex;
|
||||||
p->cy = usey;
|
p->cy = usey;
|
||||||
}
|
}
|
||||||
|
@ -1517,6 +1544,9 @@ View::View(AppData *appData){
|
||||||
fullscreen = 0;
|
fullscreen = 0;
|
||||||
screen_index = 0;
|
screen_index = 0;
|
||||||
|
|
||||||
|
centerLon = 0;
|
||||||
|
centerLat = 0;
|
||||||
|
|
||||||
maxDist = 25.0;
|
maxDist = 25.0;
|
||||||
|
|
||||||
mapMoved = 1;
|
mapMoved = 1;
|
||||||
|
|
2
View.h
2
View.h
|
@ -122,7 +122,7 @@ class View {
|
||||||
void drawPlaneIcon(int x, int y, float heading, SDL_Color planeColor);
|
void drawPlaneIcon(int x, int y, float heading, SDL_Color planeColor);
|
||||||
void drawTrails(int left, int top, int right, int bottom);
|
void drawTrails(int left, int top, int right, int bottom);
|
||||||
void drawScaleBars();
|
void drawScaleBars();
|
||||||
void drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
|
void drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max, SDL_Color color);
|
||||||
void drawLines(int left, int top, int right, int bottom, int bailTime);
|
void drawLines(int left, int top, int right, int bottom, int bailTime);
|
||||||
void drawPlaceNames();
|
void drawPlaceNames();
|
||||||
void drawGeography();
|
void drawGeography();
|
||||||
|
|
85
mapconverter-fiona-airports.py
Normal file
85
mapconverter-fiona-airports.py
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import fiona
|
||||||
|
from shapely.geometry import shape
|
||||||
|
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 = shape(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 = fiona.open(args.mapfile)
|
||||||
|
|
||||||
|
outlist = extractLines(shapefile, args.tolerance)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
bin_file = open("airportnames", "w")
|
||||||
|
|
||||||
|
shapefile = fiona.open("ne_10m_airports.shp")
|
||||||
|
|
||||||
|
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)
|
|
@ -115,9 +115,6 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
int go;
|
int go;
|
||||||
|
|
||||||
appData.connect();
|
|
||||||
|
|
||||||
|
|
||||||
view.SDL_init();
|
view.SDL_init();
|
||||||
view.font_init();
|
view.font_init();
|
||||||
|
|
||||||
|
@ -125,6 +122,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
while (go == 1)
|
while (go == 1)
|
||||||
{
|
{
|
||||||
|
appData.connect();
|
||||||
input.getInput();
|
input.getInput();
|
||||||
appData.update();
|
appData.update();
|
||||||
view.draw();
|
view.draw();
|
||||||
|
|
Loading…
Reference in a new issue