changed map representation to lines instead of polys. tried some speedups by drawing around edges of previous map texture, but need to move to tiles

Former-commit-id: 48a929dea6e2eb94785fa4e38afb1aba357c372f
This commit is contained in:
nathan 2020-06-12 20:32:42 -07:00
parent b8dd741165
commit cd1ce278c1
5 changed files with 162 additions and 141 deletions

View file

@ -3,7 +3,7 @@
# sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local # sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local
# #
CFLAGS=-O3 -Wno-write-strings CFLAGS=-O2 -Wno-write-strings
LIBS=-lm -lSDL2 -lSDL2_ttf -lSDL2_gfx LIBS=-lm -lSDL2 -lSDL2_ttf -lSDL2_gfx
CC=g++ CC=g++

112
Map.cpp
View file

@ -2,23 +2,26 @@
#include <stdio.h> #include <stdio.h>
#include <cstdlib> #include <cstdlib>
bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) { bool Map::QTInsert(QuadTree *tree, Line *line, int depth) {
// printf("Inserting %d point poly\n", polygon->numPoints); // printf("Inserting %d point poly\n", line->numPoints);
//temp maxdepth for debugging
if(depth > 10) {
return false;
}
if (!(polygon->lat_min >= tree->lat_min && if (!(line->lat_min >= tree->lat_min &&
polygon->lat_max <= tree->lat_max && line->lat_max <= tree->lat_max &&
polygon->lon_min >= tree->lon_min && line->lon_min >= tree->lon_min &&
polygon->lon_max <= tree->lon_max)) { line->lon_max <= tree->lon_max)) {
// printf("doesnt fit: %f > %f, %f < %f, %f < %f,%f > %f \n",polygon->lat_min, tree->lat_min, polygon->lat_max, tree->lat_max, polygon->lon_min, tree->lon_min, polygon->lon_max,tree->lon_max); // printf("doesnt fit: %f > %f, %f < %f, %f < %f,%f > %f \n",line->lat_min, tree->lat_min, line->lat_max, tree->lat_max, line->lon_min, tree->lon_min, line->lon_max,tree->lon_max);
return false; return false;
} }
// //temp maxdepth for debugging
// if(depth > 20) {
// tree->lines.push_back(*line);
// return true;
// }
if (tree->nw == NULL) { if (tree->nw == NULL) {
tree->nw = new QuadTree; tree->nw = new QuadTree;
@ -28,7 +31,7 @@ bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) {
tree->nw->lon_max = tree->lon_min + 0.5 * (tree->lon_max - tree->lon_min); tree->nw->lon_max = tree->lon_min + 0.5 * (tree->lon_max - tree->lon_min);
} }
if (QTInsert(tree->nw,polygon, depth++)){ if (QTInsert(tree->nw, line, depth++)){
return true; return true;
} }
@ -41,7 +44,7 @@ bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) {
tree->sw->lon_max = tree->lon_max; tree->sw->lon_max = tree->lon_max;
} }
if (QTInsert(tree->sw,polygon, depth++)){ if (QTInsert(tree->sw, line, depth++)){
return true; return true;
} }
@ -54,7 +57,7 @@ bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) {
tree->ne->lon_max = tree->lon_min + 0.5 * (tree->lon_max - tree->lon_min); tree->ne->lon_max = tree->lon_min + 0.5 * (tree->lon_max - tree->lon_min);
} }
if (QTInsert(tree->ne,polygon, depth++)){ if (QTInsert(tree->ne, line, depth++)){
return true; return true;
} }
@ -67,52 +70,50 @@ bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) {
tree->se->lon_max = tree->lon_max; tree->se->lon_max = tree->lon_max;
} }
if (QTInsert(tree->se,polygon, depth++)){ if (QTInsert(tree->se, line, depth++)){
return true; return true;
} }
tree->polygons.push_back(*polygon); tree->lines.push_back(*line);
return true; return true;
} }
std::vector<Polygon> Map::getPolysRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) { std::vector<Line> Map::getLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) {
std::vector<Polygon> retPolys; std::vector<Line> retLines;
if(tree == NULL) { if(tree == NULL) {
return retPolys; return retLines;
} }
if (tree->lat_min > screen_lat_max || screen_lat_min > tree->lat_max) { if (tree->lat_min > screen_lat_max || screen_lat_min > tree->lat_max) {
return retPolys; return retLines;
} }
if (tree->lon_min > screen_lon_max || screen_lon_min > tree->lon_max) { if (tree->lon_min > screen_lon_max || screen_lon_min > tree->lon_max) {
return retPolys; return retLines;
} }
std::vector<Line> ret;
ret = getLinesRecursive(tree->nw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
retLines.insert(retLines.end(), ret.begin(), ret.end());
std::vector<Polygon> ret; ret = getLinesRecursive(tree->sw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
ret = getPolysRecursive(tree->nw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); retLines.insert(retLines.end(), ret.begin(), ret.end());
retPolys.insert(retPolys.end(), ret.begin(), ret.end());
ret = getPolysRecursive(tree->sw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); ret = getLinesRecursive(tree->ne, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
retPolys.insert(retPolys.end(), ret.begin(), ret.end()); retLines.insert(retLines.end(), ret.begin(), ret.end());
ret = getPolysRecursive(tree->ne, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); ret = getLinesRecursive(tree->se, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
retPolys.insert(retPolys.end(), ret.begin(), ret.end()); retLines.insert(retLines.end(), ret.begin(), ret.end());
ret = getPolysRecursive(tree->se, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); retLines.insert(retLines.end(), tree->lines.begin(), tree->lines.end());
retPolys.insert(retPolys.end(), ret.begin(), ret.end());
retPolys.insert(retPolys.end(), tree->polygons.begin(), tree->polygons.end()); return retLines;
return retPolys;
} }
std::vector<Polygon> Map::getPolys(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) { std::vector<Line> Map::getLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) {
return getPolysRecursive(&root, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); return getLinesRecursive(&root, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
}; };
Map::Map() { Map::Map() {
@ -156,38 +157,19 @@ Map::Map() {
} }
} }
Polygon *currentPolygon = new Polygon; Point currentPoint;
for(int i = 0; i < mapPoints_count; i+=2) { Point nextPoint;
if(mapPoints[i] == 0) { for(int i = 0; i < mapPoints_count - 2; i+=2) {
QTInsert(&root, currentPolygon, 0); if(mapPoints[i] == 0)
currentPolygon = new Polygon; continue;
continue; currentPoint.lon = mapPoints[i];
} currentPoint.lat = mapPoints[i + 1];
currentPolygon->numPoints++;
Point *currentPoint = new Point; nextPoint.lon = mapPoints[i + 2];
nextPoint.lat = mapPoints[i + 3];
if(mapPoints[i] < currentPolygon->lon_min) { QTInsert(&root, new Line(currentPoint, nextPoint), 0);
currentPolygon->lon_min = mapPoints[i];
}
if(mapPoints[i] > currentPolygon->lon_max) {
currentPolygon->lon_max = mapPoints[i];
}
if(mapPoints[i+1] < currentPolygon->lat_min) {
currentPolygon->lat_min = mapPoints[i+1];
}
if(mapPoints[i+1] > currentPolygon->lat_max) {
currentPolygon->lat_max = mapPoints[i+1];
}
currentPoint->lon = mapPoints[i];
currentPoint->lat = mapPoints[i+1];
currentPolygon->points.push_back(*currentPoint);
} }
} }

