Routino SVN Repository Browser

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

ViewVC logotype

Contents of /trunk/src/output.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 228 - (show annotations) (download) (as text)
Sun Jul 12 09:01:48 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 14771 byte(s)
Tidy up and fix comments and include files.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/output.c,v 1.12 2009-07-12 09:01:48 amb Exp $
3
4 Routing output generator.
5
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008,2009 Andrew M. Bishop
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU Affero General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Affero General Public License for more details.
19
20 You should have received a copy of the GNU Affero General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ***************************************/
23
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <stdio.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32
33 #include "types.h"
34 #include "functions.h"
35 #include "nodes.h"
36 #include "segments.h"
37 #include "ways.h"
38 #include "results.h"
39
40
41 /*+ The option to calculate the quickest route insted of the shortest. +*/
42 extern int option_quickest;
43
44 /*+ The files to write to. +*/
45 static FILE *gpxtrackfile=NULL,*gpxroutefile=NULL,*textfile=NULL,*textallfile=NULL;
46
47 /*+ The final latitude, longitude point. +*/
48 static double finish_latitude,finish_longitude;
49
50 /*+ Heuristics for determining if a junction is important. +*/
51 static char junction_other_way[Way_Unknown][Way_Unknown]=
52 { /* M, T, P, S, T, U, R, S, T, P, B, C, F = Way type of route not taken */
53 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, /* Motorway */
54 { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Trunk */
55 { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Primary */
56 { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Secondary */
57 { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, /* Tertiary */
58 { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* Unclassified */
59 { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }, /* Residential */
60 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, /* Service */
61 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Track */
62 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Path */
63 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Bridleway */
64 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Cycleway */
65 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Footway */
66 };
67
68
69 /*++++++++++++++++++++++++++++++++++++++
70 Open the files and print the head.
71
72 const char *copyright The name of a file that might exist and contain copyright information.
73 ++++++++++++++++++++++++++++++++++++++*/
74
75 void PrintRouteHead(const char *copyright)
76 {
77 char *source=NULL,*license=NULL;
78
79 if(copyright)
80 {
81 struct stat buf;
82
83 if(!stat(copyright,&buf))
84 {
85 FILE *file=fopen(copyright,"r");
86 char *string=(char*)malloc(buf.st_size+1);
87 char *p;
88
89 fread(string,buf.st_size,1,file);
90 string[buf.st_size]=0;
91
92 p=string;
93 while(*p)
94 {
95 if(!strncmp(p,"Source:",7))
96 {
97 p+=7;
98 while(*p==' ' || *p=='t')
99 p++;
100 source=p;
101 while(*p && *p!='\r' && *p!='\n')
102 p++;
103 while(*p=='\r' || *p=='\n')
104 *p++=0;
105 }
106 else if(!strncmp(p,"License:",8) || !strncmp(p,"Licence:",8))
107 {
108 p+=8;
109 while(*p==' ' || *p=='t')
110 p++;
111 license=p;
112 while(*p && *p!='\r' && *p!='\n')
113 p++;
114 while(*p=='\r' || *p=='\n')
115 *p++=0;
116 }
117 else
118 {
119 while(*p && *p!='\r' && *p!='\n')
120 p++;
121 while(*p=='\r' || *p=='\n')
122 *p++=0;
123 }
124 }
125
126 fclose(file);
127 }
128 }
129
130 /* Open the files */
131
132 if(option_quickest==0)
133 {
134 /* Print the result for the shortest route */
135
136 gpxtrackfile=fopen("shortest-track.gpx","w");
137 gpxroutefile=fopen("shortest-route.gpx","w");
138 textfile =fopen("shortest.txt","w");
139 textallfile =fopen("shortest-all.txt","w");
140
141 if(!gpxtrackfile)
142 fprintf(stderr,"Warning: Cannot open file 'shortest-track.gpx' to write.\n");
143 if(!gpxroutefile)
144 fprintf(stderr,"Warning: Cannot open file 'shortest-route.gpx' to write.\n");
145 if(!textfile)
146 fprintf(stderr,"Warning: Cannot open file 'shortest.txt' to write.\n");
147 if(!textallfile)
148 fprintf(stderr,"Warning: Cannot open file 'shortest-all.txt' to write.\n");
149 }
150 else
151 {
152 /* Print the result for the quickest route */
153
154 gpxtrackfile=fopen("quickest-track.gpx","w");
155 gpxroutefile=fopen("quickest-route.gpx","w");
156 textfile =fopen("quickest.txt","w");
157 textallfile =fopen("quickest-all.txt","w");
158
159 if(!gpxtrackfile)
160 fprintf(stderr,"Warning: Cannot open file 'quickest-track.gpx' to write.\n");
161 if(!gpxroutefile)
162 fprintf(stderr,"Warning: Cannot open file 'quickest-route.gpx' to write.\n");
163 if(!textfile)
164 fprintf(stderr,"Warning: Cannot open file 'quickest.txt' to write.\n");
165 if(!textallfile)
166 fprintf(stderr,"Warning: Cannot open file 'quickest-all.txt' to write.\n");
167 }
168
169 /* Print the head of the files */
170
171 if(gpxtrackfile)
172 {
173 fprintf(gpxtrackfile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
174 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");
175
176 fprintf(gpxtrackfile,"<metadata>\n");
177 fprintf(gpxtrackfile,"<desc><![CDATA[%s route between 'start' and 'finish' waypoints]]></desc>\n",option_quickest?"Quickest":"Shortest");
178 if(source)
179 fprintf(gpxtrackfile,"<copyright author=\"%s\">\n",source);
180 if(license)
181 fprintf(gpxtrackfile,"<license>%s</license>\n",license);
182 if(source)
183 fprintf(gpxtrackfile,"</copyright>\n");
184 fprintf(gpxtrackfile,"</metadata>\n");
185
186 fprintf(gpxtrackfile,"<trk>\n");
187 }
188
189 if(gpxroutefile)
190 {
191 fprintf(gpxroutefile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
192 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");
193
194 fprintf(gpxroutefile,"<metadata>\n");
195 fprintf(gpxroutefile,"<desc><![CDATA[%s route between 'start' and 'finish' waypoints]]></desc>\n",option_quickest?"Quickest":"Shortest");
196 if(source)
197 fprintf(gpxroutefile,"<copyright author=\"%s\">\n",source);
198 if(license)
199 fprintf(gpxroutefile,"<license>%s</license>\n",license);
200 if(source)
201 fprintf(gpxroutefile,"</copyright>\n");
202 fprintf(gpxroutefile,"</metadata>\n");
203
204 fprintf(gpxroutefile,"<rte>\n");
205 fprintf(gpxroutefile,"<name>%s route</name>\n",option_quickest?"Quickest":"Shortest");
206 }
207
208 if(textfile)
209 {
210 if(source)
211 fprintf(textfile,"# Source: %s\n",source);
212 if(license)
213 fprintf(textfile,"# License: %s\n",license);
214 if(source || license)
215 fprintf(textfile,"#\n");
216 fprintf(textfile,"#Latitude\tLongitude\tSegment \tSegment \tTotal \tTotal \tHighway\n");
217 fprintf(textfile,"# \t \tDistance\tDuration\tDistance\tDurat'n\t \n");
218 /* "%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%3.0f min\t%s\n" */
219 }
220
221 if(textallfile)
222 {
223 if(source)
224 fprintf(textallfile,"# Source: %s\n",source);
225 if(license)
226 fprintf(textallfile,"# License: %s\n",license);
227 if(source || license)
228 fprintf(textallfile,"#\n");
229 fprintf(textallfile,"#Latitude\tLongitude\t Node\tSegment\tSegment\tTotal\tTotal \tSpeed\tHighway\n");
230 fprintf(textallfile,"# \t \t \tDist \tDurat'n\tDist \tDurat'n\t \t \n");
231 /* "%10.6f\t%11.6f\t%8d%c\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%s\n" */
232 }
233 }
234
235
236 /*++++++++++++++++++++++++++++++++++++++
237 Print the optimum route between two nodes.
238
239 Results *results The set of results to print.
240
241 Nodes *nodes The list of nodes.
242
243 Segments *segments The set of segments to use.
244
245 Ways *ways The list of ways.
246
247 Profile *profile The profile containing the transport type, speeds and allowed highways.
248 ++++++++++++++++++++++++++++++++++++++*/
249
250 void PrintRoute(Results *results,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile)
251 {
252 static distance_t cum_distance=0;
253 static duration_t cum_duration=0;
254 static int segment_count=0;
255 static int route_count=0;
256 double finish_lat,finish_lon;
257 double start_lat,start_lon;
258 distance_t junc_distance=0;
259 duration_t junc_duration=0;
260 Result *result;
261
262 fprintf(gpxtrackfile,"<trkseg>\n");
263
264 GetLatLong(nodes,results->start,&start_lat,&start_lon);
265 GetLatLong(nodes,results->finish,&finish_lat,&finish_lon);
266
267 result=FindResult(results,results->start);
268
269 do
270 {
271 double latitude,longitude;
272
273 GetLatLong(nodes,result->node,&latitude,&longitude);
274
275 if(gpxtrackfile)
276 fprintf(gpxtrackfile,"<trkpt lat=\"%.6f\" lon=\"%.6f\"/>\n",
277 radians_to_degrees(latitude),radians_to_degrees(longitude));
278
279 if(result->prev!=NO_NODE)
280 {
281 distance_t seg_distance=0;
282 duration_t seg_duration=0;
283 Segment *segment;
284 Way *resultway;
285 int other=0,change=0;
286
287 /* Get the properties of this segment */
288
289 resultway=LookupWay(ways,result->segment->way);
290
291 seg_distance+=DISTANCE(result->segment->distance);
292 seg_duration+=Duration(result->segment,resultway,profile);
293 junc_distance+=seg_distance;
294 junc_duration+=seg_duration;
295 cum_distance+=seg_distance;
296 cum_duration+=seg_duration;
297
298 /* Decide if this is an important junction */
299
300 segment=FirstSegment(segments,nodes,result->node);
301
302 do
303 {
304 index_t othernode=OtherNode(segment,result->node);
305
306 if(othernode!=result->prev)
307 if(IsNormalSegment(segment) && (!profile->oneway || !IsOnewayTo(segment,result->node)))
308 {
309 Way *way=LookupWay(ways,segment->way);
310
311 if(othernode==result->next) /* the next segment that we follow */
312 {
313 if(HIGHWAY(way->type)!=HIGHWAY(resultway->type))
314 change=1;
315 }
316 else /* a segment that we don't follow */
317 other+=junction_other_way[HIGHWAY(resultway->type)][HIGHWAY(way->type)];
318 }
319
320 segment=NextSegment(segments,segment,result->node);
321 }
322 while(segment);
323
324 /* Print out the junctions */
325
326 if(result->next==NO_NODE || other || change)
327 {
328 if(result->next!=NO_NODE)
329 {
330 if(gpxroutefile)
331 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>TRIP%03d</name></rtept>\n",
332 radians_to_degrees(latitude),radians_to_degrees(longitude),
333 ++route_count);
334 }
335 else
336 {
337 finish_latitude=latitude;
338 finish_longitude=longitude;
339 }
340
341 if(textfile)
342 fprintf(textfile,"%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%3.0f min\t%s\n",
343 radians_to_degrees(latitude),radians_to_degrees(longitude),
344 distance_to_km(junc_distance),duration_to_minutes(junc_duration),
345 distance_to_km(cum_distance),duration_to_minutes(cum_duration),
346 WayName(ways,resultway));
347
348 junc_distance=0;
349 junc_duration=0;
350 }
351
352 /* Print out all of the results */
353
354 if(textallfile)
355 fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%s\n",
356 radians_to_degrees(latitude),radians_to_degrees(longitude),
357 result->node,IsSuperNode(nodes,result->node)?'*':' ',
358 distance_to_km(seg_distance),duration_to_minutes(seg_duration),
359 distance_to_km(cum_distance),duration_to_minutes(cum_duration),
360 profile->speed[HIGHWAY(resultway->type)],WayName(ways,resultway));
361 }
362 else if(!cum_distance)
363 {
364 /* Print out the start points */
365
366 if(gpxroutefile)
367 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>START</name></rtept>\n",
368 radians_to_degrees(latitude),radians_to_degrees(longitude));
369
370 if(textfile)
371 fprintf(textfile,"%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%3.0f min\t\n",
372 radians_to_degrees(latitude),radians_to_degrees(longitude),
373 0.0,0.0,0.0,0.0);
374
375 if(textallfile)
376 fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%5.3f\t%5.2f\t%5.2f\t%5.1f\n",
377 radians_to_degrees(latitude),radians_to_degrees(longitude),
378 result->node,IsSuperNode(nodes,result->node)?'*':' ',
379 0.0,0.0,0.0,0.0);
380 }
381 else
382 {
383 /* Print out the intermediate points */
384
385 if(gpxroutefile)
386 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>INTER%d</name></rtept>\n",
387 radians_to_degrees(latitude),radians_to_degrees(longitude),
388 ++segment_count);
389 }
390
391 if(result->next!=NO_NODE)
392 result=FindResult(results,result->next);
393 else
394 result=NULL;
395 }
396 while(result);
397
398 if(gpxtrackfile)
399 fprintf(gpxtrackfile,"</trkseg>\n");
400 }
401
402
403 /*++++++++++++++++++++++++++++++++++++++
404 Print the tail and close the files.
405 ++++++++++++++++++++++++++++++++++++++*/
406
407 void PrintRouteTail(void)
408 {
409 /* Print the final point in the route */
410
411 if(gpxroutefile)
412 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>FINISH</name></rtept>\n",
413 radians_to_degrees(finish_latitude),radians_to_degrees(finish_longitude));
414
415 /* Print the tail of the files */
416
417 if(gpxtrackfile)
418 {
419 fprintf(gpxtrackfile,"</trk>\n");
420 fprintf(gpxtrackfile,"</gpx>\n");
421 }
422
423 if(gpxroutefile)
424 {
425 fprintf(gpxroutefile,"</rte>\n");
426 fprintf(gpxroutefile,"</gpx>\n");
427 }
428
429 /* Close the files */
430
431 if(gpxtrackfile)
432 fclose(gpxtrackfile);
433 if(gpxroutefile)
434 fclose(gpxroutefile);
435 if(textfile)
436 fclose(textfile);
437 if(textallfile)
438 fclose(textallfile);
439 }

Properties

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