1 /***************************************
2 $Header: /home/amb/routino/src/RCS/planetsplitter.c,v 1.73 2010/05/22 18:40:47 amb Exp $
4 OSM planet file splitter.
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008-2010 Andrew M. Bishop
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.
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.
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 ***************************************/
32 #include "functionsx.h"
33 #include "functions.h"
35 #include "segmentsx.h"
42 /* Global variables */
44 /*+ The option to use a slim mode with file-backed read-only intermediate storage. +*/
47 /*+ The name of the temporary directory. +*/
48 char *option_tmpdirname=NULL;
50 /*+ The amount of RAM to use for filesorting. +*/
51 size_t option_filesort_ramsize=0;
56 static void print_usage(int detail);
59 /*++++++++++++++++++++++++++++++++++++++
60 The main program for the planetsplitter.
61 ++++++++++++++++++++++++++++++++++++++*/
63 int main(int argc,char** argv)
66 SegmentsX *Segments,*SuperSegments=NULL,*MergedSegments=NULL;
68 int iteration=0,quit=0;
69 int max_iterations=10;
70 char *dirname=NULL,*prefix=NULL,*tagging=NULL;
71 int option_parse_only=0,option_process_only=0;
72 int option_filenames=0;
75 /* Parse the command line arguments */
77 for(arg=1;arg<argc;arg++)
79 if(!strcmp(argv[arg],"--help"))
81 else if(!strcmp(argv[arg],"--slim"))
83 else if(!strncmp(argv[arg],"--sort-ram-size=",16))
84 option_filesort_ramsize=atoi(&argv[arg][16]);
85 else if(!strncmp(argv[arg],"--dir=",6))
86 dirname=&argv[arg][6];
87 else if(!strncmp(argv[arg],"--tmpdir=",9))
88 option_tmpdirname=&argv[arg][9];
89 else if(!strncmp(argv[arg],"--prefix=",9))
91 else if(!strcmp(argv[arg],"--parse-only"))
93 else if(!strcmp(argv[arg],"--process-only"))
94 option_process_only=1;
95 else if(!strncmp(argv[arg],"--max-iterations=",17))
96 max_iterations=atoi(&argv[arg][17]);
97 else if(!strncmp(argv[arg],"--tagging=",10))
98 tagging=&argv[arg][10];
99 else if(argv[arg][0]=='-' && argv[arg][1]=='-')
105 /* Check the specified command line options */
107 if(option_parse_only && option_process_only)
110 if(option_filenames && option_process_only)
113 if(!option_filesort_ramsize)
116 option_filesort_ramsize=64*1024*1024;
118 option_filesort_ramsize=256*1024*1024;
121 option_filesort_ramsize*=1024*1024;
123 if(!option_tmpdirname)
126 option_tmpdirname=".";
128 option_tmpdirname=dirname;
131 if(tagging && ExistsFile(tagging))
133 else if(!tagging && ExistsFile(FileName(dirname,prefix,"tagging.xml")))
134 tagging=FileName(dirname,prefix,"tagging.xml");
136 if(tagging && ParseXMLTaggingRules(tagging))
138 fprintf(stderr,"Error: Cannot read the tagging rules in the file '%s'.\n",tagging);
144 fprintf(stderr,"Error: Cannot run without reading some tagging rules.\n");
148 /* Create new node, segment and way variables */
150 Nodes=NewNodeList(option_parse_only||option_process_only);
152 Segments=NewSegmentList(option_parse_only||option_process_only);
154 Ways=NewWayList(option_parse_only||option_process_only);
160 for(arg=1;arg<argc;arg++)
164 if(argv[arg][0]=='-' && argv[arg][1]=='-')
167 file=fopen(argv[arg],"rb");
171 fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",argv[arg],strerror(errno));
175 printf("\nParse OSM Data [%s]\n==============\n\n",argv[arg]);
178 if(ParseOSM(file,Nodes,Segments,Ways))
184 else if(!option_process_only)
186 printf("\nParse OSM Data\n==============\n\n");
189 if(ParseOSM(stdin,Nodes,Segments,Ways))
193 if(option_parse_only)
195 FreeNodeList(Nodes,1);
196 FreeSegmentList(Segments,1);
202 /* Process the data */
204 printf("\nProcess OSM Data\n================\n\n");
207 /* Sort the nodes, segments and ways */
211 SortSegmentList(Segments);
215 /* Remove bad segments (must be after sorting the nodes and segments) */
217 RemoveBadSegments(Nodes,Segments);
219 /* Remove non-highway nodes (must be after removing the bad segments) */
221 RemoveNonHighwayNodes(Nodes,Segments);
223 /* Measure the segments and replace node/way id with index (must be after removing non-highway nodes) */
225 UpdateSegments(Segments,Nodes,Ways);
228 /* Repeated iteration on Super-Nodes and Super-Segments */
232 printf("\nProcess Super-Data (iteration %d)\n================================%s\n\n",iteration,iteration>9?"=":"");
237 /* Select the super-nodes */
239 ChooseSuperNodes(Nodes,Segments,Ways);
241 /* Select the super-segments */
243 SuperSegments=CreateSuperSegments(Nodes,Segments,Ways,iteration);
247 SegmentsX *SuperSegments2;
249 /* Select the super-nodes */
251 ChooseSuperNodes(Nodes,SuperSegments,Ways);
253 /* Select the super-segments */
255 SuperSegments2=CreateSuperSegments(Nodes,SuperSegments,Ways,iteration);
257 if(SuperSegments->xnumber==SuperSegments2->xnumber)
260 FreeSegmentList(SuperSegments,0);
262 SuperSegments=SuperSegments2;
265 /* Sort the super-segments */
267 SortSegmentList(SuperSegments);
269 /* Remove duplicated super-segments */
271 DeduplicateSegments(SuperSegments,Nodes,Ways);
275 if(iteration>max_iterations)
280 /* Combine the super-segments */
282 printf("\nCombine Segments and Super-Segments\n===================================\n\n");
285 /* Merge the super-segments */
287 MergedSegments=MergeSuperSegments(Segments,SuperSegments);
289 FreeSegmentList(Segments,0);
291 FreeSegmentList(SuperSegments,0);
293 Segments=MergedSegments;
295 /* Rotate segments so that node1<node2 */
297 RotateSegments(Segments);
299 /* Sort the segments */
301 SortSegmentList(Segments);
303 /* Remove duplicated segments */
305 DeduplicateSegments(Segments,Nodes,Ways);
307 /* Cross reference the nodes and segments */
309 printf("\nCross-Reference Nodes and Segments\n==================================\n\n");
312 /* Sort the node list geographically */
314 SortNodeListGeographically(Nodes);
316 /* Create the real segments and nodes */
318 CreateRealNodes(Nodes,iteration);
320 CreateRealSegments(Segments,Ways);
322 /* Fix the segment and node indexes */
324 IndexNodes(Nodes,Segments);
326 IndexSegments(Segments,Nodes);
328 /* Output the results */
330 printf("\nWrite Out Database Files\n========================\n\n");
333 /* Write out the nodes */
335 SaveNodeList(Nodes,FileName(dirname,prefix,"nodes.mem"));
337 FreeNodeList(Nodes,0);
339 /* Write out the segments */
341 SaveSegmentList(Segments,FileName(dirname,prefix,"segments.mem"));
343 FreeSegmentList(Segments,0);
345 /* Write out the ways */
347 SaveWayList(Ways,FileName(dirname,prefix,"ways.mem"));
355 /*++++++++++++++++++++++++++++++++++++++
356 Print out the usage information.
358 int detail The level of detail to use - 0 = low, 1 = high.
359 ++++++++++++++++++++++++++++++++++++++*/
361 static void print_usage(int detail)
364 "Usage: planetsplitter [--help]\n"
365 " [--dir=<dirname>] [--prefix=<name>]\n"
366 " [--slim] [--sort-ram-size=<size>]\n"
367 " [--tmpdir=<dirname>]\n"
368 " [--parse-only | --process-only]\n"
369 " [--max-iterations=<number>]\n"
370 " [--tagging=<filename>]\n"
371 " [<filename.osm> ...]\n");
376 "--help Prints this information.\n"
378 "--dir=<dirname> The directory containing the routing database.\n"
379 "--prefix=<name> The filename prefix for the routing database.\n"
381 "--slim Use less RAM and more temporary files.\n"
382 "--sort-ram-size=<size> The amount of RAM (in MB) to use for data sorting\n"
383 " (defaults to 64MB with '--slim' or 256MB otherwise.)\n"
384 "--tmpdir=<dirname> The directory name for temporary files.\n"
385 " (defaults to the '--dir' option directory.)\n"
387 "--parse-only Parse the input OSM files and store the results.\n"
388 "--process-only Process the stored results from previous option.\n"
390 "--max-iterations=<number> The number of iterations for finding super-nodes.\n"
392 "--tagging=<filename> The name of the XML file containing the tagging rules\n"
393 " (defaults to 'tagging.xml' with '--dirname' and\n"
394 " '--prefix' options).\n"
396 "<filename.osm> ... The name(s) of the file(s) to process (by default\n"
397 " data is read from standard input).\n"
399 "<transport> defaults to all but can be set to:\n"
402 "<highway> can be selected from:\n"
405 "<property> can be selected from:\n"
407 TransportList(),HighwayList(),PropertyList());