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