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 174 - (hide annotations) (download) (as text)
Wed May 13 18:34:35 2009 UTC (15 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 13063 byte(s)
Remove some node macros, change some node function arguments.

1 amb 160 /***************************************
2 amb 174 $Header: /home/amb/CVS/routino/src/output.c,v 1.6 2009-05-13 18:34:35 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 165 static float 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     }
141     else
142     {
143     /* Print the result for the quickest route */
144    
145     gpxtrackfile=fopen("quickest-track.gpx","w");
146     gpxroutefile=fopen("quickest-route.gpx","w");
147     textfile =fopen("quickest.txt","w");
148     textallfile =fopen("quickest-all.txt","w");
149     }
150    
151 amb 164 /* Print the head of the files */
152 amb 160
153     fprintf(gpxtrackfile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
154     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");
155    
156     fprintf(gpxtrackfile,"<metadata>\n");
157     fprintf(gpxtrackfile,"<desc><![CDATA[%s route between 'start' and 'finish' waypoints]]></desc>\n",option_quickest?"Quickest":"Shortest");
158 amb 164 if(source)
159     fprintf(gpxtrackfile,"<copyright author=\"%s\">\n",source);
160     if(license)
161     fprintf(gpxtrackfile,"<license>%s</license>\n",license);
162     if(source)
163     fprintf(gpxtrackfile,"</copyright>\n");
164 amb 160 fprintf(gpxtrackfile,"</metadata>\n");
165    
166     fprintf(gpxtrackfile,"<trk>\n");
167    
168     fprintf(gpxroutefile,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
169     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");
170    
171     fprintf(gpxroutefile,"<metadata>\n");
172     fprintf(gpxroutefile,"<desc><![CDATA[%s route between 'start' and 'finish' waypoints]]></desc>\n",option_quickest?"Quickest":"Shortest");
173 amb 164 if(source)
174     fprintf(gpxroutefile,"<copyright author=\"%s\">\n",source);
175     if(license)
176     fprintf(gpxroutefile,"<license>%s</license>\n",license);
177     if(source)
178     fprintf(gpxroutefile,"</copyright>\n");
179 amb 160 fprintf(gpxroutefile,"</metadata>\n");
180    
181     fprintf(gpxroutefile,"<rte>\n");
182     fprintf(gpxroutefile,"<name>%s route</name>\n",option_quickest?"Quickest":"Shortest");
183    
184 amb 164 if(source)
185     fprintf(textfile,"# Source: %s\n",source);
186     if(license)
187     fprintf(textfile,"# License: %s\n",license);
188     if(source || license)
189     fprintf(textfile,"#\n");
190 amb 160 fprintf(textfile,"#Latitude\tLongitude\tSegment \tSegment \tTotal \tTotal \tHighway\n");
191     fprintf(textfile,"# \t \tDistance\tDuration\tDistance\tDurat'n\t \n");
192 amb 164 /* "%10.6f\t%11.6f\t%5.3f km\t%5.1f min\t%5.1f km\t%3.0f min\t%s\n" */
193 amb 160
194 amb 164 if(source)
195     fprintf(textallfile,"# Source: %s\n",source);
196     if(license)
197     fprintf(textallfile,"# License: %s\n",license);
198     if(source || license)
199     fprintf(textallfile,"#\n");
200 amb 160 fprintf(textallfile,"#Latitude\tLongitude\t Node\tSegment\tSegment\tTotal\tTotal \tSpeed\tHighway\n");
201     fprintf(textallfile,"# \t \t \tDist \tDurat'n\tDist \tDurat'n\t \t \n");
202 amb 164 /* "%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" */
203     }
204 amb 160
205 amb 164
206     /*++++++++++++++++++++++++++++++++++++++
207     Print the optimum route between two nodes.
208    
209     Results *Results The set of results to print.
210    
211     Nodes *nodes The list of nodes.
212    
213     Segments *segments The set of segments to use.
214    
215     Ways *ways The list of ways.
216    
217     Profile *profile The profile containing the transport type, speeds and allowed highways.
218     ++++++++++++++++++++++++++++++++++++++*/
219    
220 amb 165 void PrintRoute(Results *results,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile)
221 amb 164 {
222 amb 165 static distance_t cum_distance=0;
223     static duration_t cum_duration=0;
224     static int segment_count=0;
225     static int route_count=0;
226 amb 164 float finish_lat,finish_lon;
227     float start_lat,start_lon;
228 amb 165 distance_t junc_distance=0;
229     duration_t junc_duration=0;
230 amb 164 Result *result;
231    
232 amb 165 fprintf(gpxtrackfile,"<trkseg>\n");
233 amb 164
234 amb 174 GetLatLong(nodes,results->start,&start_lat,&start_lon);
235     GetLatLong(nodes,results->finish,&finish_lat,&finish_lon);
236 amb 160
237 amb 165 result=FindResult(results,results->start);
238    
239 amb 160 do
240     {
241     float latitude,longitude;
242    
243 amb 174 GetLatLong(nodes,result->node,&latitude,&longitude);
244 amb 160
245     fprintf(gpxtrackfile,"<trkpt lat=\"%.6f\" lon=\"%.6f\"/>\n",
246     (180/M_PI)*latitude,(180/M_PI)*longitude);
247    
248     if(result->prev)
249     {
250 amb 171 distance_t seg_distance=0;
251     duration_t seg_duration=0;
252     Segment *segment;
253     Way *resultway;
254     int other=0,change=0;
255 amb 160
256 amb 171 /* Get the properties of this segment */
257    
258     resultway=LookupWay(ways,result->segment->way);
259    
260     seg_distance+=DISTANCE(result->segment->distance);
261     seg_duration+=Duration(result->segment,resultway,profile);
262     junc_distance+=seg_distance;
263     junc_duration+=seg_duration;
264     cum_distance+=seg_distance;
265     cum_duration+=seg_duration;
266    
267     /* Decide if this is an important junction */
268    
269 amb 174 segment=FirstSegment(segments,nodes,result->node);
270 amb 160
271 amb 169 do
272     {
273 amb 171 index_t othernode=NODE(OtherNode(segment,result->node));
274    
275     if(othernode!=result->prev)
276 amb 169 if(IsNormalSegment(segment) && (!profile->oneway || !IsOnewayTo(segment,result->node)))
277     {
278 amb 171 Way *way=LookupWay(ways,segment->way);
279 amb 160
280 amb 171 if(othernode==result->next) /* the next segment that we follow */
281     {
282     if(HIGHWAY(way->type)!=HIGHWAY(resultway->type))
283     change=1;
284     }
285     else /* a segment that we don't follow */
286     if(!(way->type&Way_Roundabout))
287     other+=junction_other_way[HIGHWAY(resultway->type)][HIGHWAY(way->type)];
288 amb 169 }
289 amb 160
290 amb 169 segment=NextSegment(segments,segment,result->node);
291     }
292     while(segment);
293    
294 amb 171 /* Print out the junctions */
295 amb 169
296 amb 171 if(!result->next || other || change)
297 amb 160 {
298     if(result->next)
299     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>TRIP%03d</name></rtept>\n",
300     (180/M_PI)*latitude,(180/M_PI)*longitude,
301 amb 165 ++route_count);
302 amb 160 else
303 amb 165 {
304     finish_latitude=latitude;
305     finish_longitude=longitude;
306     }
307 amb 160
308 amb 171 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",
309 amb 160 (180/M_PI)*latitude,(180/M_PI)*longitude,
310 amb 165 distance_to_km(junc_distance),duration_to_minutes(junc_duration),
311 amb 171 distance_to_km(cum_distance),duration_to_minutes(cum_duration),
312     WayName(ways,resultway));
313 amb 160
314 amb 165 junc_distance=0;
315     junc_duration=0;
316 amb 160 }
317    
318 amb 171 /* Print out all of the results */
319    
320 amb 160 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",
321     (180/M_PI)*latitude,(180/M_PI)*longitude,
322 amb 174 result->node,IsSuperNode(nodes,result->node)?'*':' ',
323 amb 171 distance_to_km(seg_distance),duration_to_minutes(seg_duration),
324     distance_to_km(cum_distance),duration_to_minutes(cum_duration),
325     profile->speed[HIGHWAY(resultway->type)],WayName(ways,resultway));
326 amb 160 }
327 amb 165 else if(!cum_distance)
328 amb 160 {
329 amb 171 /* Print out the start points */
330    
331 amb 160 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>START</name></rtept>\n",
332     (180/M_PI)*latitude,(180/M_PI)*longitude);
333    
334     fprintf(textfile,"%10.6f\t%11.6f\t%5.3f km\t%5.1f min\t%5.1f km\t%3.0f min\t\n",
335     (180/M_PI)*latitude,(180/M_PI)*longitude,
336     0.0,0.0,0.0,0.0);
337    
338     fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%5.3f\t%5.2f\t%5.2f\t%5.1f\n",
339     (180/M_PI)*latitude,(180/M_PI)*longitude,
340 amb 174 result->node,IsSuperNode(nodes,result->node)?'*':' ',
341 amb 160 0.0,0.0,0.0,0.0);
342     }
343 amb 165 else
344     {
345 amb 171 /* Print out the intermediate points */
346    
347 amb 165 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>INTER%d</name></rtept>\n",
348     (180/M_PI)*latitude,(180/M_PI)*longitude,
349     ++segment_count);
350     }
351 amb 160
352     if(result->next)
353     result=FindResult(results,result->next);
354     else
355     result=NULL;
356     }
357     while(result);
358 amb 165
359     fprintf(gpxtrackfile,"</trkseg>\n");
360 amb 164 }
361 amb 160
362 amb 164
363     /*++++++++++++++++++++++++++++++++++++++
364     Print the tail and close the files.
365     ++++++++++++++++++++++++++++++++++++++*/
366    
367     void PrintRouteTail(void)
368     {
369 amb 165 /* Print the final point in the route */
370    
371     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>FINISH</name></rtept>\n",
372     (180/M_PI)*finish_latitude,(180/M_PI)*finish_longitude);
373    
374 amb 164 /* Print the tail of the files */
375    
376 amb 160 fprintf(gpxtrackfile,"</trk>\n");
377     fprintf(gpxtrackfile,"</gpx>\n");
378    
379     fprintf(gpxroutefile,"</rte>\n");
380     fprintf(gpxroutefile,"</gpx>\n");
381    
382 amb 164 /* Close the files */
383    
384 amb 160 fclose(gpxtrackfile);
385     fclose(gpxroutefile);
386     fclose(textfile);
387     fclose(textallfile);
388     }

Properties

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