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