Routino SVN Repository Browser

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

ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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