30
Map.h
View file

@ -8,23 +8,25 @@ typedef struct Point{
float lon; float lon;
} Point; } Point;
typedef struct Polygon{ typedef struct Line{
float lat_min; float lat_min;
float lat_max; float lat_max;
float lon_min; float lon_min;
float lon_max; float lon_max;
std::vector<Point> points; Point start;
int numPoints; Point end;
Polygon() { Line(Point start, Point end) {
lat_min = 180.0f; this->start = start;
lon_min = 180.0f; this->end = end;
lat_max = -180.0f;
lon_max = -180.0f; lat_min = std::min(start.lat,end.lat);
numPoints = 0; lat_max = std::max(start.lat,end.lat);
lon_min = std::min(start.lon,end.lon);
lon_max = std::max(start.lon,end.lon);
} }
} Polygon; } Line;
typedef struct QuadTree{ typedef struct QuadTree{
float lat_min; float lat_min;
@ -32,7 +34,7 @@ typedef struct QuadTree{
float lon_min; float lon_min;
float lon_max; float lon_max;
std::vector<Polygon> polygons; std::vector<Line> lines;
struct QuadTree *nw; struct QuadTree *nw;
struct QuadTree *sw; struct QuadTree *sw;
@ -75,9 +77,9 @@ class Map {
public: public:
QuadTree root; QuadTree root;
bool QTInsert(QuadTree *tree, Polygon *polygon, int depth); bool QTInsert(QuadTree *tree, Line *line, int depth);
std::vector<Polygon> getPolysRecursive(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<Polygon> getPolys(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);
Map(); Map();

150
View.cpp
View file

@ -10,6 +10,7 @@
#include <iostream> #include <iostream>
#include <chrono> #include <chrono>
#include <thread>
static uint64_t now() { static uint64_t now() {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
@ -249,7 +250,7 @@ void View::SDL_init() {
} }
window = SDL_CreateWindow("viz1090", SDL_WINDOWPOS_CENTERED_DISPLAY(screen_index), SDL_WINDOWPOS_CENTERED_DISPLAY(screen_index), screen_width, screen_height, flags); window = SDL_CreateWindow("viz1090", SDL_WINDOWPOS_CENTERED_DISPLAY(screen_index), SDL_WINDOWPOS_CENTERED_DISPLAY(screen_index), screen_width, screen_height, flags);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
mapTexture = SDL_CreateTexture(renderer, mapTexture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_TARGET, SDL_TEXTUREACCESS_TARGET,
@ -298,7 +299,7 @@ void View::font_init() {
style.selectedColor = pink; style.selectedColor = pink;
style.planeColor = greenblue; style.planeColor = greenblue;
style.planeGoneColor = grey; style.planeGoneColor = grey;
style.mapInnerColor = mediumblue; style.mapInnerColor = darkblue;
style.mapOuterColor = darkblue; style.mapOuterColor = darkblue;
style.scaleBarColor = lightGrey; style.scaleBarColor = lightGrey;
style.buttonColor = lightblue; style.buttonColor = lightblue;
@ -637,69 +638,43 @@ void View::drawScaleBars()
lineRGBA(renderer,10,10+5*screen_uiscale,10+scaleBarDist,10+5*screen_uiscale, style.scaleBarColor.r, style.scaleBarColor.g, style. scaleBarColor.b, 255); lineRGBA(renderer,10,10+5*screen_uiscale,10+scaleBarDist,10+5*screen_uiscale, style.scaleBarColor.r, style.scaleBarColor.g, style. scaleBarColor.b, 255);
} }
void View::drawPolys(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) { void View::drawLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max, int bailTime) {
std::vector<Polygon> polyList = map.getPolys(screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); std::vector<Line> lineList = map.getLines(screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max);
std::vector<Polygon>::iterator currentPolygon; std::vector<Line>::iterator currentLine;
for (currentPolygon = polyList.begin(); currentPolygon != polyList.end(); ++currentPolygon) { for (currentLine = lineList.begin(); currentLine != lineList.end(); ++currentLine) {
int x1,y1,x2,y2; int x1,y1,x2,y2;
float dx,dy; float dx,dy;
std::vector<Point>::iterator currentPoint;
std::vector<Point>::iterator prevPoint = currentPolygon->points.begin();
for (currentPoint = std::next(currentPolygon->points.begin()); currentPoint != currentPolygon->points.end(); ++currentPoint, ++prevPoint) { if(bailTime) {
if (elapsed(drawStartTime) > bailTime) {
pxFromLonLat(&dx, &dy, prevPoint->lon, prevPoint->lat); return;
screenCoords(&x1, &y1, dx, dy);
float d1 = dx* dx + dy * dy;
pxFromLonLat(&dx, &dy, currentPoint->lon, currentPoint->lat);
screenCoords(&x2, &y2, dx, dy);
if(outOfBounds(x1,y1) && outOfBounds(x2,y2)) {
continue;
} }
}
pxFromLonLat(&dx, &dy, currentLine->start.lon, currentLine->start.lat);
screenCoords(&x1, &y1, dx, dy);
float d2 = dx* dx + dy * dy; pxFromLonLat(&dx, &dy, currentLine->end.lon, currentLine->end.lat);
screenCoords(&x2, &y2, dx, dy);
float factor = 1.0 - (d1+d2) / (3* maxDist * maxDist); if(outOfBounds(x1,y1) && outOfBounds(x2,y2)) {
continue;
SDL_Color lineColor = lerpColor(style.mapOuterColor, style.mapInnerColor, factor);
lineRGBA(renderer, x1, y1, x2, y2, lineColor.r, lineColor.g, lineColor.b, 255);
} }
////bounding boxes lineRGBA(renderer, x1, y1, x2, y2, style.mapInnerColor.r, style.mapInnerColor.g, style.mapInnerColor.b, 255);
// int x, y;
// pxFromLonLat(&dx, &dy, currentPolygon->lon_min, currentPolygon->lat_min);
// screenCoords(&x, &y, dx, dy);
// int top = y;
// int left = x;
// pxFromLonLat(&dx, &dy, currentPolygon->lon_max, currentPolygon->lat_max);
// screenCoords(&x, &y, dx, dy);
// int bottom = y;
// int right = x;
// rectangleRGBA(renderer, left, top, right, bottom, purple.r, purple.g, purple.b, 255);
} }
} }
void View::drawGeography() { void View::drawGeography(int left, int top, int right, int bottom, int bailTime) {
float screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max; float screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max;
latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, 0, screen_height * -0.2); latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, left, top);
latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, screen_width, screen_height * 1.2); latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, right, bottom);
drawPolys(screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); drawLines(screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max, bailTime);
} }
void View::drawSignalMarks(Aircraft *p, int x, int y) { void View::drawSignalMarks(Aircraft *p, int x, int y) {
@ -1308,27 +1283,29 @@ void View::registerMouseMove(int x, int y) {
// //
void View::draw() { void View::draw() {
uint64_t drawStartTime = now(); drawStartTime = now();
moveMapToTarget(); moveMapToTarget();
zoomMapToTarget(); zoomMapToTarget();
//updatePlanes(); //updatePlanes();
if(mapMoved) { if(mapRedraw && !mapMoved) {
SDL_SetRenderTarget(renderer, mapTexture); SDL_SetRenderTarget(renderer, mapTexture);
SDL_SetRenderDrawColor(renderer, style.backgroundColor.r, style.backgroundColor.g, style.backgroundColor.b, 255); SDL_SetRenderDrawColor(renderer, style.backgroundColor.r, style.backgroundColor.g, style.backgroundColor.b, 255);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
drawGeography(); drawGeography(0, 0, screen_width, screen_height, 0);
drawScaleBars();
SDL_SetRenderTarget(renderer, NULL ); SDL_SetRenderTarget(renderer, NULL );
mapMoved = 0; mapRedraw = 0;
currentLon = centerLon;
currentLat = centerLat;
currentMaxDist = maxDist;
} }
for(int i = 0; i < 4; i++) { for(int i = 0; i < 4; i++) {
@ -1340,8 +1317,61 @@ void View::draw() {
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, mapTexture, NULL, NULL); int shiftx = 0;
int shifty = 0;
if(mapMoved) {
float dx, dy;
int x1,y1, x2, y2;
pxFromLonLat(&dx, &dy, currentLon, currentLat);
screenCoords(&x1, &y1, dx, dy);
pxFromLonLat(&dx, &dy, centerLon, centerLat);
screenCoords(&x2, &y2, dx, dy);
shiftx = x1-x2;
shifty = y1-y2;
mapRedraw = 1;
SDL_Rect dest;
dest.x = shiftx + (screen_width / 2) * (1 - currentMaxDist / maxDist);
dest.y = shifty + (screen_height / 2) * (1 - currentMaxDist / maxDist);
dest.w = screen_width * currentMaxDist / maxDist;
dest.h = screen_height * currentMaxDist / maxDist;
//left
if(dest.x > 0) {
drawGeography(0, 0, dest.x, screen_height, FRAMETIME / 4);
}
//top
if(dest.y > 0) {
drawGeography(0, screen_height - dest.y, screen_width, screen_height, FRAMETIME / 4);
}
//right
if(dest.x + dest.w < screen_width) {
drawGeography(dest.x + dest.w, 0, screen_width, screen_height, FRAMETIME / 4);
}
//bottom
if(dest.y + dest.h < screen_height) {
drawGeography(0, 0, screen_width, screen_height - dest.y - dest.h, FRAMETIME / 4);
}
//attempt rest before bailing
//drawGeography(dest.x, screen_height - dest.y, dest.x + dest.w, screen_height - dest.y - dest.h, 1);
SDL_RenderCopy(renderer, mapTexture, NULL, &dest);
mapMoved = 0;
} else {
SDL_RenderCopy(renderer, mapTexture, NULL, NULL);
}
drawScaleBars();
drawPlanes(); drawPlanes();
drawStatus(); drawStatus();
drawMouse(); drawMouse();
@ -1353,12 +1383,11 @@ void View::draw() {
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
lastFrameTime = now(); if (elapsed(drawStartTime) < FRAMETIME) {
std::this_thread::sleep_for(std::chrono::milliseconds((FRAMETIME - elapsed(drawStartTime))));
if (elapsed(drawStartTime) < FRAMETIME) {
usleep(1000 * (FRAMETIME - elapsed(drawStartTime)));
} }
lastFrameTime = now();
} }
View::View(AppData *appData){ View::View(AppData *appData){
@ -1374,6 +1403,9 @@ View::View(AppData *appData){
maxDist = 25.0; maxDist = 25.0;
mapMoved = 1;
mapRedraw = 1;
selectedAircraft = NULL; selectedAircraft = NULL;
} }

9
View.h
View file

@ -78,8 +78,8 @@ 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 drawTrail(Aircraft *p); void drawTrail(Aircraft *p);
void drawScaleBars(); void drawScaleBars();
void drawPolys(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max); void drawLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max, int bailTime);
void drawGeography(); void drawGeography(int left, int top, int right, int bottom, int bailTime);
void drawSignalMarks(Aircraft *p, int x, int y); void drawSignalMarks(Aircraft *p, int x, int y);
void drawPlaneText(Aircraft *p); void drawPlaneText(Aircraft *p);
void drawSelectedAircraftText(Aircraft *p); void drawSelectedAircraftText(Aircraft *p);
@ -107,6 +107,7 @@ class View {
bool metric; bool metric;
float maxDist; float maxDist;
float currentMaxDist;
float centerLon; float centerLon;
float centerLat; float centerLat;
@ -116,7 +117,11 @@ class View {
float mapTargetLon; float mapTargetLon;
int mapMoved; int mapMoved;
int mapRedraw;
float currentLon;
float currentLat;
uint64_t lastFrameTime; uint64_t lastFrameTime;
uint64_t drawStartTime;
Map map; Map map;