\( \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
WayHeight.cpp
1 #define _USE_MATH_DEFINES
2 #include "WayHeight.h"
3 
5  o = O;
6  h = H;
7  dstep0 = 0.01;
8  glacerate = int(2/dstep0);
9  dmin = 0.5;
10  dminur = 0.15;
11  rlimit = 2;
12  flach2 = 50;
13 
19  call_height_t();
21  glaze();
22  //show_d_h(o->get_first_KOO());
23  //show_d_confidence(o->get_first_KOO());
26 
32 }
33 WayHeight::WayHeight(HeightData* H,double* lat, double* lon,
34  int count,Neighbour** nb){
35  OSM ot;
36  o = &ot;
37  h = H;
38  double minlat = lat[0], maxlat = lat[0], minlon = lon[0], maxlon = lon[0];
39  KOO* nodes = new KOO[count];
40  KOO** node = new KOO*[count];
41  for(int i = 0; i < count; i++){
42  if(minlat > lat[i]) minlat = lat[i];
43  if(maxlat < lat[i]) maxlat = lat[i];
44  if(minlon > lon[i]) minlon = lon[i];
45  if(maxlon < lon[i]) maxlon = lon[i];
46  nodes[i].lat = lat[i];
47  nodes[i].lon = lon[i];
48  nodes[i].l = NULL;
49  nodes[i].cd = NULL;
50  nodes[i].status = NULL;
51  node[i] = &(nodes[i]);
52  }
53  for(int i = 1; i < count; i++)
54  nodes[i-1].r = &(nodes[i]);
55  nodes[count-1].r = NULL;
56  minlat -= 0.1;
57  maxlat += 0.1;
58  minlon -= 0.2;
59  maxlon += 0.2;
60  Way* w= new Way;
61  w->type = 1;
62  w->nodec = count;
63  w->l = w->r = NULL;
64  w->node = node;
65  dstep0 = 0.01;
66  glacerate = int(2/dstep0);
67  dmin = 0.5;
68  dminur = 0.15;
69  rlimit = 2;
70  flach2 = 50;
71  // trick to avoid stack overflow by deep rekursion of heavy functions
72  node[0]->r = node[count-1];
73  reset_cross_markers(node[0]);
74  mark_cross(w);
75  alloc_crossdata(node[0]);
77  h->reset_t(minlat,maxlat,minlon,maxlon);
78  add_raw_HeightData(node[0]);
79  glaze();
80  calc_crossheight(node[0]);
81  reduce_data(node[0]);
82  *nb = &(node[0]->cd->neighbours[0]);
83 }
84 
85 WayHeight::~WayHeight(){}
86 
88  if(k != NULL){
89  k->status = 0;
90  reset_cross_markers(k->l);
91  reset_cross_markers(k->r);
92  }
93 }
95  if(w != NULL){
96  if(w->type < 6){
97  for(int i = 1; i<w->nodec-1 ;i++)
98  w->node[i]->status++;
99  w->node[0]->status = 2;
100  w->node[w->nodec-1]->status = 2;
101  }
102  mark_cross(w->l);
103  mark_cross(w->r);
104  }
105 }
107  if(k!=NULL){
108  if(k->status > 1){
109  if(k->cd == NULL){
110  k->cd = (crossdata*)malloc(sizeof(crossdata));
111  k->cd->neighbours = NULL;
112  k->cd->s = (STRONG*)malloc(sizeof(STRONG));
113  k->cd->s->from = NULL;
114  k->cd->s->via = NULL;
115  }
116  k->status = 2;
117  }
118  alloc_crossdata(k->l);
119  alloc_crossdata(k->r);
120  }
121 }
123  if(w != NULL){
124  if(w->type < 6){
125  float d = 0;
126  int iold = 0;
127  for(int i = 1; i < w->nodec; i++){
128  d = d + distance(w->node[i] ->lat,w->node[i] ->lon,
129  w->node[i-1]->lat,w->node[i-1]->lon);
130  if(w->node[i]->status > 1){
131  Neighbour *n1 = NULL, *n2 = NULL;
132  n1 = o->add_Neighbour(w->node[iold],&(w->node[iold]),
133  w->node[i ],w,d,i-iold+1,fw);
134  n2 = o->add_Neighbour(w->node[i], &(w->node[iold]),
135  w->node[iold],w,d,i-iold+1,bw);
136 
137  if(n1 != NULL && n2 != NULL){
138  n1->brthr = n2;
139  n2->brthr = n1;
140  }
141  else{
142  /*Kreisverkehr*/
143  if(n1 != NULL) n1->brthr = n1;
144  if(n2 != NULL) n2->brthr = n2;
145  if((n1 != NULL || n2 != NULL)&&w->node[i] != w->node[iold])
146  QMessageBox(QMessageBox::NoIcon,
147  "Error",
148  "Neighbour add failure").exec();
149  }
150  d = 0;
151  iold = i;
152  }
153  }
154  }
155  alloc_neighbours(w->l);
156  alloc_neighbours(w->r);
157  }
158 }
160  double latmin = 90, latmax = -90, lonmin = 180, lonmax = -180;
161  check_brect(o->get_first_Way(),&latmin,&latmax,&lonmin,&lonmax);
162  latmin -= 0.1;
163  latmax += 0.1;
164  lonmin -= 0.2;
165  lonmax += 0.2;
166  h->reset_t(latmin,latmax,lonmin,lonmax);
167 }
168 void WayHeight::check_brect(Way* w, double* latmin, double* latmax,
169  double* lonmin, double* lonmax){
170  if(w != NULL){
171  if(w->type < 6){
172  if(w->maxlat > *latmax) *latmax = w->maxlat;
173  if(w->maxlon > *lonmax) *lonmax = w->maxlon;
174  if(w->minlat < *latmin) *latmin = w->minlat;
175  if(w->minlon < *lonmin) *lonmin = w->minlon;
176  }
177  check_brect(w->l,latmin,latmax,lonmin,lonmax);
178  check_brect(w->r,latmin,latmax,lonmin,lonmax);
179  }
180 }
182  if(k!=NULL){
183  if(k->status > 1){
184  Neighbour* nb = k->cd->neighbours;
185  while(nb != NULL){
186  if(nb->rd == fw){
187  long N, n = 0;
188  double t[3] = {0,0,0}, dstep = 0;
189  if(nb->d > 0){
190  N = qMax(long(2),long(1+ceil(nb->d/dstep0)));
191  double dN;
192  double d0 = 0, dlon, dlat, di, lon, lat;
193  dstep = nb->d / (N-1);
194  nb->tp = (trackpoint*)malloc(2*N*sizeof(trackpoint));
195 
196  for(int i = 0; i < nb->nodec-1; i++){
197  /*Fuer jedesWegstueck ...*/
198  di = distance(nb->node[i ]->lat,nb->node[i ]->lon,
199  nb->node[i+1]->lat,nb->node[i+1]->lon);
200  if(di > 0){
201  dlon = (nb->node[i+1]->lon-nb->node[i]->lon)/(di/dstep);
202  dlat = (nb->node[i+1]->lat-nb->node[i]->lat)/(di/dstep);
203  t[2] = dlon * cos(M_PI/180.*k->lat);
204  t[1] = dlat / sqrt(t[2]*t[2]+dlat*dlat);
205  t[2] = t[2] / sqrt(t[2]*t[2]+dlat*dlat);
206  }
207  else
208  dlon = dlat = 0;
209  dN = (n*dstep-d0)/dstep;
210  lon = nb->node[i]->lon + dN*dlon;
211  lat = nb->node[i]->lat + dN*dlat;
212 
213  while(n < N && n*dstep < d0+di){
214  /*falls ein zu verzeichnender Punkt auf das
215  Wegstueck faellt*/
216  nb->tp[N+n].h = h->height_t(lon,lat,&t[0],4);
217  nb->tp[N+n].d = float(n*dstep);
218  nb->tp[ n].h = 0;
219  nb->tp[ n].d = float(t[0]);
220 
221  n++;
222  lon = lon + dlon;
223  lat = lat + dlat;
224  }
225 
226  d0 = d0 + di;
227  }
228  }
229  else{
230  N = 2;
231  nb->tp = (trackpoint*)malloc(2*N*sizeof(trackpoint));
232  nb->tp[2*N-2].h = h->height_t(nb->node[0]->lon, nb->node[0]->lat, &t[0], 4);
233  nb->tp[2*N-2].d = 0;
234  nb->tp[N-2].d = float(t[0]);
235  nb->tp[N-2].h = 0;
236  }
237  //if(nb->nodec == 0)
238  // MessageBox(NULL,L"",NULL,NULL);
239  //t[1]=t[2]=0;
240  nb->tp[2*N-1].h = h->height_t(nb->node[nb->nodec-1]->lon, nb->node[nb->nodec-1]->lat, &t[0], 4);
241  nb->tp[2*N-1].d = float((N-1)*dstep);
242  nb->tp[N-1].d = float(t[0]);
243  nb->tp[N-1].h = 0;
244 
245 
246  nb->tpc = N;
247  nb->brthr->tp = nb->tp;
248  nb->brthr->tpc = N;
249 
250  }
251  nb = nb->next;
252  }
253  }
254  add_raw_HeightData(k->l);
255  add_raw_HeightData(k->r);
256  }
257 }
260  for(int i = 0; i < glacerate; i++){
264  }
266 }
268  if(k != NULL){
269  if(k->cd != NULL){
270  Neighbour* nb = k->cd->neighbours;
271  while(nb != NULL){
272  if(nb->rd == fw){
273  for(long i = 1; i < nb->tpc-1; i++){
274  nb->tp[i-1].h = nb->tp[i-1].h + nb->tp[i].d + nb->tp[i-1].d;
275  nb->tp[i+1].h = nb->tp[i+1].h + nb->tp[i].d + nb->tp[i+1].d;
276  }
277  nb->tp[1 ].h = nb->tp[1].h
278  + nb->tp[0].d
279  + nb->tp[1].d;
280  nb->tp[nb->tpc-2].h = nb->tp[nb->tpc-2].h
281  + nb->tp[nb->tpc-1].d
282  + nb->tp[nb->tpc-2].d;
283  }
284  nb = nb->next;
285  }
286  }
287  portion_way(k->l);
288  portion_way(k->r);
289  }
290 }
292  if(k != NULL){
293  if(k->cd != NULL){
295  while(pi != NULL){
296  for(int i = 0; i < pi->Pcount; i++)
297  pi->PI[i].dest->h = float( pi->PI[i].dest->h
298  + pi->src->d*pi->PI[i].cos);
299  pi->src->h = pi->src->h + pi->src->d;
300  pi = pi->next;
301  }
302  }
303  portion_cross(k->l);
304  portion_cross(k->r);
305  }
306 }
308  if(k != NULL){
309  if(k->cd != NULL){
310  Neighbour* nb = k->cd->neighbours;
311  PortionInstructionCol pic, *p = &pic;
312 
313  /*Abgehende Straße zaehlen*/
314  int nbcount = 0;
315  while(nb != NULL){
316  nbcount++;
317  nb = nb->next;
318  }
319 
320  /*Richtungen berechnen*/
321  double* phi = (double*)malloc(nbcount*sizeof(double)),dlon,dlat;
322  nb = k->cd->neighbours;
323  trackpoint** tp = (trackpoint**)malloc(nbcount*sizeof(trackpoint*));
324  nbcount = 0;
325  while(nb != NULL){
326  if(nb->rd == fw){
327  dlon = nb->node[1]->lon-nb->node[0]->lon;
328  dlat = nb->node[1]->lat-nb->node[0]->lat;
329  tp[nbcount] = &(nb->tp[0]);
330  }
331  else{
332  dlon = nb->node[nb->nodec-2]->lon-nb->node[nb->nodec-1]->lon;
333  dlat = nb->node[nb->nodec-2]->lat-nb->node[nb->nodec-1]->lat;
334  tp[nbcount] = &(nb->tp[nb->tpc-1]);
335  }
336  dlon = dlon * cos(nb->node[0]->lat/180*M_PI);
337  phi[nbcount] = atan2(dlat,dlon);
338  nbcount++;
339  nb = nb->next;
340  }
341 
342  /*Verteilungsschluessel generieren*/
343  nb = k->cd->neighbours;
344  for(int i = 0; i < nbcount; i++){
345  p->next = (PortionInstructionCol*)malloc(sizeof(PortionInstructionCol));
346  p = p->next;
347  p->Pcount = nbcount-1;
348  p->next = NULL;
349  p->nb = nb;
350  p->SumCos = 0;
351  p->PI = (PortionInstruction*)malloc(p->Pcount*sizeof(PortionInstruction));
352  p->src = tp[i];
353  int q = 0;
354  for(int j = 0; j < nbcount; j++)
355  if(i != j){
356  p->PI[q].dest = tp[j];
357  p->PI[q].cos = -(cos(phi[i]-phi[j]));
358  if(p->PI[q].cos < 0) p->PI[q].cos = 0;
359  p->SumCos = p->SumCos + p->PI[q].cos;
360  q++;
361  }
362  nb = nb->next;
363 
364  /*Verteilungsschlüssel speichern*/
365  k->cd->s->from = pic.next;
366  }
367  free(phi);
368  free(tp);
369  }
372  }
373 }
375  if(k != NULL){
376  if(k->cd != NULL){
377  PortionInstructionCol *p0 = (PortionInstructionCol*) k->cd->s->from, *p = p0;
378  while(p != NULL){
379  p0 = p;
380  free(p0->PI);
381  p = p0->next;
382  free(p0);
383  }
384  }
387  }
388 }
390  if(k != NULL){
391  if(k->cd != NULL){
392  /*Wegemitten mitteln, d.h. dividieren*/
393  Neighbour* nb = k->cd->neighbours;
394  while(nb != NULL){
395  if(nb->rd == fw)
396  for(long i = 1; i < nb->tpc-1; i++){
397  nb->tp[i].d = float(nb->tp[i].h / 4.);
398  nb->tp[i].h = 0;
399  }
400  nb = nb->next;
401  }
402 
403  /*Kreuzungsenden mitteln*/
405  while(pic != NULL){
406  pic->src->d = float(pic->src->h / (3 + pic->SumCos));
407  pic->src->h = 0;
408  pic = pic->next;
409  }
410  }
411  portion_divide(k->l);
412  portion_divide(k->r);
413  }
414 }
416  if(k != NULL){
417  if(k->cd != NULL){
418  /*Wegemitten mitteln, d.h. dividieren*/
419  Neighbour* nb = k->cd->neighbours;
420  while(nb != NULL){
421  if(nb->rd == fw)
422  for(long i = 0; i < nb->tpc; i++){
423  nb->tp[i].h = nb->tp[nb->tpc+i].h;
424  nb->tp[i].d = nb->tp[nb->tpc+i].d;
425  }
426  nb = nb->next;
427  }
428  }
429  show_d_h(k->l);
430  show_d_h(k->r);
431  }
432 }
434  if(k != NULL){
435  if(k->cd != NULL){
436  /*Wegemitten mitteln, d.h. dividieren*/
437  Neighbour* nb = k->cd->neighbours;
438  while(nb != NULL){
439  if(nb->rd == fw)
440  for(long i = 0; i < nb->tpc; i++){
441  nb->tp[i].h = nb->tp[i].d;
442  nb->tp[i].d = nb->tp[nb->tpc+i].d;
443  }
444  nb = nb->next;
445  }
446  }
447  show_d_confidence(k->l);
448  show_d_confidence(k->r);
449  }
450 }
452  if(k != NULL){
453  if(k->cd != NULL){
454  double rl = 0; //reliability limit
455  int i = 0, irl = 0;
456  Neighbour* n = k->cd->neighbours, *c = NULL;
457  /*Bestimme die unzuverlässigste Höhenangabe*/
458  while(n != NULL){
459  if((n->rd == fw && n->tp[0].d > rl)
460  ||(n->rd == bw && n->tp[n->tpc-1].d > rl)){
461  c = n;
462  irl = i;
463  if(n->rd == fw)
464  rl = n->tp[0].d;
465  else
466  rl = n->tp[n->tpc-1].d;
467  }
468  n = n->next;
469  i++;
470  }
471 
472  if(rl>rlimit){
473  /*falls die unzuverlaessigste Angabe ueber der Toleranz liegt
474  muss eine neue verbindliche Hoehe für alle Wege bestimmt werden*/
475  /*Die Richtung des Hanggradienten wird ermittelt*/
476  double latcorr = cos(k->lat/180.*M_PI);
477  double phi = h->height_t(k->lon,k->lat,NULL,3);
478  double dlat = - cos(phi) * 0.08/111./10.;
479  double dlon = - sin(phi)/latcorr * 0.08/111./10.;
480  /*Entlang des Hanggradienten wird versucht, in fuenf 10-Meter-
481  Schritten den Talboden zu erreichen*/
482  double dxt = h->height_t(k->lon,k->lat,NULL,1);
483  double dyt = h->height_t(k->lon,k->lat,NULL,2);
484  double grad20 = dxt*dxt + dyt*dyt*latcorr*latcorr,
485  grad2 = grad20;
486  irl = 0;
487  for(int i = 1; i < 10; i++){
488  /*Versuche einen besseren Punkt für die Kreuzung zu finden*/
489  dxt = h->height_t(k->lon+dlon*i,k->lat+dlat*i,NULL,1);
490  dyt = h->height_t(k->lon+dlon*i,k->lat+dlat*i,NULL,2);
491  if( dxt*dxt + dyt*dyt*latcorr*latcorr < grad2*0.9){
492  /*Forderung: der Hang wird immer flacher, sonst
493  abbrechen*/
494  grad2 = dxt*dxt + dyt*dyt*latcorr*latcorr;
495  irl = i;
496  }
497  else
498  i = 10;
499  }
500 
501  if(irl > 0 &&
502  grad2 < flach2 && //neuer Punkt liegt absolut flach
503  grad2 < grad20/5.&& //neueer Punkt liegt flacher als alter
504  h->height_t(k->lon+irl*dlon,k->lat+irl*dlat,NULL,0)
505  - h->height_t(k->lon+10*dlon,k->lat+irl*dlat,NULL,0) < 5
506  //wenn man nochweiter geht, setzt sich
507  //der Hang nicht fort
508  ){
509  double newheight = h->height_t(k->lon+dlon*irl,
510  k->lat+dlat*irl,NULL,0);
511  double dh = h->height_t(k->lon,k->lat,NULL,0) - newheight;
512  n = k->cd->neighbours;
513  while(n != NULL){
514  if(n->d > 0){
515  if(n->rd == fw){
516  for(long i = n->tpc; i < 2*n->tpc -1; i++){
517  n->tp[i].h = float(n->tp[i].h
518  - (n->d - n->tp[i].d)/n->d * dh);
519  }
520  }
521  else{
522  for(long i = n->tpc; i < 2*n->tpc; i++){
523  n->tp[i].h = float(n->tp[i].h
524  - ( n->tp[i].d)/n->d * dh);
525  }
526  }
527  }
528  else{
529  if(n->rd == fw)n->tp[0].h = float(newheight);
530  else n->tp[n->tpc-1].h = float(newheight);
531  }
532  n = n->next;
533  }
534  }
535  }
536  }
537  calc_crossheight(k->r);
538  calc_crossheight(k->l);
539  }
540 }
542 if(k != NULL){
543  if(k->cd != NULL){
544  Neighbour* n = k->cd->neighbours;
545  while(n != NULL){
546  if(n->rd == fw){
547  select_heights(n,0,n->tpc-1);
548  finalize_data(n);
549  }
550  n = n->next;
551  }
552  }
553  reduce_data(k->r);
554  reduce_data(k->l);
555  }
556 }
557 void WayHeight::select_heights(Neighbour* n,long s,long e){
558  short keep = 0;
559  double d0 = n->tp[n->tpc + s].d, d1 = n->tp[n->tpc + e].d;
560  double d = d1 - d0;
561  if(d > dminur){
562  double h0 = n->tp[n->tpc + s].h, h1 = n->tp[n->tpc + e].h;
563  double dh = h1 - h0;
564  double grd = dh / d;
565  long max= 0, min = 0, maxur = 0, minur = 0;
566  double maxh = 0, minh = 0, maxhur = 0, minhur = 0;
567 
568  for(long i = s + 1; i < e - 1; i++){
569  /*Bestimme den konkavesten und den konvexesten Punkt auf der Strecke*/
570  dh = n->tp[n->tpc + i].h - (h0 + (n->tp[n->tpc + i].d-d0)*grd);
571  if(d > dmin && //n->tp[i].d < rlimit &&
572  n->tp[n->tpc + i].d-d0 > dmin && d1-n->tp[n->tpc + i].d > dmin){
573  /*aus verlaesslichen Daten*/
574  if(dh > maxh){ maxh = dh; max = i;}
575  if(dh < minh && n->tp[i].d < rlimit){ minh = dh; min = i;}
576  }
577  else
578  if(n->tp[n->tpc + i].d-d0 > dminur && d1-n->tp[n->tpc + i].d > dminur){
579  /*aus unverlaesslichen Daten*/
580  if(dh > maxhur){ maxhur = dh; maxur = i;}
581  if(dh < minhur){ minhur = dh; minur = i;}
582  }
583  }
584 
585  /*Widerhole den Prozess für die entstandenen Teilstrecken*/
586  if( min > 0 && max > 0){
587  long first = qMin(min,max);
588  long second = qMax(min,max);
589  select_heights(n, s , first);
590  select_heights(n, first , second);
591  select_heights(n, second, e);
592  keep++;
593  }
594  else{
595  if(min > 0){
596  select_heights(n, s , min);
597  select_heights(n, min, e);
598  keep++;
599  }
600  if(max > 0){
601  select_heights(n, s, max);
602  select_heights(n, max, e);
603  keep++;
604  }
605  }
606 
607  /*Falls nur unzuverlaessige Daten vorhanden waren: Versuche, ueber
608  unzuverlaessige Stuetzpunkte weiterzumachen*/
609  if( min == 0 && max == 0 && (minur != 0 || maxur != 0)){
610  if( minhur + maxhur <= 0
611  && n->tp[n->tpc + minur].h > qMin(h0,h1)
612  && n->tp[n->tpc + minur].h < qMax(h0,h1)){
613  select_heights(n, s , minur);
614  select_heights(n, minur, e);
615  keep++;
616  }
617  if(-minhur < maxhur
618  && n->tp[n->tpc + maxur].h > qMin(h0,h1)
619  && n->tp[n->tpc + maxur].h < qMax(h0,h1)){
620  select_heights(n, s , maxur);
621  select_heights(n, maxur, e);
622  keep++;
623  }
624  }
625  }
626 
627  if(!keep)
628  /*zum Loeschen markieren, falls keine weiterverarbeitung erreicht
629  wurde*/
630  for(long i = n->tpc + s + 1; i < n->tpc + e; i++){
631  n->tp[i].d = -1;
632  }
633 
634 }
636  /*sinvolle Hoehenpunkte zaehlen*/
637  long tpc = 0;
638  for(long i = n->tpc; i < 2*n->tpc; i++){
639  if(n->tp[i].d >= 0)
640  tpc++;
641  }
642 
643  /*daraus neue Daten anlegen*/
644  trackpoint* tpt = (trackpoint*)malloc(tpc*sizeof(trackpoint));
645  tpc = 0;
646  for(long i = n->tpc; i < 2*n->tpc; i++)
647  if(n->tp[i].d >= 0){
648  tpt[tpc] = n->tp[i];
649  tpc++;
650  }
651 
652  /*Altes trackpoint-array loeschen*/
653  free(n->tp);
654 
655  /*neues zuweisen*/
656  n->tp = tpt;
657  n->tpc = tpc;
658  n->brthr->tp = tpt;
659  n->brthr->tpc = tpc;
660 
661  /*Hoehenmeter ermitteln und speichern*/
662  float hmup = 0, hmdown = 0;
663  for(long i = 0; i < n->tpc-1; i++)
664  if(n->tp[i].h < n->tp[i+1].h) hmup = hmup
665  + (n->tp[i+1].h - n->tp[i].h);
666  else hmdown = hmdown
667  + (n->tp[i].h - n->tp[i+1].h);
668 
669  n->hm = hmup;
670  n->brthr->hm = hmdown;
671 
672 }
674  if(k != NULL){
675  if(k->cd != NULL){
676  Neighbour* n = k->cd->neighbours;
677  while(n != NULL){
678  if(n->rd == fw)
679  if(n->tp[n->tpc].d != 0)
680  return 0;
681  n = n->next;
682  }
683  }
684  return (check0(k->l) && check0(k->r));
685  }
686  return 1;
687 }
689  lines* l = *(o->NoHeight);
690  while(l != NULL){
691  l->way->type = l->way->type + 10;
692  l = l->next;
693  }
694 }
696  lines* l = *(o->NoHeight);
697  while(l != NULL){
698  l->way->type = l->way->type - 10;
699  l = l->next;
700  }
701 }
703  lines* l = *(o->NoHeight);
704  while(l != NULL){
705  Way* w = l->way;
706  if(w->type < 6){
707  float d = 0;
708  int iold = 0;
709  for(int i = 1; i < w->nodec; i++){
710  d = d + distance(w->node[i] ->lat,w->node[i] ->lon,
711  w->node[i-1]->lat,w->node[i-1]->lon);
712  if(w->node[i]->status > 1){
713  Neighbour *n1 = NULL, *n2 = NULL;
714  n1 = o->add_Neighbour(w->node[iold],&(w->node[iold]),
715  w->node[i ],w,d,i-iold+1,fw);
716  n2 = o->add_Neighbour(w->node[i], &(w->node[iold]),
717  w->node[iold],w,d,i-iold+1,bw);
718 
719  if(n1 != NULL && n2 != NULL){
720  n1->brthr = n2;
721  n2->brthr = n1;
722  }
723  else{
724  /*Kreisverkehr*/
725  if(n1 != NULL) n1->brthr = n1;
726  if(n2 != NULL) n2->brthr = n2;
727  if((n1 != NULL || n2 != NULL)&&w->node[i] != w->node[iold])
728  QMessageBox(QMessageBox::NoIcon,"Error",
729  "Neighbour add failure").exec();
730  }
731  d = 0;
732  iold = i;
733  }
734  }
735  }
736  l = l->next;
737  }
738 }
740  if(k != NULL){
741  if(k->cd != NULL){
742  Neighbour* nb = k->cd->neighbours;
743  while(nb != NULL){
744  if(nb->way->type > 9 && nb->rd == fw){
745  nb->tpc = nb->brthr->tpc = 2;
746  nb->tp = nb->brthr->tp =
747  (trackpoint*)malloc(2*sizeof(trackpoint));
748  KOO kfake;
749  nb->tp[0].d = 0;
750  nb->tp[1].d = nb->d;
751 
752  /*fuer Startpunkt bestimmen*/
753  KOOlist kl1; kl1.next = NULL; kl1.k = &kfake;
754  trackpointlist tl1; tl1.next = NULL;
755  trace_to_HeightData(0,k,&kl1,&tl1);
756  trackpointlist* tt = tl1.next;
757  float srho = 0;
758  nb->tp[0].h = 0;
759  while(tt != NULL){
760  if(tt->t.d != 0){
761  nb->tp[0].h = nb->tp[0].h + tt->t.h * 1. / tt->t.d;
762  srho = srho + 1. / tt->t.d;
763  tt = tt->next;
764  }
765  else{
766  nb->tp[0].h = tt->t.h;
767  srho = 0;
768  tt = NULL;
769  }
770  }
771  if(srho > 0)
772  nb->tp[0].h = nb->tp[0].h / srho;
773  /*fuer Endpunkt bestimmen*/
774  KOOlist kl2; kl2.next = NULL; kl2.k = &kfake;
775  trackpointlist tl2; tl2.next = NULL;
776  trace_to_HeightData(0,k,&kl2,&tl2);
777  tt = tl2.next;
778  srho = 0;
779  nb->tp[1].h = 0;
780  while(tt != NULL){
781  if(tt->t.d != 0){
782  nb->tp[1].h = nb->tp[1].h + tt->t.h * 1. / tt->t.d;
783  srho = srho + 1. / tt->t.d;
784  tt = tt->next;
785  }
786  else{
787  nb->tp[1].h = tt->t.h;
788  srho = 0;
789  tt = NULL;
790  }
791  }
792  if(srho > 0)
793  nb->tp[1].h = nb->tp[1].h / srho;
794  /*Listen freigeben*/
795  KOOlist *kbuf1, *kbuf2;
796  trackpointlist *tbuf1, *tbuf2;
797  kbuf1 = kl1.next;
798  while(kbuf1 != NULL){
799  kbuf2 = kbuf1; kbuf1 = kbuf1->next; free(kbuf2);
800  }
801  kbuf1 = kl2.next;
802  while(kbuf1 != NULL){
803  kbuf2 = kbuf1; kbuf1 = kbuf1->next; free(kbuf2);
804  }
805  tbuf1 = tl1.next;
806  while(tbuf1 != NULL){
807  tbuf2 = tbuf1; tbuf1 = tbuf1->next; free(tbuf2);
808  }
809  tbuf1 = tl2.next;
810  while(tbuf1 != NULL){
811  tbuf2 = tbuf1; tbuf1 = tbuf1->next; free(tbuf2);
812  }
813  }
814  nb = nb->next;
815  }
816  }
819  }
820 }
822  if(k != NULL && !KOO_already_used(k,kl)){
823  /*zuerst k als benutzt kennzeichnen*/
824  KOOlist *ktnew = (KOOlist*) malloc(sizeof(KOOlist));
825  ktnew->next = kl->next;
826  kl->next = ktnew;
827  ktnew->k = k;
828  /*jett nach adäquaten Hoehendaten suchen*/
829  Neighbour *nb = k->cd->neighbours;
830  while(nb != NULL && nb->way->type > 9)
831  nb = nb->next;
832  if(nb != NULL){
833  /*adäquate Hoehendaten in nb*/
834  trackpointlist *tlnew = (trackpointlist*) malloc(sizeof(trackpointlist));
835  tlnew->next = tl->next;
836  tl->next = tlnew;
837  if(nb->rd == fw) tlnew->t = nb->tp[0];
838  else tlnew->t = nb->tp[nb->tpc-1];
839  tlnew->t.d = d;
840  }
841  else{
842  /*keine adäquaten Hoehendaten gefunden*/
843  nb = k->cd->neighbours;
844  while(nb != NULL){
845  trace_to_HeightData(d + nb->d, nb->nb, kl, tl);
846  nb = nb->next;
847  }
848  }
849  }
850 }
852  while(kl != NULL){
853  if(kl->k == k)
854  return 1;
855  else
856  kl = kl->next;
857  }
858  return 0;
859 }
int KOO_already_used(KOO *k, KOOlist *kl)
help function of trace_to_HeightData()
Definition: WayHeight.cpp:851
void calc_crossheight(KOO *k)
determines the common crossheight fromthe domiciled Neighbour
Definition: WayHeight.cpp:451
Neighbour * via
connection to reach this STRONG
Definition: DataTyps.h:258
void check_brect(Way *w, double *latmin, double *latmax, double *lonmin, double *lonmax)
adapt bounding rect to cover whole data set
Definition: WayHeight.cpp:168
double height_t(double lon, double lat, void *hc, short mode)
returns height data operating at the precalculated data grid
Definition: HeightData.cpp:343
void trace_to_HeightData(float d, KOO *k, KOOlist *kl, trackpointlist *tl)
work function of add_NoHeights_HeightData()
Definition: WayHeight.cpp:821
double rlimit
maximum accepted mistrust index
Definition: WayHeight.h:47
void portion_divide(KOO *k)
normalize the distributes mistrust index
Definition: WayHeight.cpp:389
void alloc_neighbours(Way *w)
search allong way for neighbouring cross, link them with Neighbour data
Definition: WayHeight.cpp:122
Way * way
Neighbour lives uses this Way.
Definition: DataTyps.h:53
double dminur
minimum section length to cross
Definition: WayHeight.h:47
void portion_way(KOO *k)
smearing out the mistrust index within the Neighbour data
Definition: WayHeight.cpp:267
void mark_NoHeights()
if a Way is tunnel or bridge height must be interpolated lineary
Definition: WayHeight.cpp:688
void delete_PortionInstructions(KOO *k)
delete the angular relation of Neighbour at a cross
Definition: WayHeight.cpp:374
float maxlon
bounding rect, for rendering
Definition: DataTyps.h:126
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
double dstep0
interpolation step size in km
Definition: WayHeight.h:47
KOO ** node
reference to KOO (of way)
Definition: DataTyps.h:61
char status
state of the KOO when used by different classes
Definition: DataTyps.h:100
double lat
Definition: DataTyps.h:86
int glacerate
how many times is glazed
Definition: WayHeight.h:52
KOO * nb
Definition: DataTyps.h:54
void alloc_NoHeights_neighbours()
create Neighbour data (end &amp; start only) for members of osm::NoHeight
Definition: WayHeight.cpp:702
void add_NoHeights_HeightData(KOO *k)
determine the heights of tunnels and bridges at start and end
Definition: WayHeight.cpp:739
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
main container list climbanalyse
Definition: DataTyps.h:162
int nodec
count of used KOO in way
Definition: DataTyps.h:59
short check0(KOO *k)
returns zero if a zero distance Neighbour was found
Definition: WayHeight.cpp:673
STRONG * s
memory for routing algorithms
Definition: DataTyps.h:75
Neighbour * add_Neighbour(KOO *k, KOO **node, KOO *nb, Way *w, float d, int KOOc, readdirection rd)
add Neighbour cross to k
Definition: osm.cpp:1695
double flach2
move cross to place with (grad^2)
Definition: WayHeight.h:47
void call_height_t()
Definition: WayHeight.cpp:159
holds digital elevation model extracted from SRTM3 data
Definition: HeightData.h:26
readdirection rd
Definition: DataTyps.h:52
char type
classification
Definition: DataTyps.h:129
void reset_t(double minlat, double maxlat, double minlon, double maxlon)
generates the data grid being
Definition: HeightData.cpp:327
container for line geodata
Definition: DataTyps.h:122
void dismark_NoHeights()
reduces Way::type by 10 if member of osm::NoHeight data
Definition: WayHeight.cpp:695
void * from
&lt; pointer to STRONG or FibunacciHeap
Definition: DataTyps.h:257
void reduce_data(KOO *k)
run select_heights() and finalize_data() on every Neighbour
Definition: WayHeight.cpp:541
WayHeight(HeightData *H, OSM *O)
constructor runs the whole calculation
Definition: WayHeight.cpp:4
KOO ** node
array KOO pointers
Definition: DataTyps.h:125
void glaze()
smear out gaussian the mistrust index over several hundred meter
Definition: WayHeight.cpp:258
void finalize_data(Neighbour *n)
keep selected data and delete unused data
Definition: WayHeight.cpp:635
lines ** NoHeight
Definition: osm.h:70
float d
distance
Definition: DataTyps.h:58
void portion_cross(KOO *k)
smearing out at the borders of the Neighbour data, i.g. at the cross
Definition: WayHeight.cpp:291
void add_raw_HeightData(KOO *k)
assign raw height data to all Neighbour datasets
Definition: WayHeight.cpp:181
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 generate_PortionInstructions(KOO *k)
generate the angular relation of Neighbour at a cross
Definition: WayHeight.cpp:307
void select_heights(Neighbour *n, long s, long e)
select the most charakteristicand trustful heighdata of a Neighbour
Definition: WayHeight.cpp:557
double dmin
minimum section length in km
Definition: WayHeight.h:47
KOO * k
reference to KOO data
Definition: DataTyps.h:173
container struct to hold data of a cross
Definition: DataTyps.h:73
void reset_cross_markers(KOO *k)
set status of every KOO zero
Definition: WayHeight.cpp:87
container struct for Track to hold distance and height data
Definition: DataTyps.h:33
float hm
total height meter, for routing
Definition: DataTyps.h:57
void mark_cross(Way *w)
Definition: WayHeight.cpp:94
trackpoint * tp
heighdata of this Neighbour
Definition: DataTyps.h:62
main container for Track, WayHeight and ClimbAnalyse
Definition: DataTyps.h:172
osm data container list for line like data (roads, rivers)
Definition: DataTyps.h:143
void show_d_confidence(KOO *k)
Definition: WayHeight.cpp:433
Way * get_first_Way()
returns root of Way-AVL tree
Definition: osm.cpp:1689
int nodec
count of KOO
Definition: DataTyps.h:124
Way * way
reference element of this list
Definition: DataTyps.h:144
void alloc_crossdata(KOO *k)
allocs crossdata if KOO was marked as cross
Definition: WayHeight.cpp:106
Neighbour * brthr
related Neighbour with opposite read direction supposed to store brthr
Definition: DataTyps.h:56
void show_d_h(KOO *k)
visualization for developers
Definition: WayHeight.cpp:415
main struct for routing purpose
Definition: DataTyps.h:255