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/planetsplitter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 645 - (hide annotations) (download) (as text)
Sat Feb 26 19:26:03 2011 UTC (14 years ago) by amb
File MIME type: text/x-csrc
File size: 12812 byte(s)
Fixed the turn relations with a few more functions.

1 amb 2 /***************************************
2     OSM planet file splitter.
3 amb 151
4     Part of the Routino routing software.
5 amb 2 ******************/ /******************
6 amb 643 This file Copyright 2008-2011 Andrew M. Bishop
7 amb 2
8 amb 151 This program is free software: you can redistribute it and/or modify
9     it under the terms of the GNU Affero General Public License as published by
10     the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12    
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU Affero General Public License for more details.
17    
18     You should have received a copy of the GNU Affero General Public License
19     along with this program. If not, see <http://www.gnu.org/licenses/>.
20 amb 2 ***************************************/
21    
22    
23     #include <stdio.h>
24     #include <stdlib.h>
25 amb 60 #include <string.h>
26 amb 330 #include <errno.h>
27 amb 2
28 amb 449 #include "types.h"
29     #include "ways.h"
30    
31 amb 199 #include "typesx.h"
32 amb 109 #include "nodesx.h"
33     #include "segmentsx.h"
34     #include "waysx.h"
35 amb 498 #include "relationsx.h"
36 amb 109 #include "superx.h"
37 amb 449
38     #include "files.h"
39 amb 519 #include "logging.h"
40 amb 449 #include "functions.h"
41     #include "functionsx.h"
42 amb 395 #include "tagging.h"
43 amb 2
44    
45 amb 395 /* Global variables */
46 amb 284
47 amb 256 /*+ The name of the temporary directory. +*/
48 amb 284 char *option_tmpdirname=NULL;
49 amb 249
50 amb 358 /*+ The amount of RAM to use for filesorting. +*/
51     size_t option_filesort_ramsize=0;
52 amb 284
53 amb 358
54 amb 342 /* Local functions */
55    
56 amb 490 static void print_usage(int detail,const char *argerr,const char *err);
57 amb 342
58    
59     /*++++++++++++++++++++++++++++++++++++++
60 amb 395 The main program for the planetsplitter.
61 amb 342 ++++++++++++++++++++++++++++++++++++++*/
62    
63 amb 2 int main(int argc,char** argv)
64     {
65 amb 498 NodesX *Nodes;
66     SegmentsX *Segments,*SuperSegments=NULL,*MergedSegments=NULL;
67     WaysX *Ways;
68     RelationsX *Relations;
69     int iteration=0,quit=0;
70     int max_iterations=10;
71     char *dirname=NULL,*prefix=NULL,*tagging=NULL;
72     int option_parse_only=0,option_process_only=0;
73     int option_filenames=0;
74     int arg;
75 amb 26
76 amb 82 /* Parse the command line arguments */
77    
78 amb 327 for(arg=1;arg<argc;arg++)
79 amb 60 {
80 amb 327 if(!strcmp(argv[arg],"--help"))
81 amb 490 print_usage(1,NULL,NULL);
82 amb 358 else if(!strncmp(argv[arg],"--sort-ram-size=",16))
83     option_filesort_ramsize=atoi(&argv[arg][16]);
84 amb 327 else if(!strncmp(argv[arg],"--dir=",6))
85     dirname=&argv[arg][6];
86     else if(!strncmp(argv[arg],"--tmpdir=",9))
87     option_tmpdirname=&argv[arg][9];
88     else if(!strncmp(argv[arg],"--prefix=",9))
89     prefix=&argv[arg][9];
90     else if(!strcmp(argv[arg],"--parse-only"))
91 amb 326 option_parse_only=1;
92 amb 327 else if(!strcmp(argv[arg],"--process-only"))
93 amb 326 option_process_only=1;
94 amb 519 else if(!strcmp(argv[arg],"--loggable"))
95     option_loggable=1;
96 amb 327 else if(!strncmp(argv[arg],"--max-iterations=",17))
97     max_iterations=atoi(&argv[arg][17]);
98 amb 395 else if(!strncmp(argv[arg],"--tagging=",10))
99     tagging=&argv[arg][10];
100 amb 327 else if(argv[arg][0]=='-' && argv[arg][1]=='-')
101 amb 490 print_usage(0,argv[arg],NULL);
102 amb 327 else
103     option_filenames++;
104 amb 60 }
105 amb 26
106 amb 395 /* Check the specified command line options */
107    
108 amb 326 if(option_parse_only && option_process_only)
109 amb 490 print_usage(0,NULL,"Cannot use '--parse-only' and '--process-only' at the same time.");
110 amb 326
111 amb 327 if(option_filenames && option_process_only)
112 amb 490 print_usage(0,NULL,"Cannot use '--process-only' and filenames at the same time.");
113 amb 327
114 amb 358 if(!option_filesort_ramsize)
115     {
116 amb 452 #if SLIM
117 amb 358 option_filesort_ramsize=64*1024*1024;
118 amb 452 #else
119 amb 358 option_filesort_ramsize=256*1024*1024;
120 amb 452 #endif
121 amb 358 }
122     else
123     option_filesort_ramsize*=1024*1024;
124    
125 amb 284 if(!option_tmpdirname)
126 amb 252 {
127     if(!dirname)
128 amb 284 option_tmpdirname=".";
129 amb 252 else
130 amb 284 option_tmpdirname=dirname;
131 amb 252 }
132    
133 amb 481 if(tagging)
134 amb 395 {
135 amb 481 if(!ExistsFile(tagging))
136     {
137     fprintf(stderr,"Error: The '--tagging' option specifies a file that does not exist.\n");
138     return(1);
139     }
140 amb 395 }
141 amb 481 else
142     {
143     if(ExistsFile(FileName(dirname,prefix,"tagging.xml")))
144     tagging=FileName(dirname,prefix,"tagging.xml");
145     else if(ExistsFile(FileName(DATADIR,NULL,"tagging.xml")))
146     tagging=FileName(DATADIR,NULL,"tagging.xml");
147     else
148     {
149     fprintf(stderr,"Error: The '--tagging' option was not used and the default 'tagging.xml' does not exist.\n");
150     return(1);
151     }
152     }
153 amb 395
154 amb 481 if(ParseXMLTaggingRules(tagging))
155 amb 395 {
156 amb 481 fprintf(stderr,"Error: Cannot read the tagging rules in the file '%s'.\n",tagging);
157 amb 395 return(1);
158     }
159    
160 amb 498 /* Create new node, segment, way and relation variables */
161 amb 82
162 amb 326 Nodes=NewNodeList(option_parse_only||option_process_only);
163 amb 275
164 amb 326 Segments=NewSegmentList(option_parse_only||option_process_only);
165 amb 275
166 amb 326 Ways=NewWayList(option_parse_only||option_process_only);
167 amb 26
168 amb 498 Relations=NewRelationList(option_parse_only||option_process_only);
169    
170 amb 89 /* Parse the file */
171 amb 2
172 amb 327 if(option_filenames)
173 amb 326 {
174 amb 327 for(arg=1;arg<argc;arg++)
175     {
176     FILE *file;
177    
178     if(argv[arg][0]=='-' && argv[arg][1]=='-')
179     continue;
180    
181     file=fopen(argv[arg],"rb");
182    
183     if(!file)
184     {
185 amb 330 fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",argv[arg],strerror(errno));
186 amb 327 exit(EXIT_FAILURE);
187     }
188    
189     printf("\nParse OSM Data [%s]\n==============\n\n",argv[arg]);
190     fflush(stdout);
191    
192 amb 498 if(ParseOSM(file,Nodes,Segments,Ways,Relations))
193 amb 395 exit(EXIT_FAILURE);
194 amb 327
195     fclose(file);
196     }
197     }
198     else if(!option_process_only)
199     {
200 amb 326 printf("\nParse OSM Data\n==============\n\n");
201     fflush(stdout);
202 amb 2
203 amb 498 if(ParseOSM(stdin,Nodes,Segments,Ways,Relations))
204 amb 395 exit(EXIT_FAILURE);
205 amb 326 }
206 amb 80
207 amb 326 if(option_parse_only)
208     {
209     FreeNodeList(Nodes,1);
210     FreeSegmentList(Segments,1);
211     FreeWayList(Ways,1);
212 amb 498 FreeRelationList(Relations,1);
213 amb 326
214     return(0);
215     }
216    
217 amb 229 /* Process the data */
218    
219     printf("\nProcess OSM Data\n================\n\n");
220 amb 227 fflush(stdout);
221 amb 8
222 amb 498 /* Sort the nodes, segments, ways and relations */
223 amb 263
224     SortNodeList(Nodes);
225    
226 amb 275 SortSegmentList(Segments);
227 amb 80
228 amb 256 SortWayList(Ways);
229 amb 87
230 amb 559 SortRelationList(Relations);
231    
232 amb 549 /* Remove bad segments (must be after sorting the nodes and segments) */
233 amb 498
234 amb 549 RemoveBadSegments(Nodes,Segments);
235    
236     /* Remove non-highway nodes (must be after removing the bad segments) */
237    
238     RemoveNonHighwayNodes(Nodes,Segments);
239    
240 amb 542 /* Process the route and first part of turn relations (must be before compacting the ways) */
241 amb 498
242     ProcessRouteRelations(Relations,Ways);
243    
244 amb 645 ProcessTurnRelations1(Relations,Nodes,Ways);
245 amb 498
246 amb 499 /* Compact the ways (must be before measuring the segments) */
247    
248     CompactWayList(Ways);
249    
250 amb 279 /* Measure the segments and replace node/way id with index (must be after removing non-highway nodes) */
251 amb 247
252 amb 644 MeasureSegments(Segments,Nodes,Ways);
253 amb 66
254 amb 643 /* Index the segments */
255 amb 66
256 amb 643 IndexSegments(Segments,Nodes);
257    
258 amb 645 /* Convert the turn relations from ways into nodes */
259 amb 643
260 amb 645 ProcessTurnRelations2(Relations,Nodes,Segments,Ways);
261    
262    
263 amb 258 /* Repeated iteration on Super-Nodes and Super-Segments */
264 amb 58
265     do
266     {
267 amb 229 printf("\nProcess Super-Data (iteration %d)\n================================%s\n\n",iteration,iteration>9?"=":"");
268 amb 227 fflush(stdout);
269 amb 80
270 amb 90 if(iteration==0)
271     {
272     /* Select the super-nodes */
273 amb 58
274 amb 256 ChooseSuperNodes(Nodes,Segments,Ways);
275 amb 58
276 amb 90 /* Select the super-segments */
277 amb 58
278 amb 256 SuperSegments=CreateSuperSegments(Nodes,Segments,Ways,iteration);
279 amb 90 }
280     else
281     {
282 amb 97 SegmentsX *SuperSegments2;
283 amb 58
284 amb 90 /* Select the super-nodes */
285    
286 amb 256 ChooseSuperNodes(Nodes,SuperSegments,Ways);
287 amb 90
288     /* Select the super-segments */
289    
290 amb 256 SuperSegments2=CreateSuperSegments(Nodes,SuperSegments,Ways,iteration);
291 amb 90
292 amb 282 if(SuperSegments->xnumber==SuperSegments2->xnumber)
293 amb 104 quit=1;
294    
295 amb 326 FreeSegmentList(SuperSegments,0);
296 amb 90
297 amb 97 SuperSegments=SuperSegments2;
298 amb 90 }
299    
300 amb 275 /* Sort the super-segments */
301 amb 58
302 amb 275 SortSegmentList(SuperSegments);
303 amb 58
304 amb 229 /* Remove duplicated super-segments */
305    
306 amb 279 DeduplicateSegments(SuperSegments,Nodes,Ways);
307 amb 229
308 amb 643 /* Index the segments */
309    
310     IndexSegments(SuperSegments,Nodes);
311    
312     /* Check for end condition */
313    
314 amb 89 iteration++;
315 amb 58
316 amb 89 if(iteration>max_iterations)
317     quit=1;
318     }
319     while(!quit);
320 amb 58
321 amb 229 /* Combine the super-segments */
322    
323     printf("\nCombine Segments and Super-Segments\n===================================\n\n");
324 amb 227 fflush(stdout);
325 amb 58
326 amb 104 /* Merge the super-segments */
327    
328 amb 256 MergedSegments=MergeSuperSegments(Segments,SuperSegments);
329 amb 104
330 amb 326 FreeSegmentList(Segments,0);
331 amb 256
332 amb 326 FreeSegmentList(SuperSegments,0);
333 amb 58
334 amb 256 Segments=MergedSegments;
335 amb 90
336 amb 275 /* Sort the segments */
337 amb 258
338 amb 275 SortSegmentList(Segments);
339 amb 258
340 amb 643 /* Index the segments */
341 amb 275
342 amb 643 IndexSegments(Segments,Nodes);
343 amb 275
344 amb 229 /* Cross reference the nodes and segments */
345 amb 90
346 amb 229 printf("\nCross-Reference Nodes and Segments\n==================================\n\n");
347     fflush(stdout);
348 amb 90
349 amb 645 /* Fix the node indexes and convert nodes to segments */
350    
351     ProcessTurnRelations3(Relations,Segments);
352    
353 amb 212 /* Sort the node list geographically */
354 amb 209
355 amb 256 SortNodeListGeographically(Nodes);
356 amb 212
357 amb 643 /* Fix the node and segment indexes after sorting */
358 amb 212
359 amb 643 UpdateNodes(Nodes,Segments,iteration);
360 amb 645
361 amb 644 UpdateSegments(Segments,Nodes,Ways);
362 amb 212
363 amb 645 UpdateTurnRelations(Relations,Nodes);
364 amb 551
365 amb 559 SortTurnRelationList(Relations);
366 amb 551
367 amb 229 /* Output the results */
368    
369     printf("\nWrite Out Database Files\n========================\n\n");
370     fflush(stdout);
371    
372 amb 89 /* Write out the nodes */
373 amb 58
374 amb 256 SaveNodeList(Nodes,FileName(dirname,prefix,"nodes.mem"));
375 amb 95
376 amb 326 FreeNodeList(Nodes,0);
377 amb 226
378 amb 89 /* Write out the segments */
379 amb 58
380 amb 256 SaveSegmentList(Segments,FileName(dirname,prefix,"segments.mem"));
381 amb 58
382 amb 326 FreeSegmentList(Segments,0);
383 amb 226
384 amb 89 /* Write out the ways */
385 amb 58
386 amb 398 SaveWayList(Ways,FileName(dirname,prefix,"ways.mem"));
387 amb 58
388 amb 326 FreeWayList(Ways,0);
389 amb 226
390 amb 549 /* Write out the relations */
391    
392     SaveRelationList(Relations,FileName(dirname,prefix,"relations.mem"));
393    
394     FreeRelationList(Relations,0);
395    
396 amb 2 return(0);
397     }
398 amb 342
399    
400     /*++++++++++++++++++++++++++++++++++++++
401     Print out the usage information.
402    
403     int detail The level of detail to use - 0 = low, 1 = high.
404 amb 490
405     const char *argerr The argument that gave the error (if there is one).
406    
407     const char *err Other error message (if there is one).
408 amb 342 ++++++++++++++++++++++++++++++++++++++*/
409    
410 amb 490 static void print_usage(int detail,const char *argerr,const char *err)
411 amb 342 {
412     fprintf(stderr,
413     "Usage: planetsplitter [--help]\n"
414     " [--dir=<dirname>] [--prefix=<name>]\n"
415 amb 452 " [--sort-ram-size=<size>]\n"
416 amb 358 " [--tmpdir=<dirname>]\n"
417 amb 342 " [--parse-only | --process-only]\n"
418 amb 519 " [--loggable]\n"
419 amb 342 " [--max-iterations=<number>]\n"
420 amb 395 " [--tagging=<filename>]\n"
421 amb 342 " [<filename.osm> ...]\n");
422    
423 amb 490 if(argerr)
424     fprintf(stderr,
425     "\n"
426     "Error with command line parameter: %s\n",argerr);
427    
428 amb 491 if(err)
429 amb 490 fprintf(stderr,
430     "\n"
431     "Error: %s\n",err);
432    
433 amb 342 if(detail)
434     fprintf(stderr,
435     "\n"
436     "--help Prints this information.\n"
437     "\n"
438     "--dir=<dirname> The directory containing the routing database.\n"
439     "--prefix=<name> The filename prefix for the routing database.\n"
440     "\n"
441 amb 358 "--sort-ram-size=<size> The amount of RAM (in MB) to use for data sorting\n"
442 amb 452 #if SLIM
443     " (defaults to 64MB otherwise.)\n"
444     #else
445     " (defaults to 256MB otherwise.)\n"
446     #endif
447 amb 342 "--tmpdir=<dirname> The directory name for temporary files.\n"
448 amb 358 " (defaults to the '--dir' option directory.)\n"
449 amb 342 "\n"
450     "--parse-only Parse the input OSM files and store the results.\n"
451     "--process-only Process the stored results from previous option.\n"
452     "\n"
453 amb 519 "--loggable Print progress messages suitable for logging to file.\n"
454     "\n"
455 amb 342 "--max-iterations=<number> The number of iterations for finding super-nodes.\n"
456     "\n"
457 amb 395 "--tagging=<filename> The name of the XML file containing the tagging rules\n"
458 amb 488 " (defaults to 'tagging.xml' with '--dir' and\n"
459 amb 481 " '--prefix' options or the file installed in\n"
460     " '" DATADIR "').\n"
461 amb 395 "\n"
462 amb 358 "<filename.osm> ... The name(s) of the file(s) to process (by default\n"
463     " data is read from standard input).\n"
464 amb 342 "\n"
465     "<transport> defaults to all but can be set to:\n"
466     "%s"
467     "\n"
468     "<highway> can be selected from:\n"
469     "%s"
470     "\n"
471     "<property> can be selected from:\n"
472     "%s",
473     TransportList(),HighwayList(),PropertyList());
474    
475     exit(!detail);
476     }

Properties

Name Value
cvs:description Planet file splitter.