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 440 - (hide annotations) (download) (as text)
Wed Jul 7 17:31:06 2010 UTC (14 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 32690 byte(s)
Remove compilation warning.

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

Properties

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