1 /*
2
3 Geogrid-Viewer overlay file Version 0.9.3
4
5 A detail description of the ASCII-overlay-fomat you can find in the
6 helpfile of Geogrid-Viewer.
7
8 Latest changes at 11.01.2005 by Fredie Kern
9
10 Copyright (C) 2005 Fredie Kern, f.kern@xdesy.de
11
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
26
27 */
28 #include "defs.h"
29 #include "grtcirc.h"
30
31 static short_handle mkshort_handle;
32
33 #define MYNAME "overlay"
34 #define PARAMETER_FILE "overlay.def"
35
36 #undef MAPNAME
37 #define MAPNAME "Bundesrepublik 1:1 Mio"
38 #undef MAPNAME
39 #define MAPNAME "Top. Karte 1:50.000 Nieders."
40
41 static gbfile* fpout;
42 static gbfile* fpin;
43 static int govl_cnt;
44 static double govl_sum_e=0.0;
45 static double govl_sum_n=0.0;
46 static double govl_sumcnt=0.0;
47 static int govl_symbol_cnt=0;
48 static int govl_group_cnt=0;
49 /*
50 static double govl_last_east=0.0;
51 static double govl_last_north=0.0;
52 */
53
54 static int govl_col=1;
55 static char* govl_col_s = NULL;
56 static int govl_size=101;
57 static char* govl_size_s = NULL;
58 static double govl_dir=0.0;
59
60 static char* govl_mapname = NULL;
61 static int govl_zoomfc = 100;
62 static char* govl_zoomfc_s = NULL;
63 static int govl_dimmfc = 100;
64 static char* govl_dimmfc_s = NULL;
65
66
67 static int govl_txtcol=1;
68 static int govl_txtsize=120;
69 static int govl_font=1;
70 static int govl_txttrans=0;
71
72 static char* govl_txtcol_s = NULL;
73 static char* govl_txtsize_s = NULL;
74 static char* govl_font_s = NULL;
75 static char* govl_txttrans_s = NULL;
76
77 static char* govl_file_s = NULL;
78
79 static arglist_t ovl_args[] = {
80 {
81 "col", &govl_col_s, "color index [1-9] for routes",
82 NULL, ARGTYPE_INT, "1", "9"
83 },
84 {
85 "size", &govl_size_s, "size index [101-] for routes",
86 NULL, ARGTYPE_INT, "101", NULL
87 },
88 {
89 "mapname", &govl_mapname, "name of map",
90 NULL, ARGTYPE_STRING, ARG_NOMINMAX
91 },
92 {
93 "zoomfc", &govl_zoomfc_s, "zoom factor of map in %",
94 NULL, ARGTYPE_INT, ARG_NOMINMAX
95 },
96 {
97 "dimmfc", &govl_dimmfc_s, "dimmer factor of map in %",
98 NULL, ARGTYPE_INT, ARG_NOMINMAX
99 },
100 {
101 "txtcol", &govl_txtcol_s, "color index [1-9] for waypoint names",
102 NULL, ARGTYPE_INT, "1", "9"
103 },
104 {
105 "txtsize", &govl_txtsize_s, "text size [101-] for waypoint names",
106 NULL, ARGTYPE_INT, "101", NULL
107 },
108 {
109 "font", &govl_font_s, "font index [1-] for waypoint names",
110 NULL, ARGTYPE_INT, "1", NULL
111 },
112 {
113 "txttrans", &govl_txttrans_s, "set text background to transparent",
114 NULL, ARGTYPE_BOOL, ARG_NOMINMAX
115 },
116 {
117 "file", &govl_file_s, "use file of parameters (parameters on command line overwrites file parameters)",
118 NULL, ARGTYPE_STRING, ARG_NOMINMAX
119 },
120 ARG_TERMINATOR
121 };
122
123
124 static char* Keywords[]= {
125 "Typ",
126 "Group",
127 "Col",
128 "Zoom",
129 "Size",
130 "Art",
131 "Punkte",
132 "Path",
133 "Dir",
134 "Font",
135 "Area",
136 "Text",
137 "Width",
138 "Height",
139 "Trans",
140 "TransByte",
141 NULL
142 };
143
144 #define KEY_TYP 0
145 #define KEY_GROUP 1
146 #define KEY_COL 2
147 #define KEY_ZOOM 3
148 #define KEY_SIZE 4
149 #define KEY_ART 5
150 #define KEY_PUNKTE 6
151 #define KEY_PATH 7
152 #define KEY_DIR 8
153 #define KEY_FONT 9
154 #define KEY_AREA 10
155 #define KEY_TEXT 11
156 #define KEY_WIDTH 12
157 #define KEY_HEIGHT 13
158 #define KEY_TRANS 14
159 #define KEY_TRANSBYTE 15
160
isKeyword(char * str,char ** keys)161 static int isKeyword(char* str,char** keys)
162 {
163 int i;
164
165 i = 0;
166 while (keys[i]!=NULL && strcmp(str,keys[i])) {
167 i++;
168 }
169 return(keys[i]==NULL ? -1 : i);
170 }
171
172 /*----------------------------------------------*/
173
174 static
ovl_rd_init(char const * fname)175 void ovl_rd_init(char const* fname)
176 {
177 fpin = gbfopen(fname, "r", MYNAME);
178 }
179
180 #define SECTION_NONE 0
181 #define SECTION_SYMBOL 1
182 #define SECTION_PUNKTE 2
183 #define SECTION_OVERLAY 3
184
185 #define MAXLINE 512
186
187 static struct _group {
188 int group;
189 char* name;
190 }* groups;
191 static int groups_cnt;
192
ovl_add_group(int aktgrp,char * akttxt)193 static void ovl_add_group(int aktgrp,char* akttxt)
194 {
195 int i;
196
197 i = 0;
198 while (i<groups_cnt && groups[i].group!=aktgrp) {
199 i++;
200 }
201 if (i==groups_cnt) {
202 groups = (struct _group*) xrealloc(groups,(groups_cnt+1)*sizeof(struct _group));
203 groups[i].group = aktgrp;
204 groups[i].name = NULL;
205 groups_cnt++;
206 }
207 groups[i].name = (char*) xrealloc(groups[i].name,(strlen(akttxt)+1)*sizeof(char));
208 strcpy(groups[i].name,akttxt);
209 }
210
211 /*
212 The name of route is stored in a 'Text'-symbol with identical 'Group'-number.
213 */
route_add_name(const route_head * hd)214 static void route_add_name(const route_head* hd)
215 {
216 int grp;
217 int i;
218 char name[MAXLINE];
219 route_head* route;
220
221 route = (route_head*) hd;
222 grp = atoi(route->rte_name);
223 i = 0;
224 while (i<groups_cnt && groups[i].group!=grp) {
225 i++;
226 }
227 if (i==groups_cnt) { // not found
228 sprintf(name,"undef(%d)",grp); /* pseudo name*/
229 sprintf(name,"?%d",grp);
230 } else {
231 strcpy(name,groups[i].name);
232 }
233 route->rte_name = (char*) xrealloc(route->rte_name,(strlen(name)+1)*sizeof(char));
234 strcpy(route->rte_name,name);
235 }
236
ovl_read(void)237 static void ovl_read(void)
238 {
239 char* line;
240 int isSection;
241 int aktTyp,aktCol,aktSize,aktArt,aktGroup;
242 int aktArea,aktWidth,aktHeight,aktTrans,aktTransByte,aktDir;
243 double aktX,aktY;
244 char* aktPath;
245 char* aktText;
246 char* pstr;
247 int keyw,i;
248 double rwert;
249 route_head* route_head = NULL;
250 waypoint* wpt;
251 int sym_cnt;
252 int lineno = 0;
253
254 groups = NULL;
255 groups_cnt = 0;
256 aktTyp = aktCol = aktSize = aktArt = aktGroup = -1;
257 aktArea = aktWidth = aktHeight = aktTrans = aktTransByte = aktDir = -1;
258 aktX = aktY = 0.0;
259 aktText = NULL;
260 aktPath = NULL;
261 sym_cnt = 0;
262 isSection = SECTION_NONE;
263 while ((line = gbfgetstr(fpin))) {
264 if ((lineno == 0) && fpin->unicode) {
265 cet_convert_init(CET_CHARSET_UTF8, 1);
266 }
267 lineno++;
268 line = lrtrim(line);
269 if ((pstr = strstr(line,"[Symbol "))!= NULL) {
270 sym_cnt++;
271 isSection = SECTION_SYMBOL;
272 } else if ((pstr = strstr(line,"[Overlay]"))!= NULL) {
273 isSection = SECTION_OVERLAY;
274 } else if (isSection==SECTION_SYMBOL) {
275 pstr = strtok(line,"=");
276 if (pstr!=NULL) {
277 keyw = isKeyword(pstr,Keywords);
278 pstr = strtok(NULL,"\n");
279 if (pstr!=NULL) {
280 switch (keyw) {
281 case KEY_TYP :
282 aktTyp = atoi(pstr);
283 break;
284 case KEY_GROUP :
285 aktGroup = atoi(pstr);
286 ovl_add_group(aktGroup,"?"); /* 'Group' without relation to 'Text'-Symbol */
287 switch (aktTyp) {
288 case 3: // Linie
289 route_head = route_head_alloc();
290 route_head->rte_num = sym_cnt;
291 route_head->rte_name = xstrdup(pstr); /* use group-number for the moment */
292 route_add_head(route_head);
293 break;
294 }
295 break;
296 case KEY_COL :
297 aktCol = atoi(pstr);
298 break;
299 case KEY_ZOOM :
300 break;
301 case KEY_SIZE :
302 aktSize = atoi(pstr);
303 break;
304 case KEY_ART :
305 aktArt = atoi(pstr);
306 break;
307 case KEY_AREA :
308 aktArea = atoi(pstr);
309 if (aktTyp==5 || aktTyp==5 || aktTyp==7) {
310 isSection = SECTION_PUNKTE; // Rechteck, Kreis, Dreieck
311 }
312 break;
313 case KEY_PUNKTE :
314 isSection = SECTION_PUNKTE; // Linie, Fl�che
315 break;
316 #ifdef WITH_BITMAP
317 case KEY_PATH :
318 aktPath = xstrdup(pstr);
319 isSection = SECTION_PUNKTE; // Bitmap
320 break;
321 case KEY_TRANS :
322 aktTrans = atoi(pstr);
323 break;
324 case KEY_TRANSBYTE :
325 aktTransByte = atoi(pstr);
326 break;
327 #endif
328 case KEY_TEXT :
329 aktText = xstrdup(pstr);
330 /* The last 'Text'-symbol wins as a information block for
331 waypoint/route description.
332 Infos from previous symbols get overwrited.
333 */
334 ovl_add_group(aktGroup,aktText);
335 break;
336 case KEY_WIDTH :
337 aktWidth = atoi(pstr);
338 break;
339 case KEY_HEIGHT :
340 aktHeight = atoi(pstr);
341 break;
342 case KEY_DIR :
343 aktDir = atoi(pstr);
344 if (aktTyp==2) {
345 isSection = SECTION_PUNKTE; // Text
346 }
347 break;
348 }
349 }
350 }
351 } else if (isSection==SECTION_PUNKTE) {
352 pstr = strtok(line,"=");
353 if (strstr(pstr,"XKoord")!=NULL || strstr(pstr,"YKoord")!=NULL) {
354 if ((pstr = strtok(NULL,"\n"))!=NULL) {
355 rwert = atof(pstr);
356 if (line[0]=='X') {
357 aktX = rwert;
358 } else if (line[0]=='Y') {
359 aktY = rwert;
360 switch (aktTyp) {
361 #ifdef WITH_BITMAP
362 case 1: // Bitmap
363 wpt = waypt_new();
364 wpt->latitude = aktY;
365 wpt->longitude = aktX;
366 wpt->altitude = 0.0;
367 wpt->shortname = strdup(aktPath);
368 waypt_add(wpt);
369 break;
370 #endif
371 case 2: // Text
372 isSection = SECTION_SYMBOL;
373 break;
374 case 3: // Linie
375 wpt = waypt_new();
376 wpt->latitude = aktY;
377 wpt->longitude = aktX;
378 wpt->altitude = 0.0;
379 route_add_wpt(route_head, wpt);
380 break;
381 case 4: // Fl�che
382 break;
383 case 5: // Rechteck
384 break;
385 case 6: // Kreis
386 break;
387 case 7: // Dreieck
388 break;
389 }
390 }
391 }
392 }
393 } else if (isSection==SECTION_OVERLAY) {
394 isSection = SECTION_NONE;
395 }
396 }
397 route_disp_all(route_add_name,NULL,NULL);
398 if (aktText!=NULL) {
399 xfree(aktText);
400 }
401 if (aktPath!=NULL) {
402 xfree(aktPath);
403 }
404 for (i=0; i<groups_cnt; i++) {
405 if (groups[i].name!=NULL) {
406 xfree(groups[i].name);
407 }
408 }
409 xfree(groups);
410 }
411
ovl_rd_deinit(void)412 static void ovl_rd_deinit(void)
413 {
414 gbfclose(fpin);
415 }
416
417 /*------------------------------------------*/
ovl_read_parameter(const char * fname)418 void ovl_read_parameter(const char* fname)
419 {
420 gbfile* fpin;
421 arglist_t* p;
422 char* str;
423 char* pstr;
424
425 fpin = gbfopen(fname, "r", MYNAME);
426 if (fpin!=NULL) {
427 while ((str = gbfgetstr(fpin))) {
428 str = lrtrim(str); // trim
429 if (str[0]!=';') {
430 p = ovl_args;
431 pstr = strtok(str,"=");
432 if (pstr!=NULL) {
433 while (p->argstring!=NULL) {
434 if (strcmp(pstr,p->argstring)==0) {
435 pstr = strtok(NULL,"\n");
436 if (p->argtype==ARGTYPE_BOOL) {
437 *(p->argval) = atoi(pstr) ? xstrdup(pstr) : NULL;
438 } else {
439 *(p->argval) = xstrdup(pstr);
440 }
441 break;
442 }
443 p++;
444 }
445 }
446 }
447 }
448 gbfclose(fpin);
449 }
450 }
451
ovl_wr_init(const char * fname)452 static void ovl_wr_init(const char* fname)
453 {
454 fpout = gbfopen(fname, "w", MYNAME);
455 govl_sum_n = 0.0;
456 govl_sum_e = 0.0;
457 govl_sumcnt = 0.0;
458 govl_symbol_cnt = 0;
459
460
461 ovl_read_parameter(govl_file_s!=NULL ? govl_file_s : PARAMETER_FILE);
462
463 if (govl_col_s!=NULL) {
464 govl_col = atoi(govl_col_s);
465 }
466 if (govl_size_s!=NULL) {
467 govl_size = atoi(govl_size_s);
468 }
469 if (govl_mapname==NULL) {
470 govl_mapname = xstrdup(MAPNAME);
471 }
472 if (govl_zoomfc_s!=NULL) {
473 govl_zoomfc = atoi(govl_zoomfc_s);
474 }
475 if (govl_dimmfc_s!=NULL) {
476 govl_dimmfc = atoi(govl_dimmfc_s);
477 }
478 if (govl_txtcol_s!=NULL) {
479 govl_txtcol = atoi(govl_txtcol_s);
480 }
481 if (govl_txtsize_s!=NULL) {
482 govl_txtsize = atoi(govl_txtsize_s);
483 }
484 if (govl_font_s!=NULL) {
485 govl_font = atoi(govl_font_s);
486 }
487 if (govl_txttrans_s!=NULL) {
488 govl_txttrans = 1;
489 }
490 }
491
ovl_wr_deinit(void)492 static void ovl_wr_deinit(void)
493 {
494 gbfprintf(fpout,"[Overlay]\n");
495 gbfprintf(fpout,"Symbols=%d\n",govl_symbol_cnt);
496 gbfprintf(fpout,"[MapLage]\n");
497 gbfprintf(fpout,"MapName=%s\n",govl_mapname);
498 gbfprintf(fpout,"DimmFc=%d\n",govl_dimmfc);
499 gbfprintf(fpout,"ZoomFc=%d\n",govl_zoomfc);
500 if (govl_symbol_cnt) {
501 gbfprintf(fpout,"CenterLat=%.8lf\n",govl_sum_n/govl_sumcnt); // precision 8 = better than 1mm
502 gbfprintf(fpout,"CenterLong=%.8lf\n",govl_sum_e/govl_sumcnt);
503 } else {
504 gbfprintf(fpout,"CenterLong=10.52374295\n"); // Braunschweiger L�we, Mittelpunkt der Welt :-)
505 gbfprintf(fpout,"CenterLat=52.26474445\n");
506 }
507 gbfprintf(fpout,"RefOn=0\n");
508
509 gbfclose(fpout);
510 }
511
symbol_init(const route_head * hd)512 static void symbol_init(const route_head* hd)
513 {
514 gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1);
515 gbfprintf(fpout,"Typ=3\n"); // Linie
516 gbfprintf(fpout,"Group=%d\n" ,govl_group_cnt+1+1); // group==1 : not a group
517 gbfprintf(fpout,"Col=%d\n" ,govl_col);
518 gbfprintf(fpout,"Zoom=2\n");
519 gbfprintf(fpout,"Size=%d\n" ,govl_size);
520 gbfprintf(fpout,"Art=1\n");
521 gbfprintf(fpout,"Punkte=%d\n" ,hd->rte_waypt_ct);
522 govl_cnt = 0;
523 govl_symbol_cnt++;
524 govl_group_cnt++;
525 }
526
symbol_text(double east,double north,char * text,int group)527 static void symbol_text(double east,double north,char* text,int group)
528 {
529 gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1);
530 gbfprintf(fpout,"Typ=2\n"); // Text
531 gbfprintf(fpout,"Group=%d\n",group+1); // group==1 : not a group
532 gbfprintf(fpout,"Col=%d\n",govl_txtcol);
533 gbfprintf(fpout,"Area=%d\n",govl_txttrans ? 1 : 2); // =2 opak =1 transparent
534 gbfprintf(fpout,"Zoom=%d\n",2);
535 gbfprintf(fpout,"Size=%d\n",govl_txtsize);
536 gbfprintf(fpout,"Font=%d\n",govl_font);
537 gbfprintf(fpout,"Dir=%d\n",100+((int) govl_dir));
538 gbfprintf(fpout,"XKoord=%.8lf\n",east); // precision 8 = better than 1mm
539 gbfprintf(fpout,"YKoord=%.8lf\n",north);
540 gbfprintf(fpout,"Text=%s\n",text);
541 govl_symbol_cnt++;
542 }
543
symbol_point(const waypoint * wpt)544 static void symbol_point(const waypoint* wpt)
545 {
546 double east,north;
547
548 east = wpt->longitude;
549 north = wpt->latitude;
550 gbfprintf(fpout,"XKoord%d=%.8lf\n",govl_cnt,east); // precision 8 = better than 1mm
551 gbfprintf(fpout,"YKoord%d=%.8lf\n",govl_cnt,north);
552 govl_cnt++;
553 govl_sum_e += east;
554 govl_sum_n += north;
555 govl_sumcnt += 1.0;
556 /*
557 govl_last_east = east;
558 govl_last_north = north;
559 */
560 }
561
562
symbol_deinit(const route_head * hd)563 static void symbol_deinit(const route_head* hd)
564 {
565 queue* elem, *tmp;
566 waypoint* waypointp;
567 int i;
568 double lat1,lon1,lat2,lon2;
569 double lats,lons,late,lone;
570 double dist,d,dd;
571
572 lat1 = lon1 = lat2 = lon2 = 0.0;
573 lats = lons = late = lone = 0.0;
574 dist = 0.0;
575 i = 0;
576 QUEUE_FOR_EACH(&(hd->waypoint_list), elem, tmp) {
577 waypointp = (waypoint*) elem;
578 lat2 = RAD(waypointp->latitude);
579 lon2 = RAD(waypointp->longitude);
580 if (i) {
581 d = gcdist(lat1, lon1, lat2, lon2);
582 dist += d;
583 } else {
584 lats = lat2; // start point
585 lons = lon2;
586 }
587 lat1 = lat2;
588 lon1 = lon2;
589 i++;
590 }
591 late = lat2; // end point
592 lone = lon2;
593 dd = 0;
594 i = 0;
595 elem = QUEUE_FIRST(&(hd->waypoint_list));
596 while (elem!=&(hd->waypoint_list) && dd<dist/2.0) {
597 waypointp = (waypoint*) elem;
598 lat2 = RAD(waypointp->latitude);
599 lon2 = RAD(waypointp->longitude);
600 if (i) {
601 d = gcdist(lat1, lon1, lat2, lon2);
602 dd += d;
603 }
604 lat1 = lat2;
605 lon1 = lon2;
606 elem = QUEUE_NEXT(elem);
607 i++;
608 }
609
610 d = gcdist(lats,lons,late,lone);
611 // d = acos( sin(lats)*sin(late)+cos(lats)*cos(late)*cos(lone-lons) );
612 dd = acos((sin(late) - sin(lats)*cos(d))/(cos(lats)*sin(d)));
613 if (lone<lons) {
614 dd = -dd; // correction because the ambiguity of acos function
615 }
616 dd = DEG(dd); // azimuth
617 dd = 360.0 - (dd + 270.0); // make it anticlockwise and start counting on x-axis
618 dd = dd < 0.0 ? dd + 360.0 : dd; // normalizing
619 dd = dd > 360.0 ? dd - 360.0 : dd; // normalizing
620
621 /* name of route */
622 /* plot text at the last point of route */
623 govl_dir = dd; // approximated text rotation, correct value must be the azimuth in UTM
624 symbol_text(DEG(lon1),DEG(lat1),hd->rte_name,govl_group_cnt);
625 govl_dir = 0.0; // restore
626 }
627
overlay_waypt_pr(const waypoint * waypointp)628 static void overlay_waypt_pr(const waypoint* waypointp)
629 {
630 const char* oname;
631 char* odesc;
632
633 /*
634 * Desparation time, try very hard to get a good shortname
635 */
636 odesc = waypointp->notes;
637 if (!odesc) {
638 odesc = waypointp->description;
639 }
640 if (!odesc) {
641 odesc = waypointp->shortname;
642 }
643 oname = global_opts.synthesize_shortnames ?
644 mkshort(mkshort_handle, odesc) :
645 waypointp->shortname;
646
647 gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1);
648 gbfprintf(fpout,"Typ=1\n");
649 gbfprintf(fpout,"Group=1\n");
650 gbfprintf(fpout,"Width=100\n");
651 gbfprintf(fpout,"Height=100\n");
652 gbfprintf(fpout,"Dir=%d\n",100+((int) govl_dir));
653 gbfprintf(fpout,"Zoom=2\n");
654 gbfprintf(fpout,"Trans=2\n");
655 gbfprintf(fpout,"TransByte=5\n");
656 gbfprintf(fpout,"Path=%s\n","waypoint.bmp");
657 gbfprintf(fpout,"XKoord=%.8lf\n",waypointp->longitude);
658 gbfprintf(fpout,"YKoord=%.8lf\n",waypointp->latitude);
659 govl_symbol_cnt++;
660 govl_sum_e += waypointp->longitude;
661 govl_sum_n += waypointp->latitude;
662 govl_sumcnt += 1.0;
663
664 }
665
ovl_write(void)666 static void ovl_write(void)
667 {
668 waypt_disp_all(overlay_waypt_pr);
669 track_disp_all(symbol_init, symbol_deinit, symbol_point);
670 route_disp_all(symbol_init, symbol_deinit, symbol_point);
671 /*
672 switch(global_opts.objective)
673 {
674 case wptdata:
675 break;
676 case trkdata:
677 break;
678 }
679 */
680 }
681
682
683 ff_vecs_t overlay_vecs = {
684 ff_type_internal,
685 FF_CAP_RW_ALL,
686 ovl_rd_init,
687 ovl_wr_init,
688 ovl_rd_deinit,
689 ovl_wr_deinit,
690 ovl_read,
691 ovl_write,
692 NULL,
693 ovl_args,
694 CET_CHARSET_ASCII, 0 /* CET-REVIEW */
695 };
696