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 460 - (hide annotations) (download) (as text)
Sat Jul 24 10:09:07 2010 UTC (14 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 33254 byte(s)
Finished slim mode for the router by adding ways.

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

Properties

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