Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /trunk/src/output.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1677 - (hide annotations) (download) (as text)
Wed May 20 18:36:31 2015 UTC (9 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 38836 byte(s)
Change a static variable to a const to clarify it usage.

1 amb 160 /***************************************
2     Routing output generator.
3    
4     Part of the Routino routing software.
5     ******************/ /******************
6 amb 1501 This file Copyright 2008-2014 Andrew M. Bishop
7 amb 160
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 amb 165 #include <stdlib.h>
24 amb 160 #include <string.h>
25 amb 164 #include <ctype.h>
26 amb 160 #include <stdio.h>
27 amb 316 #include <math.h>
28 amb 330 #include <errno.h>
29 amb 164 #include <unistd.h>
30 amb 160
31     #include "types.h"
32     #include "nodes.h"
33     #include "segments.h"
34     #include "ways.h"
35 amb 449
36     #include "functions.h"
37 amb 532 #include "fakes.h"
38 amb 449 #include "translations.h"
39 amb 160 #include "results.h"
40 amb 378 #include "xmlparse.h"
41 amb 160
42 amb 955
43 amb 1564 #define DEBUG 0
44    
45 amb 927 /* Constants */
46 amb 160
47 amb 927 #define IMP_IGNORE -1 /*+ Ignore this point. +*/
48     #define IMP_UNIMPORTANT 0 /*+ An unimportant, intermediate, node. +*/
49     #define IMP_RB_NOT_EXIT 1 /*+ A roundabout exit that is not taken. +*/
50     #define IMP_JUNCT_CONT 2 /*+ An un-interesting junction where the route continues without comment. +*/
51     #define IMP_CHANGE 3 /*+ The highway changes type but nothing else happens. +*/
52     #define IMP_JUNCT_IMPORT 4 /*+ An interesting junction to be described. +*/
53     #define IMP_RB_ENTRY 5 /*+ The entrance to a roundabout. +*/
54     #define IMP_RB_EXIT 6 /*+ The exit from a roundabout. +*/
55 amb 929 #define IMP_MINI_RB 7 /*+ The location of a mini-roundabout. +*/
56     #define IMP_UTURN 8 /*+ The location of a U-turn. +*/
57     #define IMP_WAYPOINT 9 /*+ A waypoint. +*/
58 amb 927
59 amb 955
60 amb 360 /* Global variables */
61    
62 amb 160 /*+ The option to calculate the quickest route insted of the shortest. +*/
63     extern int option_quickest;
64    
65 amb 324 /*+ The options to select the format of the output. +*/
66 amb 1465 extern int option_html,option_gpx_track,option_gpx_route,option_text,option_text_all,option_stdout;
67 amb 324
68 amb 955
69 amb 360 /* Local variables */
70    
71 amb 171 /*+ Heuristics for determining if a junction is important. +*/
72 amb 1677 static const char junction_other_way[Highway_Count][Highway_Count]=
73 amb 492 { /* M, T, P, S, T, U, R, S, T, C, P, S, F = Way type of route not taken */
74     { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Motorway */
75     { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Trunk */
76     { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Primary */
77     { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Secondary */
78     { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Tertiary */
79     { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 }, /* Unclassified */
80     { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 }, /* Residential */
81     { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 }, /* Service */
82     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1 }, /* Track */
83     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1 }, /* Cycleway */
84     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Path */
85     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Steps */
86     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Ferry */
87 amb 171 };
88 amb 165
89 amb 360
90 amb 160 /*++++++++++++++++++++++++++++++++++++++
91 amb 379 Print the optimum route between two nodes.
92    
93 amb 1501 Results **results The set of results to print (consecutive in array even if not consecutive waypoints).
94 amb 379
95     int nresults The number of results in the list.
96    
97 amb 680 Nodes *nodes The set of nodes to use.
98 amb 379
99     Segments *segments The set of segments to use.
100    
101 amb 680 Ways *ways The set of ways to use.
102 amb 379
103     Profile *profile The profile containing the transport type, speeds and allowed highways.
104 amb 164 ++++++++++++++++++++++++++++++++++++++*/
105 amb 160
106 amb 379 void PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile)
107 amb 164 {
108 amb 379 FILE *htmlfile=NULL,*gpxtrackfile=NULL,*gpxroutefile=NULL,*textfile=NULL,*textallfile=NULL;
109    
110 amb 922 char *prev_bearing=NULL,*prev_wayname=NULL;
111 amb 1539 index_t prev_node=NO_NODE;
112 amb 379 distance_t cum_distance=0;
113     duration_t cum_duration=0;
114 amb 922
115 amb 1501 int point=0;
116 amb 683 int segment_count=0,route_count=0;
117     int point_count=0;
118 amb 926 int roundabout=0;
119 amb 379
120 amb 164 /* Open the files */
121 amb 160
122 amb 1465 if(option_stdout)
123 amb 160 {
124 amb 324 if(option_html)
125 amb 1465 htmlfile =stdout;
126 amb 324 if(option_gpx_track)
127 amb 1465 gpxtrackfile=stdout;
128 amb 324 if(option_gpx_route)
129 amb 1465 gpxroutefile=stdout;
130 amb 324 if(option_text)
131 amb 1465 textfile =stdout;
132 amb 324 if(option_text_all)
133 amb 1465 textallfile =stdout;
134 amb 160 }
135     else
136     {
137 amb 1465 if(option_quickest==0)
138     {
139     /* Print the result for the shortest route */
140 amb 160
141 amb 1465 if(option_html)
142     htmlfile =fopen("shortest.html","w");
143     if(option_gpx_track)
144     gpxtrackfile=fopen("shortest-track.gpx","w");
145     if(option_gpx_route)
146     gpxroutefile=fopen("shortest-route.gpx","w");
147     if(option_text)
148     textfile =fopen("shortest.txt","w");
149     if(option_text_all)
150     textallfile =fopen("shortest-all.txt","w");
151 amb 177
152 amb 1465 if(option_html && !htmlfile)
153     fprintf(stderr,"Warning: Cannot open file 'shortest.html' for writing [%s].\n",strerror(errno));
154     if(option_gpx_track && !gpxtrackfile)
155     fprintf(stderr,"Warning: Cannot open file 'shortest-track.gpx' for writing [%s].\n",strerror(errno));
156     if(option_gpx_route && !gpxroutefile)
157     fprintf(stderr,"Warning: Cannot open file 'shortest-route.gpx' for writing [%s].\n",strerror(errno));
158     if(option_text && !textfile)
159     fprintf(stderr,"Warning: Cannot open file 'shortest.txt' for writing [%s].\n",strerror(errno));
160     if(option_text_all && !textallfile)
161     fprintf(stderr,"Warning: Cannot open file 'shortest-all.txt' for writing [%s].\n",strerror(errno));
162     }
163     else
164     {
165     /* Print the result for the quickest route */
166    
167     if(option_html)
168     htmlfile =fopen("quickest.html","w");
169     if(option_gpx_track)
170     gpxtrackfile=fopen("quickest-track.gpx","w");
171     if(option_gpx_route)
172     gpxroutefile=fopen("quickest-route.gpx","w");
173     if(option_text)
174     textfile =fopen("quickest.txt","w");
175     if(option_text_all)
176     textallfile =fopen("quickest-all.txt","w");
177    
178     if(option_html && !htmlfile)
179     fprintf(stderr,"Warning: Cannot open file 'quickest.html' for writing [%s].\n",strerror(errno));
180     if(option_gpx_track && !gpxtrackfile)
181     fprintf(stderr,"Warning: Cannot open file 'quickest-track.gpx' for writing [%s].\n",strerror(errno));
182     if(option_gpx_route && !gpxroutefile)
183     fprintf(stderr,"Warning: Cannot open file 'quickest-route.gpx' for writing [%s].\n",strerror(errno));
184     if(option_text && !textfile)
185     fprintf(stderr,"Warning: Cannot open file 'quickest.txt' for writing [%s].\n",strerror(errno));
186     if(option_text_all && !textallfile)
187     fprintf(stderr,"Warning: Cannot open file 'quickest-all.txt' for writing [%s].\n",strerror(errno));
188     }
189 amb 160 }
190    
191 amb 164 /* Print the head of the files */
192 amb 160
193 amb 323 if(htmlfile)
194     {
195 amb 1505 fprintf(htmlfile,"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n");
196     fprintf(htmlfile,"<html>\n");
197 amb 893 if(translate_xml_copyright_creator[0] && translate_xml_copyright_creator[1])
198     fprintf(htmlfile,"<!-- %s : %s -->\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
199     if(translate_xml_copyright_source[0] && translate_xml_copyright_source[1])
200     fprintf(htmlfile,"<!-- %s : %s -->\n",translate_xml_copyright_source[0],translate_xml_copyright_source[1]);
201     if(translate_xml_copyright_license[0] && translate_xml_copyright_license[1])
202     fprintf(htmlfile,"<!-- %s : %s -->\n",translate_xml_copyright_license[0],translate_xml_copyright_license[1]);
203 amb 1505 fprintf(htmlfile,"<head>\n");
204     fprintf(htmlfile,"<title>");
205 amb 893 fprintf(htmlfile,translate_html_title,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
206 amb 1505 fprintf(htmlfile,"</title>\n");
207     fprintf(htmlfile,"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
208     fprintf(htmlfile,"<style type=\"text/css\">\n");
209 amb 323 fprintf(htmlfile,"<!--\n");
210 amb 376 fprintf(htmlfile," table {table-layout: fixed; border: none; border-collapse: collapse;}\n");
211     fprintf(htmlfile," table.c {color: grey; font-size: x-small;} /* copyright */\n");
212     fprintf(htmlfile," tr {border: 0px;}\n");
213     fprintf(htmlfile," tr.c {display: none;} /* coords */\n");
214     fprintf(htmlfile," tr.n {} /* node */\n");
215     fprintf(htmlfile," tr.s {} /* segment */\n");
216     fprintf(htmlfile," tr.t {font-weight: bold;} /* total */\n");
217     fprintf(htmlfile," td.l {font-weight: bold;}\n");
218     fprintf(htmlfile," td.r {}\n");
219     fprintf(htmlfile," span.w {font-weight: bold;} /* waypoint */\n");
220     fprintf(htmlfile," span.h {text-decoration: underline;} /* highway */\n");
221     fprintf(htmlfile," span.d {} /* segment distance */\n");
222     fprintf(htmlfile," span.j {font-style: italic;} /* total journey distance */\n");
223     fprintf(htmlfile," span.t {font-variant: small-caps;} /* turn */\n");
224     fprintf(htmlfile," span.b {font-variant: small-caps;} /* bearing */\n");
225 amb 323 fprintf(htmlfile,"-->\n");
226 amb 1505 fprintf(htmlfile,"</style>\n");
227     fprintf(htmlfile,"</head>\n");
228     fprintf(htmlfile,"<body>\n");
229     fprintf(htmlfile,"<h1>");
230 amb 893 fprintf(htmlfile,translate_html_title,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
231 amb 1505 fprintf(htmlfile,"</h1>\n");
232 amb 323 fprintf(htmlfile,"<table>\n");
233     }
234    
235 amb 177 if(gpxtrackfile)
236     {
237     fprintf(gpxtrackfile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
238     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");
239 amb 160
240 amb 177 fprintf(gpxtrackfile,"<metadata>\n");
241 amb 893 fprintf(gpxtrackfile,"<desc>%s : %s</desc>\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
242     if(translate_xml_copyright_source[1])
243 amb 376 {
244 amb 893 fprintf(gpxtrackfile,"<copyright author=\"%s\">\n",translate_xml_copyright_source[1]);
245 amb 376
246 amb 893 if(translate_xml_copyright_license[1])
247     fprintf(gpxtrackfile,"<license>%s</license>\n",translate_xml_copyright_license[1]);
248 amb 376
249 amb 177 fprintf(gpxtrackfile,"</copyright>\n");
250 amb 376 }
251 amb 177 fprintf(gpxtrackfile,"</metadata>\n");
252 amb 160
253 amb 177 fprintf(gpxtrackfile,"<trk>\n");
254 amb 376 fprintf(gpxtrackfile,"<name>");
255 amb 893 fprintf(gpxtrackfile,translate_gpx_name,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
256 amb 376 fprintf(gpxtrackfile,"</name>\n");
257     fprintf(gpxtrackfile,"<desc>");
258 amb 893 fprintf(gpxtrackfile,translate_gpx_desc,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
259 amb 376 fprintf(gpxtrackfile,"</desc>\n");
260 amb 177 }
261 amb 160
262 amb 177 if(gpxroutefile)
263     {
264     fprintf(gpxroutefile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
265     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");
266 amb 160
267 amb 177 fprintf(gpxroutefile,"<metadata>\n");
268 amb 893 fprintf(gpxroutefile,"<desc>%s : %s</desc>\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
269     if(translate_xml_copyright_source[1])
270 amb 376 {
271 amb 893 fprintf(gpxroutefile,"<copyright author=\"%s\">\n",translate_xml_copyright_source[1]);
272 amb 376
273 amb 893 if(translate_xml_copyright_license[1])
274     fprintf(gpxroutefile,"<license>%s</license>\n",translate_xml_copyright_license[1]);
275 amb 376
276 amb 177 fprintf(gpxroutefile,"</copyright>\n");
277 amb 376 }
278 amb 177 fprintf(gpxroutefile,"</metadata>\n");
279 amb 160
280 amb 177 fprintf(gpxroutefile,"<rte>\n");
281 amb 360 fprintf(gpxroutefile,"<name>");
282 amb 893 fprintf(gpxroutefile,translate_gpx_name,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
283 amb 360 fprintf(gpxroutefile,"</name>\n");
284 amb 376 fprintf(gpxroutefile,"<desc>");
285 amb 893 fprintf(gpxroutefile,translate_gpx_desc,option_quickest?translate_xml_route_quickest:translate_xml_route_shortest);
286 amb 376 fprintf(gpxroutefile,"</desc>\n");
287 amb 177 }
288 amb 160
289 amb 177 if(textfile)
290     {
291 amb 893 if(translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1])
292     fprintf(textfile,"# %s : %s\n",translate_raw_copyright_creator[0],translate_raw_copyright_creator[1]);
293     if(translate_raw_copyright_source[0] && translate_raw_copyright_source[1])
294     fprintf(textfile,"# %s : %s\n",translate_raw_copyright_source[0],translate_raw_copyright_source[1]);
295     if(translate_raw_copyright_license[0] && translate_raw_copyright_license[1])
296     fprintf(textfile,"# %s : %s\n",translate_raw_copyright_license[0],translate_raw_copyright_license[1]);
297     if((translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1]) ||
298     (translate_raw_copyright_source[0] && translate_raw_copyright_source[1]) ||
299     (translate_raw_copyright_license[0] && translate_raw_copyright_license[1]))
300 amb 177 fprintf(textfile,"#\n");
301 amb 376
302 amb 316 fprintf(textfile,"#Latitude\tLongitude\tSection \tSection \tTotal \tTotal \tPoint\tTurn\tBearing\tHighway\n");
303     fprintf(textfile,"# \t \tDistance\tDuration\tDistance\tDuration\tType \t \t \t \n");
304     /* "%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" */
305 amb 177 }
306 amb 160
307 amb 177 if(textallfile)
308     {
309 amb 893 if(translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1])
310     fprintf(textallfile,"# %s : %s\n",translate_raw_copyright_creator[0],translate_raw_copyright_creator[1]);
311     if(translate_raw_copyright_source[0] && translate_raw_copyright_source[1])
312     fprintf(textallfile,"# %s : %s\n",translate_raw_copyright_source[0],translate_raw_copyright_source[1]);
313     if(translate_raw_copyright_license[0] && translate_raw_copyright_license[1])
314     fprintf(textallfile,"# %s : %s\n",translate_raw_copyright_license[0],translate_raw_copyright_license[1]);
315     if((translate_raw_copyright_creator[0] && translate_raw_copyright_creator[1]) ||
316     (translate_raw_copyright_source[0] && translate_raw_copyright_source[1]) ||
317     (translate_raw_copyright_license[0] && translate_raw_copyright_license[1]))
318 amb 177 fprintf(textallfile,"#\n");
319 amb 376
320 amb 316 fprintf(textallfile,"#Latitude\tLongitude\t Node\tType\tSegment\tSegment\tTotal\tTotal \tSpeed\tBearing\tHighway\n");
321     fprintf(textallfile,"# \t \t \t \tDist \tDurat'n\tDist \tDurat'n\t \t \t \n");
322     /* "%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" */
323 amb 177 }
324 amb 160
325 amb 922 /* Loop through all the sections of the route and print them */
326 amb 164
327 amb 1501 do
328 amb 316 {
329 amb 1564 int first=1;
330 amb 922 int next_point=point;
331 amb 316 distance_t junc_distance=0;
332     duration_t junc_duration=0;
333     Result *result;
334 amb 160
335 amb 1564 #if DEBUG
336     printf("Route section %d - waypoint %d to waypoint %d\n",point,results[point]->start_waypoint,results[point]->finish_waypoint);
337     printf(" start_node=%"Pindex_t" prev_segment=%"Pindex_t"\n",results[point]->start_node,results[point]->prev_segment);
338     printf(" finish_node=%"Pindex_t" last_segment=%"Pindex_t"\n",results[point]->finish_node,results[point]->last_segment);
339    
340     Result *r=FindResult(results[point],results[point]->start_node,results[point]->prev_segment);
341    
342     while(r)
343     {
344     printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
345    
346     r=r->next;
347     }
348     #endif
349    
350 amb 922 result=FindResult(results[point],results[point]->start_node,results[point]->prev_segment);
351    
352     /* Print the start of the segment */
353    
354 amb 324 if(gpxtrackfile)
355     fprintf(gpxtrackfile,"<trkseg>\n");
356 amb 303
357 amb 922 /* Loop through all the points within a section of the route and print them */
358 amb 165
359 amb 316 do
360 amb 160 {
361 amb 316 double latitude,longitude;
362 amb 1078 Node *resultnodep=NULL;
363 amb 922 index_t realsegment=NO_SEGMENT,next_realsegment=NO_SEGMENT;
364 amb 1078 Segment *resultsegmentp=NULL,*next_resultsegmentp=NULL;
365     Way *resultwayp=NULL,*next_resultwayp=NULL;
366 amb 922 Result *next_result;
367 amb 927 int important=IMP_UNIMPORTANT;
368 amb 160
369 amb 922 distance_t seg_distance=0;
370     duration_t seg_duration=0;
371     speed_t seg_speed=0;
372     char *waynameraw=NULL,*wayname=NULL,*next_waynameraw=NULL,*next_wayname=NULL;
373     int bearing_int=0,turn_int=0,next_bearing_int=0;
374     char *turn=NULL,*next_bearing=NULL;
375    
376     /* Calculate the information about this point */
377    
378     if(IsFakeNode(result->node))
379     GetFakeLatLong(result->node,&latitude,&longitude);
380 amb 316 else
381 amb 1447 {
382 amb 1078 resultnodep=LookupNode(nodes,result->node,6);
383 amb 171
384 amb 1447 GetLatLong(nodes,result->node,resultnodep,&latitude,&longitude);
385     }
386    
387 amb 922 /* Calculate the next result */
388 amb 171
389 amb 922 next_result=result->next;
390    
391     if(!next_result)
392 amb 1501 {
393     next_point++;
394 amb 171
395 amb 1501 if(next_point<nresults)
396     {
397     next_result=FindResult(results[next_point],results[next_point]->start_node,results[next_point]->prev_segment);
398     next_result=next_result->next;
399     }
400     }
401    
402 amb 922 /* Calculate the information about this segment */
403 amb 459
404 amb 1580 if(!first) /* not first point of a section of the route */
405 amb 169 {
406 amb 1580 if(IsFakeSegment(result->segment))
407     {
408     resultsegmentp=LookupFakeSegment(result->segment);
409     realsegment=IndexRealSegment(result->segment);
410     }
411     else
412     {
413     resultsegmentp=LookupSegment(segments,result->segment,2);
414     realsegment=result->segment;
415     }
416 amb 922
417 amb 1580 resultwayp=LookupWay(ways,resultsegmentp->way,1);
418 amb 316
419 amb 1168 seg_distance+=DISTANCE(resultsegmentp->distance);
420 amb 1078 seg_duration+=Duration(resultsegmentp,resultwayp,profile);
421 amb 922
422     /* Calculate the cumulative distance/duration */
423    
424 amb 316 junc_distance+=seg_distance;
425     junc_duration+=seg_duration;
426     cum_distance+=seg_distance;
427     cum_duration+=seg_duration;
428 amb 922 }
429 amb 316
430 amb 922 /* Calculate the information about the next segment */
431 amb 316
432 amb 922 if(next_result)
433     {
434     if(IsFakeSegment(next_result->segment))
435     {
436 amb 1078 next_resultsegmentp=LookupFakeSegment(next_result->segment);
437 amb 922 next_realsegment=IndexRealSegment(next_result->segment);
438     }
439 amb 316 else
440 amb 303 {
441 amb 1078 next_resultsegmentp=LookupSegment(segments,next_result->segment,1);
442 amb 922 next_realsegment=next_result->segment;
443     }
444     }
445 amb 160
446 amb 926 /* Decide if this is a roundabout */
447    
448     if(next_result)
449     {
450 amb 1078 next_resultwayp=LookupWay(ways,next_resultsegmentp->way,2);
451 amb 926
452 amb 1174 if(next_resultwayp->type&Highway_Roundabout)
453 amb 926 {
454     if(roundabout==0)
455     {
456     roundabout++;
457 amb 927 important=IMP_RB_ENTRY;
458 amb 926 }
459     else
460     {
461 amb 1539 Segment *segmentp;
462 amb 926
463 amb 1539 if(resultnodep)
464     segmentp=FirstSegment(segments,resultnodep,3);
465     else
466     segmentp=FirstFakeSegment(result->node);
467    
468 amb 926 do
469     {
470 amb 1078 index_t othernode=OtherNode(segmentp,result->node);
471 amb 1539 index_t thissegment;
472 amb 926
473 amb 1539 if(IsFakeNode(result->node))
474     thissegment=IndexFakeSegment(segmentp);
475     else
476     thissegment=IndexSegment(segments,segmentp);
477    
478 amb 1543 if(othernode!=prev_node && othernode!=next_result->node &&
479     thissegment!=realsegment && IsNormalSegment(segmentp))
480     {
481     int canexit=1;
482    
483     if(profile->oneway && IsOnewayTo(segmentp,result->node))
484 amb 926 {
485 amb 1543 if(profile->allow!=Transports_Bicycle)
486     canexit=0;
487     else
488     {
489     Way *wayp=LookupWay(ways,segmentp->way,3);
490    
491 amb 1559 if(!(wayp->type&Highway_CycleBothWays))
492 amb 1543 canexit=0;
493     }
494     }
495    
496     if(canexit)
497     {
498 amb 1078 Way *wayp=LookupWay(ways,segmentp->way,3);
499 amb 926
500 amb 1174 if(!(wayp->type&Highway_Roundabout))
501 amb 1543 {
502     roundabout++;
503     important=IMP_RB_NOT_EXIT;
504     }
505 amb 926 }
506 amb 1543 }
507 amb 926
508 amb 1539 if(resultnodep)
509     segmentp=NextSegment(segments,segmentp,result->node);
510     else
511     segmentp=NextFakeSegment(segmentp,result->node);
512 amb 926 }
513 amb 1078 while(segmentp);
514 amb 926 }
515     }
516     else
517     if(roundabout)
518     {
519     roundabout++;
520 amb 927 important=IMP_RB_EXIT;
521 amb 926 }
522     }
523    
524 amb 922 /* Decide if this is an important junction */
525 amb 303
526 amb 1539 if(point_count==0) /* first point overall = Waypoint */
527 amb 927 important=IMP_WAYPOINT;
528 amb 1564 else if(result->next==NULL) /* Waypoint */
529 amb 927 important=IMP_WAYPOINT;
530 amb 1564 else if(first) /* first point of a section of the route */
531 amb 927 important=IMP_IGNORE;
532 amb 1539 else if(roundabout) /* roundabout */
533     ;
534 amb 922 else if(realsegment==next_realsegment) /* U-turn */
535 amb 927 important=IMP_UTURN;
536 amb 1078 else if(resultnodep && (resultnodep->flags&NODE_MINIRNDBT))
537 amb 929 important=IMP_MINI_RB; /* mini-roundabout */
538 amb 922 else
539     {
540 amb 1078 Segment *segmentp=FirstSegment(segments,resultnodep,3);
541 amb 316
542 amb 922 do
543     {
544 amb 1078 index_t seg=IndexSegment(segments,segmentp);
545 amb 316
546 amb 1543 if(seg!=realsegment && IsNormalSegment(segmentp))
547     {
548     int cango=1;
549    
550     if(profile->oneway && IsOnewayTo(segmentp,result->node))
551 amb 922 {
552 amb 1543 if(profile->allow!=Transports_Bicycle)
553     cango=0;
554     else
555     {
556     Way *wayp=LookupWay(ways,segmentp->way,3);
557    
558 amb 1559 if(!(wayp->type&Highway_CycleBothWays))
559 amb 1543 cango=0;
560     }
561     }
562    
563     if(cango)
564     {
565 amb 1078 Way *wayp=LookupWay(ways,segmentp->way,3);
566 amb 922
567 amb 1074 if(seg==next_realsegment) /* the next segment that we follow */
568 amb 922 {
569 amb 1078 if(HIGHWAY(wayp->type)!=HIGHWAY(resultwayp->type))
570 amb 927 if(important<IMP_CHANGE)
571     important=IMP_CHANGE;
572 amb 303 }
573 amb 922 else /* a segment that we don't follow */
574     {
575 amb 1078 if(junction_other_way[HIGHWAY(resultwayp->type)-1][HIGHWAY(wayp->type)-1])
576 amb 927 if(important<IMP_JUNCT_IMPORT)
577     important=IMP_JUNCT_IMPORT;
578 amb 160
579 amb 927 if(important<IMP_JUNCT_CONT)
580     important=IMP_JUNCT_CONT;
581 amb 922 }
582     }
583 amb 1543 }
584 amb 922
585 amb 1078 segmentp=NextSegment(segments,segmentp,result->node);
586 amb 303 }
587 amb 1078 while(segmentp);
588 amb 922 }
589 amb 169
590 amb 922 /* Calculate the strings to be used */
591 amb 169
592 amb 1565 if(!first && textallfile)
593 amb 922 {
594 amb 1078 waynameraw=WayName(ways,resultwayp);
595 amb 922 if(!*waynameraw)
596 amb 1078 waynameraw=translate_raw_highway[HIGHWAY(resultwayp->type)];
597 amb 922
598 amb 1078 bearing_int=(int)BearingAngle(nodes,resultsegmentp,result->node);
599 amb 922
600 amb 1078 seg_speed=profile->speed[HIGHWAY(resultwayp->type)];
601 amb 922 }
602    
603 amb 927 if(next_result && important>IMP_JUNCT_CONT)
604 amb 922 {
605 amb 1565 if(!first && (htmlfile || textfile))
606 amb 177 {
607 amb 1565 if(DISTANCE(resultsegmentp->distance)==0 || DISTANCE(next_resultsegmentp->distance)==0)
608     turn_int=0;
609     else
610     turn_int=(int)TurnAngle(nodes,resultsegmentp,next_resultsegmentp,result->node);
611    
612 amb 922 turn=translate_xml_turn[((202+turn_int)/45)%8];
613     }
614 amb 303
615 amb 922 if(gpxroutefile || htmlfile)
616     {
617 amb 1078 next_waynameraw=WayName(ways,next_resultwayp);
618 amb 922 if(!*next_waynameraw)
619 amb 1078 next_waynameraw=translate_raw_highway[HIGHWAY(next_resultwayp->type)];
620 amb 378
621 amb 922 next_wayname=ParseXML_Encode_Safe_XML(next_waynameraw);
622     }
623 amb 411
624 amb 922 if(htmlfile || gpxroutefile || textfile)
625     {
626 amb 1580 if(!first && DISTANCE(next_resultsegmentp->distance)==0)
627 amb 1565 next_bearing_int=(int)BearingAngle(nodes,resultsegmentp,result->node);
628     else
629     next_bearing_int=(int)BearingAngle(nodes,next_resultsegmentp,next_result->node);
630    
631 amb 922 next_bearing=translate_xml_heading[(4+(22+next_bearing_int)/45)%8];
632     }
633     }
634 amb 378
635 amb 922 /* Print out the important points (junctions / waypoints) */
636    
637 amb 927 if(important>IMP_JUNCT_CONT)
638 amb 922 {
639     if(htmlfile)
640     {
641     char *type;
642    
643 amb 927 if(important==IMP_WAYPOINT)
644 amb 922 type=translate_html_waypoint;
645 amb 929 else if(important==IMP_MINI_RB)
646     type=translate_html_roundabout;
647 amb 922 else
648     type=translate_html_junction;
649    
650     if(point_count>0) /* not the first point */
651     {
652     /* <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>] */
653 amb 378 fprintf(htmlfile,"<tr class='s'><td class='l'>%s:<td class='r'>",translate_html_segment[0]);
654     fprintf(htmlfile,translate_html_segment[1],
655 amb 926 (roundabout>1?translate_html_roundabout:prev_wayname),
656 amb 922 distance_to_km(junc_distance),duration_to_minutes(junc_duration));
657 amb 379 fprintf(htmlfile," [<span class='j'>");
658 amb 378 fprintf(htmlfile,translate_html_total[1],
659 amb 922 distance_to_km(cum_distance),duration_to_minutes(cum_duration));
660 amb 378 fprintf(htmlfile,"</span>]\n");
661 amb 922 }
662 amb 378
663 amb 922 /* <tr class='c'><td class='l'>*N*:<td class='r'>*latitude* *longitude* */
664     fprintf(htmlfile,"<tr class='c'><td class='l'>%d:<td class='r'>%.6f %.6f\n",
665     point_count+1,
666     radians_to_degrees(latitude),radians_to_degrees(longitude));
667 amb 378
668 amb 922 if(point_count==0) /* first point */
669     {
670     /* <tr class='n'><td class='l'>Start:<td class='r'>At <span class='w'>Waypoint</span>, head <span class='b'>*heading*</span> */
671     fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_start[0]);
672     fprintf(htmlfile,translate_html_start[1],
673     translate_html_waypoint,
674     next_bearing);
675     fprintf(htmlfile,"\n");
676     }
677     else if(next_result) /* middle point */
678     {
679 amb 1539 if(roundabout>1 && important!=IMP_WAYPOINT)
680 amb 926 {
681     /* <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> */
682     fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_rbnode[0]);
683     fprintf(htmlfile,translate_html_rbnode[1],
684     translate_html_roundabout,
685     translate_xml_ordinal[roundabout-2],
686     next_bearing);
687     fprintf(htmlfile,"\n");
688     }
689     else
690     {
691     /* <tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>*direction*</span> heading <span class='b'>*heading*</span> */
692     fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_node[0]);
693     fprintf(htmlfile,translate_html_node[1],
694     type,
695     turn,
696     next_bearing);
697     fprintf(htmlfile,"\n");
698     }
699 amb 922 }
700     else /* end point */
701     {
702     /* <tr class='n'><td class='l'>Stop:<td class='r'>At <span class='w'>Waypoint</span> */
703     fprintf(htmlfile,"<tr class='n'><td class='l'>%s:<td class='r'>",translate_html_stop[0]);
704     fprintf(htmlfile,translate_html_stop[1],
705     translate_html_waypoint);
706     fprintf(htmlfile,"\n");
707 amb 378
708 amb 922 /* <tr class='t'><td class='l'>Total:<td class='r'><span class='j'>*distance* km, *time* minutes</span> */
709     fprintf(htmlfile,"<tr class='t'><td class='l'>%s:<td class='r'><span class='j'>",translate_html_total[0]);
710     fprintf(htmlfile,translate_html_total[1],
711     distance_to_km(cum_distance),duration_to_minutes(cum_duration));
712     fprintf(htmlfile,"</span>\n");
713 amb 378 }
714 amb 922 }
715 amb 378
716 amb 922 if(gpxroutefile)
717     {
718     if(point_count>0) /* not first point */
719 amb 332 {
720 amb 378 fprintf(gpxroutefile,"<desc>");
721 amb 360 fprintf(gpxroutefile,translate_gpx_step,
722 amb 922 prev_bearing,
723     prev_wayname,
724 amb 378 distance_to_km(junc_distance),duration_to_minutes(junc_duration));
725     fprintf(gpxroutefile,"</desc></rtept>\n");
726 amb 922 }
727 amb 316
728 amb 922 if(point_count==0) /* first point */
729     {
730     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s</name>\n",
731     radians_to_degrees(latitude),radians_to_degrees(longitude),
732     translate_gpx_start);
733     }
734     else if(!next_result) /* end point */
735     {
736     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s</name>\n",
737     radians_to_degrees(latitude),radians_to_degrees(longitude),
738     translate_gpx_finish);
739     fprintf(gpxroutefile,"<desc>");
740     fprintf(gpxroutefile,translate_gpx_final,
741     distance_to_km(cum_distance),duration_to_minutes(cum_duration));
742     fprintf(gpxroutefile,"</desc></rtept>\n");
743     }
744     else /* middle point */
745     {
746 amb 927 if(important==IMP_WAYPOINT)
747 amb 360 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%d</name>\n",
748 amb 378 radians_to_degrees(latitude),radians_to_degrees(longitude),
749     translate_gpx_inter,++segment_count);
750 amb 332 else
751 amb 360 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%03d</name>\n",
752 amb 378 radians_to_degrees(latitude),radians_to_degrees(longitude),
753     translate_gpx_trip,++route_count);
754 amb 332 }
755 amb 922 }
756 amb 316
757 amb 922 if(textfile)
758     {
759     char *type;
760 amb 316
761 amb 927 if(important==IMP_WAYPOINT)
762 amb 922 type="Waypt";
763     else
764     type="Junct";
765 amb 316
766 amb 922 if(point_count==0) /* first point */
767     {
768     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",
769     radians_to_degrees(latitude),radians_to_degrees(longitude),
770     0.0,0.0,0.0,0.0,
771     type,
772     ((22+next_bearing_int)/45+4)%8-4,
773     next_waynameraw);
774     }
775     else if(!next_result) /* end point */
776     {
777     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",
778     radians_to_degrees(latitude),radians_to_degrees(longitude),
779     distance_to_km(junc_distance),duration_to_minutes(junc_duration),
780     distance_to_km(cum_distance),duration_to_minutes(cum_duration),
781     type);
782     }
783     else /* middle point */
784     {
785     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",
786     radians_to_degrees(latitude),radians_to_degrees(longitude),
787     distance_to_km(junc_distance),duration_to_minutes(junc_duration),
788     distance_to_km(cum_distance),duration_to_minutes(cum_duration),
789     type,
790     (22+turn_int)/45,
791     ((22+next_bearing_int)/45+4)%8-4,
792     next_waynameraw);
793     }
794     }
795 amb 322
796 amb 922 junc_distance=0;
797     junc_duration=0;
798 amb 322
799 amb 922 if(htmlfile || gpxroutefile)
800     {
801     if(prev_wayname)
802     free(prev_wayname);
803 amb 322
804 amb 922 if(next_wayname)
805     prev_wayname=strcpy((char*)malloc(strlen(next_wayname)+1),next_wayname);
806     else
807     prev_wayname=NULL;
808 amb 316
809 amb 922 if(next_wayname && next_wayname!=next_waynameraw)
810     free(next_wayname);
811 amb 165 }
812 amb 160
813 amb 922 if(gpxroutefile)
814     prev_bearing=next_bearing;
815 amb 926
816     if(roundabout>1)
817     roundabout=0;
818 amb 922 }
819 amb 303
820 amb 922 /* Print out all of the results */
821    
822     if(gpxtrackfile)
823     fprintf(gpxtrackfile,"<trkpt lat=\"%.6f\" lon=\"%.6f\"/>\n",
824     radians_to_degrees(latitude),radians_to_degrees(longitude));
825    
826 amb 927 if(important>IMP_IGNORE)
827 amb 922 {
828 amb 316 if(textallfile)
829     {
830     char *type;
831    
832 amb 927 if(important==IMP_WAYPOINT)
833 amb 316 type="Waypt";
834 amb 927 else if(important==IMP_UTURN)
835 amb 926 type="U-turn";
836 amb 929 else if(important==IMP_MINI_RB)
837     type="Mini-RB";
838 amb 927 else if(important==IMP_CHANGE)
839 amb 316 type="Change";
840 amb 1075 else if(important==IMP_JUNCT_CONT || important==IMP_RB_NOT_EXIT)
841     type="Junct-";
842 amb 927 else if(important==IMP_UNIMPORTANT)
843     type="Inter";
844     else
845 amb 316 type="Junct";
846    
847 amb 922 if(point_count==0) /* first point */
848 amb 474 {
849 amb 922 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",
850     radians_to_degrees(latitude),radians_to_degrees(longitude),
851     IsFakeNode(result->node)?(NODE_FAKE-result->node):result->node,
852 amb 1078 (resultnodep && IsSuperNode(resultnodep))?'*':' ',type,
853 amb 922 0.0,0.0,0.0,0.0);
854 amb 474 }
855 amb 927 else /* not the first point */
856 amb 378 {
857 amb 922 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",
858     radians_to_degrees(latitude),radians_to_degrees(longitude),
859     IsFakeNode(result->node)?(NODE_FAKE-result->node):result->node,
860 amb 1078 (resultnodep && IsSuperNode(resultnodep))?'*':' ',type,
861 amb 922 distance_to_km(seg_distance),duration_to_minutes(seg_duration),
862     distance_to_km(cum_distance),duration_to_minutes(cum_duration),
863     speed_to_kph(seg_speed),
864     bearing_int,
865     waynameraw);
866 amb 378 }
867 amb 316 }
868 amb 160 }
869 amb 378
870 amb 922 if(wayname && wayname!=waynameraw)
871     free(wayname);
872 amb 160
873 amb 922 result=next_result;
874 amb 323
875 amb 927 if(important>IMP_JUNCT_CONT)
876 amb 922 point_count++;
877 amb 1564
878     first=0;
879 amb 922 }
880     while(point==next_point);
881 amb 171
882 amb 922 /* Print the end of the segment */
883 amb 171
884 amb 316 if(gpxtrackfile)
885     fprintf(gpxtrackfile,"</trkseg>\n");
886 amb 160
887 amb 922 point=next_point;
888 amb 1539
889     if(result)
890     prev_node=result->node;
891     else
892     prev_node=NO_NODE;
893 amb 160 }
894 amb 1501 while(point<nresults);
895 amb 160
896 amb 164 /* Print the tail of the files */
897    
898 amb 323 if(htmlfile)
899     {
900     fprintf(htmlfile,"</table>\n");
901 amb 376
902 amb 893 if((translate_xml_copyright_creator[0] && translate_xml_copyright_creator[1]) ||
903     (translate_xml_copyright_source[0] && translate_xml_copyright_source[1]) ||
904     (translate_xml_copyright_license[0] && translate_xml_copyright_license[1]))
905 amb 376 {
906     fprintf(htmlfile,"<p>\n");
907     fprintf(htmlfile,"<table class='c'>\n");
908 amb 893 if(translate_xml_copyright_creator[0] && translate_xml_copyright_creator[1])
909     fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translate_xml_copyright_creator[0],translate_xml_copyright_creator[1]);
910     if(translate_xml_copyright_source[0] && translate_xml_copyright_source[1])
911     fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translate_xml_copyright_source[0],translate_xml_copyright_source[1]);
912     if(translate_xml_copyright_license[0] && translate_xml_copyright_license[1])
913     fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translate_xml_copyright_license[0],translate_xml_copyright_license[1]);
914 amb 376 fprintf(htmlfile,"</table>\n");
915     }
916    
917 amb 1505 fprintf(htmlfile,"</body>\n");
918     fprintf(htmlfile,"</html>\n");
919 amb 323 }
920    
921 amb 177 if(gpxtrackfile)
922     {
923     fprintf(gpxtrackfile,"</trk>\n");
924     fprintf(gpxtrackfile,"</gpx>\n");
925     }
926 amb 160
927 amb 177 if(gpxroutefile)
928     {
929     fprintf(gpxroutefile,"</rte>\n");
930     fprintf(gpxroutefile,"</gpx>\n");
931     }
932 amb 160
933 amb 164 /* Close the files */
934    
935 amb 1465 if(!option_stdout)
936     {
937     if(htmlfile)
938     fclose(htmlfile);
939     if(gpxtrackfile)
940     fclose(gpxtrackfile);
941     if(gpxroutefile)
942     fclose(gpxroutefile);
943     if(textfile)
944     fclose(textfile);
945     if(textallfile)
946     fclose(textallfile);
947     }
948 amb 160 }

Properties

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