1 #define _USE_MATH_DEFINES
13 Track::Track(
double** KOOarray,
int count){
17 for(
int i = 0; i < count; i++)
18 kl[i].k = add_to_KOOpool(KOOarray[0][i],KOOarray[1][i]);
20 for(
int i = 1; i < count; i++)
21 kl[i].d = distance(KOOarray[0][i],KOOarray[1][i],
22 KOOarray[0][i-1],KOOarray[1][i-1])
32 this->tc = this->kc = 0;
42 Track::Track(
double *d,
double *h,
double *lat,
double *lon,
int count){
47 for(
int i = 0; i < count; i++){
49 kl[i].
k->lon = lon[i];
64 for(
int i = 0; i < nc; i++){
66 tc += narray[i]->
tpc -1;
72 if(narray[0]->rd == fw){
73 tpl[0] = narray[0]->
tp[0];
77 tpl[0] = narray[0]->
tp[narray[0]->
tpc-1];
87 for(
int i = 0; i < nc; i++){
88 if(narray[i]->rd == fw){
90 for(
int j = 1; j < narray[i]->
nodec; j++){
91 kl[cik+j].
k = narray[i]->
node[j];
92 kl[cik+j].
d =
kl[cik+j-1].
d
93 + distance(
kl[cik+j ].k->lat,
kl[cik+j ].
k->lon,
97 for(
int j = 1; j < narray[i]->
tpc; j++){
98 tpl[cit+j].h = narray[i]->
tp[j].h;
99 tpl[cit+j].d = narray[i]->
tp[j].d + d0;
101 cik += narray[i]->
nodec-1;
102 cit += narray[i]->
tpc-1;
105 d0 =
kl[cik].
d + narray[i]->
tp[narray[i]->
tpc-1].d;
106 cik += narray[i]->
nodec-1;
107 cit += narray[i]->
tpc-1;
108 for(
int j = narray[i]->nodec-2; j >= 0; j--){
109 kl[cik-j].
k = narray[i]->
node[j];
110 kl[cik-j].
d =
kl[cik-j-1].
d
111 + distance(
kl[cik-j ].k->lat,
kl[cik-j ].
k->lon,
115 for(
int j = narray[i]->tpc-2; j >= 0; j--){
116 tpl[cit-j].h = narray[i]->
tp[j].h;
117 tpl[cit-j].d = d0 - narray[i]->
tp[j].d;
137 if(tracktocopy != NULL)
152 if(this->kl == NULL){
154 memcpy(&(this->kl[0]),kl,kc*
sizeof(
KOOlist));
158 int newkc = this->kc + kc -1;
160 memcpy(&(newkl[0]),this->kl,this->kc*
sizeof(
KOOlist));
161 memcpy(&(newkl[this->kc]),&(kl[1]),(kc-1)*
sizeof(
KOOlist));
162 for(
int i = 0; i < kc-1; i++){
163 newkl[i+this->
kc].
d += this->kl[this->kc-1].
d;
164 if(newkl[i+this->kc].tpi >= 0)
165 newkl[i+this->
kc].
tpi += this->tc - 1;
172 if(this->tpl == NULL){
174 memcpy(&(this->tpl[0]),tpl,tc*
sizeof(
trackpoint));
178 int newtc = this->tc + tc -1;
180 memcpy(&(newtpl[0]),this->tpl,this->tc*
sizeof(
trackpoint));
181 memcpy(&(newtpl[this->tc]),&(tpl[1]),(tc-1)*
sizeof(
trackpoint));
182 for(
int i = 0; i < tc-1; i++)
183 newtpl[this->tc+i].d += this->tpl[this->tc-1].d;
190 if(tpl != NULL) *tpl = this->
tpl;
191 if(tc != NULL) *tc = this->
tc;
192 if(kl != NULL) *kl = this->
kl;
193 if(kc != NULL) *kc = this->
kc;
195 void Track::add(
Track* t2){
196 if(t2 != NULL && t2->
notNULL()){
200 t2->get_data_ref(&atpl,&atc,&akl,&akc);
201 add(atpl,atc,akl,akc);
221 double** result =
KOOa;
237 for(
long int j = 0; j <
tc; j++){
255 KOOa =
new double*[2];
258 for(
long int j = 0; j <
kc; j++){
260 KOOa[1][j] = kl[j].
k->lon;
267 long int Track::get_array_length(){
270 long int Track::get_KOOa_length(){
276 for(
int i = 1; i <
tc; i++)
277 if(tpl[i].h - tpl[i-1].h > 0)
278 result += tpl[i].h - tpl[i-1].h;
286 int ll = 0, lr = tc-1;
287 while(ll+1 < lr && tpl[ll].d != tpl[lr].d){
288 if(tpl[(ll+lr)/2].d > dmin)
293 int rl = 0, rr = tc-1;
294 while(rl+1 < rr && tpl[rl].d != tpl[rr].d){
295 if(tpl[(rl+rr)/2].d > dmax)
301 if(tpl[ll].d == tpl[lr].d || tpl[rl].d == tpl[rr].d)
305 for(
int i = ll; i < rr; i++)
306 if(tpl[i+1].h - tpl[i].h > 0)
307 result += tpl[i+1].h - tpl[i].h;
308 if(tpl[lr].h > tpl[ll].h)
309 result -= (tpl[lr].h - tpl[ll].h)
310 * (dmin-tpl[ll].d)/(tpl[lr].d-tpl[ll].d);
311 if(tpl[rr].h > tpl[rl].h)
312 result -= (tpl[rr].h - tpl[rl].h)
313 * (tpl[rr].d-dmax)/(tpl[rr].d-tpl[rl].d);
326 KOO* Track::get_last_KOO(){
332 KOO* Track::add_to_KOOpool(
double lat,
double lon){
351 void Track::free_KOOpool(
KOO* k){
361 while(l+1 < r && kl[l].d != kl[r].d){
362 if(kl[(l+r)/2].d > d)
367 if(kl[l].d == kl[r].d)
370 double dd = kl[r].
d-kl[l].
d;
371 k->
lat = kl[r].
k->
lat*(d-kl[l].
d)/dd + kl[l].k->
lat*(kl[r].
d-d)/dd;
372 k->lon = kl[r].
k->lon*(d-kl[l].
d)/dd + kl[l].k->lon*(kl[r].
d-d)/dd;
382 while(l+1 < r && tpl[l].d != tpl[r].d){
383 if(tpl[(l+r)/2].d > d)
389 if(tpl[l].d == tpl[r].d)
392 double dd = tpl[l].d-tpl[r].d;
393 *h = tpl[r].h*(tpl[l].d-d)/dd + tpl[l].h*(d-tpl[r].d)/dd;
403 while(l+1 < r && kl[l].d != kl[r].d){
404 if(kl[(l+r)/2].d > d)
409 if(kl[l].d == kl[r].d)
412 *azimut = atan2((kl[r].k->lon-kl[l].
k->lon)
413 *cos((kl[r].k->
lat+kl[l].
k->
lat)/360.*M_PI),
425 double dmin = distance(lat,lon,kl[0].k->
lat,kl[0].
k->lon), a,b,c,h;
428 for(
int i = 1; i <
kc; i++){
430 a = distance( lat, lon,kl[i].k->
lat,kl[i].
k->lon);
431 c = kl[i].
d - kl[i-1].
d;
432 if(a*a + c*c <= b*b){
440 if(b*b + c*c <= a*a){
449 h = sqrt((4*a*a*b*b-(c*c-a*a-b*b)*(c*c-a*a-b*b))/(4*c*c));
452 *d = kl[i-1].
d + sqrt(b*b-h*h);
466 while(ci >= 0 && (c < nr || kl[ci].k->cd == NULL)){
467 if(kl[ci].k->cd != NULL && kl[ci].
tpi >= 0)
471 trim_right(ci,kl[ci].tpi);
478 for(
int i = kc-1; i >= 0; i--)
496 realloc(kl,kc*
sizeof(
KOOlist));
523 double lonc = cos(kl[ci].k->
lat/180*M_PI)*cos(kl[ci].k->
lat/180*M_PI);
525 &&(kl[ci].k->
lat-lat)*(kl[ci].
k->
lat-lat)
526 +(kl[ci].
k->lon-lon)*(kl[ci].
k->lon-lon)*lonc >limit
537 void Track::trim_right(
float d){
538 if(d < kl[kc-1].d && d < tpl[tc-1].d){
541 KOO* k = add_to_KOOpool(0,0);
544 while(kci > 0 && kl[kci].d > d)
552 while(tci > 0 && tpl[tci].d > d)
561 void Track::trim_left(
float d){
562 if(d > kl[0].d && d > tpl[0].d){
565 KOO* k = add_to_KOOpool(0,0);
568 while(kci < kc && kl[kci].d < d)
577 while(tci < tc && tpl[tci].d < d)
586 void Track::trim_left(
KOO* k){
589 for(
int i = 0; i <
kc; i++)
594 int tci = kl[kci].
tpi;
599 void Track::trim_right(
KOO* k){
602 for(
int i = kc-1; i >= 0; i--)
607 int tci = kl[kci].
tpi;
611 void Track::trim_left(
int kci,
int tci){
612 if(kci == kc-1 || tci == tc-1)
617 memcpy(&(newkl[0]),&(kl[kci]),kc*
sizeof(
KOOlist));
623 memcpy(&(newtpl[0]),&(tpl[tci]),tc*
sizeof(
trackpoint));
627 for(
int i = kc - 1; i >= 0; i--){
633 for(
int i = tc - 1; i >= 0; i--)
634 tpl[i].d -= tpl[0].d;
636 if(kl[0].k->cd != NULL)
642 void Track::trim_right(
int kci,
int tci){
643 if(kci == 0 || tci == 0)
648 memcpy(&(newkl[0]),kl,kc*
sizeof(
KOOlist));
654 memcpy(&(newtpl[0]),tpl,tc*
sizeof(
trackpoint));
660 if(kl[kc-1].k->cd != NULL)
667 void Track::invert(){
670 for(
int i = 0; i <
kc; i++){
671 newkl[i] = kl[kc-1-i];
672 newkl[i].
d = kl[kc-1].
d-newkl[i].
d;
673 if(newkl[i].tpi >= 0)
674 newkl[i].
tpi = tc - 1 - newkl[i].
tpi;
679 for(
int i = 0; i <
tc; i++){
680 newtpl[i].h = tpl[tc-1-i].h;
681 newtpl[i].d = tpl[tc-1].d - tpl[tc-1-i].d;
688 double* lonmin,
double* lonmax){
690 for(
int i = 0; i <
kc; i++){
691 if(kl[i].k->
lat > *latmax) *latmax = kl[i].
k->
lat;
692 if(kl[i].k->
lat < *latmin) *latmin = kl[i].
k->
lat;
693 if(kl[i].k->lon > *lonmax) *lonmax = kl[i].
k->lon;
694 if(kl[i].k->lon < *lonmin) *lonmin = kl[i].
k->lon;
698 double* lonmin,
double* lonmax){
705 int Track::owns(
KOO* k){
706 for(
int i = 0; i <
kc; i++)
713 for(
int i = 0; i <
kc; i++)
721 while(kl[ci].k != k && ci < kc)
724 if(ci < kc-1 && ci > 0){
725 if(kl[ci].marked == 0)
744 if(d > 0 && d < kl[kc-1].d){
746 while(kl[ci].d < d || kl[ci].marked == 0){
747 if(kl[ci].marked) *kfrom = kl[ci].
k;
754 short Track::found_anchors(
double clickedlat,
double clickedlon,
755 float maxd,
KOO** kfrom,
KOO** kto){
759 for(
int i = 0; i <
kc; i++)
761 && distance(clickedlat,clickedlon,
762 kl[i].k->
lat,kl[i].
k->lon) < dmax){
765 dmax = distance(clickedlat,clickedlon,
766 kl[i].k->
lat,kl[i].
k->lon);
774 while(ci < kc-1 && !kl[ci].marked)
782 while(ci > 0 && !kl[ci].marked)
795 KOO** kdot,
float maxd){
800 for(
int i = 0; i <
kc; i++)
802 && distance(clickedlat,clickedlon,
803 kl[i].k->
lat,kl[i].
k->lon) < dmax){
806 if(kl[i].marked) marked = 1;
808 dmax = distance(clickedlat,clickedlon,
809 kl[i].k->
lat,kl[i].
k->lon);
822 float ang1, ang2, tbend;
825 for(
int i = 0; i < kc-2; i++){
826 d = d + distance(kl[i].k->
lat,kl[i].
k->lon,kl[i+1].
k->
lat,kl[i+1].
k->lon);
827 ang1 = atan2(kl[i+1].k->
lat-kl[i].
k->
lat,
828 kl[i+1].
k->lon-kl[i].
k->lon);
829 ang2 = atan2(kl[i+2].k->
lat-kl[i+1].
k->
lat,
830 kl[i+2].
k->lon-kl[i+1].
k->lon);
832 if(tbend < -M_PI) tbend = tbend + 2*M_PI;
833 if(tbend > M_PI) tbend = tbend - 2*M_PI;
834 if(tbend *cbend < 0){
835 result = result + cbend*cbend/M_PI/M_PI;
839 cbend = cbend + tbend;
842 result = result + cbend*cbend/M_PI/M_PI;
849 FILE* f = fopen(filename,
"wb");
850 fwrite(&kc,
sizeof(kc),1,f);
852 for(
int i = 0; i <
kc; i++){
853 floatbuf = float(kl[i].k->
lat);
854 fwrite(&(floatbuf),
sizeof(
float),1,f);
855 floatbuf = float(kl[i].k->lon);
856 fwrite(&(floatbuf),
sizeof(
float),1,f);
861 FILE* f = fopen(filename,
"w");
862 fprintf(f,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
863 fprintf(f,
"<gpx \nversion=\"1.0\" creator=\"GPSBabel - http://www.gpsbabel.org\"");
864 fprintf(f,
"\nxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
865 fprintf(f,
"\nxmlns=\"http://www.topografix.com/GPX/1/0\"");
866 fprintf(f,
"\nxsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">");
867 fprintf(f,
"\n<time>2010-03-14T06:49:54Z</time>\n");
868 double minlat,minlon, maxlat, maxlon;
869 get_brect(&minlat,&maxlat,&minlon,&maxlon);
870 fprintf(f,
"<bounds minlat=\"");
871 fprintf(f,
"%f\" minlon =\"%f\" maxlat=\"%f\" maxlon=\"%f\" />"
872 ,minlat,minlon,maxlat,maxlon);
874 fprintf(f,
"<trkseg>\n");
875 for(
int i = 0; i <
kc; i++)
876 fprintf(f,
"\n<trkpt lat=\"%f\" lon=\"%f\">\n<ele>0.000000</ele>\n</trkpt>"
877 ,kl[i].k->
lat,kl[i].
k->lon);
879 fprintf(f,
"</trkseg>\n");
880 fprintf(f,
"</trk>\n</gpx>");
883 KOO Track::get_firstKOO(){
887 KOO k; k.
lat = 0; k.lon = 0;
892 KOO Track::get_lastKOO(){
894 return *(kl[kc-1].
k);
896 KOO k; k.
lat = 0; k.lon = 0;
void reset_markers()
set markers to zero
KOOlist * kl
KOO data array.
container struct to hold data of a coordinate
void refresh_KOOa()
refreshs KOOa
KOO ** node
reference to KOO (of way)
char status
state of the KOO when used by different classes
short next_d(double lat, double lon, double *d)
searches for closest point on track to point (lat,lon)
double ** get_d_h_array()
returns reference
short notNULL()
is track empty or not
float get_height_meters()
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 next_cross(double clickedlat, double clickedlon, KOO **kdot, float maxd)
stores cross in kdot which is closest to (clickedlat,clickedlon)
int tpi
index of related element in synchronized trackpoint array
void delete_cross(int nr)
deletes last nr cross of Track
routing container struct, connects cross via Way with each other
short extract_h(double d, double *h)
creates double for height refering distance point d
void delete_to_cross(KOO *k)
deletes cross after k
double ** get_KOOa()
returns reference
int nodec
count of used KOO in way
double ** d_h_array
distance height output, d:0, h:1
official representation of Track in BTP3
void to_gpx(char *filename)
save to gpx file
double get_length()
returns Track length [km]
double ** KOOa
coordinate output, lat:0, lon:1
short near_check(double lat, double lon, double limit)
check if point (lat,lon) is closer to track then limit
void to_binary_KOO(char *filename)
save binary KOOa to file (website)
short toggle_marker(KOO *k)
a KOO of the track can be marked or not, used for drag&drop routing
void adapt_brect(double *latmin, double *latmax, double *lonmin, double *lonmax)
increases rect to contain track, if necessary
int tpc
count of trackpoint
float d
current distance, synchronized to trackpoint array
KOO * KOOpool
stores dynamically allocated KOO if public a function requires that
void refresh_d_h_array()
refreshs d_h_array
short keep_lists
destructor instruction, kl might be used outside this class
KOO * k
reference to KOO data
float get_bend()
return serpentine index
container struct for Track to hold distance and height data
KOO * prev
AVL tree pointers.
short marked
labels elements for drag-drop-routing:
trackpoint * tp
heighdata of this Neighbour
double ** get_KOOa_copy()
returns deep copy
main container for Track, WayHeight and ClimbAnalyse
short extract_azimtut(double d, double *azimut)
extract way direction at distance point d
void get_anchors(float d, KOO **kfrom, KOO **kto)
check if k is an element of Track