Imported Upstream version 1.5
[routino] / src / filedumper.c
1 /***************************************
2  $Header: /home/amb/routino/src/RCS/filedumper.c,v 1.54 2010/09/15 18:19:36 amb Exp $
3
4  Memory file dumper.
5
6  Part of the Routino routing software.
7  ******************/ /******************
8  This file Copyright 2008-2010 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 <stdlib.h>
27 #include <string.h>
28 #include <sys/stat.h>
29 #include <sys/time.h>
30 #include <time.h>
31
32 #include "types.h"
33 #include "nodes.h"
34 #include "segments.h"
35 #include "ways.h"
36
37 #include "files.h"
38 #include "visualiser.h"
39 #include "xmlparse.h"
40
41
42 /* Local functions */
43
44 static void print_node(Nodes* nodes,index_t item);
45 static void print_segment(Segments *segments,index_t item);
46 static void print_way(Ways *ways,index_t item);
47
48 static void print_head_osm(void);
49 static void print_node_osm(Nodes* nodes,index_t item);
50 static void print_segment_osm(Segments *segments,index_t item,Ways *ways);
51 static void print_tail_osm(void);
52
53 static char *RFC822Date(time_t t);
54
55 static void print_usage(int detail,const char *argerr,const char *err);
56
57
58 /*++++++++++++++++++++++++++++++++++++++
59   The main program for the file dumper.
60   ++++++++++++++++++++++++++++++++++++++*/
61
62 int main(int argc,char** argv)
63 {
64  Nodes    *OSMNodes;
65  Segments *OSMSegments;
66  Ways     *OSMWays;
67  int       arg;
68  char     *dirname=NULL,*prefix=NULL;
69  char     *nodes_filename,*segments_filename,*ways_filename;
70  int       option_statistics=0;
71  int       option_visualiser=0,coordcount=0;
72  double    latmin=0,latmax=0,lonmin=0,lonmax=0;
73  char     *option_data=NULL;
74  int       option_dump=0;
75  int       option_dump_osm=0,option_no_super=0;
76
77  /* Parse the command line arguments */
78
79  for(arg=1;arg<argc;arg++)
80    {
81     if(!strcmp(argv[arg],"--help"))
82        print_usage(1,NULL,NULL);
83     else if(!strncmp(argv[arg],"--dir=",6))
84        dirname=&argv[arg][6];
85     else if(!strncmp(argv[arg],"--prefix=",9))
86        prefix=&argv[arg][9];
87     else if(!strcmp(argv[arg],"--statistics"))
88        option_statistics=1;
89     else if(!strcmp(argv[arg],"--visualiser"))
90        option_visualiser=1;
91     else if(!strcmp(argv[arg],"--dump"))
92        option_dump=1;
93     else if(!strcmp(argv[arg],"--dump-osm"))
94        option_dump_osm=1;
95     else if(!strncmp(argv[arg],"--latmin",8) && argv[arg][8]=='=')
96       {latmin=degrees_to_radians(atof(&argv[arg][9]));coordcount++;}
97     else if(!strncmp(argv[arg],"--latmax",8) && argv[arg][8]=='=')
98       {latmax=degrees_to_radians(atof(&argv[arg][9]));coordcount++;}
99     else if(!strncmp(argv[arg],"--lonmin",8) && argv[arg][8]=='=')
100       {lonmin=degrees_to_radians(atof(&argv[arg][9]));coordcount++;}
101     else if(!strncmp(argv[arg],"--lonmax",8) && argv[arg][8]=='=')
102       {lonmax=degrees_to_radians(atof(&argv[arg][9]));coordcount++;}
103     else if(!strncmp(argv[arg],"--data",6) && argv[arg][6]=='=')
104        option_data=&argv[arg][7];
105     else if(!strcmp(argv[arg],"--no-super"))
106        option_no_super=1;
107     else if(!strncmp(argv[arg],"--node=",7))
108        ;
109     else if(!strncmp(argv[arg],"--segment=",10))
110        ;
111     else if(!strncmp(argv[arg],"--way=",6))
112        ;
113     else
114        print_usage(0,argv[arg],NULL);
115    }
116
117  if((option_statistics + option_visualiser + option_dump + option_dump_osm)!=1)
118     print_usage(0,NULL,"Must choose --visualiser, --statistics, --dump or --dump-osm.");
119
120  /* Load in the data - Note: No error checking because Load*List() will call exit() in case of an error. */
121
122  OSMNodes=LoadNodeList(nodes_filename=FileName(dirname,prefix,"nodes.mem"));
123
124  OSMSegments=LoadSegmentList(segments_filename=FileName(dirname,prefix,"segments.mem"));
125
126  OSMWays=LoadWayList(ways_filename=FileName(dirname,prefix,"ways.mem"));
127
128  /* Write out the visualiser data */
129
130  if(option_visualiser)
131    {
132     if(coordcount!=4)
133        print_usage(0,NULL,"The --visualiser option must have --latmin, --latmax, --lonmin, --lonmax.\n");
134
135     if(!option_data)
136        print_usage(0,NULL,"The --visualiser option must have --data.\n");
137
138     if(!strcmp(option_data,"junctions"))
139        OutputJunctions(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
140     else if(!strcmp(option_data,"super"))
141        OutputSuper(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
142     else if(!strcmp(option_data,"oneway"))
143        OutputOneway(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
144     else if(!strcmp(option_data,"speed"))
145        OutputSpeedLimits(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
146     else if(!strcmp(option_data,"weight"))
147        OutputWeightLimits(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
148     else if(!strcmp(option_data,"height"))
149        OutputHeightLimits(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
150     else if(!strcmp(option_data,"width"))
151        OutputWidthLimits(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
152     else if(!strcmp(option_data,"length"))
153        OutputLengthLimits(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
154     else
155        print_usage(0,option_data,NULL);
156    }
157
158  /* Print out statistics */
159
160  if(option_statistics)
161    {
162     struct stat buf;
163
164     /* Examine the files */
165
166     printf("Files\n");
167     printf("-----\n");
168     printf("\n");
169
170     stat(nodes_filename,&buf);
171
172     printf("'%s%snodes.mem'    - %9lld Bytes\n",prefix?prefix:"",prefix?"-":"",(long long)buf.st_size);
173     printf("%s\n",RFC822Date(buf.st_mtime));
174     printf("\n");
175
176     stat(segments_filename,&buf);
177
178     printf("'%s%ssegments.mem' - %9lld Bytes\n",prefix?prefix:"",prefix?"-":"",(long long)buf.st_size);
179     printf("%s\n",RFC822Date(buf.st_mtime));
180     printf("\n");
181
182     stat(ways_filename,&buf);
183
184     printf("'%s%sways.mem'     - %9lld Bytes\n",prefix?prefix:"",prefix?"-":"",(long long)buf.st_size);
185     printf("%s\n",RFC822Date(buf.st_mtime));
186     printf("\n");
187
188     /* Examine the nodes */
189
190     printf("Nodes\n");
191     printf("-----\n");
192     printf("\n");
193
194     printf("sizeof(Node) =%9d Bytes\n",sizeof(Node));
195     printf("Number       =%9d\n",OSMNodes->file.number);
196     printf("Number(super)=%9d\n",OSMNodes->file.snumber);
197     printf("\n");
198
199     printf("Lat bins= %4d\n",OSMNodes->file.latbins);
200     printf("Lon bins= %4d\n",OSMNodes->file.lonbins);
201     printf("\n");
202
203     printf("Lat zero=%5d (%8.4f deg)\n",OSMNodes->file.latzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->file.latzero))));
204     printf("Lon zero=%5d (%8.4f deg)\n",OSMNodes->file.lonzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->file.lonzero))));
205
206     /* Examine the segments */
207
208     printf("\n");
209     printf("Segments\n");
210     printf("--------\n");
211     printf("\n");
212
213     printf("sizeof(Segment)=%9d Bytes\n",sizeof(Segment));
214     printf("Number(total)  =%9d\n",OSMSegments->file.number);
215     printf("Number(super)  =%9d\n",OSMSegments->file.snumber);
216     printf("Number(normal) =%9d\n",OSMSegments->file.nnumber);
217
218     /* Examine the ways */
219
220     printf("\n");
221     printf("Ways\n");
222     printf("----\n");
223     printf("\n");
224
225     printf("sizeof(Way)      =%9d Bytes\n",sizeof(Way));
226     printf("Number(compacted)=%9d\n",OSMWays->file.number);
227     printf("Number(original) =%9d\n",OSMWays->file.onumber);
228     printf("\n");
229
230     printf("Total names =%9ld Bytes\n",(long)buf.st_size-sizeof(Ways)-OSMWays->file.number*sizeof(Way));
231     printf("\n");
232
233     printf("Included transports: %s\n",AllowedNameList(OSMWays->file.allow));
234     printf("Included properties: %s\n",PropertiesNameList(OSMWays->file.props));
235    }
236
237  /* Print out internal data */
238
239  if(option_dump)
240    {
241     index_t item;
242
243     for(arg=1;arg<argc;arg++)
244        if(!strcmp(argv[arg],"--node=all"))
245          {
246           for(item=0;item<OSMNodes->file.number;item++)
247              print_node(OSMNodes,item);
248          }
249        else if(!strncmp(argv[arg],"--node=",7))
250          {
251           item=atoi(&argv[arg][7]);
252
253           if(item>=0 && item<OSMNodes->file.number)
254              print_node(OSMNodes,item);
255           else
256              printf("Invalid node number; minimum=0, maximum=%d.\n",OSMNodes->file.number-1);
257          }
258        else if(!strcmp(argv[arg],"--segment=all"))
259          {
260           for(item=0;item<OSMSegments->file.number;item++)
261              print_segment(OSMSegments,item);
262          }
263        else if(!strncmp(argv[arg],"--segment=",10))
264          {
265           item=atoi(&argv[arg][10]);
266
267           if(item>=0 && item<OSMSegments->file.number)
268              print_segment(OSMSegments,item);
269           else
270              printf("Invalid segment number; minimum=0, maximum=%d.\n",OSMSegments->file.number-1);
271          }
272        else if(!strcmp(argv[arg],"--way=all"))
273          {
274           for(item=0;item<OSMWays->file.number;item++)
275              print_way(OSMWays,item);
276          }
277        else if(!strncmp(argv[arg],"--way=",6))
278          {
279           item=atoi(&argv[arg][6]);
280
281           if(item>=0 && item<OSMWays->file.number)
282              print_way(OSMWays,item);
283           else
284              printf("Invalid way number; minimum=0, maximum=%d.\n",OSMWays->file.number-1);
285          }
286    }
287
288  /* Print out internal data in XML format */
289
290  if(option_dump_osm)
291    {
292     if(coordcount>0 && coordcount!=4)
293        print_usage(0,NULL,"The --dump-osm option must have all of --latmin, --latmax, --lonmin, --lonmax or none.\n");
294
295     print_head_osm();
296
297     if(coordcount)
298       {
299        int32_t latminbin=latlong_to_bin(radians_to_latlong(latmin))-OSMNodes->file.latzero;
300        int32_t latmaxbin=latlong_to_bin(radians_to_latlong(latmax))-OSMNodes->file.latzero;
301        int32_t lonminbin=latlong_to_bin(radians_to_latlong(lonmin))-OSMNodes->file.lonzero;
302        int32_t lonmaxbin=latlong_to_bin(radians_to_latlong(lonmax))-OSMNodes->file.lonzero;
303        int latb,lonb,llbin;
304        index_t item,index1,index2;
305
306        /* Loop through all of the nodes. */
307
308        for(latb=latminbin;latb<=latmaxbin;latb++)
309           for(lonb=lonminbin;lonb<=lonmaxbin;lonb++)
310             {
311              llbin=lonb*OSMNodes->file.latbins+latb;
312
313              if(llbin<0 || llbin>(OSMNodes->file.latbins*OSMNodes->file.lonbins))
314                 continue;
315
316              index1=LookupNodeOffset(OSMNodes,llbin);
317              index2=LookupNodeOffset(OSMNodes,llbin+1);
318
319              for(item=index1;item<index2;item++)
320                {
321                 Node *node=LookupNode(OSMNodes,item,1);
322                 double lat=latlong_to_radians(bin_to_latlong(OSMNodes->file.latzero+latb)+off_to_latlong(node->latoffset));
323                 double lon=latlong_to_radians(bin_to_latlong(OSMNodes->file.lonzero+lonb)+off_to_latlong(node->lonoffset));
324
325                 if(lat>latmin && lat<latmax && lon>lonmin && lon<lonmax)
326                   {
327                    Segment *segment;
328
329                    print_node_osm(OSMNodes,item);
330
331                    segment=FirstSegment(OSMSegments,OSMNodes,item);
332
333                    while(segment)
334                      {
335                       if(item>OtherNode(segment,item))
336                          if(!option_no_super || IsNormalSegment(segment))
337                             print_segment_osm(OSMSegments,IndexSegment(OSMSegments,segment),OSMWays);
338
339                       segment=NextSegment(OSMSegments,segment,item);
340                      }
341                   }
342                }
343             }
344       }
345     else
346       {
347        index_t item;
348
349        for(item=0;item<OSMNodes->file.number;item++)
350           print_node_osm(OSMNodes,item);
351
352        for(item=0;item<OSMSegments->file.number;item++)
353           if(!option_no_super || IsNormalSegment(LookupSegment(OSMSegments,item,1)))
354              print_segment_osm(OSMSegments,item,OSMWays);
355       }
356
357     print_tail_osm();
358    }
359
360  return(0);
361 }
362
363
364 /*++++++++++++++++++++++++++++++++++++++
365   Print out the contents of a node from the routing database.
366
367   Nodes *nodes The set of nodes to use.
368
369   index_t item The node index to print.
370   ++++++++++++++++++++++++++++++++++++++*/
371
372 static void print_node(Nodes* nodes,index_t item)
373 {
374  Node *node=LookupNode(nodes,item,1);
375  double latitude,longitude;
376
377  GetLatLong(nodes,item,&latitude,&longitude);
378
379  printf("Node %d\n",item);
380  printf("  firstseg=%d\n",node->firstseg);
381  printf("  latoffset=%d lonoffset=%d (latitude=%.6f longitude=%.6f)\n",node->latoffset,node->lonoffset,radians_to_degrees(latitude),radians_to_degrees(longitude));
382  printf("  allow=%02x (%s)\n",node->allow,AllowedNameList(node->allow));
383  if(IsSuperNode(nodes,item))
384     printf("  Super-Node\n");
385 }
386
387
388 /*++++++++++++++++++++++++++++++++++++++
389   Print out the contents of a segment from the routing database.
390
391   Segments *segments The set of segments to use.
392
393   index_t item The segment index to print.
394   ++++++++++++++++++++++++++++++++++++++*/
395
396 static void print_segment(Segments *segments,index_t item)
397 {
398  Segment *segment=LookupSegment(segments,item,1);
399
400  printf("Segment %d\n",item);
401  printf("  node1=%d node2=%d\n",segment->node1,segment->node2);
402  printf("  next2=%d\n",segment->next2);
403  printf("  way=%d\n",segment->way);
404  printf("  distance=%d (%.3f km)\n",DISTANCE(segment->distance),distance_to_km(DISTANCE(segment->distance)));
405  if(IsSuperSegment(segment) && IsNormalSegment(segment))
406     printf("  Super-Segment AND normal Segment\n");
407  else if(IsSuperSegment(segment) && !IsNormalSegment(segment))
408     printf("  Super-Segment\n");
409  if(IsOnewayTo(segment,segment->node1))
410     printf("  One-Way from node2 to node1\n");
411  if(IsOnewayTo(segment,segment->node2))
412     printf("  One-Way from node1 to node2\n");
413 }
414
415
416 /*++++++++++++++++++++++++++++++++++++++
417   Print out the contents of a way from the routing database.
418
419   Ways *ways The set of ways to use.
420
421   index_t item The way index to print.
422   ++++++++++++++++++++++++++++++++++++++*/
423
424 static void print_way(Ways *ways,index_t item)
425 {
426  Way *way=LookupWay(ways,item,1);
427
428  printf("Way %d\n",item);
429  if(*WayName(ways,way))
430     printf("  name=%s\n",WayName(ways,way));
431  printf("  type=%02x (%s%s%s)\n",way->type,HighwayName(HIGHWAY(way->type)),way->type&Way_OneWay?",One-Way":"",way->type&Way_Roundabout?",Roundabout":"");
432  printf("  allow=%02x (%s)\n",way->allow,AllowedNameList(way->allow));
433  if(way->props)
434     printf("  props=%02x (%s)\n",way->props,PropertiesNameList(way->props));
435  if(way->speed)
436     printf("  speed=%d (%d km/hr)\n",way->speed,speed_to_kph(way->speed));
437  if(way->weight)
438     printf("  weight=%d (%.1f tonnes)\n",way->weight,weight_to_tonnes(way->weight));
439  if(way->height)
440     printf("  height=%d (%.1f m)\n",way->height,height_to_metres(way->height));
441  if(way->width)
442     printf("  width=%d (%.1f m)\n",way->width,width_to_metres(way->width));
443  if(way->length)
444     printf("  length=%d (%.1f m)\n",way->length,length_to_metres(way->length));
445 }
446
447
448 /*++++++++++++++++++++++++++++++++++++++
449   Print out a header in OSM XML format.
450   ++++++++++++++++++++++++++++++++++++++*/
451
452 static void print_head_osm(void)
453 {
454  printf("<?xml version='1.0' encoding='UTF-8'?>\n");
455  printf("<osm version='0.6' generator='JOSM'>\n");
456 }
457
458
459 /*++++++++++++++++++++++++++++++++++++++
460   Print out the contents of a node from the routing database in OSM XML format.
461
462   Nodes *nodes The set of nodes to use.
463
464   index_t item The node index to print.
465   ++++++++++++++++++++++++++++++++++++++*/
466
467 static void print_node_osm(Nodes* nodes,index_t item)
468 {
469  Node *node=LookupNode(nodes,item,1);
470  double latitude,longitude;
471
472  GetLatLong(nodes,item,&latitude,&longitude);
473
474  if(IsSuperNode(nodes,item))
475    {
476     int i;
477
478     printf("  <node id='%lu' lat='%.7f' lon='%.7f' version='1'>\n",(unsigned long)item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
479     printf("    <tag k='routino:super' v='yes' />\n");
480
481     for(i=1;i<Transport_Count;i++)
482        if(!(node->allow & ALLOWED(i)))
483           printf("    <tag k='%s' v='no' />\n",TransportName(i));
484
485     printf("  </node>\n");
486    }
487  else
488     printf("  <node id='%lu' lat='%.7f' lon='%.7f' version='1' />\n",(unsigned long)item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
489 }
490
491
492 /*++++++++++++++++++++++++++++++++++++++
493   Print out the contents of a segment from the routing database as a way in OSM XML format.
494
495   Segments *segments The set of segments to use.
496
497   index_t item The segment index to print.
498
499   Ways *ways The set of ways to use.
500   ++++++++++++++++++++++++++++++++++++++*/
501
502 static void print_segment_osm(Segments *segments,index_t item,Ways *ways)
503 {
504  Segment *segment=LookupSegment(segments,item,1);
505  Way *way=LookupWay(ways,segment->way,1);
506  int i;
507
508  printf("  <way id='%lu' version='1'>\n",(unsigned long)item+1);
509
510  if(IsOnewayTo(segment,segment->node1))
511    {
512     printf("    <nd ref='%lu' />\n",(unsigned long)segment->node2+1);
513     printf("    <nd ref='%lu' />\n",(unsigned long)segment->node1+1);
514    }
515  else
516    {
517     printf("    <nd ref='%lu' />\n",(unsigned long)segment->node1+1);
518     printf("    <nd ref='%lu' />\n",(unsigned long)segment->node2+1);
519    }
520
521  if(IsSuperSegment(segment))
522     printf("    <tag k='routino:super' v='yes' />\n");
523  if(IsNormalSegment(segment))
524     printf("    <tag k='routino:normal' v='yes' />\n");
525
526  if(way->type & Way_OneWay)
527     printf("    <tag k='oneway' v='yes' />\n");
528  if(way->type & Way_Roundabout)
529     printf("    <tag k='junction' v='roundabout' />\n");
530
531  printf("    <tag k='highway' v='%s' />\n",HighwayName(HIGHWAY(way->type)));
532
533  if(IsNormalSegment(segment) && *WayName(ways,way))
534     printf("    <tag k='name' v='%s' />\n",ParseXML_Encode_Safe_XML(WayName(ways,way)));
535
536  for(i=1;i<Transport_Count;i++)
537     if(way->allow & ALLOWED(i))
538        printf("    <tag k='%s' v='yes' />\n",TransportName(i));
539
540  for(i=1;i<Property_Count;i++)
541     if(way->props & PROPERTIES(i))
542        printf("    <tag k='%s' v='yes' />\n",PropertyName(i));
543
544  if(way->speed)
545     printf("    <tag k='maxspeed' v='%d' />\n",speed_to_kph(way->speed));
546
547  if(way->weight)
548     printf("    <tag k='maxweight' v='%.1f' />\n",weight_to_tonnes(way->weight));
549  if(way->height)
550     printf("    <tag k='maxheight' v='%.1f' />\n",height_to_metres(way->height));
551  if(way->width)
552     printf("    <tag k='maxwidth' v='%.1f' />\n",width_to_metres(way->width));
553  if(way->length)
554     printf("    <tag k='maxlength' v='%.1f' />\n",length_to_metres(way->length));
555
556  printf("  </way>\n");
557 }
558
559
560 /*++++++++++++++++++++++++++++++++++++++
561   Print out a tail in OSM XML format.
562   ++++++++++++++++++++++++++++++++++++++*/
563
564 static void print_tail_osm(void)
565 {
566  printf("</osm>\n");
567 }
568
569
570 /*+ Conversion from time_t to date string (day of week). +*/
571 static const char* const weekdays[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
572
573 /*+ Conversion from time_t to date string (month of year). +*/
574 static const char* const months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
575
576
577 /*++++++++++++++++++++++++++++++++++++++
578   Convert the time into an RFC 822 compliant date.
579
580   char *RFC822Date Returns a pointer to a fixed string containing the date.
581
582   time_t t The time.
583   ++++++++++++++++++++++++++++++++++++++*/
584
585 static char *RFC822Date(time_t t)
586 {
587  static char value[32];
588  char weekday[4];
589  char month[4];
590  struct tm *tim;
591
592  tim=gmtime(&t);
593
594  strcpy(weekday,weekdays[tim->tm_wday]);
595  strcpy(month,months[tim->tm_mon]);
596
597  /* Sun, 06 Nov 1994 08:49:37 GMT    ; RFC 822, updated by RFC 1123 */
598
599  sprintf(value,"%3s, %02d %3s %4d %02d:%02d:%02d %s",
600          weekday,
601          tim->tm_mday,
602          month,
603          tim->tm_year+1900,
604          tim->tm_hour,
605          tim->tm_min,
606          tim->tm_sec,
607          "GMT"
608          );
609
610  return(value);
611 }
612
613
614 /*++++++++++++++++++++++++++++++++++++++
615   Print out the usage information.
616
617   int detail The level of detail to use - 0 = low, 1 = high.
618
619   const char *argerr The argument that gave the error (if there is one).
620
621   const char *err Other error message (if there is one).
622   ++++++++++++++++++++++++++++++++++++++*/
623
624 static void print_usage(int detail,const char *argerr,const char *err)
625 {
626  fprintf(stderr,
627          "Usage: filedumper [--help]\n"
628          "                  [--dir=<dirname>] [--prefix=<name>]\n"
629          "                  [--statistics]\n"
630          "                  [--visualiser --latmin=<latmin> --latmax=<latmax>\n"
631          "                                --lonmin=<lonmin> --lonmax=<lonmax>\n"
632          "                                --data=<data-type>]\n"
633          "                  [--dump [--node=<node> ...]\n"
634          "                          [--segment=<segment> ...]\n"
635          "                          [--way=<way> ...]]\n"
636          "                  [--dump-osm [--no-super]\n"
637          "                              [--latmin=<latmin> --latmax=<latmax>\n"
638          "                               --lonmin=<lonmin> --lonmax=<lonmax>]]\n");
639
640  if(argerr)
641     fprintf(stderr,
642             "\n"
643             "Error with command line parameter: %s\n",argerr);
644
645  if(err)
646     fprintf(stderr,
647             "\n"
648             "Error: %s\n",err);
649
650  if(detail)
651     fprintf(stderr,
652             "\n"
653             "--help                    Prints this information.\n"
654             "\n"
655             "--dir=<dirname>           The directory containing the routing database.\n"
656             "--prefix=<name>           The filename prefix for the routing database.\n"
657             "\n"
658             "--statistics              Print statistics about the routing database.\n"
659             "\n"
660             "--visualiser              Extract selected data from the routing database:\n"
661             "  --latmin=<latmin>       * the minimum latitude (degrees N).\n"
662             "  --latmax=<latmax>       * the maximum latitude (degrees N).\n"
663             "  --lonmin=<lonmin>       * the minimum longitude (degrees E).\n"
664             "  --lonmax=<lonmax>       * the maximum longitude (degrees E).\n"
665             "  --data=<data-type>      * the type of data to select.\n"
666             "\n"
667             "  <data-type> can be selected from:\n"
668             "      junctions = segment count at each junction.\n"
669             "      super     = super-node and super-segments.\n"
670             "      oneway    = oneway segments.\n"
671             "      speed     = speed limits.\n"
672             "      weight    = weight limits.\n"
673             "      height    = height limits.\n"
674             "      width     = width limits.\n"
675             "      length    = length limits.\n"
676             "\n"
677             "--dump                    Dump selected contents of the database.\n"
678             "  --node=<node>           * the node with the selected number.\n"
679             "  --segment=<segment>     * the segment with the selected number.\n"
680             "  --way=<way>             * the way with the selected number.\n"
681             "                          Use 'all' instead of a number to get all of them.\n"
682             "\n"
683             "--dump-osm                Dump all or part of the database as an XML file.\n"
684             "  --no-super              * exclude the super-segments.\n"
685             "  --latmin=<latmin>       * the minimum latitude (degrees N).\n"
686             "  --latmax=<latmax>       * the maximum latitude (degrees N).\n"
687             "  --lonmin=<lonmin>       * the minimum longitude (degrees E).\n"
688             "  --lonmax=<lonmax>       * the maximum longitude (degrees E).\n");
689
690  exit(!detail);
691 }