Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /branches/MSVC/src/output.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1501 - (hide annotations) (download) (as text)
Wed Jan 29 19:57:08 2014 UTC (11 years, 1 month ago) by amb
Original Path: trunk/src/output.c
File MIME type: text/x-csrc
File size: 36307 byte(s)
Refactor the code so that the Results data type has the start and finish
waypoints defined within it and the array passed to the PrintRoute() function
doesn't have holes in it.

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

Properties

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