\( \def\bold#1{\bf #1} \newcommand{\d}{\mathrm{d}} \) BTP: Manual and Source Code Documentation

Power Uphill

bike mass [kg]
body mass [kg]
altitude gain [m]
climb length [km]
gradient [%]
time [s]
speed [km/h]
power [W]
power/mass [W/kg]
climbrate [m/min]

average power on climb stage

BTP  3.0
Routing/ClimbAnalysis/PowerCalculation
Routing.cpp
1 #include "Routing.h"
2 
3 Routing::Routing(OSM *o){
4  this->o = o;
5 }
6 Routing::~Routing(void){
7 }
8 short Routing::DijkstraFib(KOO* s, KOO* e, char max, char min, OSM* o,int Si){
9  Neighbour* n;
10  resetSTRONG(o->get_first_KOO(),Si);
12  STRONGfib* t = f.ins(0), *t2;
13  s->cd->s[Si].from = new STRONGfib;
14  ((STRONGfib*)(s->cd->s[Si].from))->d = -1;
15  s->cd->s[Si].via = NULL;
16  t->k = s;
17  t->from = NULL;
18  t->via = s->cd->neighbours;
19 
20  t = f.extmin();
21  while(t != NULL && t->d >-1){
22  /*Die Prioritaetswarteliste hatte noch Elemente und das gewaehlte
23  Element ist nicht zum ueberspringen freigegeben (d.h. t->d = -1)*/
24  n = t->k->cd->neighbours;
25  while(n != NULL){
26  if(n->way->type >= min && n->way->type <= max ){
27  /*Der Weg erfüllt die Anforderung an den Typ und hat die
28  Prioritaetswarteschlange noch nie durchlaufen*/
29  if( n->nb->cd->s[Si].from == NULL
30  && n->nb->cd->s[Si].via == NULL){
31  /*KOO wurde noch nie erreicht*/
32  t2 = f.ins(t->d + n->d);
33  t2->k = n->nb;
34  t2->from = &(t->k->cd->s[Si]);
35  t2->via = n;
36  n->nb->cd->s[Si].from = t2;
37  }
38  else{
39  /*KOO wurde schon erreicht, pruefe: hat der Punkt die
40  Prioritaetswarteschlange schon wieder verlassen, falls
41  nicht: pruefe, ob Distanz jetzt kuerzer ist*/
42  if( n->nb->cd->s[Si].via == NULL &&
43  ((STRONGfib*)(n->nb->cd->s[Si].from))->d > t->d + n->d){
44  /*alten Eintrag löschen und neuen erzeugen*/
45  ((STRONGfib*)(n->nb->cd->s[Si].from))->d = -1;
46  t2 = f.ins(t->d + n->d);
47  t2->k = n->nb;
48  t2->from = &(t->k->cd->s[Si]);
49  t2->via = n;
50  n->nb->cd->s[Si].from = t2;
51  }
52  }
53  }
54  n = n->next;
55  }
56  /*KOO ist abgehandelt, Daten koennen gespeichert werden*/
57  t->k->cd->s[Si].via = t->via;
58  t->k->cd->s[Si].from = t->from;
59 
60 
61  if(t->k != e)
62  do{
63  delete(t); //Datenstruktur des FibunacciHeap free
64  t = f.extmin();//naechste zu bearbeitende KOO
65  }while(t != NULL && t->d < 0);
66  else
67  t->d = -1; //Endpunkt erreicht
68  }
69 
70  if(t == NULL)
71  return 0; //Endpunkt wurde nicht erreicht
72  else{
73  delete(t);
74  return 1; //Endpunkt wurde erreicht
75  }
76 }
77 short Routing::DijkstraFib_minHM(KOO* s, KOO* e, char max, char min, OSM* o,
78  int Si){
79  Neighbour* n;
80  resetSTRONG(o->get_first_KOO(),Si);
82  STRONGfib* t = f.ins(0), *t2;
83  s->cd->s[Si].from = new STRONGfib;
84  ((STRONGfib*)(s->cd->s[Si].from))->d = -1;
85  s->cd->s[Si].via = NULL;
86  t->k = s;
87  t->from = NULL;
88  t->via = s->cd->neighbours;
89 
90  t = f.extmin();
91  while(t != NULL && t->d >-1){
92  /*Die Prioritaetswarteliste hatte noch Elemente und das gewaehlte
93  Element ist nicht zum ueberspringen freigegeben (d.h. t->d = -1)*/
94  n = t->k->cd->neighbours;
95  while(n != NULL){
96  if(n->way->type >= min && n->way->type <= max ){
97  /*Der Weg erfüllt die Anforderung an den Typ und hat die
98  Prioritaetswarteschlange noch nie durchlaufen*/
99  if(n->nb->cd->s[Si].from == NULL && n->nb->cd->s[Si].via == NULL){
100  /*KOO wurde noch nie erreicht*/
101  t2 = f.ins(t->d + n->hm);
102  t2->k = n->nb;
103  t2->from = &(t->k->cd->s[Si]);
104  t2->via = n;
105  n->nb->cd->s[Si].from = t2;
106  }
107  else{
108  /*KOO wurde schon erreicht, pruefe: hat der Punkt die
109  Prioritaetswarteschlange schon wieder verlassen, falls
110  nicht: pruefe, ob Distanz jetzt kuerzer ist*/
111  if( n->nb->cd->s[Si].via == NULL &&
112  ((STRONGfib*)(n->nb->cd->s[Si].from))->d > t->d + n->hm){
113  /*alten Eintrag löschen und neuen erzeugen*/
114  ((STRONGfib*)(n->nb->cd->s[Si].from))->d = -1;
115  t2 = f.ins(t->d + n->hm);
116  t2->k = n->nb;
117  t2->from = &(t->k->cd->s[Si]);
118  t2->via = n;
119  n->nb->cd->s[Si].from = t2;
120  }
121  }
122  }
123  n = n->next;
124  }
125  /*KOO ist abgehandelt, Daten koennen gespeichert werden*/
126  t->k->cd->s[Si].via = t->via;
127  t->k->cd->s[Si].from = t->from;
128 
129 
130  if(t->k != e)
131  do{
132  delete(t); //Datenstruktur des FibunacciHeap free
133  t = f.extmin();//naechste zu bearbeitende KOO
134  }while(t != NULL && t->d < 0);
135  else
136  t->d = -1; //Endpunkt erreicht
137  }
138 
139  if(t == NULL)
140  return 0; //Endpunkt wurde nicht erreicht
141  else{
142  delete(t);
143  return 1; //Endpunkt wurde erreicht
144  }
145 
146 }
147 void Routing::resetSTRONG(KOO* k, int STRONGindex){
148  if(k != NULL){
149  if(k->cd != NULL)
150  if(k->cd->s != NULL){
151  k->cd->s[STRONGindex].from = NULL;
152  k->cd->s[STRONGindex].via = NULL;
153  }
154  resetSTRONG(k->r, STRONGindex);
155  resetSTRONG(k->l, STRONGindex);
156  }
157 }
158 void Routing::setSTRONG(KOO* k, KOO* s, KOO* e, float radius, int n){
159  if(k != NULL){
160  if(k->cd != NULL){
161  if( s == NULL || e == NULL ||
162  distance(k->lat,k->lon,s->lat,s->lon)
163  +distance(k->lat,k->lon,e->lat,e->lon) < radius){
164  delete(k->cd->s);
165  k->cd->s = new STRONG[n];
166  for(int i = 0; i < n; i++){
167  k->cd->s[i].from = NULL;
168  k->cd->s[i].via = NULL;
169  }
170  }
171  else{
172  delete(k->cd->s);
173  k->cd->s = NULL;
174  }
175  }
176  setSTRONG(k->l, s, e, radius, n);
177  setSTRONG(k->r, s, e, radius, n);
178  }
179 }
181  Neighbour ***nl,int* nc){
182  STRONG* st = e;
183  int nct = 0;
184  while(st != s){
185  st = (STRONG*)st->from;
186  nct++;
187  }
188  *nl = new Neighbour*[nct];
189  *nc = nct;
190  st = e;
191  while(st != s){
192  nct--;
193  (*nl)[nct] = st->via;
194  st = (STRONG*)st->from;
195  }
196 }
198  setSTRONG(o->get_first_KOO(), NULL, NULL,0,2);
199 }
201  if(k!= NULL){
202  if(k->cd != NULL){
203  Neighbour* n = k->cd->neighbours;
204  while(n != NULL){
205  n->d = 0;
206  n = n->next;
207  }
208  }
209  STRONGlayer_reset_d(k->l);
210  STRONGlayer_reset_d(k->r);
211  }
212 }
214  if(k!= NULL){
215  if(k->cd != NULL){
216  Neighbour* n = k->cd->neighbours;
217  while(n != NULL){
218  n->d = n->tp[n->tpc-1].d;
219  n = n->next;
220  }
221  }
224  }
225 }
227  if(k!= NULL){
228  if(k->cd != NULL){
229  if(k->lon > SLlonmax) SLlonmax = k->lon;
230  if(k->lon < SLlonmin) SLlonmin = k->lon;
231  if(k->lat > SLlatmax) SLlatmax = k->lat;
232  if(k->lat < SLlatmin) SLlatmin = k->lat;
233  Neighbour* n = k->cd->neighbours;
234  while(n != NULL){
235  if(n->rd == fw) (*nbc)++;
236  n = n->next;
237  }
238  }
239  STRONGlayer_count_neighbours(k->l, nbc);
240  STRONGlayer_count_neighbours(k->r, nbc);
241  }
242 }
244  if(k!= NULL){
245  if( k->cd != NULL
246  && k->cd->s != NULL
247  && k->cd->s[si].from != NULL)
248  if(STRONGlayer_grid_free(k)){
249  STRONG* s = &(k->cd->s[si]);
250  while(s != NULL){
251  if(s->via->rd == fw) s->via->d ++;
252  else s->via->brthr->d ++;
253  s = (STRONG*) s->from;
254  }
255  }
256  STRONGlayer_mark_neighbours(k->l, si);
257  STRONGlayer_mark_neighbours(k->r, si);
258  }
259 }
261  int *nbc){
262  if(k!= NULL){
263  if(k->cd != NULL){
264  Neighbour* n = k->cd->neighbours;
265  while(n != NULL){
266  if(n->rd == fw){
267  data[*nbc].n = n;
268  (*nbc)++;
269  }
270  n = n->next;
271  }
272  }
273  STRONGlayer_fill_neighbours(k->l, data, nbc);
274  STRONGlayer_fill_neighbours(k->r, data, nbc);
275  }
276 }
278  double gridperkm = 0.5;
279  SLlatmax = SLlatmax +0.01;
280  SLlonmax = SLlonmax +0.01;
281  SLlatmin = SLlatmin -0.01;
282  SLlonmin = SLlonmin -0.01;
285  nlat = dlat*111*gridperkm;
286  nlon = dlon*111*sin(double((SLlatmax+SLlatmin)/360.*3.14159265))*gridperkm;
287  SLgrid = new char*[nlon];
288  for(int x = 0; x < nlon; x++){
289  SLgrid[x] = new char[nlat];
290  }
291 }
293  for(int x = 0; x < nlon; x++)
294  for(int y = 0; y < nlat; y++)
295  SLgrid[x][y] = 0;
296 }
298  int x = int((k->lon-SLlonmin)/dlon*nlon);
299  int y = int((k->lat-SLlatmin)/dlat*nlat);
300  if( x >= 0 && x < nlon && y >= 0 && y < nlat && SLgrid[x][y] == 0){
301  SLgrid[x][y] = 1;
302  return 1;
303  }
304  else
305  return 0;
306 }
308  for(int x = 0; x < nlon; x++)
309  delete(SLgrid[x]);
310  delete(SLgrid);
311 }
313  if(SL == NULL) return STRONGlayer_create(N);
314  /*andernfalls liegen neighbourpointer schon vor*/
315  /*Indeces absammeln*/
319  // for(int i = 0; i <= N; i++)
321  for(int j = 0; j < SL->ncount; j++){
322  /*double maxq = 0, d,hm;
323  for(int i = 10; i < N; i++){
324  STRONG* s = &(SL->data[j].n->brthr->nb->cd->s[i]);
325  d = hm = 0;
326  while(s != NULL){
327  d += s->via->d;
328  hm += s->via->hm;
329  s = (STRONG*) s->from;
330  }
331  if(d > 0 && hm/d > maxq)
332  maxq = hm/d;
333  }
334  SL->data[j].index = maxq;*/
335  SL->data[j].index = SL->data[j].n->d;
336 
337  }
339 
340  /*Indeces normieren*/
341  float max = 0;
342  for(int j = 0; j < SL->ncount; j++){
343  if(SL->data[j].index > max)
344  max = SL->data[j].index;
345  }
346  for(int j = 0; j < SL->ncount; j++){
347  SL->data[j].index = SL->data[j].index / max;
348  }
349  /*Distanz wieder herstellen (wurde zum Rechnen benutzt)*/
351 
352  STRONGlayer_sort(SL,0,SL->ncount-1);
353  return SL;
354 }
356  int nbc = 0;
357  SLlonmax = -90; SLlatmax = -180; SLlonmin = 90; SLlatmin = 180;
359  STRONGlayer* SL = new STRONGlayer;
360  SL->ncount = nbc;
361  SL->data = new STRONGlayerele[nbc];
362 
363  /*Nachbarschaftrelation ins Array laden*/
364  nbc = 0;
365  STRONGlayer_fill_neighbours(o->get_first_KOO(),SL->data,&nbc);
366 
367  SL = STRONGlayer_create(SL,N);
368  return SL;
369 }
371  qint64 kid,knid; KOO* k;
372  FILE* f = fopen(filename,"rb");
373  STRONGlayer* SL = new STRONGlayer;
374  fread(&(SL->ncount),sizeof(int),1,f);
375  SL->data = new STRONGlayerele[SL->ncount];
376  Neighbour* n;
377  for(int j = 0; j < SL->ncount; j++){
378  fread(&(kid),sizeof(qint64),1,f);
379  fread(&(knid),sizeof(qint64),1,f);
380  fread(&(SL->data[j].index),sizeof(float),1,f);
381  k = o->search(kid,o->get_first_KOO());
382  if(k != NULL && k->cd != NULL){
383  n = k->cd->neighbours;
384  while( n!= NULL && n->nb->id != knid){
385  n = n->next;
386  }
387  if(n != NULL)
388  SL->data[j].n = n;
389  else
390  SL->data[j].n = NULL;
391  }
392  else
393  SL->data[j].n = NULL;
394  }
395  fclose(f);
396  return SL;
397 }
398 void Routing::STRONGlayer_save(char* filename, STRONGlayer *SL){
399  /*Datei speichern*/
400  FILE* f = fopen(filename,"wb");
401  fwrite(&(SL->ncount),sizeof(int),1,f);
402  for(int j = 0; j < SL->ncount; j++){
403  fwrite(&(SL->data[j].n->node[0]->id),sizeof(qint64),1,f);
404  fwrite(&(SL->data[j].n->nb->id),sizeof(qint64),1,f);
405  fwrite(&(SL->data[j].index),sizeof(float),1,f);
406  }
407  fclose(f);
408 }
409 void Routing::STRONGlayer_sort(STRONGlayer* SL, long s, long e){
410  long l = s, r = e;
411  STRONGlayerele c;
412  float p = SL->data[(s+e)/2].index;
413  do{
414  while(SL->data[l].index < p) l++;
415  while(SL->data[r].index > p) r--;
416  if(l<=r){
417  c = SL->data[l];
418  SL->data[l] = SL->data[r];
419  SL->data[r] = c;
420  l++;
421  r--;
422  }
423  }while(l <= r);
424  if(s < r) STRONGlayer_sort(SL,s,r);
425  if(l < e) STRONGlayer_sort(SL,l,e);
426 }
427 
Neighbour * via
connection to reach this STRONG
Definition: DataTyps.h:258
void STRONGlayer_save(char *filename, STRONGlayer *SL)
saves STRONGlayer to file
Definition: Routing.cpp:398
float index
connection to be drawn
Definition: DataTyps.h:346
Way * way
Neighbour lives uses this Way.
Definition: DataTyps.h:53
double SLlatmax
Definition: Routing.h:91
void STRONGlayer_count_neighbours(KOO *k, int *nbc)
counts total Neighbour count on osm data set
Definition: Routing.cpp:226
list elements to handle multiple STRONGlayers
Definition: DataTyps.h:349
KOO * get_first_KOO()
returns root of node-AVL tree
Definition: osm.cpp:1692
container struct to hold data of a coordinate
Definition: DataTyps.h:82
STRONGlayer * STRONGlayer_load(char *filename)
loades STRONGlayer from file
Definition: Routing.cpp:370
STRONG * from
pointer to related STRONG struct
Definition: DataTyps.h:265
KOO ** node
reference to KOO (of way)
Definition: DataTyps.h:61
double lat
Definition: DataTyps.h:86
KOO * nb
Definition: DataTyps.h:54
void extract_neighbourlist(STRONG *s, STRONG *e, Neighbour ***nl, int *nc)
collects a Neighbour list from STRONG network
Definition: Routing.cpp:180
void finish_STRONG()
resets STRONG network of a STRONGcalc to normal Dijkstra state
Definition: Routing.cpp:197
FibunacciHeap element to store STRONG data.
Definition: DataTyps.h:261
short STRONGlayer_grid_free(KOO *k)
Definition: Routing.cpp:297
routing container struct, connects cross via Way with each other
Definition: DataTyps.h:47
Neighbour * next
next Neighbour, set to NULL if last
Definition: DataTyps.h:63
void STRONGlayer_grid_new()
Definition: Routing.cpp:277
base information to draw road section in STRONGlayers
Definition: DataTyps.h:344
STRONG * s
memory for routing algorithms
Definition: DataTyps.h:75
qint64 id
id inherited from OSM data
Definition: DataTyps.h:83
double dlon
Definition: Routing.h:91
readdirection rd
Definition: DataTyps.h:52
double SLlonmin
Definition: Routing.h:91
char type
classification
Definition: DataTyps.h:129
float d
current distance at STRONG
Definition: DataTyps.h:263
Neighbour * via
connection to STRONG
Definition: DataTyps.h:267
KOO * search(qint64 id, KOO *s)
Definition: osm.cpp:105
void * from
&lt; pointer to STRONG or FibunacciHeap
Definition: DataTyps.h:257
void resetSTRONG(KOO *k, int STRONGindex)
resets the STRONG network to begin calculation
Definition: Routing.cpp:147
KOO * k
current KOO
Definition: DataTyps.h:266
void setSTRONG(KOO *k, KOO *s, KOO *e, float radius, int n)
body of finish_STRONG();
Definition: Routing.cpp:158
void STRONGlayer_mark_neighbours(KOO *k, int si)
increment Neighbour attribute d by its usage rate on STRONG network
Definition: Routing.cpp:243
double SLlonmax
Definition: Routing.h:91
short DijkstraFib_minHM(KOO *s, KOO *e, char max, char min, OSM *o, int Si)
see DijkstraFib(), but minimizing Hm instead of distance
Definition: Routing.cpp:77
float d
distance
Definition: DataTyps.h:58
void STRONGlayer_grid_delete()
Definition: Routing.cpp:307
STRONGlayer * STRONGlayer_create(STRONGlayer *SL, int N)
creates STRONGlayer from a unfinalized STRONG network
Definition: Routing.cpp:312
int tpc
count of trackpoint
Definition: DataTyps.h:60
Neighbour * neighbours
neigbours to link to other cross
Definition: DataTyps.h:74
BTP3 database, created from OpenStreetMap data.
Definition: osm.h:34
void STRONGlayer_reconstruct_d(KOO *k)
reconstructs Neighbour distance attribute d from Way data
Definition: Routing.cpp:213
short DijkstraFib(KOO *s, KOO *e, char max, char min, OSM *o, int Si)
this is famous Dijkstra shortes path algothim
Definition: Routing.cpp:8
double SLlatmin
Definition: Routing.h:91
double dlat
Definition: Routing.h:91
void STRONGlayer_sort(STRONGlayer *SL, long s, long e)
quicksort neighbours by its usage rate
Definition: Routing.cpp:409
void STRONGlayer_fill_neighbours(KOO *k, STRONGlayerele *data, int *nbc)
copy Neighbour attribut d to STRONGlayer data
Definition: Routing.cpp:260
float hm
total height meter, for routing
Definition: DataTyps.h:57
trackpoint * tp
heighdata of this Neighbour
Definition: DataTyps.h:62
int nlat
Definition: Routing.h:90
void STRONGlayer_grid_reset()
Definition: Routing.cpp:292
char ** SLgrid
Definition: Routing.h:89
int nlon
Definition: Routing.h:90
void STRONGlayer_reset_d(KOO *k)
sets Neighbour distance attribute d to zero
Definition: Routing.cpp:200
Neighbour * brthr
related Neighbour with opposite read direction supposed to store brthr
Definition: DataTyps.h:56
main struct for routing purpose
Definition: DataTyps.h:255