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
#
CFLAGS=-O3 -Wno-write-strings
CFLAGS=-O2 -Wno-write-strings
LIBS=-lm -lSDL2 -lSDL2_ttf -lSDL2_gfx
CC=g++

112
Map.cpp
View file

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

30
Map.h
View file

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

148
View.cpp
View file

@ -10,6 +10,7 @@
#include <iostream>
#include <chrono>
#include <thread>
static uint64_t now() {
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);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
mapTexture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_TARGET,
@ -298,7 +299,7 @@ void View::font_init() {
style.selectedColor = pink;
style.planeColor = greenblue;
style.planeGoneColor = grey;
style.mapInnerColor = mediumblue;
style.mapInnerColor = darkblue;
style.mapOuterColor = darkblue;
style.scaleBarColor = lightGrey;
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);
}
void View::drawPolys(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) {
std::vector<Polygon> polyList = map.getPolys(screen_lat_min, screen_lat_max, screen_lon_min, 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<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;
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) {
pxFromLonLat(&dx, &dy, prevPoint->lon, prevPoint->lat);
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;
if(bailTime) {
if (elapsed(drawStartTime) > bailTime) {
return;
}
float d2 = dx* dx + dy * dy;
float factor = 1.0 - (d1+d2) / (3* maxDist * maxDist);
SDL_Color lineColor = lerpColor(style.mapOuterColor, style.mapInnerColor, factor);
lineRGBA(renderer, x1, y1, x2, y2, lineColor.r, lineColor.g, lineColor.b, 255);
}
////bounding boxes
pxFromLonLat(&dx, &dy, currentLine->start.lon, currentLine->start.lat);
screenCoords(&x1, &y1, dx, dy);
// int x, y;
pxFromLonLat(&dx, &dy, currentLine->end.lon, currentLine->end.lat);
screenCoords(&x2, &y2, dx, dy);
// pxFromLonLat(&dx, &dy, currentPolygon->lon_min, currentPolygon->lat_min);
// screenCoords(&x, &y, dx, dy);
if(outOfBounds(x1,y1) && outOfBounds(x2,y2)) {
continue;
}
// 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);
lineRGBA(renderer, x1, y1, x2, y2, style.mapInnerColor.r, style.mapInnerColor.g, style.mapInnerColor.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;
latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, 0, screen_height * -0.2);
latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, screen_width, screen_height * 1.2);
latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, left, top);
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) {
@ -1308,27 +1283,29 @@ void View::registerMouseMove(int x, int y) {
//
void View::draw() {
uint64_t drawStartTime = now();
drawStartTime = now();
moveMapToTarget();
zoomMapToTarget();
//updatePlanes();
if(mapMoved) {
if(mapRedraw && !mapMoved) {
SDL_SetRenderTarget(renderer, mapTexture);
SDL_SetRenderDrawColor(renderer, style.backgroundColor.r, style.backgroundColor.g, style.backgroundColor.b, 255);
SDL_RenderClear(renderer);
drawGeography();
drawScaleBars();
drawGeography(0, 0, screen_width, screen_height, 0);
SDL_SetRenderTarget(renderer, NULL );
mapMoved = 0;
mapRedraw = 0;
currentLon = centerLon;
currentLat = centerLat;
currentMaxDist = maxDist;
}
for(int i = 0; i < 4; i++) {
@ -1340,8 +1317,61 @@ void View::draw() {
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();
drawStatus();
drawMouse();
@ -1353,12 +1383,11 @@ void View::draw() {
SDL_RenderPresent(renderer);
lastFrameTime = now();
if (elapsed(drawStartTime) < FRAMETIME) {
usleep(1000 * (FRAMETIME - elapsed(drawStartTime)));
if (elapsed(drawStartTime) < FRAMETIME) {
std::this_thread::sleep_for(std::chrono::milliseconds((FRAMETIME - elapsed(drawStartTime))));
}
lastFrameTime = now();
}
View::View(AppData *appData){
@ -1374,6 +1403,9 @@ View::View(AppData *appData){
maxDist = 25.0;
mapMoved = 1;
mapRedraw = 1;
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 drawTrail(Aircraft *p);
void drawScaleBars();
void drawPolys(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
void drawGeography();
void drawLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max, int bailTime);
void drawGeography(int left, int top, int right, int bottom, int bailTime);
void drawSignalMarks(Aircraft *p, int x, int y);
void drawPlaneText(Aircraft *p);
void drawSelectedAircraftText(Aircraft *p);
@ -107,6 +107,7 @@ class View {
bool metric;
float maxDist;
float currentMaxDist;
float centerLon;
float centerLat;
@ -116,7 +117,11 @@ class View {
float mapTargetLon;
int mapMoved;
int mapRedraw;
float currentLon;
float currentLat;
uint64_t lastFrameTime;
uint64_t drawStartTime;
Map map;