1 #define _USE_MATH_DEFINES 
    2 #include "ClimbAnalyse.h" 
    5                                   double minS, 
double maxdwnHM, 
double minHM,
 
   27 ClimbAnalyse::~ClimbAnalyse(){
 
   28     if(
f != NULL) 
f->~FibunacciHeap();
 
   47             if(c->c->state != climbend)
 
   70     float result = 0, hup, hdown;
 
   71     for(
int i = 0; i < arraylength -1; i++){
 
   74         for(
int j = i+1; j < arraylength; j++){
 
   76                 hup = hup + t[j].h - t[j-1].h;
 
   78                 hdown = hdown -t[j].h + t[j-1].h;
 
   80                 &&  hup / 1000. / (t[j].d - t[i].d) > 
minSlope 
   81                 &&  hup*hup / 1000. / (t[j].d - t[i].d) > result)
 
   82                 result = float(hup*hup / 1000. / (t[j].d - t[i].d));
 
   88                                   double minS, 
double maxdwnHM, 
double minHM){
 
  100             k->cd->
s->
from = NULL;
 
  101             k->cd->
s->
via = NULL;
 
  118 void ClimbAnalyse::init_climb(
climb* c, 
KOO* k){
 
  133     c->
state = climbstart;
 
  156     if(tp != NULL && tp != tpstop){
 
  184             tpl->t.h = t[tpc-1].h;
 
  188         for(
int i = 1; i < tpc; i++){
 
  190             tpl->next->prev = tpl;
 
  193             tpl->t.d = t[i].d + doffset;
 
  197         float dmax = t[tpc-1].d;
 
  198         for(
int i = tpc-2; i >= 0; i--){
 
  200             tpl->next->prev = tpl;
 
  203             tpl->t.d = (dmax-t[i].d) + doffset;
 
  210     float hmdown= 0, hmup = 0;
 
  212     while(t->prev != NULL){
 
  213         if(t->prev->t.h < t->t.h)
 
  214             hmdown = hmdown - t->prev->t.h + t->t.h;
 
  216             hmup = hmup + t->prev->t.h - t->t.h;
 
  217         if(  hmdown*hmdown/(tp->t.d-t->prev->t.d)/1000.> 
minP 
  218             &&hmdown/(tp->t.d-t->prev->t.d)/1000. > 
minSlope 
  227     if(c->
state == outofuse)
 
  238     climb* ct = c, *cfirst = NULL ,*clast = NULL;
 
  241         if(clast == NULL && ct->
state == outofuse)
 
  243         if(ct->
state == outofuse)
 
  247                 dautonom = dautonom + ct->
tend->t.d;
 
  249                 dautonom = dautonom + ct->
t->t.d;
 
  250             if(ct->prev != c->
cst)
 
  251                 dautonom = dautonom - ct->prev->
t->t.d;
 
  253                 dautonom = dautonom - c->
tst->t.d;
 
  257     if(( cfirst == NULL) || 
 
  259         dautonom/(c->
tend->t.d-c->
tst->t.d) > 0.5))
 
  275     float hmdown= 0, hmup = 0;
 
  278     while(t->prev != NULL && t != c->prev->
t){
 
  283         while(t2->prev != NULL){
 
  285             if(t2->prev->t.h < t2->t.h)
 
  286                 hmdown  = hmdown - t2->prev->
t.h + t2->t.h;
 
  288                 hmup    = hmup   + t2->prev->t.h - t2->t.h;
 
  290             if(ccst->
t != NULL && t2->prev->t.d < ccst->
t->t.d)
 
  293             if( (t->t.d-t2->prev->t.d) != 0 &&
 
  296                 hmdown/(t->t.d-t2->prev->t.d)/1000.> 
minSlope &&
 
  297                 hmdown/(t->t.d-t2->prev->t.d)/1000.< 0.35 &&
 
  298                 hmdown*hmdown/(t->t.d-t2->prev->t.d)/1000.> c->
Pmax){
 
  300                 c->
Pmax = float(hmdown*hmdown/(t->t.d-t2->prev->t.d)/1000.);
 
  303                 c->
d = t->t.d-t2->prev->t.d;
 
  306                 c->
hstart = t2->prev->t.h;
 
  353             c->
state = increasing;
 
  355             c->
state = decreasing;
 
  380                 ct->
state = outofuse;
 
  405         while(ct->next != NULL && ct->next != c){
 
  408         if(ct->next != NULL){
 
  409             ct->next = ct->next->next;
 
  420 void ClimbAnalyse::count_climbs(
KOO* k){
 
  472     for(
long i = climbcount-1; i >= 0; i--){
 
  487                 if(ct->via == c->
via)
 
  489                     ct->state = outofuse;
 
  496 short ClimbAnalyse::check(
KOO* k){
 
  499             if(k->cd->
s->
from != NULL){
 
  506         return check(k->l)*check(k->r);
 
  514     while(ct != c->c->
cst){
 
  521     while(ct != c->c->
cst){
 
  527     c->t = 
new Track(narray,nc);
 
  529     if(c->c->
cst->
t == NULL)
 
  532         d0 = c->c->
cst->
t->t.d;
 
  533     c->t->trim_right(c->c->
tend->t.d - d0);
 
  534     c->t->trim_left (c->c->
tst->t.d - d0);
 
  540         result ->climbcount = 0;
 
  543                 result->climbcount++;
 
  546         if(result->climbcount == 0){
 
  561                 result->climb[ci].dhcount  = 
climbpool[i].t->get_array_length();
 
  563                 result->climb[ci].KOOcount = 
climbpool[i].t->get_KOOa_length();
 
  565                 result->climb[ci].
slope    = result->climb[ci].
hmup/ result->climb[ci].
d / 10.;
 
  568                 result->climb[ci].midlat = k.
lat;
 
  569                 result->climb[ci].midlon = k.lon;
 
  570                 result->climb[ci].name = 
climbpool[i].name;
 
  575         for(
long i = 0; i < result->climbcount; i++){
 
  577             for(
long j = 0; j < result->climbcount; j++)
 
  579                         float(result->climb[j].
P 
  580                         * exp(-distance(result->climb[i].midlat,
 
  581                                         result->climb[i].midlon,
 
  582                                         result->climb[j].midlat,
 
  583                                         result->climb[j].midlon)/30)));
 
  584             result->climb[i].
LocRank = result->climb[i].
P / m;
 
  592 climblayer* ClimbAnalyse::load_ClimbLayer(
char* filename){
 
  593     FILE* 
f = fopen(filename,
"rb");
 
  596         fread(&(c->climbcount),
sizeof(c->climbcount),1,f);
 
  598         for(
long i = 0; i < c->climbcount; i++){
 
  599             fread(&(c->climb[i].
d        ),
sizeof(c->climb[i].
d       ),1,f);
 
  600             fread(&(c->climb[i].dhcount  ),
sizeof(c->climb[i].dhcount ),1,f);
 
  601             fread(&(c->climb[i].
hend     ),
sizeof(c->climb[i].
hend    ),1,f);
 
  602             fread(&(c->climb[i].
hmdown   ),
sizeof(c->climb[i].
hmdown  ),1,f);
 
  603             fread(&(c->climb[i].
hmup     ),
sizeof(c->climb[i].
hmup    ),1,f);
 
  604             fread(&(c->climb[i].
hstart   ),
sizeof(c->climb[i].
hstart  ),1,f);
 
  605             fread(&(c->climb[i].KOOcount ),
sizeof(c->climb[i].KOOcount),1,f);
 
  606             fread(&(c->climb[i].
P        ),
sizeof(c->climb[i].
P       ),1,f);
 
  607             fread(&(c->climb[i].
slope    ),
sizeof(c->climb[i].
slope   ),1,f);
 
  608             fread(&(c->climb[i].
bend     ),
sizeof(c->climb[i].
bend    ),1,f);
 
  609             fread(&(c->climb[i].midlat   ),
sizeof(c->climb[i].midlat  ),1,f);
 
  610             fread(&(c->climb[i].midlon   ),
sizeof(c->climb[i].midlon  ),1,f);
 
  612             c->climb[i].dharray = 
new double*[2];
 
  613             c->climb[i].dharray[0] = 
new double[c->climb[i].dhcount];
 
  614             c->climb[i].dharray[1] = 
new double[c->climb[i].dhcount];
 
  615             fread(c->climb[i].dharray[0],
sizeof(
double),c->climb[i].dhcount,f);
 
  616             fread(c->climb[i].dharray[1],
sizeof(
double),c->climb[i].dhcount,f);
 
  617             c->climb[i].KOOarray = 
new double*[2];
 
  618             c->climb[i].KOOarray[0] = 
new double[c->climb[i].KOOcount];
 
  619             c->climb[i].KOOarray[1] = 
new double[c->climb[i].KOOcount];
 
  620             fread(c->climb[i].KOOarray[0],
sizeof(
double),c->climb[i].KOOcount,f);
 
  621             fread(c->climb[i].KOOarray[1],
sizeof(
double),c->climb[i].KOOcount,f);
 
  623             fread(&length,
sizeof(
int),1,f);
 
  625                 c->climb[i].name = 
new char[length+1];
 
  626                 fread(&(c->climb[i].name[0]),
sizeof(
char),length,f);
 
  627                 c->climb[i].name[length] = 
'\0';
 
  630                 c->climb[i].name = NULL;
 
  637 void ClimbAnalyse::save_ClimbLayer(
char* projectname, 
char* folder,
climblayer *c){
 
  639         QString filename = QString(folder).append(projectname).append(
".bbl");
 
  640         FILE* f = fopen(filename.toLocal8Bit().data(),
"wb");
 
  642             fwrite(&(c->climbcount),
sizeof(c->climbcount),1,f);
 
  643             for(
long i = 0; i < c->climbcount; i++){
 
  644                 fwrite(&(c->climb[i].
d       ),
sizeof(c->climb[i].
d       ),1,f);
 
  645                 fwrite(&(c->climb[i].dhcount ),
sizeof(c->climb[i].dhcount ),1,f);
 
  646                 fwrite(&(c->climb[i].
hend    ),
sizeof(c->climb[i].
hend    ),1,f);
 
  647                 fwrite(&(c->climb[i].
hmdown  ),
sizeof(c->climb[i].
hmdown      ),1,f);
 
  648                 fwrite(&(c->climb[i].
hmup    ),
sizeof(c->climb[i].
hmup    ),1,f);
 
  649                 fwrite(&(c->climb[i].
hstart  ),
sizeof(c->climb[i].
hstart      ),1,f);
 
  650                 fwrite(&(c->climb[i].KOOcount),
sizeof(c->climb[i].KOOcount),1,f);
 
  651                 fwrite(&(c->climb[i].
P       ),
sizeof(c->climb[i].
P       ),1,f);
 
  652                 fwrite(&(c->climb[i].
slope   ),
sizeof(c->climb[i].
slope   ),1,f);
 
  653                 fwrite(&(c->climb[i].
bend    ),
sizeof(c->climb[i].
bend    ),1,f);
 
  654                 fwrite(&(c->climb[i].midlat  ),
sizeof(c->climb[i].midlat  ),1,f);
 
  655                 fwrite(&(c->climb[i].midlon  ),
sizeof(c->climb[i].midlon  ),1,f);
 
  659                 fwrite(c->climb[i].dharray[0],
sizeof(
double),c->climb[i].dhcount,f);
 
  660                 fwrite(c->climb[i].dharray[1],
sizeof(
double),c->climb[i].dhcount,f);
 
  661                 fwrite(c->climb[i].KOOarray[0],
sizeof(
double),c->climb[i].KOOcount,f);
 
  662                 fwrite(c->climb[i].KOOarray[1],
sizeof(
double),c->climb[i].KOOcount,f);
 
  665                 if(c->climb[i].name != NULL)
 
  666                    length = strlen(c->climb[i].name);
 
  667                 fwrite(&length,
sizeof(
int),1,f);
 
  669                     fwrite(&(c->climb[i].name[0]),
sizeof(
char),length,f);
 
  675 void ClimbAnalyse::create_MAP(
char* projectname, 
char* folder, 
HeightData* h,
 
  678         double minlat=90,maxlat=-90,minlon=180,maxlon=-180;
 
  679         for(
long i = climbcount-1; i >= 0; i--){
 
  685         QString filename = QString(folder).append(projectname).append(
"climblist.txt");
 
  690 void ClimbAnalyse::create_html(
char* projectname, 
char* folder){
 
  695         QString path0 = QString(folder).append(
"/").append(projectname).append(
"-%1.png");
 
  696         QString path1 = QString(folder).append(
"/").append(projectname).append(
"-BinaryList.src");
 
  697         QString path2 = QString(folder).append(
"/").append(projectname).append(
"-%1.trk");
 
  698         QString path4 = QString(folder).append(
"/").append(projectname).append(
"-names.txt");
 
  704         unsigned int realclimbs =0;
 
  708                 if(
o->
isin(&kt,minlat,maxlat,minlon,maxlon))
 
  714             f = fopen(path1.toLocal8Bit().data(),
"wb");
 
  716             fnames = fopen(path4.toLocal8Bit().data(),
"w");
 
  717             fwrite(&realclimbs,4,1,f);
 
  718             int realindex = -1, length;
 
  722                     if(
o->
isin(&kt,minlat,maxlat,minlon,maxlon)){
 
  732                         sb = short(
climbpool[i].t->get_bend()*100);
 
  742                         QString filename = QString(path0).arg(realindex);
 
  743                         p.save_to_png(filename);
 
  745                         filename = QString(path2).arg(realindex);
 
  751                             fwrite(&(
climbpool[i].name[0]),
sizeof(
char),
 
  753                         fwrite(&newline,
sizeof(
char),1,fnames);
 
  761 void ClimbAnalyse::create_list(
char* projectname, 
char* folder){
 
  763         QString filename = QString(folder).append(
"\\").append(projectname).append(
"climblist.txt");
 
  764         FILE* f = fopen(filename.toLocal8Bit().data(),
"w");
 
  765         for(
long i = climbcount; i >= 0; i--){
 
  767                 fprintf(f,
"%5.1f P\t %4.1f %% \t %.2f km\t %6.1f m\t %6.1f m\t %6.1f m\t %6.1f m\t %6.1f serpentine/km\t%s\t Start-id: %12li\t End-id:%12li \n",
 
  784     if(resident->prev->
home == aspirant->prev->
home){
 
  786         if( (resident->
cst == aspirant->
cst && resident->
t->t.d <= aspirant->
t->t.d) ||
 
  788              resident->
state == increasing && 
 
  789              resident->
P > aspirant->
P)
 
  798 nameaspirant::nameaspirant(
char* name){
 
  799     this->name = QString().fromUtf8(name);
 
  802 nameaspirant::nameaspirant(
char* name, 
float d){
 
  803     this->name = QString().fromUtf8(name);
 
  808     if(this->name == o.name)
 
  814     for(
long i = climbcount-1; i >= 0; i--){
 
  817             QList<nameaspirant> wn;
 
  820             QList<nameaspirant> pn;
 
  831             for(
int i = 0; i < pn.length(); i++)
 
  832                 if(max < (pn[i].e-pn[i].s)*pn[i].d > max){
 
  833                     max = (pn[i].e-pn[i].s)*pn[i].d;
 
  836             if(max>0.125 && !pn[maxi].name.isNull()){
 
  838                 name.append(pn[maxi].name);
 
  842                 for(
int i = 0; i < pn.length(); i++)
 
  843                     if(max < (-pn[i].e+pn[i].s)*pn[i].d > max){
 
  844                         max = (-pn[i].e+pn[i].s)*pn[i].d;
 
  847                 if(max>0.125 && !pn[maxi].name.isNull())
 
  848                     name.append(
" (").append(pn[maxi].name).append(
")");
 
  852             qSort(wn.begin(),wn.end());
 
  853             if(!wn[0].name.isEmpty()){
 
  857                     if(wn.length()>1 && !wn[1].name.isEmpty()
 
  858                        && wn[0].d + wn[1].d > 0.66)
 
  859                         wname.append(wn[0].name)
 
  863             if(!wname.isEmpty()){
 
  865                     name.append(
", ").append(wname);
 
  870             if(!foundname && pn.length() > 0){
 
  871                 qSort(pn.begin(),pn.end());
 
  872                 if(!pn[0].name.isEmpty() && pn[0].d > 0.5)
 
  873                     name.append(
" [").append(pn[0].name).append(
"]");
 
  877                 climbpool[i].name = 
new char[strlen(name.toUtf8().data())+1];
 
  878                 strcpy(
climbpool[i].name,name.toUtf8().data());
 
  881                 QString none = 
"none";
 
  882                 climbpool[i].name = 
new char[strlen(name.toUtf8().data())+1];
 
  883                 strcpy(
climbpool[i].name,name.toUtf8().data());
 
  892     climb* c = c0, *clast;
 
  895         if( i > -1) (*wn)[i].
d += c->
via->
d;
 
  902     int ie = wn->indexOf(clast->via->way->name);
 
  903     (*wn)[is].
d -= c0->
t  ->t.d - c0->
tend  ->t.d;
 
  904     if(c0->
cst->
t != NULL)
 
  905         (*wn)[ie].d -= c0->
tst->t.d - c0->
cst->
t->t.d;
 
  907         (*wn)[ie].d -= c0->
tst->t.d;
 
  908     for(
int i = 0; i < wn->length(); i++)
 
  909         (*wn)[i].d = (*wn)[i].d / c0->
d;
 
  912                                     double fac, 
Track* t, 
bool validstart){
 
  913     bool calcfromindex = fac < 0;
 
  916     KOO ks = t->get_firstKOO();
 
  917     KOO ke = t->get_lastKOO();
 
  919     float hs = h->
height(ks.lon,ks.
lat,NULL,0);
 
  920     float he = h->
height(ke.lon,ke.
lat,NULL,0);
 
  921     float dlimit = distance(ks.
lat,ks.lon,ke.
lat,ke.lon);
 
  923     double latmin,latmax,lonmin,lonmax;
 
  924     t->
get_brect(&latmin,&latmax,&lonmin,&lonmax);
 
  925     double dd = sqrt((latmax-latmin)*(latmax-latmin)+
 
  926                      (lonmax-lonmin)*(lonmax-lonmin));
 
  932         if(o->isin(pts->
k,latmin,latmax,lonmin,lonmax)){
 
  933             if(calcfromindex) fac = 1.1*(1-exp(-sqrt(pts->
index/800)));
 
  936             d = distance(ktt.
lat,ktt.lon,pts->
k->
lat,pts->
k->lon);
 
  940                 pn->last().e = qMax(0.,
 
  941                                     (1-distance(ke.
lat,ke.lon,pts->
k->
lat,pts->
k->lon)
 
  942                                     /dlimit)*(1-qAbs(h0-he)/dh));
 
  944                     pn->last().s = qMax(0.,
 
  945                                         (1-distance(ks.
lat,ks.lon,pts->
k->
lat,pts->
k->lon)
 
  946                                          /dlimit)*(1-qAbs(hs-h0)/dh));
 
  955                              double minlon, 
double maxlon){
 
  957     this->maxlat = maxlat;
 
  958     this->minlon = minlon;
 
  959     this->maxlon = maxlon;
 
void sort_climbpool(long s, long e)
quicksort for collected climbs 
double minlat
bounding rect, saved html data is limited to 
void calc_climb(climb *c)
calcs P, Pmax, Prec, tst of a climb 
KOO * home
cross, climb refers to 
Neighbour * via
connection to reach this STRONG 
void create_names()
create names from OSM data 
void create_climb_Track(climbpoolele *c)
trace back climb to start and creates Track instance from it 
Way * way
Neighbour lives uses this Way. 
double height(double lon, double lat, void *hc, short mode)
returns height data 
void set_parameters(short mintype, short maxtype, double minP, double minSlope, double maxdwnHM, double minHM)
set the definitons of the climb 
short isin(lines *l, double minlat, double maxlat, double minlon, double maxlon)
void collect_climbs(KOO *k)
picks raw climbs from street net, to be selected (select_climbs()) 
float index
for summit ranking 
climbpoolele * climbpool
container to store climbs when collect_climbs() 
KOO * get_first_KOO()
returns root of node-AVL tree 
container struct to hold data of a coordinate 
short next_d(double lat, double lon, double *d)
searches for closest point on track to point (lat,lon) 
climb * cst
start point as climb struct 
short branches
count of branching chilf climbs 
short all_active(climb *c)
checks, whether used road are still avaiable in select_climbs() 
short extract_KOO(KOO *k, double d)
creates KOO refering distance point d 
void get_brect(double *latmin, double *latmax, double *lonmin, double *lonmax)
return bounding rect of Track 
double ** get_d_h_array_copy()
returns deep copy 
short enough_active(climb *c)
checks climb, whether used roads are sufficently independend 
routing container struct, connects cross via Way with each other 
void reset_STRONG(KOO *k)
preparing cross to be inserted into f 
void free_tpl(trackpointlist *tp, trackpointlist *tpstop)
deletes a trackpointlist down to tpstop 
Neighbour * next
next Neighbour, set to NULL if last 
container struct for ClimbAnalyse 
main container list climbanalyse 
STRONG * s
memory for routing algorithms 
climblayer * get_ClimbLayer()
qint64 id
id inherited from OSM data 
trackpointlist * t
track profil so far, to trace back 
char * name
OSM name of point 
holds digital elevation model extracted from SRTM3 data 
trackpointlist * tst
start point in track profil 
official representation of Track in BTP3 
climb * root
root of the whole climb tree 
void save_to_png(QString filename)
save map as picture to hard disk 
void * from
< pointer to STRONG or FibunacciHeap 
plotting 2D-Data sets as the height profile of a track or poweranalysis data 
void to_binary_KOO(char *filename)
save binary KOOa to file (website) 
short crossunused(climb *c, KOO *k)
varifies, that climb has not used the cross at k before 
void select_climbs()
selects collected climbs, if suffiently independed or difficult 
climbstate state
current state at ClimbAnalyse 
void del_climb(climb *c)
deletes the whole climb recursivly 
void set_brect(double minlat, double maxlat, double minlon, double maxlon)
restrict saved data to a rectangular area 
void adapt_brect(double *latmin, double *latmax, double *lonmin, double *lonmax)
increases rect to contain track, if necessary 
void eval_point_names(QList< nameaspirant > *pn, points **p, double fac, Track *t, bool validstart)
create climb name aspirant list from summits and other point data 
short is_climb(trackpointlist *tp)
checks whether the list represents a climb 
void set_data(double **dataxy, int count)
setting one dataset and repaint plot 
int tpc
count of trackpoint 
Neighbour * neighbours
neigbours to link to other cross 
BTP3 database, created from OpenStreetMap data. 
short storeif_climb(Neighbour *n, trackpointlist *tp, climb *from)
checks for existing climbs at cross and executes looses() 
FibunacciHeap< CAfib > * f
priority queue to store active cross sorted by height 
trackpointlist * add(trackpointlist *tp, trackpoint *t, int tpc, readdirection rd)
adds an branch t to a axisting trackpointlist 
float get_bend()
return serpentine index 
Neighbour * via
last used link 
void eval_Way_names(QList< nameaspirant > *wn, climb *c0)
create climb name aspirant list according to street names 
container struct for Track to hold distance and height data 
float calc_P(trackpointlist *tp)
calcs climb difficulty with fixed climb end 
trackpoint * tp
heighdata of this Neighbour 
char * name
name ref owned by lines 
short looses(climb *resident, climb *aspirant)
determines, whether a new climb can stop an existing or vice versa 
double ** get_KOOa_copy()
returns deep copy 
osm data container list for point like data (summits, towns, ...) 
void expand(climb *c)
makes this climb expand over all Neighbour relations