moved drawtrails into map redraw logic for faster refresh when trails are long

Former-commit-id: 526374dcda6c078f3b58720b48c62edc16824903
This commit is contained in:
nathan 2020-06-17 22:01:18 -07:00
parent e8cf66ebb9
commit 14f0e15c76
3 changed files with 131 additions and 203 deletions

View file

@ -22,7 +22,8 @@ sudo apt-get install build-essential
``` ```
sudo apt-get install libsdl2-dev libsdl2-ttf-dev libsdl2-gfx-dev librtlsdr-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.
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 spidr 2. Download and build spidr
``` ```
@ -35,7 +36,7 @@ make clean; make
3. Download and process map data 3. Download and process map data
Until more comprehensive map source (e.g., Mapbox) is integrated, viz1090 uses the lat/lon SVG files from https://www.mccurley.org Until more comprehensive map source (e.g., Mapbox) is integrated, viz1090 uses the lat/lon SVG files from https://www.mccurley.org
The getmap.sh pulls the svg file for the contiguous 48 US states and produces a binary file for viz1090 to read. The getmap.sh pulls the large SVG file for the contiguous 48 US states and produces a binary file for viz1090 to read.
``` ```
sudo apt install python3 python3-pip sudo apt install python3 python3-pip
@ -43,6 +44,8 @@ pip3 install lxml numpy tqdm
./getmap.sh ./getmap.sh
``` ```
There is also a world map avaiable from McCurley (https://mccurley.org/svg/data/World.svgz), which is much lower resolution and thus better for lower power hardware.
The mapconverter script called by getmap.sh downsamples the file to render resonably quickly on a Raspberri Pi 4. If you are on a slower device (e.g, a Raspberry Pi 3), you may want to try something like: The mapconverter script called by getmap.sh downsamples the file to render resonably quickly on a Raspberri Pi 4. If you are on a slower device (e.g, a Raspberry Pi 3), you may want to try something like:
``` ```

264
View.cpp
View file

@ -184,7 +184,11 @@ void View::screenCoords(int *outX, int *outY, float dx, float dy) {
} }
int View::outOfBounds(int x, int y) { int View::outOfBounds(int x, int y) {
if(x < 0 || x >= screen_width || y < 0 || y >= screen_height ) { return outOfBounds(x, y, 0, 0, screen_width, screen_height);
}
int View::outOfBounds(int x, int y, int left, int top, int right, int bottom) {
if(x < left || x >= right || y < top || y >= bottom ) {
return 1; return 1;
} else { } else {
return 0; return 0;
@ -531,20 +535,18 @@ void View::drawPlaneIcon(int x, int y, float heading, SDL_Color planeColor)
filledTrigonRGBA (renderer, x1, y1, x2, y2, x+round(-body*.5*vec[0]), y+round(-body*.5*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); filledTrigonRGBA (renderer, x1, y1, x2, y2, x+round(-body*.5*vec[0]), y+round(-body*.5*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE);
} }
void View::drawTrail(Aircraft *p) { void View::drawTrails(int left, int top, int right, int bottom) {
int currentX, currentY, prevX, prevY; int currentX, currentY, prevX, prevY;
float dx, dy; float dx, dy;
Aircraft *p = appData->aircraftList.head;
while(p) {
if (p->lon && p->lat) {
if(p->lonHistory.empty()) { if(p->lonHistory.empty()) {
return; return;
} }
// pxFromLonLat(&dx, &dy, p->lonHistory.back(), p->latHistory.back());
// screenCoords(&currentX, &currentY, dx, dy);
// circleRGBA(renderer, currentX, currentY, 4 * screen_uiscale, 255,255,255,127);
std::vector<float>::iterator lon_idx = p->lonHistory.begin(); std::vector<float>::iterator lon_idx = p->lonHistory.begin();
std::vector<float>::iterator lat_idx = p->latHistory.begin(); std::vector<float>::iterator lat_idx = p->latHistory.begin();
std::vector<float>::iterator heading_idx = p->headingHistory.begin(); std::vector<float>::iterator heading_idx = p->headingHistory.begin();
@ -559,11 +561,7 @@ void View::drawTrail(Aircraft *p) {
pxFromLonLat(&dx, &dy, *lon_idx, *lat_idx); pxFromLonLat(&dx, &dy, *lon_idx, *lat_idx);
screenCoords(&prevX, &prevY, dx, dy); screenCoords(&prevX, &prevY, dx, dy);
if(outOfBounds(currentX,currentY)) { if(outOfBounds(currentX,currentY,left,top,right,bottom) && outOfBounds(prevX,prevY,left,top,right,bottom)) {
continue;
}
if(outOfBounds(prevX,prevY)) {
continue; continue;
} }
@ -574,43 +572,11 @@ void View::drawTrail(Aircraft *p) {
thickLineRGBA(renderer, prevX, prevY, currentX, currentY, 2 * screen_uiscale, 255, 255, 255, colorVal); thickLineRGBA(renderer, prevX, prevY, currentX, currentY, 2 * screen_uiscale, 255, 255, 255, colorVal);
//age = pow(1.0 - (float)idx / 10.0f, 2.2);
//colorVal = (uint8_t)floor(255.0 * clamp(age,0.1,1));
// float vec[3];
// vec[0] = sin(*heading_idx * M_PI / 180);
// vec[1] = -cos(*heading_idx * M_PI / 180);
// vec[2] = 0;
// float up[] = {0,0,1};
// float out[3];
// CROSSVP(out,vec,up);
// int x1, y1, x2, y2;
// int cross_size = 5 * screen_uiscale * age;
// // //forward cross
// x1 = currentX + round(-cross_size*vec[0]);
// y1 = currentY + round(-cross_size*vec[1]);
// x2 = currentX + round(cross_size*vec[0]);
// y2 = currentY + round(cross_size*vec[1]);
// thickLineRGBA(renderer,x1,y1,x2,y2,screen_uiscale,255,255,255,64);
// //side cross
// x1 = currentX + round(-cross_size*out[0]);
// y1 = currentY + round(-cross_size*out[1]);
// x2 = currentX + round(cross_size*out[0]);
// y2 = currentY + round(cross_size*out[1]);
// thickLineRGBA(renderer,x1,y1,x2,y2,screen_uiscale,255,255,255,64);
idx--; idx--;
} }
}
p = p->next;
}
} }
void View::drawScaleBars() void View::drawScaleBars()
@ -643,6 +609,18 @@ 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::drawLines(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, 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);
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) {
if(tree == NULL) { if(tree == NULL) {
return; return;
@ -691,51 +669,89 @@ void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen
} }
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<Line*>::iterator currentLine; void View::drawGeography() {
for (currentLine = lineList.begin(); currentLine != lineList.end(); ++currentLine) { if((mapRedraw && !mapMoved) || (mapAnimating && elapsed(lastRedraw) > 8 * FRAMETIME)) {
int x1,y1,x2,y2;
float dx,dy;
if(bailTime) { SDL_SetRenderTarget(renderer, mapTexture);
if (elapsed(drawStartTime) > bailTime) {
return; SDL_SetRenderDrawColor(renderer, style.backgroundColor.r, style.backgroundColor.g, style.backgroundColor.b, 255);
}
SDL_RenderClear(renderer);
drawLines(0, 0, screen_width, screen_height, 0);
SDL_SetRenderTarget(renderer, NULL );
mapMoved = 0;
mapRedraw = 0;
mapAnimating = 0;
lastRedraw = now();
currentLon = centerLon;
currentLat = centerLat;
currentMaxDist = maxDist;
} }
pxFromLonLat(&dx, &dy, (*currentLine)->start.lon, (*currentLine)->start.lat);
SDL_SetRenderDrawColor(renderer, style.backgroundColor.r, style.backgroundColor.g, style.backgroundColor.b, 255);
SDL_RenderClear(renderer);
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); screenCoords(&x1, &y1, dx, dy);
pxFromLonLat(&dx, &dy, centerLon, centerLat);
pxFromLonLat(&dx, &dy, (*currentLine)->end.lon, (*currentLine)->end.lat);
screenCoords(&x2, &y2, dx, dy); screenCoords(&x2, &y2, dx, dy);
lineCount++; shiftx = x1-x2;
shifty = y1-y2;
if(outOfBounds(x1,y1) && outOfBounds(x2,y2)) { SDL_Rect dest;
continue;
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) {
drawLines(0, 0, dest.x, screen_height, FRAMETIME / 4);
} }
if(x1 == x2 && y1 == y2) { //top
continue; if(dest.y > 0) {
drawLines(0, screen_height - dest.y, screen_width, screen_height, FRAMETIME / 4);
} }
lineRGBA(renderer, x1, y1, x2, y2, style.mapInnerColor.r, style.mapInnerColor.g, style.mapInnerColor.b, 255); //right
if(dest.x + dest.w < screen_width) {
drawLines(dest.x + dest.w, 0, screen_width, screen_height, FRAMETIME / 4);
} }
} //bottom
if(dest.y + dest.h < screen_height) {
drawLines(0, 0, screen_width, screen_height - dest.y - dest.h, FRAMETIME / 4);
}
void View::drawGeography(int left, int top, int right, int bottom, int bailTime) { //attempt rest before bailing
float screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max; //drawGeography(dest.x, screen_height - dest.y, dest.x + dest.w, screen_height - dest.y - dest.h, 1);
latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, left, top); SDL_RenderCopy(renderer, mapTexture, NULL, &dest);
latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, right, bottom);
drawLinesRecursive(&(map.root), screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); mapRedraw = 1;
mapMoved = 0;
//drawLines(screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max, bailTime); } else {
SDL_RenderCopy(renderer, mapTexture, NULL, NULL);
}
} }
void View::drawSignalMarks(Aircraft *p, int x, int y) { void View::drawSignalMarks(Aircraft *p, int x, int y) {
@ -768,7 +784,6 @@ void View::drawPlaneText(Aircraft *p) {
int currentLine = 0; int currentLine = 0;
float pressure_scale = 2.0f; //this should be set by a UI slider eventually float pressure_scale = 2.0f; //this should be set by a UI slider eventually
if(p->pressure * screen_width < pressure_scale) { if(p->pressure * screen_width < pressure_scale) {
@ -1103,15 +1118,6 @@ void View::drawPlanes() {
Aircraft *p = appData->aircraftList.head; Aircraft *p = appData->aircraftList.head;
SDL_Color planeColor; SDL_Color planeColor;
// draw all trails first so they don't cover up planes and text
// also find closest plane to selection point
while(p) {
if (p->lon && p->lat) {
drawTrail(p);
}
p = p->next;
}
if(selectedAircraft) { if(selectedAircraft) {
mapTargetLon = selectedAircraft->lon; mapTargetLon = selectedAircraft->lon;
mapTargetLat = selectedAircraft->lat; mapTargetLat = selectedAircraft->lat;
@ -1399,99 +1405,17 @@ void View::draw() {
moveMapToTarget(); moveMapToTarget();
zoomMapToTarget(); zoomMapToTarget();
//updatePlanes();
lineCount = 0;
if((mapRedraw && !mapMoved) || (mapAnimating && elapsed(lastRedraw) > 8 * FRAMETIME)) {
SDL_SetRenderTarget(renderer, mapTexture);
SDL_SetRenderDrawColor(renderer, style.backgroundColor.r, style.backgroundColor.g, style.backgroundColor.b, 255);
SDL_RenderClear(renderer);
drawGeography(0, 0, screen_width, screen_height, 0);
SDL_SetRenderTarget(renderer, NULL );
mapMoved = 0;
mapRedraw = 0;
mapAnimating = 0;
lastRedraw = now();
currentLon = centerLon;
currentLat = centerLat;
currentMaxDist = maxDist;
}
for(int i = 0; i < 4; i++) { for(int i = 0; i < 4; i++) {
resolveLabelConflicts(); resolveLabelConflicts();
} }
//SDL_SetRenderDrawColor( renderer, 0, 15, 30, 0); lineCount = 0;
SDL_SetRenderDrawColor(renderer, style.backgroundColor.r, style.backgroundColor.g, style.backgroundColor.b, 255);
SDL_RenderClear(renderer);
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;
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);
mapRedraw = 1;
mapMoved = 0;
} else {
SDL_RenderCopy(renderer, mapTexture, NULL, NULL);
}
drawGeography();
drawScaleBars(); drawScaleBars();
drawPlanes(); drawPlanes();
drawStatus(); drawStatus();
drawMouse(); //drawMouse();
drawClick(); drawClick();
char fps[40] = " "; char fps[40] = " ";

7
View.h
View file

@ -86,13 +86,14 @@ class View {
void latLonFromScreenCoords(float *lat, float *lon, int x, int y); void latLonFromScreenCoords(float *lat, float *lon, int x, int y);
void screenCoords(int *outX, int *outY, float dx, float dy); void screenCoords(int *outX, int *outY, float dx, float dy);
int outOfBounds(int x, int y); int outOfBounds(int x, int y);
int outOfBounds(int x, int y, int left, int top, int right, int bottom);
void drawPlaneOffMap(int x, int y, int *returnx, int *returny, SDL_Color planeColor); void drawPlaneOffMap(int x, int y, int *returnx, int *returny, SDL_Color planeColor);
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 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);
void drawLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max, int bailTime); void drawLines(int left, int top, int right, int bottom, int bailTime);
void drawGeography(int left, int top, int right, int bottom, int bailTime); void drawGeography();
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);