spdxl/src/aprstat.c

1514 wiersze
42 KiB
C

/*
* dxlAPRS toolchain
*
* Copyright (C) Christian Rabler <oe5dxl@oevsv.at>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#define X2C_int32
#define X2C_index32
#ifndef aprstat_H_
#include "aprstat.h"
#endif
#define aprstat_C_
#ifndef maptool_H_
#include "maptool.h"
#endif
#ifndef aprsdecode_H_
#include "aprsdecode.h"
#endif
#ifndef aprspos_H_
#include "aprspos.h"
#endif
#ifndef osi_H_
#include "osi.h"
#endif
#include <osic.h>
#ifndef aprsstr_H_
#include "aprsstr.h"
#endif
#ifndef useri_H_
#include "useri.h"
#endif
#ifndef aprstext_H_
#include "aprstext.h"
#endif
/* aprs statistc graphs by oe5dxl */
#define aprstat_KMHTIME 600
static void setpix(maptool_pIMAGE img, int32_t x, int32_t y,
int32_t rr, int32_t gg, int32_t bb)
{
struct maptool_PIX * anonym;
{ /* with */
struct maptool_PIX * anonym = &img->Adr[(x)*img->Len0+y];
anonym->r = (uint16_t)rr;
anonym->g = (uint16_t)gg;
anonym->b = (uint16_t)bb;
}
} /* end setpix() */
static void str(maptool_pIMAGE img, uint32_t x, uint32_t y, char s[],
uint32_t s_len)
{
uint32_t i;
uint32_t l;
int32_t inc;
struct aprsdecode_COLTYP col;
X2C_PCOPY((void **)&s,s_len);
l = aprsstr_Length(s, s_len);
i = 0UL;
maptool_Colset(&col, 'W');
while (i<l) {
maptool_drawchar(img, s[i], (float)x, (float)y, &inc, 700UL, 1UL,
col, 0);
x += (uint32_t)inc;
++i;
}
X2C_PFREE(s);
} /* end str() */
static void num(maptool_pIMAGE img, int32_t x, int32_t y, int32_t n,
char h[], uint32_t h_len)
{
char s[51];
X2C_PCOPY((void **)&h,h_len);
aprsstr_IntToStr(n, 1UL, s, 51ul);
aprsstr_Append(s, 51ul, h, h_len);
str(img, (uint32_t)x, (uint32_t)y, s, 51ul);
X2C_PFREE(h);
} /* end num() */
static float sq(float x)
{
return x*x;
} /* end sq() */
static uint32_t pixl(float x, float y)
{
x = x*x+y*y;
if (x<=0.0f) return 0UL;
return aprsdecode_trunc(256.0f*osic_sqrt(x));
} /* end pixl() */
/*
BEGIN RETURN TRUNC(256.0*(ABS(x) + ABS(y))) END pixl;
*/
#define aprstat_KL 512
static void addpix(maptool_pIMAGE img, float x, float y, uint32_t rr,
uint32_t gg, uint32_t bb)
{
float fy;
float fx;
uint32_t l;
uint32_t yy;
uint32_t xx;
struct maptool_PIX * anonym;
struct maptool_PIX * anonym0;
struct maptool_PIX * anonym1;
struct maptool_PIX * anonym2;
xx = aprsdecode_trunc(x);
yy = aprsdecode_trunc(y);
fx = x-(float)xx;
fy = y-(float)yy;
l = pixl(1.0f-fx, 1.0f-fy);
{ /* with */
struct maptool_PIX * anonym = &img->Adr[(xx)*img->Len0+yy];
anonym->r += (uint16_t)((rr*l)/512UL);
anonym->g += (uint16_t)((gg*l)/512UL);
anonym->b += (uint16_t)((bb*l)/512UL);
}
l = pixl(fx, 1.0f-fy);
{ /* with */
struct maptool_PIX * anonym0 = &img->Adr[(xx+1UL)*img->Len0+yy];
anonym0->r += (uint16_t)((rr*l)/512UL);
anonym0->g += (uint16_t)((gg*l)/512UL);
anonym0->b += (uint16_t)((bb*l)/512UL);
}
l = pixl(1.0f-fx, fy);
{ /* with */
struct maptool_PIX * anonym1 = &img->Adr[(xx)*img->Len0+(yy+1UL)];
anonym1->r += (uint16_t)((rr*l)/512UL);
anonym1->g += (uint16_t)((gg*l)/512UL);
anonym1->b += (uint16_t)((bb*l)/512UL);
}
l = pixl(fx, fy);
{ /* with */
struct maptool_PIX * anonym2 = &img->Adr[(xx+1UL)*img->Len0+(yy+1UL)];
anonym2->r += (uint16_t)((rr*l)/512UL);
anonym2->g += (uint16_t)((gg*l)/512UL);
anonym2->b += (uint16_t)((bb*l)/512UL);
}
} /* end addpix() */
#define aprstat_KL0 512
static void fillpix(maptool_pIMAGE img, uint32_t x, uint32_t yfrom,
float yto, uint32_t rr, uint32_t gg, uint32_t bb)
{
float fy;
uint32_t yy;
struct maptool_PIX * anonym;
yy = aprsdecode_trunc(yto);
fy = yto-(float)yy;
while (yfrom<=yy) {
{ /* with */
struct maptool_PIX * anonym = &img->Adr[(x)*img->Len0+yfrom];
anonym->r += (uint16_t)rr;
anonym->g += (uint16_t)gg;
anonym->b += (uint16_t)bb;
}
++yfrom;
}
} /* end fillpix() */
static uint32_t sfact(float y)
{
uint32_t m;
uint32_t s;
s = 1UL;
m = 2UL;
while (X2C_DIVR(y,(float)s)>X2C_DIVR(200.0f,
(float)(aprsdecode_lums.fontysize+2UL))) {
s = s*m;
if (m==2UL) m = 5UL;
else m = 2UL;
}
return s;
} /* end sfact() */
static uint32_t dynmaxx(uint32_t margin, uint32_t min0,
uint32_t max0)
{
if (max0+margin*2UL>(uint32_t)maptool_xsize) {
if ((uint32_t)maptool_xsize>min0) {
max0 = (uint32_t)maptool_xsize-margin*2UL;
}
else max0 = min0-margin*2UL;
}
return max0;
} /* end dynmaxx() */
#define aprstat_MAXT 7200
#define aprstat_X 620
#define aprstat_Y 150
#define aprstat_MARGIN1 16
#define aprstat_XI 636
#define aprstat_YI 166
extern void aprstat_btimehist(maptool_pIMAGE * img, aprsdecode_pOPHIST op)
{
uint32_t t[7200];
aprsdecode_pFRAMEHIST pf;
uint32_t textd;
uint32_t textx;
uint32_t max0;
uint32_t expand;
uint32_t scale0;
uint32_t xm;
uint32_t sum;
uint32_t y;
uint32_t i;
uint32_t dt;
char s[256];
uint32_t tmp;
size_t tmp0[2];
if (op==0) return;
for (i = 0UL; i<=7199UL; i++) {
t[i] = 0UL;
} /* end for */
pf = op->frames;
sum = 0UL;
if (pf) {
while (pf->next) {
if (maptool_vistime(pf->time0) && pf->next->time0>=pf->time0) {
dt = pf->next->time0-pf->time0;
if (dt<=7199UL) {
++t[dt];
++sum;
}
}
pf = pf->next;
}
}
sum -= sum/20UL;
xm = 0UL;
y = 0UL;
do {
y += t[xm];
++xm;
} while (!(xm>=7199UL || y>=sum));
++xm;
if (xm<120UL) xm = 120UL;
for (i = xm+1UL; i<=7199UL; i++) {
t[xm] += t[i]; /* add not shown rest to last shown element */
} /* end for */
scale0 = ((xm+620UL)-1UL)/620UL;
textd = 50UL;
if (scale0>30UL) {
scale0 = 60UL;
textx = 50UL;
}
else if (scale0>12UL) {
scale0 = 30UL;
textx = 20UL;
}
else if (scale0>6UL) {
scale0 = 12UL;
textx = 10UL;
}
else if (scale0>3UL) {
scale0 = 6UL;
textx = 5UL;
}
else if (scale0>2UL) {
scale0 = 3UL;
textx = 3UL;
textd = 60UL;
}
else if (scale0>1UL) {
scale0 = 2UL;
textx = 2UL;
textd = 60UL;
}
else {
scale0 = 1UL;
textx = 1UL;
textd = 60UL;
}
if (scale0>1UL) {
for (i = 1UL; i<=7199UL; i++) {
if (i%scale0==0UL) t[i/scale0] = 0UL;
t[i/scale0] += t[i];
} /* end for */
}
xm = ((xm+scale0)-1UL)/scale0;
expand = 1UL;
if (xm<310UL) expand = 2UL;
else if (xm>620UL) xm = 620UL;
else if (xm==0UL) return;
xm = xm*expand;
max0 = 0UL;
tmp = xm-1UL;
i = 0UL;
if (i<=tmp) for (;; i++) {
if (t[i]>max0) max0 = t[i];
if (i==tmp) break;
} /* end for */
if (max0==0UL) return;
tmp = xm-1UL;
i = 0UL;
if (i<=tmp) for (;; i++) {
t[i] = (t[i]*150UL)/max0;
if (i==tmp) break;
} /* end for */
X2C_DYNALLOCATE((char **)img,sizeof(struct maptool_PIX),
(tmp0[0] = xm+16UL,tmp0[1] = 166U,tmp0),2u);
useri_debugmem.screens += (*img)->Len1*(*img)->Size1;
if (*img==0) {
osi_WrStrLn("error image alloc", 18ul);
return;
}
maptool_clr(*img);
tmp = xm-1UL;
i = 0UL;
if (i<=tmp) for (;; i++) {
setpix(*img, (int32_t)(i+8UL), 7L, 0L, 500L, 800L);
if ((i/expand)%10UL==0UL) {
setpix(*img, (int32_t)(i+8UL), 6L, 0L, 500L, 800L);
}
if ((i/expand)%textd==0UL) {
setpix(*img, (int32_t)(i+8UL), 5L, 0L, 500L, 800L);
setpix(*img, (int32_t)(i+8UL), 4L, 0L, 500L, 800L);
}
for (y = 0UL; y<=149UL; y++) {
setpix(*img, (int32_t)(i+8UL), (int32_t)(y+8UL), 50L,
(int32_t)(20UL*(uint32_t)(char)((i/expand)/10UL&1)
+30UL), 30L);
} /* end for */
y = 0UL;
while (y<t[i/expand]) {
setpix(*img, (int32_t)(i+8UL), (int32_t)(y+8UL), 500L, 500L,
0L);
++y;
}
if (i==tmp) break;
} /* end for */
for (i = 0UL; i<=149UL; i++) {
setpix(*img, 7L, (int32_t)((i+8UL)-1UL), 0L, 500L, 800L);
if (i%10UL==0UL) {
setpix(*img, 6L, (int32_t)((i+8UL)-1UL), 0L, 500L, 800L);
}
} /* end for */
strncpy(s," Beacons per Time ",256u);
aprsstr_Append(s, 256ul, op->call, 9ul);
num(*img, 10L, (int32_t)((166UL-aprsdecode_lums.fontysize)-1UL),
(int32_t)max0, s, 256ul);
num(*img, (int32_t)((expand*textd+8UL)-12UL), 8L, (int32_t)textx, "m",
2ul);
/*
DISPOSE(img);
*/
} /* end btimehist() */
#define aprstat_MAXX 1584
#define aprstat_MINX 584
#define aprstat_MAXY 120
#define aprstat_MARGIN 8
#define aprstat_XSTEPS 8
/* in 1 pixel */
#define aprstat_FILTERLEN 6
/* median filter span in pixels */
#define aprstat_NOINFOTIME 300
/* seconds timeout to no info */
#define aprstat_MINSPAN 3600
#define aprstat_MAXSPAN 28800
extern void aprstat_kmhist(maptool_pIMAGE * img, aprsdecode_pOPHIST op,
char * test)
{
aprsdecode_pFRAMEHIST fold;
aprsdecode_pFRAMEHIST fto;
aprsdecode_pFRAMEHIST ffrom;
aprsdecode_pFRAMEHIST fr;
uint32_t ot;
uint32_t t1;
uint32_t t0;
uint32_t markkm;
uint32_t markx;
uint32_t maxx;
uint32_t maxkm10;
uint32_t maxkm;
uint32_t tf;
uint32_t sp;
uint32_t i;
uint32_t xi;
uint32_t xt;
float ys;
float dy;
float maxy;
char h[256];
char s[256];
struct aprspos_POSITION po;
float vt[12720];
char marks[1584];
uint32_t tops[5];
struct aprsdecode_DAT dat;
uint32_t tmp;
size_t tmp0[2];
if (op==0 || op->frames==0) {
*test = 0;
return;
}
fto = 0;
ffrom = 0;
fr = op->frames;
po = fr->vardat->pos;
fold = 0;
do {
/* find first to last move */
if (((maptool_vistime(fr->time0) && !(fr->nodraw&~0x1U))
&& aprspos_posvalid(fr->vardat->pos)) && aprspos_distance(po,
fr->vardat->pos)>0.05f) {
/* find last move */
fto = fr;
po = fr->vardat->pos;
if (ffrom==0) ffrom = fold;
fold = fr;
}
fr = fr->next;
} while (fr);
if (fto==0 || ffrom==0) {
*test = 0; /* no move */
return;
}
if (*test) return;
*img = 0;
for (xi = 0UL; xi<=1583UL; xi++) {
marks[xi] = 0;
} /* end for */
/*
IF ffrom=NIL THEN ffrom:=op^.frames END;
*/
t1 = fto->time0;
while (ffrom->next && (!(~ffrom->nodraw&0x1U) || ffrom->time0+28800UL<t1))
ffrom = ffrom->next;
t0 = ffrom->time0;
if (t1<t0+3600UL) {
t1 = t0+3600UL;
fto = 0;
}
/* find peak speeds to filter extrem values */
for (i = 0UL; i<=4UL; i++) {
tops[i] = 0UL;
} /* end for */
fr = ffrom;
for (;;) {
if ((!(fr->nodraw&~0x1U) && aprsdecode_Decode(fr->vardat->raw, 500ul,
&dat)>=0L) && dat.speed<X2C_max_longcard) {
i = 0UL;
for (;;) {
if (dat.speed>=tops[i]) {
tops[i] = dat.speed;
break;
}
++i;
if (i>4UL) break;
}
}
if (fr==fto) break;
fr = fr->next;
if (fr==0) break;
}
/*FOR i:=0 TO HIGH(tops) DO WrInt(tops[i], 10) END; */
while ((float)tops[0U]>(float)tops[1U]*1.5f) {
for (i = 0UL; i<=3UL; i++) {
tops[i] = tops[i+1UL];
} /* end for */
}
markx = 0UL;
markkm = 0UL;
maxx = (1584UL*((t1-t0)+3600UL))/28800UL; /* guess picture width */
if (maxx<584UL) maxx = 584UL;
else if (maxx>1584UL) maxx = 1584UL;
ot = t0;
fr = ffrom;
xi = 0UL;
maxy = 0.0f;
dy = 0.0f;
tf = 0UL;
for (;;) {
if ((!(fr->nodraw&~0x1U) && aprsdecode_Decode(fr->vardat->raw, 500ul,
&dat)>=0L) && (!useri_configon(useri_fTRACKFILT)
|| dat.speed<tops[0U])) {
dy = (float)aprsdecode_knottokmh((int32_t)dat.speed)+0.5f;
if (dy>1000.0f) dy = 1000.0f;
if (fr->time0>ot+300UL) tf = 48UL;
xt = aprsdecode_trunc((X2C_DIVR((float)(fr->time0-t0),
(float)(t1-t0)))*(float)(maxx*8UL-1UL));
/* x position in picture */
if (xt>=maxx*8UL-1UL) xt = maxx*8UL;
if (xi/8UL>3UL) marks[xi/8UL-3UL] = 1;
if (dy>maxy) maxy = dy;
while (xi<xt) {
/* constant speed till next waypoint */
vt[xi] = dy;
++xi;
if (tf>0UL) {
--tf;
if (tf==0UL) dy = 0.0f;
}
}
ot = fr->time0;
if ((dat.pos.lat==aprsdecode_click.markpos.lat && dat.pos.long0==aprsdecode_click.markpos.long0)
&& aprsdecode_click.markpost==ot) {
markx = xi/8UL;
markkm = (uint32_t)aprsdecode_knottokmh((int32_t)dat.speed);
}
}
if (fr==fto) break;
fr = fr->next;
if (fr==0) break;
}
tf = 48UL;
while (xi<=12719UL) {
vt[xi] = dy;
++xi;
if (tf>0UL) --tf;
else dy = 0.0f;
}
tmp = maxx*8UL-1UL;
xi = 0UL;
if (xi<=tmp) for (;; xi++) {
dy = 0.0f;
for (xt = 0UL; xt<=47UL; xt++) {
dy = dy+vt[xi+xt]*(1.0f-sq((float)xt*4.1666666666667E-2f-1.0f));
/* FIR lowpass */
} /* end for */
vt[xi] = dy;
if (xi==tmp) break;
} /* end for */
maxkm = aprsdecode_trunc(maxy);
maxkm10 = ((maxkm+9UL)/10UL)*10UL;
if (maxy>=2.0f) {
maxy = X2C_DIVR(3.75f,(float)maxkm10); /* FIR gain integral 1-x^2 */
for (xi = 0UL; xi<=12719UL; xi++) {
vt[xi] = vt[xi]*maxy; /* fit y in picture */
} /* end for */
X2C_DYNALLOCATE((char **)img,sizeof(struct maptool_PIX),
(tmp0[0] = maxx+16UL,tmp0[1] = 136U,tmp0),2u);
useri_debugmem.screens += (*img)->Len1*(*img)->Size1;
if (*img==0) {
osi_WrStrLn("error image alloc", 18ul);
return;
}
maptool_clr(*img);
/*
FOR xt:=MARGIN TO MAXY+MARGIN-1 DO
FOR xi:=MARGIN TO MAXX+MARGIN-1 DO
WITH img^[xi+xt*(MAXX+2*MARGIN)] DO
r:=30; g:=60+50*ORD(ODD(xt DIV 10));
b:=80+200*ORD(marks[xi-MARGIN]);
END;
END;
END;
*/
dy = (X2C_DIVR(120.0f,(float)maxkm10))*10.0f;
ys = 0.0f;
xt = 0UL;
sp = 0UL;
do {
/* draw y scale and paper and waypoints*/
for (i = 6UL-2UL*(uint32_t)(sp%5UL==0UL); i<=8UL; i++) {
setpix(*img, (int32_t)i,
(int32_t)(aprsdecode_trunc(ys+0.5f)+8UL), 200L, 1000L,
200L);
} /* end for */
ys = ys+dy;
while (xt<aprsdecode_trunc(ys) && xt<120UL) {
tmp = (maxx+8UL)-1UL;
xi = 8UL;
if (xi<=tmp) for (;; xi++) {
setpix(*img, (int32_t)xi, (int32_t)(xt+8UL), 20L,
(int32_t)(30UL+50UL*(uint32_t)(char)(sp&1)),
(int32_t)(60UL+200UL*(uint32_t)marks[xi-8UL]));
if (xi==tmp) break;
} /* end for */
++xt;
}
++sp;
} while (ys<121.0f);
tmp = maxx-1UL;
xi = 0UL;
if (xi<=tmp) for (;; xi++) {
setpix(*img, (int32_t)(xi+8UL), 8L, 200L, 1000L, 200L);
if (xi==tmp) break;
} /* end for */
for (xi = 0UL; xi<=120UL; xi++) {
setpix(*img, 8L, (int32_t)(xi+8UL), 200L, 1000L, 200L);
} /* end for */
sp = t0/3600UL+1UL;
ot = sp*3600UL;
ys = X2C_DIVR((float)(maxx*(ot-t0)),(float)(t1-t0));
/* x of first full hour */
dy = X2C_DIVR((float)(maxx*3600UL),(float)(t1-t0));
/* x size of 1h */
if (dy>20.0f && ys<=(float)maxx) {
if (ys-dy*0.5f>0.0f) {
/* draw 1/2 h mark */
for (i = 6UL; i<=7UL; i++) {
setpix(*img, (int32_t)(aprsdecode_trunc(ys-dy*0.5f)+8UL),
(int32_t)i, 200L, 1000L, 200L);
} /* end for */
}
sp = sp+24UL+useri_localtime()/3600UL;
do {
/* draw h and rest of 1/2h marks */
for (i = 4UL; i<=7UL; i++) {
setpix(*img, (int32_t)(aprsdecode_trunc(ys)+8UL),
(int32_t)i, 200L, 1000L, 200L);
} /* end for */
if (ys+dy*0.5f<=(float)maxx) {
for (i = 6UL; i<=7UL; i++) {
setpix(*img, (int32_t)(aprsdecode_trunc(ys+dy*0.5f)+8UL),
(int32_t)i, 200L, 1000L, 200L);
} /* end for */
}
num(*img, (int32_t)((aprsdecode_trunc(ys)+8UL)-6UL), 8L,
(int32_t)(sp%24UL), "h", 2ul);
++sp;
ys = ys+dy;
} while (ys<=(float)maxx);
}
if (markx>3UL) {
markx -= 3UL;
for (xi = 8UL; xi<=128UL; xi++) {
setpix(*img, (int32_t)(markx+8UL), (int32_t)xi, 500L, 200L,
50L);
} /* end for */
}
tmp = maxx*8UL-1UL;
xi = 8UL;
if (xi<=tmp) for (;; xi++) {
/* draw graph */
dy = vt[xi];
if (dy>=0.1f) {
if (dy>120.0f) dy = 120.0f;
addpix(*img, (float)xi*0.125f+8.0f, dy+8.0f, 125UL, 125UL,
12UL);
}
if (xi==tmp) break;
} /* end for */
strncpy(s," ",256u);
aprsstr_Append(s, 256ul, op->call, 9ul);
aprsstr_Append(s, 256ul, " max=", 6ul);
aprsstr_IntToStr((int32_t)maxkm, 1UL, h, 256ul);
aprsstr_Append(s, 256ul, h, 256ul);
if (markx>0UL) {
aprsstr_Append(s, 256ul, " cursor=", 9ul);
aprsstr_IntToStr((int32_t)markkm, 1UL, h, 256ul);
aprsstr_Append(s, 256ul, h, 256ul);
}
aprsstr_Append(s, 256ul, "km/h", 5ul);
num(*img, 10L, (int32_t)((136UL-aprsdecode_lums.fontysize)-1UL),
(int32_t)maxkm10, s, 256ul);
}
/*
IF img<>NIL THEN DISPOSE(img) END;
*/
} /* end kmhist() */
static void paper(maptool_pIMAGE * img, float yax0, float yax1,
uint32_t step, uint32_t margin, uint32_t maxx,
uint32_t maxy, char name[], uint32_t name_len)
{
uint32_t y;
uint32_t x;
int32_t so;
int32_t s;
float v;
struct maptool_PIX * anonym;
uint32_t tmp;
uint32_t tmp0;
X2C_PCOPY((void **)&name,name_len);
so = osi_realint(aprsdecode_floor(X2C_DIVR(yax0,(float)step)));
tmp = maxy-1UL;
y = 0UL;
if (y<=tmp) for (;; y++) {
setpix(*img, (int32_t)margin, (int32_t)(y+margin), 200L, 1000L,
200L);
v = yax0+(yax1-yax0)*(float)y*(X2C_DIVR(1.0f,(float)maxy));
s = osi_realint(aprsdecode_floor(X2C_DIVR(v,(float)step)));
tmp0 = (maxx-1UL)+margin;
x = margin+1UL;
if (x<=tmp0) for (;; x++) {
{ /* with */
struct maptool_PIX * anonym = &(*img)->Adr[(x)*(*img)
->Len0+(y+margin)];
anonym->r += 60U;
anonym->g += (uint16_t)(50UL+40UL*(uint32_t)(char)
(s&1));
anonym->b += 60U;
}
if (x==tmp0) break;
} /* end for */
if (s!=so) {
tmp0 = margin-1UL;
x = margin-3UL;
if (x<=tmp0) for (;; x++) {
setpix(*img, (int32_t)x, (int32_t)(y+margin), 200L, 1000L,
200L);
if (x==tmp0) break;
} /* end for */
num(*img, (int32_t)(margin+1UL), (int32_t)((y+margin)-6UL),
s*(int32_t)step, "", 1ul);
so = s;
}
if (y==tmp) break;
} /* end for */
str(*img, margin+50UL, ((maxy+margin*2UL)-aprsdecode_lums.fontysize)-1UL,
name, name_len);
X2C_PFREE(name);
} /* end paper() */
#define aprstat_MAXXX 720
#define aprstat_MAXY0 120
#define aprstat_MARGIN0 8
#define aprstat_XSTEPS0 8
/* in 1 pixel */
#define aprstat_EMPTY (-10000)
#define aprstat_MAXALT 50000
static float aprstat_E = (-1.E+4f);
static void decodealt(uint32_t * beacons, float * resol, float wdiv,
uint32_t * rejs, uint32_t * acks, uint32_t * msgs,
struct aprsdecode_DAT * dat, float ground[5760],
float alt[5760], char * end, float * waysum,
aprsdecode_pOPHIST op, int32_t * markalt,
uint32_t * markx1, uint32_t * markx, char do0)
{
aprsdecode_pFRAMEHIST fr;
struct aprspos_POSITION opos;
float ognd;
float a3;
float a2;
float a1;
float a;
uint32_t xc;
uint32_t x;
*markx = 0UL;
*markx1 = 0UL;
*markalt = X2C_min_longint;
fr = op->frames;
aprsdecode_posinval(&opos);
*waysum = 0.0f;
xc = 1UL;
a = (-1.E+4f);
a2 = (-1.E+4f);
a3 = (-1.E+4f);
ognd = (-1.E+4f);
*end = 0;
for (x = 0UL; x<=5759UL; x++) {
alt[x] = (-1.E+4f);
} /* end for */
for (x = 0UL; x<=5759UL; x++) {
ground[x] = (-1.E+4f);
} /* end for */
for (;;) {
/* sum up km driven */
if (maptool_vistime(fr->time0) && aprsdecode_Decode(fr->vardat->raw,
500ul, dat)>=0L) {
if (dat->type==aprsdecode_MSG) {
/* count msg stuff */
if (dat->ackrej==aprsdecode_MSGMSG) ++*msgs;
else if (dat->ackrej==aprsdecode_MSGACK) ++*acks;
else ++*rejs;
}
if (!useri_configon(useri_fTRACKFILT) || !(fr->nodraw&~0x1U)) {
if (!aprspos_posvalid(dat->pos)) dat->pos = fr->vardat->pos;
if (aprspos_posvalid(dat->pos)) {
x = aprsdecode_trunc( *waysum*wdiv);
if (aprspos_posvalid(opos)) {
*waysum = *waysum+aprspos_distance(opos, dat->pos);
}
if (dat->altitude>-10000L && dat->altitude<=50000L) {
a1 = (float)dat->altitude;
if (do0) {
if (x>5759UL) x = 5759UL;
if (a2>(-1.E+4f)) {
if (!useri_configon(useri_fTRACKFILT) || (float)
fabs(((a-a1)+a)-a2)*0.25f<(float)fabs(a2-a1)) {
/* median error filter */
if (alt[x]<=(-1.E+4f)) {
alt[x] = a;
xc = 1UL;
}
else {
++xc;
alt[x] = alt[x]*(1.0f-X2C_DIVR(1.0f,
(float)xc))+X2C_DIVR(a,(float)xc);
}
}
}
if (*markalt>X2C_min_longint && *markx==0UL) {
*markx = x/8UL;
}
if ((dat->pos.lat==aprsdecode_click.markpos.lat && dat->pos.long0==aprsdecode_click.markpos.long0)
&& aprsdecode_click.markpost==fr->time0) {
*markalt = dat->altitude;
}
ground[x] = ognd; /* delay same as gps filter */
ognd = maptool_getsrtm(dat->pos, 0UL, resol);
if (ognd>=20000.0f) ognd = (-1.E+4f);
}
if (!*end) a3 = a2;
a2 = a;
a = a1;
}
opos = dat->pos;
}
if (!*end) ++*beacons;
}
}
if (*end) break;
if (fr->next) fr = fr->next;
else *end = 1;
}
if (a3<=(-1.E+4f)) *waysum = 0.0f;
} /* end decodealt() */
static float aprstat_E0 = (-1.E+4f);
static void interpol(float a[], uint32_t a_len)
{
uint32_t j;
uint32_t i;
float k;
float y;
i = 0UL;
j = 0UL;
y = (-1.E+4f);
while (i<=a_len-1) {
if (a[i]>(-1.E+4f)) {
if (y<=(-1.E+4f)) y = a[i];
if (i>j) {
k = X2C_DIVR(1.0f,(float)(i-j));
while (j<i) {
a[j] = y+(a[i]-y)*(1.0f-(float)(i-j)*k);
++j;
}
}
else ++j;
y = a[i];
}
++i;
}
while (j<=a_len-1) {
a[j] = y;
++j;
}
} /* end interpol() */
static float aprstat_E1 = (-1.E+4f);
static void norm(float * hdiv, char * gndok, float ground[5760],
float alt[5760], float * maxaltd, float * minaltd,
float * maxalt, float * minalt)
{
uint32_t i;
*minalt = 2.147483647E+9f;
*maxalt = (-2.147483648E+9f);
*minaltd = 2.147483647E+9f;
*maxaltd = (-2.147483648E+9f);
for (i = 0UL; i<=5759UL; i++) {
/*IF alt[i]>E THEN WrFixed(alt[i], 10, 20); WrStrLn("=alt") END; */
if (alt[i]>(-1.E+4f) && alt[i]<*minaltd) *minaltd = alt[i];
if (alt[i]>*maxaltd) *maxaltd = alt[i];
if (ground[i]>(-1.E+4f) && ground[i]<*minalt) *minalt = ground[i];
if (ground[i]>*maxalt) *maxalt = ground[i];
} /* end for */
if (*minaltd-((*maxaltd-*minaltd)+100.0f)>*minalt || (*maxaltd-*minaltd)
*0.05f>*maxalt-*minalt) {
/* ground graph is too far below */
/* ground graph is a flat line */
*minalt = *minaltd; /* make no ground graph */
*maxalt = *maxaltd;
}
else {
if (*minaltd<*minalt) *minalt = *minaltd;
if (*maxaltd>*maxalt) *maxalt = *maxaltd;
*gndok = 1;
}
if (*maxalt-*minalt>8.3333333333333E-3f) {
*hdiv = X2C_DIVR(120.0f,*maxalt-*minalt); /* normalize */
}
else *hdiv = 1.0f;
for (i = 0UL; i<=5759UL; i++) {
alt[i] = (alt[i]-*minalt)* *hdiv;
ground[i] = (ground[i]-*minalt)* *hdiv;
} /* end for */
} /* end norm() */
extern void aprstat_althist(maptool_pIMAGE * img, aprsdecode_pOPHIST op,
char * test, float * way, uint32_t * beacons,
uint32_t * msgs, uint32_t * acks, uint32_t * rejs)
{
char h[256];
char s[256];
float maxaltd;
float minaltd;
float maxalt;
float minalt;
float ground[5760];
float alt[5760];
float hdiv;
float wdiv;
uint32_t markx1;
uint32_t markx;
uint32_t xc;
uint32_t sc;
uint32_t x;
uint32_t Maxx;
struct aprsdecode_DAT dat;
float resol;
float waysum;
int32_t markalt;
char end;
char gndok;
size_t tmp[2];
uint32_t tmp0;
*way = 0.0f;
*beacons = 0UL;
*msgs = 0UL;
*acks = 0UL;
*rejs = 0UL;
gndok = 0;
minaltd = 0.0f;
maxaltd = 0.0f;
if (op==0 || op->frames==0) {
*test = 0;
return;
}
Maxx = dynmaxx(8UL, 400UL, 720UL);
decodealt(beacons, &resol, wdiv, rejs, acks, msgs, &dat, ground, alt,
&end, &waysum, op, &markalt, &markx1, &markx, 0);
*way = waysum;
if (waysum<0.05f) {
*test = 0; /* no altitudes or km */
return;
}
if (*test) return;
X2C_DYNALLOCATE((char **)img,sizeof(struct maptool_PIX),
(tmp[0] = Maxx+16UL,tmp[1] = 136U,tmp),2u);
useri_debugmem.screens += (*img)->Len1*(*img)->Size1;
if (*img==0) {
osi_WrStrLn("error image alloc", 18ul);
return;
}
maptool_clr(*img);
wdiv = X2C_DIVR((float)(Maxx*8UL-1UL),waysum);
decodealt(beacons, &resol, wdiv, rejs, acks, msgs, &dat, ground, alt,
&end, &waysum, op, &markalt, &markx1, &markx, 1);
interpol(alt, 5760ul);
interpol(ground, 5760ul);
norm(&hdiv, &gndok, ground, alt, &maxaltd, &minaltd, &maxalt, &minalt);
/*
FOR x:=0 TO HIGH(alt) DO
IF alt[x]>=0.0 THEN WrFixed(alt[x], 3,11) ELSE WrStr(".") END;
END;
WrStrLn("");
*/
/*sc:=VAL(CARDINAL, maxalt-minalt) DIV sfact(FLOAT(maxalt-minalt)); */
sc = sfact(maxalt-minalt);
strncpy(s," ",256u);
aprsstr_Append(s, 256ul, op->call, 9ul);
aprsstr_Append(s, 256ul, " dist=", 7ul);
aprsstr_FixToStr(waysum, 2UL, h, 256ul);
aprsstr_Append(s, 256ul, h, 256ul);
aprsstr_Append(s, 256ul, "km min=", 8ul);
aprsstr_IntToStr(osi_realint(minaltd), 1UL, h, 256ul);
aprsstr_Append(s, 256ul, h, 256ul);
aprsstr_Append(s, 256ul, "m max=", 7ul);
aprsstr_IntToStr(osi_realint(maxaltd), 1UL, h, 256ul);
aprsstr_Append(s, 256ul, h, 256ul);
if (markalt>X2C_min_longint) {
aprsstr_Append(s, 256ul, "m curs=", 8ul);
aprsstr_IntToStr(markalt, 1UL, h, 256ul);
aprsstr_Append(s, 256ul, h, 256ul);
}
aprsstr_Append(s, 256ul, "m (NN)", 7ul);
paper(img, minalt, maxalt, sc, 8UL, Maxx, 120UL, s, 256ul);
tmp0 = Maxx+8UL;
x = 5UL;
if (x<=tmp0) for (;; x++) {
setpix(*img, (int32_t)x, 8L, 200L, 1000L, 200L);
if (x==tmp0) break;
} /* end for */
strncpy(h,"km",256u);
if (waysum<5.0f) {
waysum = waysum*1000.0f;
strncpy(h,"m",256u);
}
sc = sfact(waysum);
hdiv = X2C_DIVR((float)sc*(float)Maxx,waysum);
wdiv = 0.0f;
xc = 0UL;
do {
for (x = 5UL; x<=7UL; x++) {
setpix(*img, (int32_t)(aprsdecode_trunc(wdiv)+8UL), (int32_t)x,
200L, 1000L, 200L);
} /* end for */
if (xc>0UL && aprsdecode_trunc(wdiv)<Maxx-10UL) {
num(*img, (int32_t)((aprsdecode_trunc(wdiv)+8UL)-6UL), 8L,
(int32_t)xc, h, 256ul);
h[0U] = 0;
}
xc += sc;
wdiv = wdiv+hdiv;
} while (aprsdecode_trunc(wdiv)<=Maxx);
if (markx>0UL) {
for (x = 8UL; x<=128UL; x++) {
setpix(*img, (int32_t)(markx+8UL), (int32_t)x, 50L, 400L, 500L);
} /* end for */
}
tmp0 = Maxx*8UL-1UL;
x = 0UL;
if (x<=tmp0) for (;; x++) {
/* draw graph */
addpix(*img, (float)x*0.125f+8.0f, alt[x]+8.0f, 62UL, 75UL, 87UL);
if (gndok) {
addpix(*img, (float)x*0.125f+8.0f, ground[x]+8.0f, 31UL, 18UL,
0UL);
}
if (x==tmp0) break;
} /* end for */
if (gndok) {
tmp0 = Maxx-1UL;
x = 0UL;
if (x<=tmp0) for (;; x++) {
fillpix(*img, x+8UL, 8UL, ground[x*8UL]+7.0f, 63UL, 38UL, 0UL);
if (x==tmp0) break;
} /* end for */
}
} /* end althist() */
#define aprstat_TIMESPAN 86400
#define aprstat_MAXXX0 720
#define aprstat_MINXSIZE 320
#define aprstat_MAXY1 120
#define aprstat_MARGIN2 8
#define aprstat_ARRSIZE 1440
/* XSTEP=FLOAT(MAXXX)/FLOAT(ARRSIZE); */
#define aprstat_INCHMM 0.254
/* inch/100 to mm */
#define aprstat_INVAL (-1.E+4)
#define aprstat_MAXJOIN 65
/* maximum interpolated span min */
struct WX;
struct WX {
float temp;
float hyg;
float baro;
float wind;
float rain;
float lumi;
float siev;
};
#define aprstat_F 0.9
static void scale(float v[], uint32_t v_len, float min0,
float max0, float ysize, float maxamp,
float * smin, float * smax, uint32_t * step)
{
uint32_t i;
float d;
float a;
float k;
uint32_t tmp;
if (min0==(-1.E+4f)) {
min0 = 0.0f;
d = max0;
if (d<=maxamp) d = maxamp;
a = X2C_DIVR(ysize,d);
k = 0.0f;
}
else {
d = max0-min0;
if (d<=maxamp) d = maxamp;
a = X2C_DIVR(ysize*0.9f,d);
k = ysize*0.05f;
}
*step = sfact(d);
*smin = min0-X2C_DIVR(k,a);
*smax = min0+X2C_DIVR(k,a)+d;
tmp = v_len-1;
i = 0UL;
if (i<=tmp) for (;; i++) {
if (v[i]!=(-1.E+4f)) v[i] = (v[i]-min0)*a+k;
if (i==tmp) break;
} /* end for */
} /* end scale() */
static char newimg(uint32_t Maxx, maptool_pIMAGE * img)
{
size_t tmp[2];
if (*img==0) {
X2C_DYNALLOCATE((char **)img,sizeof(struct maptool_PIX),
(tmp[0] = Maxx+16UL,tmp[1] = 136U,tmp),2u);
useri_debugmem.screens += (*img)->Len1*(*img)->Size1;
}
if (*img==0) return 0;
maptool_clr(*img);
return 1;
} /* end newimg() */
static void timeline(uint32_t stime, maptool_pIMAGE * img,
uint32_t Maxx)
{
uint32_t y;
uint32_t x;
uint32_t to;
uint32_t t;
uint32_t tmp;
to = 0UL;
tmp = Maxx-1UL;
x = 0UL;
if (x<=tmp) for (;; x++) {
setpix(*img, (int32_t)(x+8UL), 8L, 200L, 1000L, 200L);
t = ((stime+useri_localtime())-(((Maxx-1UL)-x)*86400UL)/Maxx)/3600UL;
if (to==0UL) to = t;
if (to!=t) {
to = t;
for (y = 5UL; y<=7UL; y++) {
setpix(*img, (int32_t)(x+8UL), (int32_t)y, 200L, 1000L,
200L);
} /* end for */
if (x>28UL && t%3UL==0UL) {
num(*img, (int32_t)((x+8UL)-6UL), 8L, (int32_t)(t%24UL), "h",
2ul);
}
}
if (x==tmp) break;
} /* end for */
} /* end timeline() */
static void dots(float XStep, maptool_pIMAGE * img, float v[],
uint32_t v_len, char join, uint32_t r,
uint32_t g, uint32_t b)
{
uint32_t i;
float dx;
float io;
float k;
float yo;
X2C_PCOPY((void **)&v,v_len*sizeof(float));
yo = (-1.E+4f);
io = 0.0f;
i = 0UL;
do {
if (v[i]!=(-1.E+4f)) {
maptool_waypoint(*img, (float)i*XStep+8.0f+0.5f, v[i]+8.0f, 2.0f,
(int32_t)r, (int32_t)g, (int32_t)b);
if (((join && yo!=(-1.E+4f)) && i>aprsdecode_trunc(io))
&& aprsdecode_trunc(io)+65UL>=i) {
k = X2C_DIVR(v[i]-yo,((float)i-io)+1.0f);
if ((float)fabs(k)>2.0f) {
dx = X2C_DIVR(2.0f,(float)fabs(k));
k = k*dx;
}
else dx = 1.0f;
while (aprsdecode_trunc(io)<=i) {
yo = yo+k;
maptool_waypoint(*img, io*XStep+8.0f, yo+8.0f, 1.2f,
(int32_t)(r/2UL), (int32_t)(g/2UL), (int32_t)(b/2UL));
io = io+dx;
}
}
yo = v[i];
io = (float)(i+1UL);
}
++i;
} while (i<=v_len-1);
X2C_PFREE(v);
} /* end dots() */
extern void aprstat_wxgraph(maptool_pIMAGE * img, aprsdecode_pOPHIST op,
uint32_t stime, uint16_t * what,
struct aprstat_LASTVAL * lastval)
{
aprsdecode_pFRAMEHIST fr;
uint32_t Maxx;
uint32_t step;
uint32_t xt;
uint32_t xi;
float XStep;
float yax1;
float yax0;
float vh;
struct WX min0;
struct WX max0;
char hh[256];
char h[256];
char s[256];
struct aprsdecode_DAT dat;
float temp[1440];
float hyg[1440];
float baro[1440];
float winds[1440];
float windd[1440];
float gust[1440];
float rain1[1440];
float rain24[1440];
float rain0[1440];
float lumi[1440];
uint16_t have;
char dirvalid;
struct WX * anonym;
if (op==0 || op->frames==0) {
/*OR (op^.lastinftyp<100)*/
return;
}
Maxx = dynmaxx(8UL, 320UL, 720UL);
XStep = X2C_DIVR((float)Maxx,1440.0f);
*img = 0;
for (xi = 0UL; xi<=1439UL; xi++) {
temp[xi] = (-1.E+4f);
hyg[xi] = (-1.E+4f);
baro[xi] = (-1.E+4f);
winds[xi] = (-1.E+4f);
windd[xi] = (-1.E+4f);
gust[xi] = (-1.E+4f);
rain1[xi] = (-1.E+4f);
rain24[xi] = (-1.E+4f);
rain0[xi] = (-1.E+4f);
lumi[xi] = (-1.E+4f);
} /* end for */
{ /* with */
struct WX * anonym = &max0;
anonym->temp = (-1.E+4f);
anonym->hyg = (-1.E+4f);
anonym->baro = (-1.E+4f);
anonym->wind = (-1.E+4f);
anonym->rain = (-1.E+4f);
anonym->lumi = (-1.E+4f);
anonym->siev = (-1.E+4f);
}
dirvalid = 0;
min0.temp = X2C_max_real;
min0.baro = X2C_max_real;
memset((char *)lastval,(char)0,sizeof(struct aprstat_LASTVAL));
fr = op->frames;
do {
if (((fr->time0>stime-86400UL && fr->time0<=stime)
&& aprsdecode_Decode(fr->vardat->raw, 500ul,
&dat)>=0L) && dat.sym=='_') {
xt = aprsdecode_trunc((float)(fr->time0-(stime-86400UL))
*1.6666666666667E-2f);
if (xt>=1440UL) xt = 1439UL;
vh = X2C_DIVR(dat.wx.temp-32.0f,1.8f);
if (vh>=(-99.0f) && vh<=99.0f) {
temp[xt] = vh;
if (vh>max0.temp) max0.temp = vh;
if (vh<min0.temp) min0.temp = vh;
lastval->temp = vh;
}
if (dat.wx.hygro>=0.0f && dat.wx.hygro<=100.0f) {
hyg[xt] = dat.wx.hygro;
if (dat.wx.hygro>max0.hyg) max0.hyg = dat.wx.hygro;
lastval->hyg = dat.wx.hygro;
}
vh = dat.wx.baro*0.1f;
if (vh>=900.0f && vh<=1100.0f) {
baro[xt] = vh;
if (vh>max0.baro) max0.baro = vh;
if (vh<min0.baro) min0.baro = vh;
lastval->baro = vh;
}
vh = dat.wx.rain24*0.254f;
if (vh>=0.0f && vh<300.0f) {
rain24[xt] = vh;
if (vh>max0.rain) max0.rain = vh;
lastval->rain24 = vh;
}
vh = dat.wx.raintoday*0.254f;
if (vh>=0.0f && vh<300.0f) {
rain0[xt] = vh;
if (vh>max0.rain) max0.rain = vh;
}
vh = dat.wx.rain1*0.254f;
if (vh>=0.0f && vh<300.0f) {
rain1[xt] = vh;
if (vh>max0.rain) max0.rain = vh;
lastval->rain = vh;
}
if (dat.wx.lum>=0.0f && dat.wx.lum<=2000.0f) {
lumi[xt] = dat.wx.lum;
if (dat.wx.lum>max0.lumi) max0.lumi = dat.wx.lum;
lastval->lumi = dat.wx.lum;
}
if (dat.wx.sievert>=0.0f && dat.wx.sievert<1000.0f) {
/* siev[xt]:=dat.wx.sievert; */
if (dat.wx.sievert>max0.siev) max0.siev = dat.wx.sievert;
lastval->siev = dat.wx.sievert;
}
if (dat.course>0UL && dat.course<=360UL) {
lastval->winddir = (float)(dat.course%360UL);
windd[xt] = lastval->winddir;
dirvalid = 1;
}
vh = (float)dat.speed*1.609f;
if (vh>=0.0f && vh<=1000.0f) {
winds[xt] = vh;
lastval->winds = vh;
if (vh>max0.wind) max0.wind = vh;
}
vh = dat.wx.gust*1.609f;
if (vh>=0.0f && vh<=1000.0f) {
gust[xt] = vh;
lastval->gust = vh;
if (vh>max0.wind) max0.wind = vh;
}
}
fr = fr->next;
} while (fr);
aprstext_DateLocToStr(stime, h, 256ul);
aprsstr_Append(h, 256ul, " ", 2ul);
aprsstr_Append(h, 256ul, op->call, 9ul);
have = 0U;
if (max0.temp!=(-1.E+4f)) {
have |= 0x1U;
if ((0x1U & *what)) {
if (!newimg(Maxx, img)) return;
scale(temp, 1440ul, min0.temp, max0.temp, 120.0f, 10.0f, &yax0,
&yax1, &step);
aprsstr_FixToStr(lastval->temp, 2UL, s, 256ul);
aprsstr_Append(s, 256ul, "\177C ", 4ul);
aprsstr_Append(s, 256ul, h, 256ul);
paper(img, yax0, yax1, step, 8UL, Maxx, 120UL, s, 256ul);
timeline(stime, img, Maxx);
dots(XStep, img, temp, 1440ul, 1, 200UL, 700UL, 40UL);
}
}
if (max0.baro!=(-1.E+4f)) {
have |= 0x2U;
if ((0x2U & *what)) {
if (!newimg(Maxx, img)) return;
scale(baro, 1440ul, min0.baro, max0.baro, 120.0f, 2.0f, &yax0,
&yax1, &step);
aprsstr_FixToStr(lastval->baro, 2UL, s, 256ul);
aprsstr_Append(s, 256ul, "hPa ", 5ul);
aprsstr_Append(s, 256ul, h, 256ul);
paper(img, yax0, yax1, step, 8UL, Maxx, 120UL, s, 256ul);
timeline(stime, img, Maxx);
dots(XStep, img, baro, 1440ul, 1, 500UL, 400UL, 500UL);
}
}
if (max0.wind!=(-1.E+4f) && max0.wind>0.0f) {
have |= 0x8U;
if ((0x8U & *what)) {
if (!newimg(Maxx, img)) return;
scale(winds, 1440ul, (-1.E+4f), max0.wind, 120.0f, 20.0f, &yax0,
&yax1, &step);
scale(gust, 1440ul, (-1.E+4f), max0.wind, 120.0f, 20.0f, &yax0,
&yax1, &step);
s[0U] = 0;
if (lastval->winds!=0.0f || lastval->gust==0.0f) {
aprsstr_FixToStr(lastval->winds, 2UL, hh, 256ul);
aprsstr_Append(hh, 256ul, "km/h Wind ", 12ul);
aprsstr_Append(s, 256ul, hh, 256ul);
}
if (lastval->gust!=0.0f) {
aprsstr_FixToStr(lastval->gust, 2UL, hh, 256ul);
aprsstr_Append(hh, 256ul, "km/h Gust ", 12ul);
aprsstr_Append(s, 256ul, hh, 256ul);
}
aprsstr_Append(s, 256ul, h, 256ul);
paper(img, yax0, yax1, step, 8UL, Maxx, 120UL, s, 256ul);
timeline(stime, img, Maxx);
dots(XStep, img, winds, 1440ul, 1, 100UL, 500UL, 700UL);
dots(XStep, img, gust, 1440ul, 1, 600UL, 100UL, 0UL);
}
if (dirvalid) {
have |= 0x10U;
if ((0x10U & *what)) {
if (!newimg(Maxx, img)) return;
scale(windd, 1440ul, (-1.E+4f), 360.0f, 120.0f, 365.0f, &yax0,
&yax1, &step);
aprsstr_FixToStr(lastval->winddir, 0UL, s, 256ul);
aprsstr_Append(s, 256ul, "deg Wind Direction ", 20ul);
aprsstr_Append(s, 256ul, h, 256ul);
paper(img, yax0, yax1, 90UL, 8UL, Maxx, 120UL, s, 256ul);
timeline(stime, img, Maxx);
dots(XStep, img, windd, 1440ul, 0, 200UL, 700UL, 700UL);
}
}
}
if (max0.hyg!=(-1.E+4f)) {
have |= 0x4U;
if ((0x4U & *what)) {
if (!newimg(Maxx, img)) return;
scale(hyg, 1440ul, (-1.E+4f), 100.0f, 120.0f, 101.0f, &yax0, &yax1,
&step);
aprsstr_FixToStr(lastval->hyg, 0UL, s, 256ul);
aprsstr_Append(s, 256ul, "% Humidty ", 11ul);
aprsstr_Append(s, 256ul, h, 256ul);
paper(img, yax0, yax1, step, 8UL, Maxx, 120UL, s, 256ul);
timeline(stime, img, Maxx);
dots(XStep, img, hyg, 1440ul, 1, 0UL, 500UL, 700UL);
}
}
if (max0.lumi!=(-1.E+4f)) {
have |= 0x40U;
if ((0x40U & *what)) {
if (!newimg(Maxx, img)) return;
scale(lumi, 1440ul, (-1.E+4f), max0.lumi, 120.0f, 50.0f, &yax0,
&yax1, &step);
aprsstr_FixToStr(lastval->lumi, 0UL, s, 256ul);
aprsstr_Append(s, 256ul, "W/m^2 Luminosity ", 18ul);
aprsstr_Append(s, 256ul, h, 256ul);
paper(img, yax0, yax1, step, 8UL, Maxx, 120UL, s, 256ul);
timeline(stime, img, Maxx);
dots(XStep, img, lumi, 1440ul, 1, 600UL, 600UL, 0UL);
}
}
if (max0.rain!=(-1.E+4f)) {
have |= 0x20U;
if ((0x20U & *what)) {
if (!newimg(Maxx, img)) return;
scale(rain1, 1440ul, (-1.E+4f), max0.rain, 120.0f, 5.0f, &yax0,
&yax1, &step);
scale(rain24, 1440ul, (-1.E+4f), max0.rain, 120.0f, 5.0f, &yax0,
&yax1, &step);
scale(rain0, 1440ul, (-1.E+4f), max0.rain, 120.0f, 5.0f, &yax0,
&yax1, &step);
aprsstr_FixToStr(lastval->rain, 2UL, s, 256ul);
aprsstr_Append(s, 256ul, "mm Rain ", 9ul);
aprsstr_Append(s, 256ul, h, 256ul);
paper(img, yax0, yax1, step, 8UL, Maxx, 120UL, s, 256ul);
timeline(stime, img, Maxx);
dots(XStep, img, rain1, 1440ul, 1, 500UL, 100UL, 0UL);
dots(XStep, img, rain24, 1440ul, 1, 50UL, 600UL, 50UL);
dots(XStep, img, rain0, 1440ul, 1, 100UL, 100UL, 700UL);
}
}
if (max0.siev>0.0f) have |= 0x400U;
*what = have;
/*
IF img<>NIL THEN DISPOSE(img) END;
*/
} /* end wxgraph() */
extern void aprstat_BEGIN(void)
{
static int aprstat_init = 0;
if (aprstat_init) return;
aprstat_init = 1;
aprstext_BEGIN();
useri_BEGIN();
aprspos_BEGIN();
osi_BEGIN();
aprsdecode_BEGIN();
aprsstr_BEGIN();
maptool_BEGIN();
}