Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /trunk/src/output.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 228 - (hide 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 amb 160 /***************************************
2 amb 228 $Header: /home/amb/CVS/routino/src/output.c,v 1.12 2009-07-12 09:01:48 amb Exp $
3 amb 160
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 amb 165 #include <stdlib.h>
26 amb 160 #include <string.h>
27 amb 164 #include <ctype.h>
28 amb 160 #include <stdio.h>
29 amb 164 #include <sys/types.h>
30     #include <sys/stat.h>
31     #include <unistd.h>
32 amb 160
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 amb 164 /*+ The files to write to. +*/
45     static FILE *gpxtrackfile=NULL,*gpxroutefile=NULL,*textfile=NULL,*textallfile=NULL;
46 amb 160
47 amb 171 /*+ The final latitude, longitude point. +*/
48 amb 219 static double finish_latitude,finish_longitude;
49 amb 164
50 amb 171 /*+ 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 amb 165
68 amb 171
69 amb 160 /*++++++++++++++++++++++++++++++++++++++
70 amb 164 Open the files and print the head.
71 amb 160
72 amb 164 const char *copyright The name of a file that might exist and contain copyright information.
73     ++++++++++++++++++++++++++++++++++++++*/
74 amb 160
75 amb 164 void PrintRouteHead(const char *copyright)
76     {
77     char *source=NULL,*license=NULL;
78 amb 160
79 amb 164 if(copyright)
80     {
81     struct stat buf;
82 amb 160
83 amb 164 if(!stat(copyright,&buf))
84     {
85     FILE *file=fopen(copyright,"r");
86     char *string=(char*)malloc(buf.st_size+1);
87     char *p;
88 amb 160
89 amb 164 fread(string,buf.st_size,1,file);
90     string[buf.st_size]=0;
91 amb 160
92 amb 164 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 amb 160
126 amb 164 fclose(file);
127     }
128     }
129 amb 160
130 amb 164 /* Open the files */
131 amb 160
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 amb 177
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 amb 160 }
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 amb 177
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 amb 160 }
168    
169 amb 164 /* Print the head of the files */
170 amb 160
171 amb 177 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 amb 160
176 amb 177 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 amb 160
186 amb 177 fprintf(gpxtrackfile,"<trk>\n");
187     }
188 amb 160
189 amb 177 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 amb 160
194 amb 177 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 amb 160
204 amb 177 fprintf(gpxroutefile,"<rte>\n");
205     fprintf(gpxroutefile,"<name>%s route</name>\n",option_quickest?"Quickest":"Shortest");
206     }
207 amb 160
208 amb 177 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 amb 160
221 amb 177 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 amb 164 }
234 amb 160
235 amb 164
236     /*++++++++++++++++++++++++++++++++++++++
237     Print the optimum route between two nodes.
238    
239 amb 228 Results *results The set of results to print.
240 amb 164
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 amb 165 void PrintRoute(Results *results,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile)
251 amb 164 {
252 amb 165 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 amb 219 double finish_lat,finish_lon;
257     double start_lat,start_lon;
258 amb 165 distance_t junc_distance=0;
259     duration_t junc_duration=0;
260 amb 164 Result *result;
261    
262 amb 165 fprintf(gpxtrackfile,"<trkseg>\n");
263 amb 164
264 amb 174 GetLatLong(nodes,results->start,&start_lat,&start_lon);
265     GetLatLong(nodes,results->finish,&finish_lat,&finish_lon);
266 amb 160
267 amb 165 result=FindResult(results,results->start);
268    
269 amb 160 do
270     {
271 amb 219 double latitude,longitude;
272 amb 160
273 amb 174 GetLatLong(nodes,result->node,&latitude,&longitude);
274 amb 160
275 amb 177 if(gpxtrackfile)
276     fprintf(gpxtrackfile,"<trkpt lat=\"%.6f\" lon=\"%.6f\"/>\n",
277 amb 198 radians_to_degrees(latitude),radians_to_degrees(longitude));
278 amb 160
279 amb 176 if(result->prev!=NO_NODE)
280 amb 160 {
281 amb 171 distance_t seg_distance=0;
282     duration_t seg_duration=0;
283     Segment *segment;
284     Way *resultway;
285     int other=0,change=0;
286 amb 160
287 amb 171 /* 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 amb 174 segment=FirstSegment(segments,nodes,result->node);
301 amb 160
302 amb 169 do
303     {
304 amb 175 index_t othernode=OtherNode(segment,result->node);
305 amb 171
306     if(othernode!=result->prev)
307 amb 169 if(IsNormalSegment(segment) && (!profile->oneway || !IsOnewayTo(segment,result->node)))
308     {
309 amb 171 Way *way=LookupWay(ways,segment->way);
310 amb 160
311 amb 171 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 amb 177 other+=junction_other_way[HIGHWAY(resultway->type)][HIGHWAY(way->type)];
318 amb 169 }
319 amb 160
320 amb 169 segment=NextSegment(segments,segment,result->node);
321     }
322     while(segment);
323    
324 amb 171 /* Print out the junctions */
325 amb 169
326 amb 176 if(result->next==NO_NODE || other || change)
327 amb 160 {
328 amb 176 if(result->next!=NO_NODE)
329 amb 177 {
330     if(gpxroutefile)
331     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>TRIP%03d</name></rtept>\n",
332 amb 198 radians_to_degrees(latitude),radians_to_degrees(longitude),
333 amb 177 ++route_count);
334     }
335 amb 160 else
336 amb 165 {
337     finish_latitude=latitude;
338     finish_longitude=longitude;
339     }
340 amb 160
341 amb 177 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 amb 198 radians_to_degrees(latitude),radians_to_degrees(longitude),
344 amb 177 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 amb 160
348 amb 165 junc_distance=0;
349     junc_duration=0;
350 amb 160 }
351    
352 amb 171 /* Print out all of the results */
353    
354 amb 177 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 amb 198 radians_to_degrees(latitude),radians_to_degrees(longitude),
357 amb 177 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 amb 160 }
362 amb 165 else if(!cum_distance)
363 amb 160 {
364 amb 171 /* Print out the start points */
365    
366 amb 177 if(gpxroutefile)
367     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>START</name></rtept>\n",
368 amb 198 radians_to_degrees(latitude),radians_to_degrees(longitude));
369 amb 160
370 amb 177 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 amb 198 radians_to_degrees(latitude),radians_to_degrees(longitude),
373 amb 177 0.0,0.0,0.0,0.0);
374 amb 160
375 amb 177 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 amb 198 radians_to_degrees(latitude),radians_to_degrees(longitude),
378 amb 177 result->node,IsSuperNode(nodes,result->node)?'*':' ',
379     0.0,0.0,0.0,0.0);
380 amb 160 }
381 amb 165 else
382     {
383 amb 171 /* Print out the intermediate points */
384    
385 amb 177 if(gpxroutefile)
386     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>INTER%d</name></rtept>\n",
387 amb 198 radians_to_degrees(latitude),radians_to_degrees(longitude),
388 amb 177 ++segment_count);
389 amb 165 }
390 amb 160
391 amb 176 if(result->next!=NO_NODE)
392 amb 160 result=FindResult(results,result->next);
393     else
394     result=NULL;
395     }
396     while(result);
397 amb 165
398 amb 177 if(gpxtrackfile)
399     fprintf(gpxtrackfile,"</trkseg>\n");
400 amb 164 }
401 amb 160
402 amb 164
403     /*++++++++++++++++++++++++++++++++++++++
404     Print the tail and close the files.
405     ++++++++++++++++++++++++++++++++++++++*/
406    
407     void PrintRouteTail(void)
408     {
409 amb 165 /* Print the final point in the route */
410    
411 amb 177 if(gpxroutefile)
412     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>FINISH</name></rtept>\n",
413 amb 198 radians_to_degrees(finish_latitude),radians_to_degrees(finish_longitude));
414 amb 165
415 amb 164 /* Print the tail of the files */
416    
417 amb 177 if(gpxtrackfile)
418     {
419     fprintf(gpxtrackfile,"</trk>\n");
420     fprintf(gpxtrackfile,"</gpx>\n");
421     }
422 amb 160
423 amb 177 if(gpxroutefile)
424     {
425     fprintf(gpxroutefile,"</rte>\n");
426     fprintf(gpxroutefile,"</gpx>\n");
427     }
428 amb 160
429 amb 164 /* Close the files */
430    
431 amb 177 if(gpxtrackfile)
432     fclose(gpxtrackfile);
433     if(gpxroutefile)
434     fclose(gpxroutefile);
435     if(textfile)
436     fclose(textfile);
437     if(textallfile)
438     fclose(textallfile);
439 amb 160 }

Properties

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