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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 665 - (show annotations) (download) (as text)
Mon Mar 21 18:24:34 2011 UTC (13 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 12921 byte(s)
Sort the segments geographically.

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

Properties

Name Value
cvs:description Planet file splitter.