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