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 174 - (show annotations) (download) (as text)
Wed May 13 18:34:35 2009 UTC (15 years, 10 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 /***************************************
2 $Header: /home/amb/CVS/routino/src/output.c,v 1.6 2009-05-13 18:34:35 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 float 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 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 /* Print the head of the files */
152
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 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 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 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 fprintf(gpxroutefile,"</metadata>\n");
180
181 fprintf(gpxroutefile,"<rte>\n");
182 fprintf(gpxroutefile,"<name>%s route</name>\n",option_quickest?"Quickest":"Shortest");
183
184 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 fprintf(textfile,"#Latitude\tLongitude\tSegment \tSegment \tTotal \tTotal \tHighway\n");
191 fprintf(textfile,"# \t \tDistance\tDuration\tDistance\tDurat'n\t \n");
192 /* "%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
194 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 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 /* "%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
205
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 void PrintRoute(Results *results,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile)
221 {
222 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 float finish_lat,finish_lon;
227 float start_lat,start_lon;
228 distance_t junc_distance=0;
229 duration_t junc_duration=0;
230 Result *result;
231
232 fprintf(gpxtrackfile,"<trkseg>\n");
233
234 GetLatLong(nodes,results->start,&start_lat,&start_lon);
235 GetLatLong(nodes,results->finish,&finish_lat,&finish_lon);
236
237 result=FindResult(results,results->start);
238
239 do
240 {
241 float latitude,longitude;
242
243 GetLatLong(nodes,result->node,&latitude,&longitude);
244
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 distance_t seg_distance=0;
251 duration_t seg_duration=0;
252 Segment *segment;
253 Way *resultway;
254 int other=0,change=0;
255
256 /* 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 segment=FirstSegment(segments,nodes,result->node);
270
271 do
272 {
273 index_t othernode=NODE(OtherNode(segment,result->node));
274
275 if(othernode!=result->prev)
276 if(IsNormalSegment(segment) && (!profile->oneway || !IsOnewayTo(segment,result->node)))
277 {
278 Way *way=LookupWay(ways,segment->way);
279
280 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 }
289
290 segment=NextSegment(segments,segment,result->node);
291 }
292 while(segment);
293
294 /* Print out the junctions */
295
296 if(!result->next || other || change)
297 {
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 ++route_count);
302 else
303 {
304 finish_latitude=latitude;
305 finish_longitude=longitude;
306 }
307
308 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 (180/M_PI)*latitude,(180/M_PI)*longitude,
310 distance_to_km(junc_distance),duration_to_minutes(junc_duration),
311 distance_to_km(cum_distance),duration_to_minutes(cum_duration),
312 WayName(ways,resultway));
313
314 junc_distance=0;
315 junc_duration=0;
316 }
317
318 /* Print out all of the results */
319
320 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 result->node,IsSuperNode(nodes,result->node)?'*':' ',
323 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 }
327 else if(!cum_distance)
328 {
329 /* Print out the start points */
330
331 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 result->node,IsSuperNode(nodes,result->node)?'*':' ',
341 0.0,0.0,0.0,0.0);
342 }
343 else
344 {
345 /* Print out the intermediate points */
346
347 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
352 if(result->next)
353 result=FindResult(results,result->next);
354 else
355 result=NULL;
356 }
357 while(result);
358
359 fprintf(gpxtrackfile,"</trkseg>\n");
360 }
361
362
363 /*++++++++++++++++++++++++++++++++++++++
364 Print the tail and close the files.
365 ++++++++++++++++++++++++++++++++++++++*/
366
367 void PrintRouteTail(void)
368 {
369 /* 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 /* Print the tail of the files */
375
376 fprintf(gpxtrackfile,"</trk>\n");
377 fprintf(gpxtrackfile,"</gpx>\n");
378
379 fprintf(gpxroutefile,"</rte>\n");
380 fprintf(gpxroutefile,"</gpx>\n");
381
382 /* Close the files */
383
384 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.