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() {
|
||||
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;
|
||||
}
|
||||
|
||||
if(connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
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() {
|
||||
if(!connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fd == ANET_ERR) || (recv(c->fd, pk_buf, sizeof(pk_buf), MSG_PEEK | MSG_DONTWAIT) == 0)) {
|
||||
free(c);
|
||||
usleep(1000000);
|
||||
|
@ -154,4 +162,6 @@ AppData::AppData(){
|
|||
|
||||
modes.interactive = 0;
|
||||
modes.quiet = 1;
|
||||
|
||||
connected = false;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ class AppData {
|
|||
//
|
||||
|
||||
struct client *c;
|
||||
bool connected;
|
||||
int fd;
|
||||
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() {
|
||||
FILE *fileptr;
|
||||
|
||||
if(!(fileptr = fopen("mapdata.bin", "rb"))) {
|
||||
printf("No map file found\n");
|
||||
return;
|
||||
}
|
||||
if((fileptr = fopen("mapdata.bin", "rb"))) {
|
||||
|
||||
|
||||
fseek(fileptr, 0, SEEK_END);
|
||||
mapPoints_count = ftell(fileptr) / sizeof(float);
|
||||
|
@ -251,8 +249,75 @@ Map::Map() {
|
|||
|
||||
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;
|
||||
|
@ -283,5 +348,38 @@ Map::Map() {
|
|||
|
||||
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");
|
||||
}
|
||||
|
|
6
Map.h
6
Map.h
|
@ -119,16 +119,22 @@ 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<Label*> mapnames;
|
||||
std::vector<Label*> airportnames;
|
||||
|
||||
Map();
|
||||
|
||||
int mapPoints_count;
|
||||
float *mapPoints;
|
||||
|
||||
int airportPoints_count;
|
||||
float *airportPoints;
|
||||
|
||||
};
|
||||
#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_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);
|
||||
}
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
@ -665,13 +667,13 @@ void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen
|
|||
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;
|
||||
|
||||
|
@ -695,7 +697,7 @@ void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen
|
|||
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
|
||||
|
@ -742,6 +744,20 @@ void View::drawPlaceNames() {
|
|||
|
||||
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() {
|
||||
|
@ -1202,6 +1218,13 @@ void View::drawPlanes() {
|
|||
|
||||
while(p) {
|
||||
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;
|
||||
|
||||
float dx, dy;
|
||||
|
@ -1256,6 +1279,10 @@ void View::drawPlanes() {
|
|||
drawPlaneOffMap(x, y, &(p->cx), &(p->cy), planeColor);
|
||||
} else {
|
||||
drawPlaneIcon(usex, usey, p->track, planeColor);
|
||||
|
||||
p->x += usex - p->cx;
|
||||
p->y += usey - p->cy;
|
||||
|
||||
p->cx = usex;
|
||||
p->cy = usey;
|
||||
}
|
||||
|
@ -1517,6 +1544,9 @@ View::View(AppData *appData){
|
|||
fullscreen = 0;
|
||||
screen_index = 0;
|
||||
|
||||
centerLon = 0;
|
||||
centerLat = 0;
|
||||
|
||||
maxDist = 25.0;
|
||||
|
||||
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 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);
|
||||
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 drawPlaceNames();
|
||||
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;
|
||||
|
||||
appData.connect();
|
||||
|
||||
|
||||
view.SDL_init();
|
||||
view.font_init();
|
||||
|
||||
|
@ -125,6 +122,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
while (go == 1)
|
||||
{
|
||||
appData.connect();
|
||||
input.getInput();
|
||||
appData.update();
|
||||
view.draw();
|
||||
|
|
Loading…
Reference in a new issue