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 300 - (hide annotations) (download) (as text)
Tue Nov 3 18:44:30 2009 UTC (15 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 14567 byte(s)
Rename Way_Unknown to Way_Count to make more sense and match the properties.

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

Properties

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