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