Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/output.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 926 - (show annotations) (download) (as text)
Tue Dec 6 17:19:02 2011 UTC (13 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 34374 byte(s)
Output HTML directions for roundabouts.

1 /***************************************
2 Routing output generator.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-2011 Andrew M. Bishop
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Affero General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ***************************************/
21
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <stdio.h>
27 #include <math.h>
28 #include <errno.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32
33 #include "types.h"
34 #include "nodes.h"
35 #include "segments.h"
36 #include "ways.h"
37
38 #include "files.h"
39 #include "functions.h"
40 #include "fakes.h"
41 #include "translations.h"
42 #include "results.h"
43 #include "xmlparse.h"
44
45
46 /* Global variables */
47
48 /*+ The option to calculate the quickest route insted of the shortest. +*/
49 extern int option_quickest;
50
51 /*+ The options to select the format of the output. +*/
52 extern int option_html,option_gpx_track,option_gpx_route,option_text,option_text_all;
53
54 /* Local variables */
55
56 /*+ Heuristics for determining if a junction is important. +*/
57 static char junction_other_way[Way_Count][Way_Count]=
58 { /* M, T, P, S, T, U, R, S, T, C, P, S, F = Way type of route not taken */
59 { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Motorway */
60 { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Trunk */
61 { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Primary */
62 { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Secondary */
63 { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Tertiary */
64 { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 }, /* Unclassified */
65 { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 }, /* Residential */
66 { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 }, /* Service */
67 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1 }, /* Track */
68 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1 }, /* Cycleway */
69 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Path */
70 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Steps */
71 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Ferry */
72 };
73
74
75 /*++++++++++++++++++++++++++++++++++++++
76 Print the optimum route between two nodes.
77
78 Results **results The set of results to print (some may be NULL - ignore them).
79
80 int nresults The number of results in the list.
81
82 Nodes *nodes The set of nodes to use.
83
84 Segments *segments The set of segments to use.
85
86 Ways *ways The set of ways to use.
87
88 Profile *profile The profile containing the transport type, speeds and allowed highways.
89 ++++++++++++++++++++++++++++++++++++++*/
90
91 void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile)
92 {
93 FILE *htmlfile=NULL,*gpxtrackfile=NULL,*gpxroutefile=NULL,*textfile=NULL,*textallfile=NULL;
94
95 char *prev_bearing=NULL,*prev_wayname=NULL;
96 distance_t cum_distance=0;
97 duration_t cum_duration=0;
98
99 int point=1;
100 int segment_count=0,route_count=0;
101 int point_count=0;
102 int roundabout=0;
103
104 /* Open the files */
105
106 if(option_quickest==0)
107 {
108 /* Print the result for the shortest route */
109
110 if(option_html)
111 htmlfile =fopen("shortest.html","w");
112 if(option_gpx_track)
113 gpxtrackfile=fopen("shortest-track.gpx","w");
114 if(option_gpx_route)
115 gpxroutefile=fopen("shortest-route.gpx","w");
116 if(option_text)
117 textfile =fopen("shortest.txt","w");
118 if(option_text_all)
119 textallfile =fopen("shortest-all.txt","w");
120
121 if(option_html && !htmlfile)
122 fprintf(stderr,"Warning: Cannot open file 'shortest.html' for writing [%s].\n",strerror(errno));
123 if(option_gpx_track && !gpxtrackfile)
124 fprintf(stderr,"Warning: Cannot open file 'shortest-track.gpx' for writing [%s].\n",strerror(errno));
125 if(option_gpx_route && !gpxroutefile)
126 fprintf(stderr,"Warning: Cannot open file 'shortest-route.gpx' for writing [%s].\n",strerror(errno));
127 if(option_text && !textfile)
128 fprintf(stderr,"Warning: Cannot open file 'shortest.txt' for writing [%s].\n",strerror(errno));
129 if(option_text_all && !textallfile)
130 fprintf(stderr,"Warning: Cannot open file 'shortest-all.txt' for writing [%s].\n",strerror(errno));
131 }
132 else
133 {
134 /* Print the result for the quickest route */
135
136 if(option_html)
137 htmlfile =fopen("quickest.html","w");
138 if(option_gpx_track)
139 gpxtrackfile=fopen("quickest-track.gpx","w");
140 if(option_gpx_route)
141 gpxroutefile=fopen("quickest-route.gpx","w");
142 if(option_text)
143 textfile =fopen("quickest.txt","w");
144 if(option_text_all)
145 textallfile =fopen("quickest-all.txt","w");
146
147 if(option_html && !htmlfile)
148 fprintf(stderr,"Warning: Cannot open file 'quickest.html' for writing [%s].\n",strerror(errno));
149 if(option_gpx_track && !gpxtrackfile)
150 fprintf(stderr,"Warning: Cannot open file 'quickest-track.gpx' for writing [%s].\n",strerror(errno));
151 if(option_gpx_route && !gpxroutefile)
152 fprintf(stderr,"Warning: Cannot open file 'quickest-route.gpx' for writing [%s].\n",strerror(errno));
153 if(option_text && !textfile)
154 fprintf(stderr,"Warning: Cannot open file 'quickest.txt' for writing [%s].\n",strerror(errno));
155 if(option_text_all && !textallfile)
156 fprintf(stderr,"Warning: Cannot open file 'quickest-all.txt' for writing [%s].\n",strerror(errno));
157 }
158
159 /* Print the head of the files */
160
161 if(htmlfile)
162 {
163 fprintf(htmlfile,"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
164 fprintf(htmlfile,"<HTML>\n");
165 if(translate_xml_copyright_creator[0] && translate_xml_copyright_creator[1])
166 fprintf(htmlfile,"<!-- %s : %s -->\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
167 if(translate_xml_copyright_source[0] && translate_xml_copyright_source[1])
168 fprintf(htmlfile,"<!-- %s : %s -->\n",translate_xml_copyright_source[0],translate_xml_copyright_source[1]);
169 if(translate_xml_copyright_license[0] && translate_xml_copyright_license[1])
170 fprintf(htmlfile,"<!-- %s : %s -->\n",translate_xml_copyright_license[0],translate_xml_copyright_license[1]);
171 fprintf(htmlfile,"<HEAD>\n");
172 fprintf(htmlfile,"<TITLE>");
173 fprintf(htmlfile,translate_html_title,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
174 fprintf(htmlfile,"</TITLE>\n");
175 fprintf(htmlfile,"<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
176 fprintf(htmlfile,"<STYLE type=\"text/css\">\n");
177 fprintf(htmlfile,"<!--\n");
178 fprintf(htmlfile," table {table-layout: fixed; border: none; border-collapse: collapse;}\n");
179 fprintf(htmlfile," table.c {color: grey; font-size: x-small;} /* copyright */\n");
180 fprintf(htmlfile," tr {border: 0px;}\n");
181 fprintf(htmlfile," tr.c {display: none;} /* coords */\n");
182 fprintf(htmlfile," tr.n {} /* node */\n");
183 fprintf(htmlfile," tr.s {} /* segment */\n");
184 fprintf(htmlfile," tr.t {font-weight: bold;} /* total */\n");
185 fprintf(htmlfile," td.l {font-weight: bold;}\n");
186 fprintf(htmlfile," td.r {}\n");
187 fprintf(htmlfile," span.w {font-weight: bold;} /* waypoint */\n");
188 fprintf(htmlfile," span.h {text-decoration: underline;} /* highway */\n");
189 fprintf(htmlfile," span.d {} /* segment distance */\n");
190 fprintf(htmlfile," span.j {font-style: italic;} /* total journey distance */\n");
191 fprintf(htmlfile," span.t {font-variant: small-caps;} /* turn */\n");
192 fprintf(htmlfile," span.b {font-variant: small-caps;} /* bearing */\n");
193 fprintf(htmlfile,"-->\n");
194 fprintf(htmlfile,"</STYLE>\n");
195 fprintf(htmlfile,"</HEAD>\n");
196 fprintf(htmlfile,"<BODY>\n");
197 fprintf(htmlfile,"<H1>");
198 fprintf(htmlfile,translate_html_title,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
199 fprintf(htmlfile,"</H1>\n");
200 fprintf(htmlfile,"<table>\n");
201 }
202
203 if(gpxtrackfile)
204 {
205 fprintf(gpxtrackfile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
206 fprintf(gpxtrackfile,"<gpx version=\"1.1\" creator=\"Routino\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/1\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n");
207
208 fprintf(gpxtrackfile,"<metadata>\n");
209 fprintf(gpxtrackfile,"<desc>%s : %s</desc>\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
210 if(translate_xml_copyright_source[1])
211 {
212 fprintf(gpxtrackfile,"<copyright author=\"%s\">\n",translate_xml_copyright_source[1]);
213
214 if(translate_xml_copyright_license[1])
215 fprintf(gpxtrackfile,"<license>%s</license>\n",translate_xml_copyright_license[1]);
216
217 fprintf(gpxtrackfile,"</copyright>\n");
218 }
219 fprintf(gpxtrackfile,"</metadata>\n");
220
221 fprintf(gpxtrackfile,"<trk>\n");
222 fprintf(gpxtrackfile,"<name>");
223 fprintf(gpxtrackfile,translate_gpx_name,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
224 fprintf(gpxtrackfile,"</name>\n");
225 fprintf(gpxtrackfile,"<desc>");
226 fprintf(gpxtrackfile,translate_gpx_desc,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
227 fprintf(gpxtrackfile,"</desc>\n");
228 }
229
230 if(gpxroutefile)
231 {
232 fprintf(gpxroutefile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
233 fprintf(gpxroutefile,"<gpx version=\"1.1\" creator=\"Routino\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/1\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n");
234
235 fprintf(gpxroutefile,"<metadata>\n");
236 fprintf(gpxroutefile,"<desc>%s : %s</desc>\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
237 if(translate_xml_copyright_source[1])
238 {
239 fprintf(gpxroutefile,"<copyright author=\"%s\">\n",translate_xml_copyright_source[1]);
240
241 if(translate_xml_copyright_license[1])
242 fprintf(gpxroutefile,"<license>%s</license>\n",translate_xml_copyright_license[1]);
243
244 fprintf(gpxroutefile,"</copyright>\n");
245 }
246 fprintf(gpxroutefile,"</metadata>\n");
247
248 fprintf(gpxroutefile,"<rte>\n");
249 fprintf(gpxroutefile,"<name>");
250 fprintf(gpxroutefile,translate_gpx_name,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
251 fprintf(gpxroutefile,"</name>\n");
252 fprintf(gpxroutefile,"<desc>");
253 fprintf(gpxroutefile,translate_gpx_desc,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
254 fprintf(gpxroutefile,"</desc>\n");
255 }
256
257 if(textfile)
258 {
259 if(translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1])
260 fprintf(textfile,"# %s : %s\n",translate_raw_copyright_creator[0],translate_raw_copyright_creator[1]);
261 if(translate_raw_copyright_source[0] && translate_raw_copyright_source[1])
262 fprintf(textfile,"# %s : %s\n",translate_raw_copyright_source[0],translate_raw_copyright_source[1]);
263 if(translate_raw_copyright_license[0] && translate_raw_copyright_license[1])
264 fprintf(textfile,"# %s : %s\n",translate_raw_copyright_license[0],translate_raw_copyright_license[1]);
265 if((translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1]) ||
266 (translate_raw_copyright_source[0] && translate_raw_copyright_source[1]) ||
267 (translate_raw_copyright_license[0] && translate_raw_copyright_license[1]))
268 fprintf(textfile,"#\n");
269
270 fprintf(textfile,"#Latitude\tLongitude\tSection \tSection \tTotal \tTotal \tPoint\tTurn\tBearing\tHighway\n");
271 fprintf(textfile,"# \t \tDistance\tDuration\tDistance\tDuration\tType \t \t \t \n");
272 /* "%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%4.0f min\t%s\t %+d\t %+d\t%s\n" */
273 }
274
275 if(textallfile)
276 {
277 if(translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1])
278 fprintf(textallfile,"# %s : %s\n",translate_raw_copyright_creator[0],translate_raw_copyright_creator[1]);
279 if(translate_raw_copyright_source[0] && translate_raw_copyright_source[1])
280 fprintf(textallfile,"# %s : %s\n",translate_raw_copyright_source[0],translate_raw_copyright_source[1]);
281 if(translate_raw_copyright_license[0] && translate_raw_copyright_license[1])
282 fprintf(textallfile,"# %s : %s\n",translate_raw_copyright_license[0],translate_raw_copyright_license[1]);
283 if((translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1]) ||
284 (translate_raw_copyright_source[0] && translate_raw_copyright_source[1]) ||
285 (translate_raw_copyright_license[0] && translate_raw_copyright_license[1]))
286 fprintf(textallfile,"#\n");
287
288 fprintf(textallfile,"#Latitude\tLongitude\t Node\tType\tSegment\tSegment\tTotal\tTotal \tSpeed\tBearing\tHighway\n");
289 fprintf(textallfile,"# \t \t \t \tDist \tDurat'n\tDist \tDurat'n\t \t \t \n");
290 /* "%10.6f\t%11.6f\t%8d%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%4d\t%s\n" */
291 }
292
293 /* Loop through all the sections of the route and print them */
294
295 while(!results[point])
296 point++;
297
298 while(point<=nresults)
299 {
300 int next_point=point;
301 distance_t junc_distance=0;
302 duration_t junc_duration=0;
303 Result *result;
304
305 result=FindResult(results[point],results[point]->start_node,results[point]->prev_segment);
306
307 /* Print the start of the segment */
308
309 if(gpxtrackfile)
310 fprintf(gpxtrackfile,"<trkseg>\n");
311
312 /* Loop through all the points within a section of the route and print them */
313
314 do
315 {
316 double latitude,longitude;
317 Node *resultnode=NULL;
318 index_t realsegment=NO_SEGMENT,next_realsegment=NO_SEGMENT;
319 Segment *resultsegment=NULL,*next_resultsegment=NULL;
320 Way *resultway=NULL,*next_resultway;
321 Result *next_result;
322 int important=0;
323
324 distance_t seg_distance=0;
325 duration_t seg_duration=0;
326 speed_t seg_speed=0;
327 char *waynameraw=NULL,*wayname=NULL,*next_waynameraw=NULL,*next_wayname=NULL;
328 int bearing_int=0,turn_int=0,next_bearing_int=0;
329 char *turn=NULL,*next_bearing=NULL;
330
331 /* Calculate the information about this point */
332
333 if(IsFakeNode(result->node))
334 GetFakeLatLong(result->node,&latitude,&longitude);
335 else
336 GetLatLong(nodes,result->node,&latitude,&longitude);
337
338 if(!IsFakeNode(result->node))
339 resultnode=LookupNode(nodes,result->node,6);
340
341 /* Calculate the next result */
342
343 next_result=result->next;
344
345 if(!next_result)
346 for(next_point=point+1;next_point<=nresults;next_point++)
347 if(results[next_point])
348 {
349 next_result=FindResult(results[next_point],results[next_point]->start_node,results[next_point]->prev_segment);
350 next_result=next_result->next;
351 break;
352 }
353
354 /* Calculate the information about this segment */
355
356 if(result->node!=results[point]->start_node) /* not first point of a section of the route */
357 {
358 if(IsFakeSegment(result->segment))
359 {
360 resultsegment=LookupFakeSegment(result->segment);
361 realsegment=IndexRealSegment(result->segment);
362 }
363 else
364 {
365 resultsegment=LookupSegment(segments,result->segment,2);
366 realsegment=result->segment;
367 }
368
369 resultway=LookupWay(ways,resultsegment->way,1);
370
371 seg_distance+=DISTANCE(resultsegment->distance);
372 seg_duration+=Duration(resultsegment,resultway,profile);
373
374 /* Calculate the cumulative distance/duration */
375
376 junc_distance+=seg_distance;
377 junc_duration+=seg_duration;
378 cum_distance+=seg_distance;
379 cum_duration+=seg_duration;
380 }
381
382 /* Calculate the information about the next segment */
383
384 if(next_result)
385 {
386 if(IsFakeSegment(next_result->segment))
387 {
388 next_resultsegment=LookupFakeSegment(next_result->segment);
389 next_realsegment=IndexRealSegment(next_result->segment);
390 }
391 else
392 {
393 next_resultsegment=LookupSegment(segments,next_result->segment,1);
394 next_realsegment=next_result->segment;
395 }
396 }
397
398 /* Decide if this is a roundabout */
399
400 if(next_result)
401 {
402 next_resultway=LookupWay(ways,next_resultsegment->way,2);
403
404 if(next_resultway->type&Way_Roundabout)
405 {
406 if(roundabout==0)
407 {
408 roundabout++;
409 important=7;
410 }
411 else
412 {
413 Segment *segment=FirstSegment(segments,resultnode,3);
414
415 do
416 {
417 index_t othernode=OtherNode(segment,result->node);
418
419 if(othernode!=result->prev->node && IndexSegment(segments,segment)!=realsegment)
420 if(IsNormalSegment(segment) && (!profile->oneway || !IsOnewayTo(segment,result->node)))
421 {
422 Way *way=LookupWay(ways,segment->way,3);
423
424 if(!(way->type&Way_Roundabout))
425 if(othernode!=next_result->node)
426 roundabout++;
427 }
428
429 segment=NextSegment(segments,segment,result->node);
430 }
431 while(segment);
432 }
433 }
434 else
435 if(roundabout)
436 {
437 roundabout++;
438 important=7;
439 }
440 }
441
442 /* Decide if this is an important junction */
443
444 if(roundabout) /* roundabout */
445 ;
446 else if(point_count==0) /* first point overall = Waypoint */
447 important=10;
448 else if(result->node==results[point]->finish_node) /* Waypoint */
449 important=10;
450 else if(result->node==results[point]->start_node) /* first point of a section of the route */
451 important=-1;
452 else if(realsegment==next_realsegment) /* U-turn */
453 important=5;
454 else
455 {
456 Segment *segment=FirstSegment(segments,resultnode,3);
457
458 do
459 {
460 index_t othernode=OtherNode(segment,result->node);
461
462 if(othernode!=result->prev->node && IndexSegment(segments,segment)!=realsegment)
463 if(IsNormalSegment(segment) && (!profile->oneway || !IsOnewayTo(segment,result->node)))
464 {
465 Way *way=LookupWay(ways,segment->way,3);
466
467 if(othernode==next_result->node) /* the next segment that we follow */
468 {
469 if(HIGHWAY(way->type)!=HIGHWAY(resultway->type))
470 if(important<2)
471 important=2;
472 }
473 else if(IsFakeNode(next_result->node))
474 ;
475 else /* a segment that we don't follow */
476 {
477 if(junction_other_way[HIGHWAY(resultway->type)-1][HIGHWAY(way->type)-1])
478 if(important<3)
479 important=3;
480
481 if(important<1)
482 important=1;
483 }
484 }
485
486 segment=NextSegment(segments,segment,result->node);
487 }
488 while(segment);
489 }
490
491 /* Calculate the strings to be used */
492
493 if(resultway && textallfile)
494 {
495 waynameraw=WayName(ways,resultway);
496 if(!*waynameraw)
497 waynameraw=translate_raw_highway[HIGHWAY(resultway->type)];
498
499 bearing_int=(int)BearingAngle(nodes,resultsegment,result->node);
500
501 seg_speed=profile->speed[HIGHWAY(resultway->type)];
502 }
503
504 if(next_result && important>1)
505 {
506 if(resultsegment && (htmlfile || textfile))
507 {
508 turn_int=(int)TurnAngle(nodes,resultsegment,next_resultsegment,result->node);
509 turn=translate_xml_turn[((202+turn_int)/45)%8];
510 }
511
512 if(gpxroutefile || htmlfile)
513 {
514 next_waynameraw=WayName(ways,next_resultway);
515 if(!*next_waynameraw)
516 next_waynameraw=translate_raw_highway[HIGHWAY(next_resultway->type)];
517
518 next_wayname=ParseXML_Encode_Safe_XML(next_waynameraw);
519 }
520
521 if(htmlfile || gpxroutefile || textfile)
522 {
523 next_bearing_int=(int)BearingAngle(nodes,next_resultsegment,next_result->node);
524 next_bearing=translate_xml_heading[(4+(22+next_bearing_int)/45)%8];
525 }
526 }
527
528 /* Print out the important points (junctions / waypoints) */
529
530 if(important>1)
531 {
532 if(htmlfile)
533 {
534 char *type;
535
536 if(important==10)
537 type=translate_html_waypoint;
538 else
539 type=translate_html_junction;
540
541 if(point_count>0) /* not the first point */
542 {
543 /* <tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>*highway name*</span> for <span class='d'>*distance* km, *time* min</span> [<span class='j'>*distance* km, *time* minutes</span>] */
544 fprintf(htmlfile,"<tr class='s'><td class='l'>%s:<td class='r'>",translate_html_segment[0]);
545 fprintf(htmlfile,translate_html_segment[1],
546 (roundabout>1?translate_html_roundabout:prev_wayname),
547 distance_to_km(junc_distance),duration_to_minutes(junc_duration));
548 fprintf(htmlfile," [<span class='j'>");
549 fprintf(htmlfile,translate_html_total[1],
550 distance_to_km(cum_distance),duration_to_minutes(cum_duration));
551 fprintf(htmlfile,"</span>]\n");
552 }
553
554 /* <tr class='c'><td class='l'>*N*:<td class='r'>*latitude* *longitude* */
555 fprintf(htmlfile,"<tr class='c'><td class='l'>%d:<td class='r'>%.6f %.6f\n",
556 point_count+1,
557 radians_to_degrees(latitude),radians_to_degrees(longitude));
558
559 if(point_count==0) /* first point */
560 {
561 /* <tr class='n'><td class='l'>Start:<td class='r'>At <span class='w'>Waypoint</span>, head <span class='b'>*heading*</span> */
562 fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_start[0]);
563 fprintf(htmlfile,translate_html_start[1],
564 translate_html_waypoint,
565 next_bearing);
566 fprintf(htmlfile,"\n");
567 }
568 else if(next_result) /* middle point */
569 {
570 if(roundabout>1)
571 {
572 /* <tr class='n'><td class='l'>At:<td class='r'>Roundabout, take <span class='t'>the *Nth* exit</span> heading <span class='b'>*heading*</span> */
573 fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_rbnode[0]);
574 fprintf(htmlfile,translate_html_rbnode[1],
575 translate_html_roundabout,
576 translate_xml_ordinal[roundabout-2],
577 next_bearing);
578 fprintf(htmlfile,"\n");
579 }
580 else
581 {
582 /* <tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>*direction*</span> heading <span class='b'>*heading*</span> */
583 fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_node[0]);
584 fprintf(htmlfile,translate_html_node[1],
585 type,
586 turn,
587 next_bearing);
588 fprintf(htmlfile,"\n");
589 }
590 }
591 else /* end point */
592 {
593 /* <tr class='n'><td class='l'>Stop:<td class='r'>At <span class='w'>Waypoint</span> */
594 fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_stop[0]);
595 fprintf(htmlfile,translate_html_stop[1],
596 translate_html_waypoint);
597 fprintf(htmlfile,"\n");
598
599 /* <tr class='t'><td class='l'>Total:<td class='r'><span class='j'>*distance* km, *time* minutes</span> */
600 fprintf(htmlfile,"<tr class='t'><td class='l'>%s:<td class='r'><span class='j'>",translate_html_total[0]);
601 fprintf(htmlfile,translate_html_total[1],
602 distance_to_km(cum_distance),duration_to_minutes(cum_duration));
603 fprintf(htmlfile,"</span>\n");
604 }
605 }
606
607 if(gpxroutefile)
608 {
609 if(point_count>0) /* not first point */
610 {
611 fprintf(gpxroutefile,"<desc>");
612 fprintf(gpxroutefile,translate_gpx_step,
613 prev_bearing,
614 prev_wayname,
615 distance_to_km(junc_distance),duration_to_minutes(junc_duration));
616 fprintf(gpxroutefile,"</desc></rtept>\n");
617 }
618
619 if(point_count==0) /* first point */
620 {
621 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s</name>\n",
622 radians_to_degrees(latitude),radians_to_degrees(longitude),
623 translate_gpx_start);
624 }
625 else if(!next_result) /* end point */
626 {
627 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s</name>\n",
628 radians_to_degrees(latitude),radians_to_degrees(longitude),
629 translate_gpx_finish);
630 fprintf(gpxroutefile,"<desc>");
631 fprintf(gpxroutefile,translate_gpx_final,
632 distance_to_km(cum_distance),duration_to_minutes(cum_duration));
633 fprintf(gpxroutefile,"</desc></rtept>\n");
634 }
635 else /* middle point */
636 {
637 if(important==10)
638 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%d</name>\n",
639 radians_to_degrees(latitude),radians_to_degrees(longitude),
640 translate_gpx_inter,++segment_count);
641 else
642 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%03d</name>\n",
643 radians_to_degrees(latitude),radians_to_degrees(longitude),
644 translate_gpx_trip,++route_count);
645 }
646 }
647
648 if(textfile)
649 {
650 char *type;
651
652 if(important==10)
653 type="Waypt";
654 else
655 type="Junct";
656
657 if(point_count==0) /* first point */
658 {
659 fprintf(textfile,"%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%4.0f min\t%s\t\t %+d\t%s\n",
660 radians_to_degrees(latitude),radians_to_degrees(longitude),
661 0.0,0.0,0.0,0.0,
662 type,
663 ((22+next_bearing_int)/45+4)%8-4,
664 next_waynameraw);
665 }
666 else if(!next_result) /* end point */
667 {
668 fprintf(textfile,"%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%4.0f min\t%s\t\t\t\n",
669 radians_to_degrees(latitude),radians_to_degrees(longitude),
670 distance_to_km(junc_distance),duration_to_minutes(junc_duration),
671 distance_to_km(cum_distance),duration_to_minutes(cum_duration),
672 type);
673 }
674 else /* middle point */
675 {
676 fprintf(textfile,"%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%4.0f min\t%s\t %+d\t %+d\t%s\n",
677 radians_to_degrees(latitude),radians_to_degrees(longitude),
678 distance_to_km(junc_distance),duration_to_minutes(junc_duration),
679 distance_to_km(cum_distance),duration_to_minutes(cum_duration),
680 type,
681 (22+turn_int)/45,
682 ((22+next_bearing_int)/45+4)%8-4,
683 next_waynameraw);
684 }
685 }
686
687 junc_distance=0;
688 junc_duration=0;
689
690 if(htmlfile || gpxroutefile)
691 {
692 if(prev_wayname)
693 free(prev_wayname);
694
695 if(next_wayname)
696 prev_wayname=strcpy((char*)malloc(strlen(next_wayname)+1),next_wayname);
697 else
698 prev_wayname=NULL;
699
700 if(next_wayname && next_wayname!=next_waynameraw)
701 free(next_wayname);
702 }
703
704 if(gpxroutefile)
705 prev_bearing=next_bearing;
706
707 if(roundabout>1)
708 roundabout=0;
709 }
710
711 /* Print out all of the results */
712
713 if(gpxtrackfile)
714 fprintf(gpxtrackfile,"<trkpt lat=\"%.6f\" lon=\"%.6f\"/>\n",
715 radians_to_degrees(latitude),radians_to_degrees(longitude));
716
717 if(important>=0)
718 {
719 if(textallfile)
720 {
721 char *type;
722
723 if(important==10)
724 type="Waypt";
725 else if(important==5)
726 type="U-turn";
727 else if(important==2)
728 type="Change";
729 else if(important>=1)
730 type="Junct";
731 else
732 type="Inter";
733
734 if(point_count==0) /* first point */
735 {
736 fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t\t\t\n",
737 radians_to_degrees(latitude),radians_to_degrees(longitude),
738 IsFakeNode(result->node)?(NODE_FAKE-result->node):result->node,
739 (resultnode && IsSuperNode(resultnode))?'*':' ',type,
740 0.0,0.0,0.0,0.0);
741 }
742 else /* not the first point */
743 {
744 fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%4d\t%s\n",
745 radians_to_degrees(latitude),radians_to_degrees(longitude),
746 IsFakeNode(result->node)?(NODE_FAKE-result->node):result->node,
747 (resultnode && IsSuperNode(resultnode))?'*':' ',type,
748 distance_to_km(seg_distance),duration_to_minutes(seg_duration),
749 distance_to_km(cum_distance),duration_to_minutes(cum_duration),
750 speed_to_kph(seg_speed),
751 bearing_int,
752 waynameraw);
753 }
754 }
755 }
756
757 if(wayname && wayname!=waynameraw)
758 free(wayname);
759
760 result=next_result;
761
762 if(important>1)
763 point_count++;
764 }
765 while(point==next_point);
766
767 /* Print the end of the segment */
768
769 if(gpxtrackfile)
770 fprintf(gpxtrackfile,"</trkseg>\n");
771
772 point=next_point;
773 }
774
775 /* Print the tail of the files */
776
777 if(htmlfile)
778 {
779 fprintf(htmlfile,"</table>\n");
780
781 if((translate_xml_copyright_creator[0] && translate_xml_copyright_creator[1]) ||
782 (translate_xml_copyright_source[0] && translate_xml_copyright_source[1]) ||
783 (translate_xml_copyright_license[0] && translate_xml_copyright_license[1]))
784 {
785 fprintf(htmlfile,"<p>\n");
786 fprintf(htmlfile,"<table class='c'>\n");
787 if(translate_xml_copyright_creator[0] && translate_xml_copyright_creator[1])
788 fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
789 if(translate_xml_copyright_source[0] && translate_xml_copyright_source[1])
790 fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translate_xml_copyright_source[0],translate_xml_copyright_source[1]);
791 if(translate_xml_copyright_license[0] && translate_xml_copyright_license[1])
792 fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translate_xml_copyright_license[0],translate_xml_copyright_license[1]);
793 fprintf(htmlfile,"</table>\n");
794 }
795
796 fprintf(htmlfile,"</BODY>\n");
797 fprintf(htmlfile,"</HTML>\n");
798 }
799
800 if(gpxtrackfile)
801 {
802 fprintf(gpxtrackfile,"</trk>\n");
803 fprintf(gpxtrackfile,"</gpx>\n");
804 }
805
806 if(gpxroutefile)
807 {
808 fprintf(gpxroutefile,"</rte>\n");
809 fprintf(gpxroutefile,"</gpx>\n");
810 }
811
812 /* Close the files */
813
814 if(htmlfile)
815 fclose(htmlfile);
816 if(gpxtrackfile)
817 fclose(gpxtrackfile);
818 if(gpxroutefile)
819 fclose(gpxroutefile);
820 if(textfile)
821 fclose(textfile);
822 if(textallfile)
823 fclose(textallfile);
824 }

Properties

Name Value
cvs:description New file to contain the function to print the output.