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 963 - (show annotations) (download) (as text)
Thu Feb 9 18:36:46 2012 UTC (13 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 14534 byte(s)
Prune isolated segments if they cannot be routed to anywhere else, not just if
they are not connected.

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

Properties

Name Value
cvs:description Planet file splitter.