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 171 - (hide annotations) (download) (as text)
Wed May 13 17:45:41 2009 UTC (15 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 13122 byte(s)
Better junction detection.

1 amb 160 /***************************************
2 amb 171 $Header: /home/amb/CVS/routino/src/output.c,v 1.5 2009-05-13 17:45:41 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 165 GetLatLong(nodes,LookupNode(nodes,results->start),&start_lat,&start_lon);
235     GetLatLong(nodes,LookupNode(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     Node *node=LookupNode(nodes,result->node);
243    
244     GetLatLong(nodes,node,&latitude,&longitude);
245    
246     fprintf(gpxtrackfile,"<trkpt lat=\"%.6f\" lon=\"%.6f\"/>\n",
247     (180/M_PI)*latitude,(180/M_PI)*longitude);
248    
249     if(result->prev)
250     {
251 amb 171 distance_t seg_distance=0;
252     duration_t seg_duration=0;
253     Segment *segment;
254     Way *resultway;
255     int other=0,change=0;
256 amb 160
257 amb 171 /* Get the properties of this segment */
258    
259     resultway=LookupWay(ways,result->segment->way);
260    
261     seg_distance+=DISTANCE(result->segment->distance);
262     seg_duration+=Duration(result->segment,resultway,profile);
263     junc_distance+=seg_distance;
264     junc_duration+=seg_duration;
265     cum_distance+=seg_distance;
266     cum_duration+=seg_duration;
267    
268     /* Decide if this is an important junction */
269    
270 amb 169 segment=FirstSegment(segments,LookupNode(nodes,result->node));
271 amb 160
272 amb 169 do
273     {
274 amb 171 index_t othernode=NODE(OtherNode(segment,result->node));
275    
276     if(othernode!=result->prev)
277 amb 169 if(IsNormalSegment(segment) && (!profile->oneway || !IsOnewayTo(segment,result->node)))
278     {
279 amb 171 Way *way=LookupWay(ways,segment->way);
280 amb 160
281 amb 171 if(othernode==result->next) /* the next segment that we follow */
282     {
283     if(HIGHWAY(way->type)!=HIGHWAY(resultway->type))
284     change=1;
285     }
286     else /* a segment that we don't follow */
287     if(!(way->type&Way_Roundabout))
288     other+=junction_other_way[HIGHWAY(resultway->type)][HIGHWAY(way->type)];
289 amb 169 }
290 amb 160
291 amb 169 segment=NextSegment(segments,segment,result->node);
292     }
293     while(segment);
294    
295 amb 171 /* Print out the junctions */
296 amb 169
297 amb 171 if(!result->next || other || change)
298 amb 160 {
299     if(result->next)
300     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>TRIP%03d</name></rtept>\n",
301     (180/M_PI)*latitude,(180/M_PI)*longitude,
302 amb 165 ++route_count);
303 amb 160 else
304 amb 165 {
305     finish_latitude=latitude;
306     finish_longitude=longitude;
307     }
308 amb 160
309 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",
310 amb 160 (180/M_PI)*latitude,(180/M_PI)*longitude,
311 amb 165 distance_to_km(junc_distance),duration_to_minutes(junc_duration),
312 amb 171 distance_to_km(cum_distance),duration_to_minutes(cum_duration),
313     WayName(ways,resultway));
314 amb 160
315 amb 165 junc_distance=0;
316     junc_duration=0;
317 amb 160 }
318    
319 amb 171 /* Print out all of the results */
320    
321 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",
322     (180/M_PI)*latitude,(180/M_PI)*longitude,
323     result->node,IsSuperNode(node)?'*':' ',
324 amb 171 distance_to_km(seg_distance),duration_to_minutes(seg_duration),
325     distance_to_km(cum_distance),duration_to_minutes(cum_duration),
326     profile->speed[HIGHWAY(resultway->type)],WayName(ways,resultway));
327 amb 160 }
328 amb 165 else if(!cum_distance)
329 amb 160 {
330 amb 171 /* Print out the start points */
331    
332 amb 160 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>START</name></rtept>\n",
333     (180/M_PI)*latitude,(180/M_PI)*longitude);
334    
335     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",
336     (180/M_PI)*latitude,(180/M_PI)*longitude,
337     0.0,0.0,0.0,0.0);
338    
339     fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%5.3f\t%5.2f\t%5.2f\t%5.1f\n",
340     (180/M_PI)*latitude,(180/M_PI)*longitude,
341     result->node,IsSuperNode(node)?'*':' ',
342     0.0,0.0,0.0,0.0);
343     }
344 amb 165 else
345     {
346 amb 171 /* Print out the intermediate points */
347    
348 amb 165 fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>INTER%d</name></rtept>\n",
349     (180/M_PI)*latitude,(180/M_PI)*longitude,
350     ++segment_count);
351     }
352 amb 160
353     if(result->next)
354     result=FindResult(results,result->next);
355     else
356     result=NULL;
357     }
358     while(result);
359 amb 165
360     fprintf(gpxtrackfile,"</trkseg>\n");
361 amb 164 }
362 amb 160
363 amb 164
364     /*++++++++++++++++++++++++++++++++++++++
365     Print the tail and close the files.
366     ++++++++++++++++++++++++++++++++++++++*/
367    
368     void PrintRouteTail(void)
369     {
370 amb 165 /* Print the final point in the route */
371    
372     fprintf(gpxroutefile,"<rtept lat=\"%.6f\" lon=\"%.6f\"><name>FINISH</name></rtept>\n",
373     (180/M_PI)*finish_latitude,(180/M_PI)*finish_longitude);
374    
375 amb 164 /* Print the tail of the files */
376    
377 amb 160 fprintf(gpxtrackfile,"</trk>\n");
378     fprintf(gpxtrackfile,"</gpx>\n");
379    
380     fprintf(gpxroutefile,"</rte>\n");
381     fprintf(gpxroutefile,"</gpx>\n");
382    
383 amb 164 /* Close the files */
384    
385 amb 160 fclose(gpxtrackfile);
386     fclose(gpxroutefile);
387     fclose(textfile);
388     fclose(textallfile);
389     }

Properties

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