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 2192 - (hide annotations) (download) (as text)
Wed Sep 18 15:49:21 2024 UTC (6 months, 1 week ago) by amb
File MIME type: text/x-csrc
File size: 49822 byte(s)
Fix compilation warnings if index_t is changed to a 64-bit type but
preserve formatting of fake nodes (shown as negative).

1 amb 160 /***************************************
2     Routing output generator.
3    
4     Part of the Routino routing software.
5     ******************/ /******************
6 amb 2188 This file Copyright 2008-2017, 2019, 2024 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 1878 #include "relations.h"
35 amb 449
36     #include "functions.h"
37 amb 532 #include "fakes.h"
38 amb 449 #include "translations.h"
39 amb 160 #include "results.h"
40 amb 378 #include "xmlparse.h"
41 amb 160
42 amb 1784 #include "routino.h"
43 amb 955
44 amb 1784
45     /*+ To help when debugging +*/
46 amb 1564 #define DEBUG 0
47    
48 amb 927 /* Constants */
49 amb 160
50 amb 1784 #define ROUTINO_POINT_IGNORE -1 /*+ Ignore this point. +*/
51 amb 927
52 amb 955
53 amb 360 /* Global variables */
54    
55 amb 160 /*+ The option to calculate the quickest route insted of the shortest. +*/
56 amb 1784 int option_quickest=0;
57 amb 160
58 amb 1784 /*+ The options to select the format of the file output. +*/
59     int option_file_html=0,option_file_gpx_track=0,option_file_gpx_route=0,option_file_text=0,option_file_text_all=0,option_file_stdout=0;
60 amb 324
61 amb 1784 /*+ The options to select the format of the linked list output. +*/
62 amb 1795 int option_list_html=0,option_list_html_all=0,option_list_text=0,option_list_text_all=0;
63 amb 955
64 amb 1784
65 amb 360 /* Local variables */
66    
67 amb 171 /*+ Heuristics for determining if a junction is important. +*/
68 amb 1677 static const char junction_other_way[Highway_Count][Highway_Count]=
69 amb 492 { /* M, T, P, S, T, U, R, S, T, C, P, S, F = Way type of route not taken */
70     { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Motorway */
71     { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Trunk */
72     { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Primary */
73     { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Secondary */
74     { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Tertiary */
75     { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 }, /* Unclassified */
76     { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 }, /* Residential */
77     { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 }, /* Service */
78     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1 }, /* Track */
79     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1 }, /* Cycleway */
80     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Path */
81     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Steps */
82     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Ferry */
83 amb 171 };
84 amb 165
85 amb 360
86 amb 160 /*++++++++++++++++++++++++++++++++++++++
87 amb 379 Print the optimum route between two nodes.
88    
89 amb 1784 Routino_Output *PrintRoute Returns a linked list of data structures representing the route if required.
90    
91 amb 1501 Results **results The set of results to print (consecutive in array even if not consecutive waypoints).
92 amb 379
93     int nresults The number of results in the list.
94    
95 amb 680 Nodes *nodes The set of nodes to use.
96 amb 379
97     Segments *segments The set of segments to use.
98    
99 amb 680 Ways *ways The set of ways to use.
100 amb 379
101 amb 1878 Relations *relations The set of relations to use.
102    
103 amb 379 Profile *profile The profile containing the transport type, speeds and allowed highways.
104 amb 1784
105     Translation *translation The set of translated strings.
106 amb 164 ++++++++++++++++++++++++++++++++++++++*/
107 amb 160
108 amb 1878 Routino_Output *PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Translation *translation)
109 amb 164 {
110 amb 1784 FILE *htmlfile=NULL,*gpxtrackfile=NULL,*gpxroutefile=NULL,*textfile=NULL,*textallfile=NULL;
111 amb 1795 Routino_Output *listhead=NULL,*htmllist=NULL, *textlist=NULL,*textalllist=NULL,*htmlalllist=NULL;
112 amb 379
113 amb 1784 char *prev_bearing=NULL,*prev_wayname=NULL,*prev_waynameraw=NULL;
114 amb 1539 index_t prev_node=NO_NODE;
115 amb 379 distance_t cum_distance=0;
116     duration_t cum_duration=0;
117 amb 922
118 amb 1501 int point=0;
119 amb 683 int point_count=0;
120 amb 926 int roundabout=0;
121 amb 379
122 amb 164 /* Open the files */
123 amb 160
124 amb 1784 if(option_file_stdout)
125 amb 160 {
126 amb 1784 if(option_file_html)
127 amb 1465 htmlfile =stdout;
128 amb 1784 if(option_file_gpx_track)
129 amb 1465 gpxtrackfile=stdout;
130 amb 1784 if(option_file_gpx_route)
131 amb 1465 gpxroutefile=stdout;
132 amb 1784 if(option_file_text)
133 amb 1465 textfile =stdout;
134 amb 1784 if(option_file_text_all)
135 amb 1465 textallfile =stdout;
136 amb 160 }
137     else
138     {
139 amb 1699 #if defined(_MSC_VER) || defined(__MINGW32__)
140     const char *open_mode="wb";
141     #else
142     const char *open_mode="w";
143     #endif
144    
145 amb 1465 if(option_quickest==0)
146     {
147     /* Print the result for the shortest route */
148 amb 160
149 amb 1784 if(option_file_html)
150 amb 1699 htmlfile =fopen("shortest.html",open_mode);
151 amb 1784 if(option_file_gpx_track)
152 amb 1699 gpxtrackfile=fopen("shortest-track.gpx",open_mode);
153 amb 1784 if(option_file_gpx_route)
154 amb 1699 gpxroutefile=fopen("shortest-route.gpx",open_mode);
155 amb 1784 if(option_file_text)
156 amb 1699 textfile =fopen("shortest.txt",open_mode);
157 amb 1784 if(option_file_text_all)
158 amb 1699 textallfile =fopen("shortest-all.txt",open_mode);
159 amb 177
160 amb 1784 #ifndef LIBROUTINO
161     if(option_file_html && !htmlfile)
162 amb 1465 fprintf(stderr,"Warning: Cannot open file 'shortest.html' for writing [%s].\n",strerror(errno));
163 amb 1784 if(option_file_gpx_track && !gpxtrackfile)
164 amb 1465 fprintf(stderr,"Warning: Cannot open file 'shortest-track.gpx' for writing [%s].\n",strerror(errno));
165 amb 1784 if(option_file_gpx_route && !gpxroutefile)
166 amb 1465 fprintf(stderr,"Warning: Cannot open file 'shortest-route.gpx' for writing [%s].\n",strerror(errno));
167 amb 1784 if(option_file_text && !textfile)
168 amb 1465 fprintf(stderr,"Warning: Cannot open file 'shortest.txt' for writing [%s].\n",strerror(errno));
169 amb 1784 if(option_file_text_all && !textallfile)
170 amb 1465 fprintf(stderr,"Warning: Cannot open file 'shortest-all.txt' for writing [%s].\n",strerror(errno));
171 amb 1784 #endif
172 amb 1465 }
173     else
174     {
175     /* Print the result for the quickest route */
176    
177 amb 1784 if(option_file_html)
178 amb 1699 htmlfile =fopen("quickest.html",open_mode);
179 amb 1784 if(option_file_gpx_track)
180 amb 1699 gpxtrackfile=fopen("quickest-track.gpx",open_mode);
181 amb 1784 if(option_file_gpx_route)
182 amb 1699 gpxroutefile=fopen("quickest-route.gpx",open_mode);
183 amb 1784 if(option_file_text)
184 amb 1699 textfile =fopen("quickest.txt",open_mode);
185 amb 1784 if(option_file_text_all)
186 amb 1699 textallfile =fopen("quickest-all.txt",open_mode);
187 amb 1465
188 amb 1784 #ifndef LIBROUTINO
189     if(option_file_html && !htmlfile)
190 amb 1465 fprintf(stderr,"Warning: Cannot open file 'quickest.html' for writing [%s].\n",strerror(errno));
191 amb 1784 if(option_file_gpx_track && !gpxtrackfile)
192 amb 1465 fprintf(stderr,"Warning: Cannot open file 'quickest-track.gpx' for writing [%s].\n",strerror(errno));
193 amb 1784 if(option_file_gpx_route && !gpxroutefile)
194 amb 1465 fprintf(stderr,"Warning: Cannot open file 'quickest-route.gpx' for writing [%s].\n",strerror(errno));
195 amb 1784 if(option_file_text && !textfile)
196 amb 1465 fprintf(stderr,"Warning: Cannot open file 'quickest.txt' for writing [%s].\n",strerror(errno));
197 amb 1784 if(option_file_text_all && !textallfile)
198 amb 1465 fprintf(stderr,"Warning: Cannot open file 'quickest-all.txt' for writing [%s].\n",strerror(errno));
199 amb 1784 #endif
200 amb 1465 }
201 amb 160 }
202    
203 amb 164 /* Print the head of the files */
204 amb 160
205 amb 323 if(htmlfile)
206     {
207 amb 1505 fprintf(htmlfile,"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n");
208     fprintf(htmlfile,"<html>\n");
209 amb 1784 if(translation->xml_copyright_creator[0] && translation->xml_copyright_creator[1])
210     fprintf(htmlfile,"<!-- %s : %s -->\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]);
211     if(translation->xml_copyright_source[0] && translation->xml_copyright_source[1])
212     fprintf(htmlfile,"<!-- %s : %s -->\n",translation->xml_copyright_source[0],translation->xml_copyright_source[1]);
213     if(translation->xml_copyright_license[0] && translation->xml_copyright_license[1])
214     fprintf(htmlfile,"<!-- %s : %s -->\n",translation->xml_copyright_license[0],translation->xml_copyright_license[1]);
215 amb 1505 fprintf(htmlfile,"<head>\n");
216     fprintf(htmlfile,"<title>");
217 amb 1784 fprintf(htmlfile,translation->html_title,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
218 amb 1505 fprintf(htmlfile,"</title>\n");
219     fprintf(htmlfile,"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
220     fprintf(htmlfile,"<style type=\"text/css\">\n");
221 amb 323 fprintf(htmlfile,"<!--\n");
222 amb 376 fprintf(htmlfile," table {table-layout: fixed; border: none; border-collapse: collapse;}\n");
223     fprintf(htmlfile," table.c {color: grey; font-size: x-small;} /* copyright */\n");
224     fprintf(htmlfile," tr {border: 0px;}\n");
225     fprintf(htmlfile," tr.c {display: none;} /* coords */\n");
226     fprintf(htmlfile," tr.n {} /* node */\n");
227     fprintf(htmlfile," tr.s {} /* segment */\n");
228     fprintf(htmlfile," tr.t {font-weight: bold;} /* total */\n");
229     fprintf(htmlfile," td.l {font-weight: bold;}\n");
230     fprintf(htmlfile," td.r {}\n");
231     fprintf(htmlfile," span.w {font-weight: bold;} /* waypoint */\n");
232     fprintf(htmlfile," span.h {text-decoration: underline;} /* highway */\n");
233     fprintf(htmlfile," span.d {} /* segment distance */\n");
234     fprintf(htmlfile," span.j {font-style: italic;} /* total journey distance */\n");
235     fprintf(htmlfile," span.t {font-variant: small-caps;} /* turn */\n");
236     fprintf(htmlfile," span.b {font-variant: small-caps;} /* bearing */\n");
237 amb 323 fprintf(htmlfile,"-->\n");
238 amb 1505 fprintf(htmlfile,"</style>\n");
239     fprintf(htmlfile,"</head>\n");
240     fprintf(htmlfile,"<body>\n");
241     fprintf(htmlfile,"<h1>");
242 amb 1784 fprintf(htmlfile,translation->html_title,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
243 amb 1505 fprintf(htmlfile,"</h1>\n");
244 amb 323 fprintf(htmlfile,"<table>\n");
245     }
246    
247 amb 177 if(gpxtrackfile)
248     {
249     fprintf(gpxtrackfile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
250     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");
251 amb 160
252 amb 177 fprintf(gpxtrackfile,"<metadata>\n");
253 amb 1784 fprintf(gpxtrackfile,"<desc>%s : %s</desc>\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]);
254     if(translation->xml_copyright_source[1])
255 amb 376 {
256 amb 1784 fprintf(gpxtrackfile,"<copyright author=\"%s\">\n",translation->xml_copyright_source[1]);
257 amb 376
258 amb 1784 if(translation->xml_copyright_license[1])
259     fprintf(gpxtrackfile,"<license>%s</license>\n",translation->xml_copyright_license[1]);
260 amb 376
261 amb 177 fprintf(gpxtrackfile,"</copyright>\n");
262 amb 376 }
263 amb 177 fprintf(gpxtrackfile,"</metadata>\n");
264 amb 160
265 amb 177 fprintf(gpxtrackfile,"<trk>\n");
266 amb 376 fprintf(gpxtrackfile,"<name>");
267 amb 1784 fprintf(gpxtrackfile,translation->gpx_name,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
268 amb 376 fprintf(gpxtrackfile,"</name>\n");
269     fprintf(gpxtrackfile,"<desc>");
270 amb 1784 fprintf(gpxtrackfile,translation->gpx_desc,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
271 amb 376 fprintf(gpxtrackfile,"</desc>\n");
272 amb 177 }
273 amb 160
274 amb 177 if(gpxroutefile)
275     {
276     fprintf(gpxroutefile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
277     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");
278 amb 160
279 amb 177 fprintf(gpxroutefile,"<metadata>\n");
280 amb 1784 fprintf(gpxroutefile,"<desc>%s : %s</desc>\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]);
281     if(translation->xml_copyright_source[1])
282 amb 376 {
283 amb 1784 fprintf(gpxroutefile,"<copyright author=\"%s\">\n",translation->xml_copyright_source[1]);
284 amb 376
285 amb 1784 if(translation->xml_copyright_license[1])
286     fprintf(gpxroutefile,"<license>%s</license>\n",translation->xml_copyright_license[1]);
287 amb 376
288 amb 177 fprintf(gpxroutefile,"</copyright>\n");
289 amb 376 }
290 amb 177 fprintf(gpxroutefile,"</metadata>\n");
291 amb 160
292 amb 177 fprintf(gpxroutefile,"<rte>\n");
293 amb 360 fprintf(gpxroutefile,"<name>");
294 amb 1784 fprintf(gpxroutefile,translation->gpx_name,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
295 amb 360 fprintf(gpxroutefile,"</name>\n");
296 amb 376 fprintf(gpxroutefile,"<desc>");
297 amb 1784 fprintf(gpxroutefile,translation->gpx_desc,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest);
298 amb 376 fprintf(gpxroutefile,"</desc>\n");
299 amb 177 }
300 amb 160
301 amb 177 if(textfile)
302     {
303 amb 1784 if(translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1])
304     fprintf(textfile,"# %s : %s\n",translation->raw_copyright_creator[0],translation->raw_copyright_creator[1]);
305     if(translation->raw_copyright_source[0] && translation->raw_copyright_source[1])
306     fprintf(textfile,"# %s : %s\n",translation->raw_copyright_source[0],translation->raw_copyright_source[1]);
307     if(translation->raw_copyright_license[0] && translation->raw_copyright_license[1])
308     fprintf(textfile,"# %s : %s\n",translation->raw_copyright_license[0],translation->raw_copyright_license[1]);
309     if((translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1]) ||
310     (translation->raw_copyright_source[0] && translation->raw_copyright_source[1]) ||
311     (translation->raw_copyright_license[0] && translation->raw_copyright_license[1]))
312 amb 177 fprintf(textfile,"#\n");
313 amb 376
314 amb 316 fprintf(textfile,"#Latitude\tLongitude\tSection \tSection \tTotal \tTotal \tPoint\tTurn\tBearing\tHighway\n");
315     fprintf(textfile,"# \t \tDistance\tDuration\tDistance\tDuration\tType \t \t \t \n");
316     /* "%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" */
317 amb 177 }
318 amb 160
319 amb 177 if(textallfile)
320     {
321 amb 1784 if(translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1])
322     fprintf(textallfile,"# %s : %s\n",translation->raw_copyright_creator[0],translation->raw_copyright_creator[1]);
323     if(translation->raw_copyright_source[0] && translation->raw_copyright_source[1])
324     fprintf(textallfile,"# %s : %s\n",translation->raw_copyright_source[0],translation->raw_copyright_source[1]);
325     if(translation->raw_copyright_license[0] && translation->raw_copyright_license[1])
326     fprintf(textallfile,"# %s : %s\n",translation->raw_copyright_license[0],translation->raw_copyright_license[1]);
327     if((translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1]) ||
328     (translation->raw_copyright_source[0] && translation->raw_copyright_source[1]) ||
329     (translation->raw_copyright_license[0] && translation->raw_copyright_license[1]))
330 amb 177 fprintf(textallfile,"#\n");
331 amb 376
332 amb 316 fprintf(textallfile,"#Latitude\tLongitude\t Node\tType\tSegment\tSegment\tTotal\tTotal \tSpeed\tBearing\tHighway\n");
333     fprintf(textallfile,"# \t \t \t \tDist \tDurat'n\tDist \tDurat'n\t \t \t \n");
334     /* "%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" */
335 amb 177 }
336 amb 160
337 amb 1784 /* Create the head of the linked list */
338    
339     if(option_list_html)
340 amb 2188 listhead=htmllist=calloc(1,sizeof(Routino_Output));
341 amb 1795 if(option_list_html_all)
342 amb 2188 listhead=htmlalllist=htmllist=calloc(1,sizeof(Routino_Output));
343 amb 1784 if(option_list_text)
344 amb 2188 listhead=textlist=calloc(1,sizeof(Routino_Output));
345 amb 1784 if(option_list_text_all)
346 amb 2188 listhead=textalllist=calloc(1,sizeof(Routino_Output));
347 amb 1784
348 amb 922 /* Loop through all the sections of the route and print them */
349 amb 164
350 amb 1501 do
351 amb 316 {
352 amb 1564 int first=1;
353 amb 922 int next_point=point;
354 amb 316 distance_t junc_distance=0;
355     duration_t junc_duration=0;
356     Result *result;
357 amb 160
358 amb 1564 #if DEBUG
359     printf("Route section %d - waypoint %d to waypoint %d\n",point,results[point]->start_waypoint,results[point]->finish_waypoint);
360     printf(" start_node=%"Pindex_t" prev_segment=%"Pindex_t"\n",results[point]->start_node,results[point]->prev_segment);
361     printf(" finish_node=%"Pindex_t" last_segment=%"Pindex_t"\n",results[point]->finish_node,results[point]->last_segment);
362    
363     Result *r=FindResult(results[point],results[point]->start_node,results[point]->prev_segment);
364    
365     while(r)
366     {
367     printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score);
368    
369     r=r->next;
370     }
371     #endif
372    
373 amb 922 result=FindResult(results[point],results[point]->start_node,results[point]->prev_segment);
374    
375     /* Print the start of the segment */
376    
377 amb 324 if(gpxtrackfile)
378     fprintf(gpxtrackfile,"<trkseg>\n");
379 amb 303
380 amb 922 /* Loop through all the points within a section of the route and print them */
381 amb 165
382 amb 316 do
383 amb 160 {
384 amb 316 double latitude,longitude;
385 amb 1078 Node *resultnodep=NULL;
386 amb 922 index_t realsegment=NO_SEGMENT,next_realsegment=NO_SEGMENT;
387 amb 1078 Segment *resultsegmentp=NULL,*next_resultsegmentp=NULL;
388     Way *resultwayp=NULL,*next_resultwayp=NULL;
389 amb 922 Result *next_result;
390 amb 1784 int important=ROUTINO_POINT_UNIMPORTANT;
391 amb 160
392 amb 922 distance_t seg_distance=0;
393     duration_t seg_duration=0;
394     speed_t seg_speed=0;
395     char *waynameraw=NULL,*wayname=NULL,*next_waynameraw=NULL,*next_wayname=NULL;
396     int bearing_int=0,turn_int=0,next_bearing_int=0;
397 amb 1784 char *turn=NULL,*turnraw=NULL,*next_bearing=NULL,*next_bearingraw=NULL;
398 amb 922
399     /* Calculate the information about this point */
400    
401     if(IsFakeNode(result->node))
402     GetFakeLatLong(result->node,&latitude,&longitude);
403 amb 316 else
404 amb 1447 {
405 amb 1078 resultnodep=LookupNode(nodes,result->node,6);
406 amb 171
407 amb 1447 GetLatLong(nodes,result->node,resultnodep,&latitude,&longitude);
408     }
409    
410 amb 922 /* Calculate the next result */
411 amb 171
412 amb 922 next_result=result->next;
413    
414     if(!next_result)
415 amb 1501 {
416     next_point++;
417 amb 171
418 amb 1501 if(next_point<nresults)
419     {
420     next_result=FindResult(results[next_point],results[next_point]->start_node,results[next_point]->prev_segment);
421     next_result=next_result->next;
422     }
423     }
424    
425 amb 922 /* Calculate the information about this segment */
426 amb 459
427 amb 1580 if(!first) /* not first point of a section of the route */
428 amb 169 {
429 amb 1580 if(IsFakeSegment(result->segment))
430     {
431     resultsegmentp=LookupFakeSegment(result->segment);
432     realsegment=IndexRealSegment(result->segment);
433     }
434     else
435     {
436     resultsegmentp=LookupSegment(segments,result->segment,2);
437     realsegment=result->segment;
438     }
439 amb 922
440 amb 1580 resultwayp=LookupWay(ways,resultsegmentp->way,1);
441 amb 316
442 amb 1168 seg_distance+=DISTANCE(resultsegmentp->distance);
443 amb 1078 seg_duration+=Duration(resultsegmentp,resultwayp,profile);
444 amb 922
445     /* Calculate the cumulative distance/duration */
446    
447 amb 316 junc_distance+=seg_distance;
448     junc_duration+=seg_duration;
449     cum_distance+=seg_distance;
450     cum_duration+=seg_duration;
451 amb 922 }
452 amb 316
453 amb 922 /* Calculate the information about the next segment */
454 amb 316
455 amb 922 if(next_result)
456     {
457     if(IsFakeSegment(next_result->segment))
458     {
459 amb 1078 next_resultsegmentp=LookupFakeSegment(next_result->segment);
460 amb 922 next_realsegment=IndexRealSegment(next_result->segment);
461     }
462 amb 316 else
463 amb 303 {
464 amb 1078 next_resultsegmentp=LookupSegment(segments,next_result->segment,1);
465 amb 922 next_realsegment=next_result->segment;
466     }
467     }
468 amb 160
469 amb 926 /* Decide if this is a roundabout */
470    
471     if(next_result)
472     {
473 amb 1078 next_resultwayp=LookupWay(ways,next_resultsegmentp->way,2);
474 amb 926
475 amb 1174 if(next_resultwayp->type&Highway_Roundabout)
476 amb 926 {
477     if(roundabout==0)
478     {
479     roundabout++;
480 amb 1784 important=ROUTINO_POINT_RB_ENTRY;
481 amb 926 }
482     else
483     {
484 amb 1539 Segment *segmentp;
485 amb 926
486 amb 1539 if(resultnodep)
487     segmentp=FirstSegment(segments,resultnodep,3);
488     else
489     segmentp=FirstFakeSegment(result->node);
490    
491 amb 926 do
492     {
493 amb 1078 index_t othernode=OtherNode(segmentp,result->node);
494 amb 1539 index_t thissegment;
495 amb 926
496 amb 1539 if(IsFakeNode(result->node))
497     thissegment=IndexFakeSegment(segmentp);
498     else
499     thissegment=IndexSegment(segments,segmentp);
500    
501 amb 1543 if(othernode!=prev_node && othernode!=next_result->node &&
502     thissegment!=realsegment && IsNormalSegment(segmentp))
503     {
504     int canexit=1;
505    
506     if(profile->oneway && IsOnewayTo(segmentp,result->node))
507 amb 926 {
508 amb 1989 if(profile->transports!=Transports_Bicycle)
509 amb 1543 canexit=0;
510     else
511     {
512     Way *wayp=LookupWay(ways,segmentp->way,3);
513    
514 amb 1559 if(!(wayp->type&Highway_CycleBothWays))
515 amb 1543 canexit=0;
516     }
517     }
518    
519     if(canexit)
520     {
521 amb 1078 Way *wayp=LookupWay(ways,segmentp->way,3);
522 amb 926
523 amb 1174 if(!(wayp->type&Highway_Roundabout))
524 amb 1543 {
525     roundabout++;
526 amb 1784 important=ROUTINO_POINT_RB_NOT_EXIT;
527 amb 1543 }
528 amb 926 }
529 amb 1543 }
530 amb 926
531 amb 1539 if(resultnodep)
532     segmentp=NextSegment(segments,segmentp,result->node);
533     else
534     segmentp=NextFakeSegment(segmentp,result->node);
535 amb 926 }
536 amb 1078 while(segmentp);
537 amb 926 }
538     }
539     else
540     if(roundabout)
541     {
542     roundabout++;
543 amb 1784 important=ROUTINO_POINT_RB_EXIT;
544 amb 926 }
545     }
546    
547 amb 922 /* Decide if this is an important junction */
548 amb 303
549 amb 1539 if(point_count==0) /* first point overall = Waypoint */
550 amb 1784 important=ROUTINO_POINT_WAYPOINT;
551 amb 1564 else if(result->next==NULL) /* Waypoint */
552 amb 1784 important=ROUTINO_POINT_WAYPOINT;
553 amb 1564 else if(first) /* first point of a section of the route */
554 amb 1784 important=ROUTINO_POINT_IGNORE;
555 amb 1539 else if(roundabout) /* roundabout */
556     ;
557 amb 922 else if(realsegment==next_realsegment) /* U-turn */
558 amb 1784 important=ROUTINO_POINT_UTURN;
559 amb 1078 else if(resultnodep && (resultnodep->flags&NODE_MINIRNDBT))
560 amb 1784 important=ROUTINO_POINT_MINI_RB; /* mini-roundabout */
561 amb 1935 else if(resultnodep)
562 amb 922 {
563 amb 1078 Segment *segmentp=FirstSegment(segments,resultnodep,3);
564 amb 316
565 amb 922 do
566     {
567 amb 1078 index_t seg=IndexSegment(segments,segmentp);
568 amb 316
569 amb 1543 if(seg!=realsegment && IsNormalSegment(segmentp))
570     {
571     int cango=1;
572    
573     if(profile->oneway && IsOnewayTo(segmentp,result->node))
574 amb 922 {
575 amb 1989 if(profile->transports!=Transports_Bicycle)
576 amb 1543 cango=0;
577     else
578     {
579     Way *wayp=LookupWay(ways,segmentp->way,3);
580    
581 amb 1559 if(!(wayp->type&Highway_CycleBothWays))
582 amb 1543 cango=0;
583     }
584     }
585    
586 amb 1878 if(profile->turns && IsSuperNode(resultnodep) && IsTurnRestrictedNode(resultnodep))
587     {
588     index_t turnrelation=FindFirstTurnRelation2(relations,result->node,realsegment);
589    
590 amb 1989 if(turnrelation!=NO_RELATION && !IsTurnAllowed(relations,turnrelation,result->node,realsegment,seg,profile->transports))
591 amb 1878 cango=0;
592     }
593    
594 amb 1543 if(cango)
595     {
596 amb 1078 Way *wayp=LookupWay(ways,segmentp->way,3);
597 amb 922
598 amb 1074 if(seg==next_realsegment) /* the next segment that we follow */
599 amb 922 {
600 amb 1078 if(HIGHWAY(wayp->type)!=HIGHWAY(resultwayp->type))
601 amb 1784 if(important<ROUTINO_POINT_CHANGE)
602     important=ROUTINO_POINT_CHANGE;
603 amb 303 }
604 amb 922 else /* a segment that we don't follow */
605     {
606 amb 1078 if(junction_other_way[HIGHWAY(resultwayp->type)-1][HIGHWAY(wayp->type)-1])
607 amb 1784 if(important<ROUTINO_POINT_JUNCT_IMPORT)
608     important=ROUTINO_POINT_JUNCT_IMPORT;
609 amb 160
610 amb 1784 if(important<ROUTINO_POINT_JUNCT_CONT)
611     important=ROUTINO_POINT_JUNCT_CONT;
612 amb 922 }
613     }
614 amb 1543 }
615 amb 922
616 amb 1078 segmentp=NextSegment(segments,segmentp,result->node);
617 amb 303 }
618 amb 1078 while(segmentp);
619 amb 922 }
620 amb 169
621 amb 922 /* Calculate the strings to be used */
622 amb 169
623 amb 1784 if(!first && (textallfile || textalllist))
624 amb 922 {
625 amb 1078 waynameraw=WayName(ways,resultwayp);
626 amb 922 if(!*waynameraw)
627 amb 1784 waynameraw=translation->raw_highway[HIGHWAY(resultwayp->type)];
628 amb 922
629 amb 1078 bearing_int=(int)BearingAngle(nodes,resultsegmentp,result->node);
630 amb 922
631 amb 1078 seg_speed=profile->speed[HIGHWAY(resultwayp->type)];
632 amb 922 }
633    
634 amb 1795 if(next_result && (important>ROUTINO_POINT_JUNCT_CONT || htmlalllist))
635 amb 922 {
636 amb 1784 if(!first && (htmlfile || htmllist || textfile || textlist))
637 amb 177 {
638 amb 1565 if(DISTANCE(resultsegmentp->distance)==0 || DISTANCE(next_resultsegmentp->distance)==0)
639     turn_int=0;
640     else
641     turn_int=(int)TurnAngle(nodes,resultsegmentp,next_resultsegmentp,result->node);
642    
643 amb 1784 turn =translation->xml_turn[((202+turn_int)/45)%8];
644     turnraw=translation->notxml_turn[((202+turn_int)/45)%8];
645 amb 922 }
646 amb 303
647 amb 1784 if(gpxroutefile || htmlfile || htmllist)
648 amb 922 {
649 amb 1078 next_waynameraw=WayName(ways,next_resultwayp);
650 amb 922 if(!*next_waynameraw)
651 amb 1784 next_waynameraw=translation->raw_highway[HIGHWAY(next_resultwayp->type)];
652 amb 378
653 amb 922 next_wayname=ParseXML_Encode_Safe_XML(next_waynameraw);
654     }
655 amb 411
656 amb 1784 if(htmlfile || htmllist || gpxroutefile || textfile || textlist)
657 amb 922 {
658 amb 1580 if(!first && DISTANCE(next_resultsegmentp->distance)==0)
659 amb 1565 next_bearing_int=(int)BearingAngle(nodes,resultsegmentp,result->node);
660     else
661     next_bearing_int=(int)BearingAngle(nodes,next_resultsegmentp,next_result->node);
662    
663 amb 1784 next_bearing =translation->xml_heading[(4+(22+next_bearing_int)/45)%8];
664     next_bearingraw=translation->notxml_heading[(4+(22+next_bearing_int)/45)%8];
665 amb 922 }
666     }
667 amb 378
668 amb 922 /* Print out the important points (junctions / waypoints) */
669    
670 amb 1784 if(important>ROUTINO_POINT_JUNCT_CONT)
671 amb 922 {
672     if(htmlfile)
673     {
674     char *type;
675    
676 amb 1784 if(important==ROUTINO_POINT_WAYPOINT)
677 amb 1815 {
678     type=malloc(sizeof("<span class='w'>")+strlen(translation->html_waypoint)+1+4+sizeof("</span>")+1);
679    
680     sprintf(type,"<span class='w'>%s#%d</span>",translation->html_waypoint,
681     (point_count==0?results[point]->start_waypoint:results[point]->finish_waypoint));
682     }
683 amb 1784 else if(important==ROUTINO_POINT_MINI_RB)
684     type=translation->html_roundabout;
685 amb 922 else
686 amb 1784 type=translation->html_junction;
687 amb 922
688     if(point_count>0) /* not the first point */
689     {
690 amb 1796 /* <tr class='s'><td>Follow <span class='h'>*highway name*</span> for <span class='d'>*distance* km, *time* min</span> [<span class='j'>*distance* km, *time* minutes</span>] */
691 amb 1784 fprintf(htmlfile,translation->html_segment,
692     (roundabout>1?translation->html_roundabout:prev_wayname),
693 amb 922 distance_to_km(junc_distance),duration_to_minutes(junc_duration));
694 amb 1784 fprintf(htmlfile,translation->html_subtotal,
695 amb 922 distance_to_km(cum_distance),duration_to_minutes(cum_duration));
696     }
697 amb 378
698 amb 1796 /* <tr class='c'>*N*: *latitude* *longitude* */
699     fprintf(htmlfile,"<tr class='c'><td>%d: %.6f %.6f\n",
700 amb 922 point_count+1,
701     radians_to_degrees(latitude),radians_to_degrees(longitude));
702 amb 378
703 amb 922 if(point_count==0) /* first point */
704     {
705 amb 1796 /* <tr class='n'><td>Start at <span class='w'>Waypoint</span>, head <span class='b'>*heading*</span> */
706 amb 1784 fprintf(htmlfile,translation->html_start,
707 amb 1815 type,
708 amb 922 next_bearing);
709     }
710     else if(next_result) /* middle point */
711     {
712 amb 1784 if(roundabout>1 && important!=ROUTINO_POINT_WAYPOINT)
713 amb 926 {
714 amb 1796 /* <tr class='n'><td>leave roundabout, take <span class='t'>the *Nth* exit</span> heading <span class='b'>*heading*</span> */
715 amb 1784 fprintf(htmlfile,translation->html_rbnode,
716     translation->html_roundabout,
717     translation->xml_ordinal[roundabout-2],
718 amb 926 next_bearing);
719     }
720     else
721     {
722 amb 1815 /* <tr class='n'><td>At *waypoint/roundabout/junction*, go <span class='t'>*direction*</span> heading <span class='b'>*heading*</span> */
723 amb 1784 fprintf(htmlfile,translation->html_node,
724 amb 926 type,
725     turn,
726     next_bearing);
727     }
728 amb 922 }
729     else /* end point */
730     {
731 amb 1796 /* <tr class='n'><td>Stop at <span class='w'>Waypoint</span> */
732 amb 1784 fprintf(htmlfile,translation->html_stop,
733 amb 1815 type);
734 amb 378
735 amb 1796 /* <tr class='t'><td><span class='j'>Total *distance* km, *time* minutes</span> */
736 amb 1784 fprintf(htmlfile,translation->html_total,
737 amb 922 distance_to_km(cum_distance),duration_to_minutes(cum_duration));
738 amb 378 }
739 amb 1815
740     if(important==ROUTINO_POINT_WAYPOINT)
741     free(type);
742 amb 922 }
743 amb 378
744 amb 1784 if(htmllist)
745     {
746     int strl;
747     char *type;
748    
749     if(important==ROUTINO_POINT_WAYPOINT)
750 amb 1815 {
751     type=malloc(strlen(translation->nothtml_waypoint)+1+4+1);
752    
753     sprintf(type,"%s#%d",translation->nothtml_waypoint,
754     (point_count==0?results[point]->start_waypoint:results[point]->finish_waypoint));
755     }
756 amb 1784 else if(important==ROUTINO_POINT_MINI_RB)
757     type=translation->nothtml_roundabout;
758     else
759     type=translation->nothtml_junction;
760    
761     if(point_count>0) /* not the first point */
762     {
763     /* Follow: *highway name* for *distance* km, *time* min */
764     strl=strlen(translation->nothtml_segment)+
765     strlen(roundabout>1?translation->nothtml_roundabout:prev_waynameraw)+8+8+1;
766    
767     htmllist->desc2=malloc(strl);
768    
769     sprintf(htmllist->desc2,translation->nothtml_segment,
770     (roundabout>1?translation->nothtml_roundabout:prev_waynameraw),
771     distance_to_km(junc_distance),duration_to_minutes(junc_duration));
772    
773     /* *distance* km, *time* minutes */
774     strl=strlen(translation->nothtml_subtotal)+8+8+1;
775    
776     htmllist->desc3=malloc(strl);
777    
778     sprintf(htmllist->desc3,translation->nothtml_subtotal,
779     distance_to_km(cum_distance),duration_to_minutes(cum_duration));
780    
781 amb 1795 if(htmlalllist)
782     htmllist=htmlalllist;
783 amb 1784
784 amb 2188 htmllist->next=calloc(1,sizeof(Routino_Output));
785 amb 1784 htmllist=htmllist->next;
786 amb 1795
787     if(htmlalllist)
788     htmlalllist=htmllist;
789 amb 1784 }
790    
791     htmllist->lon=longitude;
792     htmllist->lat=latitude;
793     htmllist->type=important;
794 amb 1795 htmllist->dist=distance_to_km(cum_distance);
795     htmllist->time=duration_to_minutes(cum_duration);
796 amb 1784
797     if(point_count==0) /* first point */
798     {
799     /* Start: At Waypoint, head *heading* */
800     strl=strlen(translation->nothtml_start)+
801 amb 1815 strlen(type)+strlen(next_bearingraw)+1;
802 amb 1784
803     htmllist->desc1=malloc(strl);
804    
805     sprintf(htmllist->desc1,translation->nothtml_start,
806 amb 1815 type,
807 amb 1784 next_bearingraw);
808    
809     htmllist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw);
810     }
811     else if(next_result) /* middle point */
812     {
813     if(roundabout>1 && important!=ROUTINO_POINT_WAYPOINT)
814     {
815     /* At: Roundabout, take the *Nth* exit heading *heading* */
816     strl=strlen(translation->nothtml_rbnode)+
817     strlen(translation->nothtml_roundabout)+strlen(translation->notxml_ordinal[roundabout-2])+strlen(next_bearingraw)+1;
818    
819     htmllist->desc1=malloc(strl);
820    
821     sprintf(htmllist->desc1,translation->nothtml_rbnode,
822     translation->nothtml_roundabout,
823     translation->notxml_ordinal[roundabout-2],
824     next_bearingraw);
825     }
826     else
827     {
828 amb 1815 /* At: Waypoint/Roundabout/Junction, go *direction* heading *heading* */
829 amb 1784 strl=strlen(translation->nothtml_node)+
830     strlen(type)+strlen(turnraw)+strlen(next_bearingraw)+1;
831    
832     htmllist->desc1=malloc(strl);
833    
834     sprintf(htmllist->desc1,translation->nothtml_node,
835     type,
836     turnraw,
837     next_bearingraw);
838     }
839    
840     htmllist->turn=turn_int;
841     htmllist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw);
842     }
843     else /* end point */
844     {
845     /* Stop: At Waypoint */
846     strl=strlen(translation->nothtml_stop)+
847 amb 1815 strlen(type)+1;
848 amb 1784
849     htmllist->desc1=malloc(strl);
850    
851     sprintf(htmllist->desc1,translation->nothtml_stop,
852 amb 1815 type);
853 amb 1784
854     /* Total: *distance* km, *time* minutes */
855     strl=strlen(translation->nothtml_total)+8+8+1;
856    
857     htmllist->desc2=malloc(strl);
858    
859     sprintf(htmllist->desc2,translation->nothtml_total,
860     distance_to_km(cum_distance),duration_to_minutes(cum_duration));
861    
862     htmllist->turn=turn_int;
863     }
864    
865     htmllist->bearing=next_bearing_int;
866 amb 1815
867     if(important==ROUTINO_POINT_WAYPOINT)
868     free(type);
869 amb 1784 }
870    
871 amb 922 if(gpxroutefile)
872     {
873     if(point_count>0) /* not first point */
874 amb 332 {
875 amb 378 fprintf(gpxroutefile,"<desc>");
876 amb 1784 fprintf(gpxroutefile,translation->gpx_step,
877 amb 922 prev_bearing,
878     prev_wayname,
879 amb 378 distance_to_km(junc_distance),duration_to_minutes(junc_duration));
880     fprintf(gpxroutefile,"</desc></rtept>\n");
881 amb 922 }
882 amb 316
883 amb 922 if(point_count==0) /* first point */
884     {
885 amb 1815 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%02d</name>\n",
886 amb 922 radians_to_degrees(latitude),radians_to_degrees(longitude),
887 amb 1815 translation->gpx_waypt,results[point]->start_waypoint);
888 amb 922 }
889     else if(!next_result) /* end point */
890     {
891 amb 1815 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%02d</name>\n",
892 amb 922 radians_to_degrees(latitude),radians_to_degrees(longitude),
893 amb 1815 translation->gpx_waypt,results[point]->finish_waypoint);
894 amb 922 fprintf(gpxroutefile,"<desc>");
895 amb 1784 fprintf(gpxroutefile,translation->gpx_final,
896 amb 922 distance_to_km(cum_distance),duration_to_minutes(cum_duration));
897     fprintf(gpxroutefile,"</desc></rtept>\n");
898     }
899     else /* middle point */
900     {
901 amb 1784 if(important==ROUTINO_POINT_WAYPOINT)
902 amb 1815 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%02d</name>\n",
903 amb 378 radians_to_degrees(latitude),radians_to_degrees(longitude),
904 amb 1815 translation->gpx_waypt,results[point]->finish_waypoint);
905 amb 332 else
906 amb 360 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>%s%03d</name>\n",
907 amb 378 radians_to_degrees(latitude),radians_to_degrees(longitude),
908 amb 1815 translation->gpx_trip,point_count);
909 amb 332 }
910 amb 922 }
911 amb 316
912 amb 922 if(textfile)
913     {
914     char *type;
915 amb 316
916 amb 1784 if(important==ROUTINO_POINT_WAYPOINT)
917 amb 1815 {
918     type=malloc(sizeof("Waypt")+1+4+1);
919    
920     sprintf(type,"Waypt#%d",(point_count==0?results[point]->start_waypoint:results[point]->finish_waypoint));
921     }
922     else if(important==ROUTINO_POINT_MINI_RB)
923     type="Mini-RB";
924 amb 922 else
925     type="Junct";
926 amb 316
927 amb 922 if(point_count==0) /* first point */
928     {
929     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",
930     radians_to_degrees(latitude),radians_to_degrees(longitude),
931     0.0,0.0,0.0,0.0,
932     type,
933     ((22+next_bearing_int)/45+4)%8-4,
934     next_waynameraw);
935     }
936     else if(!next_result) /* end point */
937     {
938     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",
939     radians_to_degrees(latitude),radians_to_degrees(longitude),
940     distance_to_km(junc_distance),duration_to_minutes(junc_duration),
941     distance_to_km(cum_distance),duration_to_minutes(cum_duration),
942     type);
943     }
944     else /* middle point */
945     {
946     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",
947     radians_to_degrees(latitude),radians_to_degrees(longitude),
948     distance_to_km(junc_distance),duration_to_minutes(junc_duration),
949     distance_to_km(cum_distance),duration_to_minutes(cum_duration),
950     type,
951     (22+turn_int)/45,
952     ((22+next_bearing_int)/45+4)%8-4,
953     next_waynameraw);
954     }
955 amb 1815
956     if(important==ROUTINO_POINT_WAYPOINT)
957     free(type);
958 amb 922 }
959 amb 322
960 amb 1784 if(textlist)
961     {
962     textlist->lon=longitude;
963     textlist->lat=latitude;
964     textlist->type=important;
965    
966     if(point_count==0) /* first point */
967     {
968 amb 2188 textlist->next=calloc(1,sizeof(Routino_Output));
969 amb 1784
970     textlist->bearing=next_bearing_int;
971     textlist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw);
972     }
973     else if(!next_result) /* end point */
974     {
975     textlist->next=NULL;
976    
977     textlist->dist=distance_to_km(cum_distance);
978     textlist->time=duration_to_minutes(cum_duration);
979     }
980     else /* middle point */
981     {
982 amb 2188 textlist->next=calloc(1,sizeof(Routino_Output));
983 amb 1784
984     textlist->dist=distance_to_km(cum_distance);
985     textlist->time=duration_to_minutes(cum_duration);
986     textlist->turn=turn_int;
987     textlist->bearing=next_bearing_int;
988     textlist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw);
989     }
990    
991     textlist=textlist->next;
992     }
993    
994 amb 922 junc_distance=0;
995     junc_duration=0;
996 amb 322
997 amb 1784 if(htmlfile || htmllist || gpxroutefile)
998 amb 922 {
999     if(prev_wayname)
1000     free(prev_wayname);
1001 amb 322
1002 amb 922 if(next_wayname)
1003     prev_wayname=strcpy((char*)malloc(strlen(next_wayname)+1),next_wayname);
1004     else
1005     prev_wayname=NULL;
1006 amb 316
1007 amb 1784 if(prev_waynameraw)
1008     free(prev_waynameraw);
1009    
1010     if(next_waynameraw)
1011     prev_waynameraw=strcpy((char*)malloc(strlen(next_waynameraw)+1),next_waynameraw);
1012     else
1013     prev_waynameraw=NULL;
1014 amb 165 }
1015 amb 160
1016 amb 922 if(gpxroutefile)
1017     prev_bearing=next_bearing;
1018 amb 926
1019     if(roundabout>1)
1020     roundabout=0;
1021 amb 922 }
1022 amb 1795 else
1023     {
1024     if(htmlalllist)
1025     {
1026 amb 2188 htmlalllist->next=calloc(1,sizeof(Routino_Output));
1027 amb 1795 htmlalllist=htmlalllist->next;
1028 amb 303
1029 amb 1795 htmlalllist->lon=longitude;
1030     htmlalllist->lat=latitude;
1031     htmlalllist->type=important;
1032     htmlalllist->dist=distance_to_km(cum_distance);
1033     htmlalllist->time=duration_to_minutes(cum_duration);
1034     htmlalllist->turn=turn_int;
1035     htmlalllist->bearing=next_bearing_int;
1036     }
1037     }
1038    
1039 amb 922 /* Print out all of the results */
1040    
1041     if(gpxtrackfile)
1042     fprintf(gpxtrackfile,"<trkpt lat=\"%.6f\" lon=\"%.6f\"/>\n",
1043     radians_to_degrees(latitude),radians_to_degrees(longitude));
1044    
1045 amb 1784 if(important>ROUTINO_POINT_IGNORE)
1046 amb 922 {
1047 amb 316 if(textallfile)
1048     {
1049     char *type;
1050    
1051 amb 1784 if(important==ROUTINO_POINT_WAYPOINT)
1052 amb 1815 {
1053     type=malloc(sizeof("Waypt")+1+4+1);
1054    
1055     sprintf(type,"Waypt#%d",(point_count==0?results[point]->start_waypoint:results[point]->finish_waypoint));
1056     }
1057 amb 1784 else if(important==ROUTINO_POINT_UTURN)
1058 amb 926 type="U-turn";
1059 amb 1784 else if(important==ROUTINO_POINT_MINI_RB)
1060 amb 929 type="Mini-RB";
1061 amb 1784 else if(important==ROUTINO_POINT_CHANGE)
1062 amb 316 type="Change";
1063 amb 1784 else if(important==ROUTINO_POINT_JUNCT_CONT || important==ROUTINO_POINT_RB_NOT_EXIT)
1064 amb 1075 type="Junct-";
1065 amb 1784 else if(important==ROUTINO_POINT_UNIMPORTANT)
1066 amb 927 type="Inter";
1067     else
1068 amb 316 type="Junct";
1069    
1070 amb 922 if(point_count==0) /* first point */
1071 amb 474 {
1072 amb 2192 if(IsFakeNode(result->node))
1073     fprintf(textallfile,"%10.6f\t%11.6f\t%8"PRId32"%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t\t\t\n",
1074     radians_to_degrees(latitude),radians_to_degrees(longitude),
1075     (int32_t)((NODE_FAKE-result->node)),
1076     ' ',type,
1077     0.0,0.0,0.0,0.0);
1078     else
1079     fprintf(textallfile,"%10.6f\t%11.6f\t%8"Pindex_t"%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t\t\t\n",
1080     radians_to_degrees(latitude),radians_to_degrees(longitude),
1081     result->node,
1082     (resultnodep && IsSuperNode(resultnodep))?'*':' ',type,
1083     0.0,0.0,0.0,0.0);
1084 amb 474 }
1085 amb 927 else /* not the first point */
1086 amb 378 {
1087 amb 2192 if(IsFakeNode(result->node))
1088     fprintf(textallfile,"%10.6f\t%11.6f\t%8"PRId32"%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%4d\t%s\n",
1089     radians_to_degrees(latitude),radians_to_degrees(longitude),
1090     (int32_t)(NODE_FAKE-result->node),
1091     ' ',type,
1092     distance_to_km(seg_distance),duration_to_minutes(seg_duration),
1093     distance_to_km(cum_distance),duration_to_minutes(cum_duration),
1094     speed_to_kph(seg_speed),
1095     bearing_int,
1096     waynameraw);
1097     else
1098     fprintf(textallfile,"%10.6f\t%11.6f\t%8"Pindex_t"%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%4d\t%s\n",
1099     radians_to_degrees(latitude),radians_to_degrees(longitude),
1100     result->node,
1101     (resultnodep && IsSuperNode(resultnodep))?'*':' ',type,
1102     distance_to_km(seg_distance),duration_to_minutes(seg_duration),
1103     distance_to_km(cum_distance),duration_to_minutes(cum_duration),
1104     speed_to_kph(seg_speed),
1105     bearing_int,
1106     waynameraw);
1107 amb 378 }
1108 amb 1815
1109     if(important==ROUTINO_POINT_WAYPOINT)
1110     free(type);
1111 amb 316 }
1112 amb 1784
1113     if(textalllist)
1114     {
1115     if(point_count==0) /* first point */
1116     ;
1117     else /* not the first point */
1118     {
1119 amb 2188 textalllist->next=calloc(1,sizeof(Routino_Output));
1120 amb 1784 textalllist=textalllist->next;
1121    
1122     textalllist->dist=distance_to_km(cum_distance);
1123     textalllist->time=duration_to_minutes(cum_duration);
1124     textalllist->speed=speed_to_kph(seg_speed);
1125     textalllist->bearing=next_bearing_int;
1126     textalllist->name=strcpy(malloc(strlen(waynameraw)+1),waynameraw);
1127     }
1128    
1129     textalllist->lon=longitude;
1130     textalllist->lat=latitude;
1131     textalllist->type=important;
1132     }
1133 amb 160 }
1134 amb 378
1135 amb 922 if(wayname && wayname!=waynameraw)
1136     free(wayname);
1137 amb 160
1138 amb 922 result=next_result;
1139 amb 323
1140 amb 1784 if(important>ROUTINO_POINT_JUNCT_CONT)
1141 amb 922 point_count++;
1142 amb 1564
1143     first=0;
1144 amb 922 }
1145     while(point==next_point);
1146 amb 171
1147 amb 922 /* Print the end of the segment */
1148 amb 171
1149 amb 316 if(gpxtrackfile)
1150     fprintf(gpxtrackfile,"</trkseg>\n");
1151 amb 160
1152 amb 922 point=next_point;
1153 amb 1539
1154     if(result)
1155     prev_node=result->node;
1156     else
1157     prev_node=NO_NODE;
1158 amb 160 }
1159 amb 1501 while(point<nresults);
1160 amb 160
1161 amb 164 /* Print the tail of the files */
1162    
1163 amb 323 if(htmlfile)
1164     {
1165     fprintf(htmlfile,"</table>\n");
1166 amb 376
1167 amb 1784 if((translation->xml_copyright_creator[0] && translation->xml_copyright_creator[1]) ||
1168     (translation->xml_copyright_source[0] && translation->xml_copyright_source[1]) ||
1169     (translation->xml_copyright_license[0] && translation->xml_copyright_license[1]))
1170 amb 376 {
1171     fprintf(htmlfile,"<p>\n");
1172     fprintf(htmlfile,"<table class='c'>\n");
1173 amb 1784 if(translation->xml_copyright_creator[0] && translation->xml_copyright_creator[1])
1174     fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]);
1175     if(translation->xml_copyright_source[0] && translation->xml_copyright_source[1])
1176     fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translation->xml_copyright_source[0],translation->xml_copyright_source[1]);
1177     if(translation->xml_copyright_license[0] && translation->xml_copyright_license[1])
1178     fprintf(htmlfile,"<tr><td class='l'>%s:<td class='r'>%s\n",translation->xml_copyright_license[0],translation->xml_copyright_license[1]);
1179 amb 376 fprintf(htmlfile,"</table>\n");
1180     }
1181    
1182 amb 1505 fprintf(htmlfile,"</body>\n");
1183     fprintf(htmlfile,"</html>\n");
1184 amb 323 }
1185    
1186 amb 177 if(gpxtrackfile)
1187     {
1188     fprintf(gpxtrackfile,"</trk>\n");
1189     fprintf(gpxtrackfile,"</gpx>\n");
1190     }
1191 amb 160
1192 amb 177 if(gpxroutefile)
1193     {
1194     fprintf(gpxroutefile,"</rte>\n");
1195     fprintf(gpxroutefile,"</gpx>\n");
1196     }
1197 amb 160
1198 amb 164 /* Close the files */
1199    
1200 amb 1784 if(!option_file_stdout)
1201 amb 1465 {
1202     if(htmlfile)
1203     fclose(htmlfile);
1204     if(gpxtrackfile)
1205     fclose(gpxtrackfile);
1206     if(gpxroutefile)
1207     fclose(gpxroutefile);
1208     if(textfile)
1209     fclose(textfile);
1210     if(textallfile)
1211     fclose(textallfile);
1212     }
1213 amb 1784
1214     return(listhead);
1215 amb 160 }

Properties

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