Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/router.c
Parent Directory
|
Revision Log
Revision 239 -
(hide annotations)
(download)
(as text)
Sat Aug 15 15:28:27 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 10936 byte(s)
Sat Aug 15 15:28:27 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 10936 byte(s)
Remove the --all, --super and --no-output command line options. Handle the renamed routing functions.
1 | amb | 2 | /*************************************** |
2 | amb | 239 | $Header: /home/amb/CVS/routino/src/router.c,v 1.57 2009-08-15 15:28:27 amb Exp $ |
3 | amb | 2 | |
4 | OSM router. | ||
5 | amb | 151 | |
6 | Part of the Routino routing software. | ||
7 | amb | 2 | ******************/ /****************** |
8 | amb | 151 | This file Copyright 2008,2009 Andrew M. Bishop |
9 | amb | 2 | |
10 | amb | 151 | 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 | amb | 2 | ***************************************/ |
23 | |||
24 | |||
25 | #include <stdio.h> | ||
26 | amb | 31 | #include <string.h> |
27 | amb | 2 | #include <stdlib.h> |
28 | amb | 130 | #include <ctype.h> |
29 | amb | 2 | |
30 | amb | 96 | #include "types.h" |
31 | amb | 2 | #include "functions.h" |
32 | amb | 82 | #include "profiles.h" |
33 | amb | 115 | #include "nodes.h" |
34 | #include "segments.h" | ||
35 | amb | 109 | #include "ways.h" |
36 | amb | 2 | |
37 | |||
38 | amb | 113 | /*+ The option not to print any progress information. +*/ |
39 | amb | 107 | int option_quiet=0; |
40 | |||
41 | amb | 113 | /*+ The option to calculate the quickest route insted of the shortest. +*/ |
42 | int option_quickest=0; | ||
43 | amb | 107 | |
44 | amb | 113 | |
45 | amb | 2 | int main(int argc,char** argv) |
46 | { | ||
47 | amb | 95 | Nodes *OSMNodes; |
48 | Segments *OSMSegments; | ||
49 | Ways *OSMWays; | ||
50 | amb | 166 | Results *results[10]={NULL}; |
51 | int point_used[10]={0}; | ||
52 | amb | 219 | double point_lon[10],point_lat[10]; |
53 | amb | 165 | int help_profile=0,help_profile_js=0,help_profile_pl=0; |
54 | amb | 95 | char *dirname=NULL,*prefix=NULL,*filename; |
55 | amb | 82 | Transport transport=Transport_None; |
56 | Profile profile; | ||
57 | amb | 176 | index_t start=NO_NODE,finish=NO_NODE; |
58 | amb | 165 | int arg,node; |
59 | amb | 2 | |
60 | amb | 44 | /* Parse the command line arguments */ |
61 | amb | 2 | |
62 | amb | 145 | if(argc<2) |
63 | amb | 2 | { |
64 | amb | 44 | usage: |
65 | amb | 75 | |
66 | amb | 165 | fprintf(stderr,"Usage: router [--lon1=]<longitude> [--lat1=]<latitude>\n" |
67 | " [--lon2=]<longitude> [--lon2=]<latitude>\n" | ||
68 | " [ ... [--lon9=]<longitude> [--lon9=]<latitude> ]\n" | ||
69 | amb | 145 | " [--help | --help-profile | --help-profile-js | --help-profile-pl]\n" |
70 | amb | 101 | " [--dir=<name>] [--prefix=<name>]\n" |
71 | amb | 122 | " [--shortest | --quickest]\n" |
72 | amb | 239 | " [--quiet]\n" |
73 | amb | 101 | " [--transport=<transport>]\n" |
74 | amb | 166 | " [--highway-<highway>=<preference> ...]\n" |
75 | amb | 101 | " [--speed-<highway>=<speed> ...]\n" |
76 | amb | 130 | " [--oneway=[0|1]]\n" |
77 | amb | 135 | " [--weight=<weight>]\n" |
78 | " [--height=<height>] [--width=<width>] [--length=<length>]\n" | ||
79 | amb | 75 | "\n" |
80 | amb | 82 | "<transport> defaults to motorcar but can be set to:\n" |
81 | amb | 75 | "%s" |
82 | "\n" | ||
83 | amb | 82 | "<highway> can be selected from:\n" |
84 | "%s" | ||
85 | amb | 103 | "\n" |
86 | amb | 166 | "<preference> is a preference expressed as a percentage\n" |
87 | amb | 82 | "<speed> is a speed in km/hour\n" |
88 | amb | 135 | "<weight> is a weight in tonnes\n" |
89 | "<height>, <width>, <length> are dimensions in metres\n" | ||
90 | amb | 82 | "\n", |
91 | amb | 75 | TransportList(),HighwayList()); |
92 | |||
93 | amb | 2 | return(1); |
94 | } | ||
95 | |||
96 | amb | 130 | /* Get the transport type if specified and fill in the default profile */ |
97 | amb | 75 | |
98 | amb | 165 | for(arg=1;arg<argc;arg++) |
99 | if(!strncmp(argv[arg],"--transport=",12)) | ||
100 | amb | 82 | { |
101 | amb | 165 | transport=TransportType(&argv[arg][12]); |
102 | amb | 75 | |
103 | amb | 82 | if(transport==Transport_None) |
104 | goto usage; | ||
105 | } | ||
106 | |||
107 | if(transport==Transport_None) | ||
108 | transport=Transport_Motorcar; | ||
109 | |||
110 | profile=*GetProfile(transport); | ||
111 | |||
112 | /* Parse the other command line arguments */ | ||
113 | |||
114 | amb | 165 | for(arg=1;arg<argc;arg++) |
115 | amb | 44 | { |
116 | amb | 165 | if(isdigit(argv[arg][0]) || |
117 | ((argv[arg][0]=='-' || argv[arg][0]=='+') && isdigit(argv[arg][1]))) | ||
118 | amb | 130 | { |
119 | amb | 166 | for(node=1;node<sizeof(point_used)/sizeof(point_used[0]);node++) |
120 | amb | 165 | if(point_used[node]!=3) |
121 | { | ||
122 | if(point_used[node]==0) | ||
123 | { | ||
124 | amb | 198 | point_lon[node]=degrees_to_radians(atof(argv[arg])); |
125 | amb | 165 | point_used[node]=1; |
126 | } | ||
127 | else /* if(point_used[node]==1) */ | ||
128 | { | ||
129 | amb | 198 | point_lat[node]=degrees_to_radians(atof(argv[arg])); |
130 | amb | 165 | point_used[node]=3; |
131 | } | ||
132 | break; | ||
133 | } | ||
134 | } | ||
135 | else if(!strncmp(argv[arg],"--lon",5) && isdigit(argv[arg][5]) && argv[arg][6]=='=') | ||
136 | { | ||
137 | node=atoi(&argv[arg][5]); | ||
138 | if(point_used[node]&1) | ||
139 | amb | 130 | goto usage; |
140 | amb | 198 | point_lon[node]=degrees_to_radians(atof(&argv[arg][7])); |
141 | amb | 165 | point_used[node]+=1; |
142 | amb | 130 | } |
143 | amb | 165 | else if(!strncmp(argv[arg],"--lat",5) && isdigit(argv[arg][5]) && argv[arg][6]=='=') |
144 | { | ||
145 | node=atoi(&argv[arg][5]); | ||
146 | if(point_used[node]&2) | ||
147 | goto usage; | ||
148 | amb | 198 | point_lat[node]=degrees_to_radians(atof(&argv[arg][7])); |
149 | amb | 165 | point_used[node]+=2; |
150 | } | ||
151 | else if(!strcmp(argv[arg],"--help")) | ||
152 | amb | 75 | goto usage; |
153 | amb | 165 | else if(!strcmp(argv[arg],"--help-profile")) |
154 | amb | 82 | help_profile=1; |
155 | amb | 165 | else if(!strcmp(argv[arg],"--help-profile-js")) |
156 | amb | 129 | help_profile_js=1; |
157 | amb | 165 | else if(!strcmp(argv[arg],"--help-profile-pl")) |
158 | amb | 145 | help_profile_pl=1; |
159 | amb | 165 | else if(!strncmp(argv[arg],"--dir=",6)) |
160 | dirname=&argv[arg][6]; | ||
161 | else if(!strncmp(argv[arg],"--prefix=",9)) | ||
162 | prefix=&argv[arg][9]; | ||
163 | else if(!strcmp(argv[arg],"--shortest")) | ||
164 | amb | 113 | option_quickest=0; |
165 | amb | 165 | else if(!strcmp(argv[arg],"--quickest")) |
166 | amb | 113 | option_quickest=1; |
167 | amb | 165 | else if(!strcmp(argv[arg],"--quiet")) |
168 | amb | 107 | option_quiet=1; |
169 | amb | 165 | else if(!strncmp(argv[arg],"--transport=",12)) |
170 | amb | 82 | ; /* Done this already*/ |
171 | amb | 165 | else if(!strncmp(argv[arg],"--highway-",10)) |
172 | amb | 75 | { |
173 | amb | 130 | Highway highway; |
174 | amb | 165 | char *equal=strchr(argv[arg],'='); |
175 | amb | 130 | char *string; |
176 | amb | 82 | |
177 | amb | 130 | if(!equal) |
178 | goto usage; | ||
179 | |||
180 | amb | 165 | string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+10); |
181 | string[equal-argv[arg]-10]=0; | ||
182 | amb | 130 | |
183 | highway=HighwayType(string); | ||
184 | |||
185 | free(string); | ||
186 | |||
187 | amb | 82 | if(highway==Way_Unknown) |
188 | goto usage; | ||
189 | |||
190 | amb | 166 | profile.highway[highway]=atof(equal+1); |
191 | amb | 75 | } |
192 | amb | 165 | else if(!strncmp(argv[arg],"--speed-",8)) |
193 | amb | 82 | { |
194 | Highway highway; | ||
195 | amb | 165 | char *equal=strchr(argv[arg],'='); |
196 | amb | 82 | char *string; |
197 | |||
198 | if(!equal) | ||
199 | goto usage; | ||
200 | |||
201 | amb | 165 | string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+8); |
202 | string[equal-argv[arg]-8]=0; | ||
203 | amb | 82 | |
204 | highway=HighwayType(string); | ||
205 | |||
206 | free(string); | ||
207 | |||
208 | if(highway==Way_Unknown) | ||
209 | goto usage; | ||
210 | |||
211 | amb | 166 | profile.speed[highway]=kph_to_speed(atof(equal+1)); |
212 | amb | 82 | } |
213 | amb | 165 | else if(!strncmp(argv[arg],"--oneway=",9)) |
214 | amb | 166 | profile.oneway=!!atoi(&argv[arg][9]); |
215 | amb | 165 | else if(!strncmp(argv[arg],"--weight=",9)) |
216 | profile.weight=tonnes_to_weight(atof(&argv[arg][9])); | ||
217 | else if(!strncmp(argv[arg],"--height=",9)) | ||
218 | profile.height=metres_to_height(atof(&argv[arg][9])); | ||
219 | else if(!strncmp(argv[arg],"--width=",8)) | ||
220 | profile.width=metres_to_width(atof(&argv[arg][8])); | ||
221 | else if(!strncmp(argv[arg],"--length=",9)) | ||
222 | profile.length=metres_to_length(atof(&argv[arg][9])); | ||
223 | amb | 44 | else |
224 | goto usage; | ||
225 | } | ||
226 | |||
227 | amb | 165 | for(node=0;node<sizeof(point_used)/sizeof(point_used[0]);node++) |
228 | if(point_used[node]==1 || point_used[node]==2) | ||
229 | goto usage; | ||
230 | |||
231 | amb | 82 | if(help_profile) |
232 | { | ||
233 | PrintProfile(&profile); | ||
234 | |||
235 | return(0); | ||
236 | } | ||
237 | amb | 129 | else if(help_profile_js) |
238 | { | ||
239 | PrintProfilesJS(); | ||
240 | amb | 82 | |
241 | amb | 129 | return(0); |
242 | } | ||
243 | amb | 145 | else if(help_profile_pl) |
244 | { | ||
245 | PrintProfilesPerl(); | ||
246 | amb | 129 | |
247 | amb | 145 | return(0); |
248 | } | ||
249 | |||
250 | amb | 166 | UpdateProfile(&profile); |
251 | |||
252 | amb | 2 | /* Load in the data */ |
253 | |||
254 | amb | 162 | OSMNodes=LoadNodeList(filename=FileName(dirname,prefix,"nodes.mem")); |
255 | amb | 95 | |
256 | amb | 100 | if(!OSMNodes) |
257 | { | ||
258 | amb | 227 | fprintf(stderr,"Error: Cannot open nodes file '%s'.\n",filename); |
259 | amb | 100 | return(1); |
260 | } | ||
261 | |||
262 | amb | 162 | OSMSegments=LoadSegmentList(filename=FileName(dirname,prefix,"segments.mem")); |
263 | amb | 66 | |
264 | amb | 100 | if(!OSMSegments) |
265 | { | ||
266 | amb | 227 | fprintf(stderr,"Error: Cannot open segments file '%s'.\n",filename); |
267 | amb | 100 | return(1); |
268 | } | ||
269 | |||
270 | amb | 162 | OSMWays=LoadWayList(filename=FileName(dirname,prefix,"ways.mem")); |
271 | amb | 31 | |
272 | amb | 100 | if(!OSMWays) |
273 | { | ||
274 | amb | 227 | fprintf(stderr,"Error: Cannot open ways file '%s'.\n",filename); |
275 | amb | 100 | return(1); |
276 | } | ||
277 | |||
278 | amb | 165 | /* Loop through all pairs of nodes */ |
279 | amb | 99 | |
280 | amb | 166 | for(node=1;node<sizeof(point_used)/sizeof(point_used[0]);node++) |
281 | amb | 107 | { |
282 | amb | 239 | Results *begin,*end; |
283 | amb | 165 | distance_t dist=km_to_distance(10); |
284 | amb | 99 | |
285 | amb | 165 | if(point_used[node]!=3) |
286 | continue; | ||
287 | amb | 107 | |
288 | amb | 165 | /* Find the node */ |
289 | amb | 107 | |
290 | amb | 174 | start=finish; |
291 | amb | 165 | |
292 | amb | 179 | finish=FindNode(OSMNodes,OSMSegments,OSMWays,point_lat[node],point_lon[node],&dist,&profile); |
293 | amb | 165 | |
294 | amb | 176 | if(finish==NO_NODE) |
295 | amb | 107 | { |
296 | amb | 227 | fprintf(stderr,"Error: Cannot find node close to specified point %d.\n",node); |
297 | amb | 107 | return(1); |
298 | } | ||
299 | |||
300 | if(!option_quiet) | ||
301 | { | ||
302 | amb | 219 | double lat,lon; |
303 | amb | 107 | |
304 | amb | 174 | GetLatLong(OSMNodes,finish,&lat,&lon); |
305 | amb | 107 | |
306 | amb | 198 | printf("Node %d: %3.6f %4.6f = %2.3f km\n",node,radians_to_degrees(lon),radians_to_degrees(lat),distance_to_km(dist)); |
307 | amb | 107 | } |
308 | |||
309 | amb | 176 | if(start==NO_NODE) |
310 | amb | 165 | continue; |
311 | |||
312 | amb | 239 | /* Calculate the beginning of the route */ |
313 | amb | 165 | |
314 | amb | 239 | if(IsSuperNode(OSMNodes,start)) |
315 | amb | 126 | { |
316 | amb | 239 | Result *result; |
317 | amb | 107 | |
318 | amb | 239 | begin=NewResultsList(1); |
319 | amb | 97 | |
320 | amb | 239 | begin->start=start; |
321 | |||
322 | result=InsertResult(begin,start); | ||
323 | |||
324 | ZeroResult(result); | ||
325 | } | ||
326 | else | ||
327 | amb | 77 | { |
328 | amb | 239 | begin=FindStartRoutes(OSMNodes,OSMSegments,OSMWays,start,&profile); |
329 | amb | 2 | |
330 | amb | 239 | if(!begin) |
331 | amb | 112 | { |
332 | amb | 239 | fprintf(stderr,"Error: Cannot find initial section of route compatible with profile.\n"); |
333 | amb | 112 | return(1); |
334 | } | ||
335 | } | ||
336 | amb | 239 | |
337 | if(FindResult(begin,finish)) | ||
338 | { | ||
339 | results[node]=begin; | ||
340 | |||
341 | results[node]->finish=finish; | ||
342 | } | ||
343 | amb | 34 | else |
344 | { | ||
345 | amb | 239 | Results *superresults; |
346 | amb | 48 | |
347 | amb | 239 | /* Calculate the end of the route */ |
348 | amb | 34 | |
349 | amb | 239 | if(IsSuperNode(OSMNodes,finish)) |
350 | amb | 34 | { |
351 | Result *result; | ||
352 | |||
353 | amb | 239 | end=NewResultsList(1); |
354 | amb | 34 | |
355 | amb | 239 | end->finish=finish; |
356 | amb | 34 | |
357 | amb | 239 | result=InsertResult(end,finish); |
358 | amb | 165 | |
359 | amb | 166 | ZeroResult(result); |
360 | amb | 34 | } |
361 | else | ||
362 | amb | 112 | { |
363 | amb | 239 | end=FindFinishRoutes(OSMNodes,OSMSegments,OSMWays,finish,&profile); |
364 | amb | 34 | |
365 | amb | 239 | if(!end) |
366 | amb | 112 | { |
367 | amb | 239 | fprintf(stderr,"Error: Cannot find final section of route compatible with profile.\n"); |
368 | amb | 112 | return(1); |
369 | } | ||
370 | } | ||
371 | |||
372 | amb | 239 | /* Calculate the middle of the route */ |
373 | |||
374 | superresults=FindMiddleRoute(OSMNodes,OSMSegments,OSMWays,begin,end,&profile); | ||
375 | |||
376 | if(!superresults) | ||
377 | amb | 165 | { |
378 | amb | 239 | fprintf(stderr,"Error: Cannot find route compatible with profile.\n"); |
379 | return(1); | ||
380 | amb | 165 | } |
381 | amb | 34 | |
382 | amb | 239 | results[node]=CombineRoutes(superresults,OSMNodes,OSMSegments,OSMWays,&profile); |
383 | amb | 34 | } |
384 | amb | 31 | } |
385 | |||
386 | amb | 239 | /* Print out the combined route */ |
387 | amb | 164 | |
388 | amb | 239 | PrintRouteHead(FileName(dirname,prefix,"copyright.txt")); |
389 | amb | 164 | |
390 | amb | 239 | for(node=1;node<sizeof(point_used)/sizeof(point_used[0]);node++) |
391 | if(results[node]) | ||
392 | PrintRoute(results[node],OSMNodes,OSMSegments,OSMWays,&profile); | ||
393 | amb | 164 | |
394 | amb | 239 | PrintRouteTail(); |
395 | |||
396 | amb | 2 | return(0); |
397 | } |
Properties
Name | Value |
---|---|
cvs:description | Router. |