Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /branches/destination-access/src/filedumper.c
Parent Directory
|
Revision Log
Revision 1990 -
(show annotations)
(download)
(as text)
Wed Apr 17 18:01:27 2019 UTC (5 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 48294 byte(s)
Wed Apr 17 18:01:27 2019 UTC (5 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 48294 byte(s)
Merge from trunk (signed/unsigned, sanitizer and name changes).
1 | /*************************************** |
2 | Memory file dumper. |
3 | |
4 | Part of the Routino routing software. |
5 | ******************/ /****************** |
6 | This file Copyright 2008-2015, 2018, 2019 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 <sys/stat.h> |
27 | #include <time.h> |
28 | #include <math.h> |
29 | |
30 | #include "version.h" |
31 | |
32 | #include "types.h" |
33 | #include "nodes.h" |
34 | #include "segments.h" |
35 | #include "ways.h" |
36 | #include "relations.h" |
37 | #include "errorlog.h" |
38 | |
39 | #include "files.h" |
40 | #include "visualiser.h" |
41 | #include "xmlparse.h" |
42 | |
43 | |
44 | /* Local functions */ |
45 | |
46 | static void print_node(Nodes *nodes,index_t item); |
47 | static void print_segment(Segments *segments,index_t item); |
48 | static void print_way(Ways *ways,index_t item); |
49 | static void print_turn_relation(Relations *relations,index_t item,Segments *segments,Nodes *nodes); |
50 | static void print_errorlog(ErrorLogs *errorlogs,index_t item); |
51 | |
52 | static void print_head_osm(int coordcount,double latmin,double latmax,double lonmin,double lonmax); |
53 | static void print_region_osm(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations, |
54 | double latmin,double latmax,double lonmin,double lonmax,int option_no_super); |
55 | static void print_node_osm(Nodes *nodes,index_t item); |
56 | static void print_segment_osm(Segments *segments,index_t item,Ways *ways); |
57 | static void print_turn_relation_osm(Relations *relations,index_t item,Segments *segments,Nodes *nodes); |
58 | static void print_tail_osm(void); |
59 | |
60 | static void print_node_visualiser(Nodes *nodes,index_t item); |
61 | static void print_segment_visualiser(Segments *segments,index_t item,Ways *ways); |
62 | static void print_turn_relation_visualiser(Relations *relations,index_t item,Segments *segments,Nodes *nodes); |
63 | static void print_errorlog_visualiser(ErrorLogs *errorlogs,index_t item); |
64 | |
65 | static char *RFC822Date(time_t t); |
66 | |
67 | static void print_usage(int detail,const char *argerr,const char *err); |
68 | |
69 | |
70 | /*++++++++++++++++++++++++++++++++++++++ |
71 | The main program for the file dumper. |
72 | ++++++++++++++++++++++++++++++++++++++*/ |
73 | |
74 | int main(int argc,char** argv) |
75 | { |
76 | Nodes *OSMNodes; |
77 | Segments *OSMSegments; |
78 | Ways *OSMWays; |
79 | Relations*OSMRelations; |
80 | ErrorLogs*OSMErrorLogs=NULL; |
81 | int arg; |
82 | char *dirname=NULL,*prefix=NULL; |
83 | char *nodes_filename,*segments_filename,*ways_filename,*relations_filename,*errorlogs_filename; |
84 | int option_statistics=0; |
85 | int option_visualiser=0,coordcount=0; |
86 | double latmin=0,latmax=0,lonmin=0,lonmax=0; |
87 | char *option_data=NULL; |
88 | int option_dump=0; |
89 | int option_dump_osm=0,option_no_super=0; |
90 | int option_dump_visualiser=0; |
91 | |
92 | /* Parse the command line arguments */ |
93 | |
94 | for(arg=1;arg<argc;arg++) |
95 | { |
96 | if(!strcmp(argv[arg],"--version")) |
97 | print_usage(-1,NULL,NULL); |
98 | else if(!strcmp(argv[arg],"--help")) |
99 | print_usage(1,NULL,NULL); |
100 | else if(!strncmp(argv[arg],"--dir=",6)) |
101 | dirname=&argv[arg][6]; |
102 | else if(!strncmp(argv[arg],"--prefix=",9)) |
103 | prefix=&argv[arg][9]; |
104 | else if(!strcmp(argv[arg],"--statistics")) |
105 | option_statistics=1; |
106 | else if(!strcmp(argv[arg],"--visualiser")) |
107 | option_visualiser=1; |
108 | else if(!strcmp(argv[arg],"--dump")) |
109 | option_dump=1; |
110 | else if(!strcmp(argv[arg],"--dump-osm")) |
111 | option_dump_osm=1; |
112 | else if(!strcmp(argv[arg],"--dump-visualiser")) |
113 | option_dump_visualiser=1; |
114 | else if(!strncmp(argv[arg],"--latmin",8) && argv[arg][8]=='=') |
115 | {latmin=degrees_to_radians(atof(&argv[arg][9]));coordcount++;} |
116 | else if(!strncmp(argv[arg],"--latmax",8) && argv[arg][8]=='=') |
117 | {latmax=degrees_to_radians(atof(&argv[arg][9]));coordcount++;} |
118 | else if(!strncmp(argv[arg],"--lonmin",8) && argv[arg][8]=='=') |
119 | {lonmin=degrees_to_radians(atof(&argv[arg][9]));coordcount++;} |
120 | else if(!strncmp(argv[arg],"--lonmax",8) && argv[arg][8]=='=') |
121 | {lonmax=degrees_to_radians(atof(&argv[arg][9]));coordcount++;} |
122 | else if(!strncmp(argv[arg],"--data",6) && argv[arg][6]=='=') |
123 | option_data=&argv[arg][7]; |
124 | else if(!strcmp(argv[arg],"--no-super")) |
125 | option_no_super=1; |
126 | else if(!strncmp(argv[arg],"--node=",7)) |
127 | ; |
128 | else if(!strncmp(argv[arg],"--segment=",10)) |
129 | ; |
130 | else if(!strncmp(argv[arg],"--way=",6)) |
131 | ; |
132 | else if(!strncmp(argv[arg],"--turn-relation=",16)) |
133 | ; |
134 | else if(!strncmp(argv[arg],"--errorlog=",11)) |
135 | ; |
136 | else |
137 | print_usage(0,argv[arg],NULL); |
138 | } |
139 | |
140 | if((option_statistics + option_visualiser + option_dump + option_dump_osm + option_dump_visualiser)!=1) |
141 | print_usage(0,NULL,"Must choose --visualiser, --statistics, --dump, --dump-osm or --dump-visualiser."); |
142 | |
143 | /* Load in the data - Note: No error checking because Load*List() will call exit() in case of an error. */ |
144 | |
145 | OSMNodes=LoadNodeList(nodes_filename=FileName(dirname,prefix,"nodes.mem")); |
146 | |
147 | OSMSegments=LoadSegmentList(segments_filename=FileName(dirname,prefix,"segments.mem")); |
148 | |
149 | OSMWays=LoadWayList(ways_filename=FileName(dirname,prefix,"ways.mem")); |
150 | |
151 | OSMRelations=LoadRelationList(relations_filename=FileName(dirname,prefix,"relations.mem")); |
152 | |
153 | if(ExistsFile(errorlogs_filename=FileName(dirname,prefix,"errorlogs.mem"))) |
154 | OSMErrorLogs=LoadErrorLogs(errorlogs_filename); |
155 | else |
156 | errorlogs_filename=NULL; |
157 | |
158 | /* Write out the visualiser data */ |
159 | |
160 | if(option_visualiser) |
161 | { |
162 | Highway highway; |
163 | Transport transport; |
164 | Property property; |
165 | |
166 | if(coordcount!=4) |
167 | print_usage(0,NULL,"The --visualiser option must have --latmin, --latmax, --lonmin, --lonmax.\n"); |
168 | |
169 | if(!option_data) |
170 | print_usage(0,NULL,"The --visualiser option must have --data.\n"); |
171 | |
172 | if(!strcmp(option_data,"junctions")) |
173 | OutputJunctions(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax); |
174 | else if(!strcmp(option_data,"super")) |
175 | OutputSuper(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax); |
176 | else if(!strcmp(option_data,"waytype-oneway")) |
177 | OutputWaytype(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,Highway_OneWay); |
178 | else if(!strcmp(option_data,"waytype-cyclebothways")) |
179 | OutputWaytype(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,Highway_CycleBothWays); |
180 | else if(!strcmp(option_data,"waytype-roundabout")) |
181 | OutputWaytype(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,Highway_Roundabout); |
182 | else if(!strncmp(option_data,"highway",7) && option_data[7]=='-' && (highway=HighwayType(option_data+8))!=Highway_None) |
183 | OutputHighway(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,highway); |
184 | else if(!strncmp(option_data,"transport",9) && option_data[9]=='-' && (transport=TransportType(option_data+10))!=Transport_None) |
185 | OutputTransport(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,transport); |
186 | else if(!strncmp(option_data,"destination",11) && option_data[11]=='-' && (transport=TransportType(option_data+12))!=Transport_None) |
187 | OutputDestination(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,transport); |
188 | else if(!strncmp(option_data,"barrier",7) && option_data[7]=='-' && (transport=TransportType(option_data+8))!=Transport_None) |
189 | OutputBarrier(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,transport); |
190 | else if(!strcmp(option_data,"turns")) |
191 | OutputTurnRestrictions(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax); |
192 | else if(!strcmp(option_data,"speed")) |
193 | OutputSpeedLimits(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax); |
194 | else if(!strcmp(option_data,"weight")) |
195 | OutputWeightLimits(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax); |
196 | else if(!strcmp(option_data,"height")) |
197 | OutputHeightLimits(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax); |
198 | else if(!strcmp(option_data,"width")) |
199 | OutputWidthLimits(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax); |
200 | else if(!strcmp(option_data,"length")) |
201 | OutputLengthLimits(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax); |
202 | else if(!strncmp(option_data,"property",8) && option_data[8]=='-' && (property=PropertyType(option_data+9))!=Property_None) |
203 | OutputProperty(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,property); |
204 | else if(!strcmp(option_data,"errorlogs")) |
205 | OutputErrorLog(OSMErrorLogs,latmin,latmax,lonmin,lonmax); |
206 | else |
207 | print_usage(0,option_data,NULL); |
208 | } |
209 | |
210 | /* Print out statistics */ |
211 | |
212 | if(option_statistics) |
213 | { |
214 | struct stat buf; |
215 | |
216 | /* Examine the files */ |
217 | |
218 | printf("Files\n"); |
219 | printf("-----\n"); |
220 | printf("\n"); |
221 | |
222 | stat(nodes_filename,&buf); |
223 | |
224 | printf("'%s%snodes.mem' - %9"PRIu64" Bytes\n",prefix?prefix:"",prefix?"-":"",(uint64_t)buf.st_size); |
225 | printf("%s\n",RFC822Date(buf.st_mtime)); |
226 | printf("\n"); |
227 | |
228 | stat(segments_filename,&buf); |
229 | |
230 | printf("'%s%ssegments.mem' - %9"PRIu64" Bytes\n",prefix?prefix:"",prefix?"-":"",(uint64_t)buf.st_size); |
231 | printf("%s\n",RFC822Date(buf.st_mtime)); |
232 | printf("\n"); |
233 | |
234 | stat(ways_filename,&buf); |
235 | |
236 | printf("'%s%sways.mem' - %9"PRIu64" Bytes\n",prefix?prefix:"",prefix?"-":"",(uint64_t)buf.st_size); |
237 | printf("%s\n",RFC822Date(buf.st_mtime)); |
238 | printf("\n"); |
239 | |
240 | stat(relations_filename,&buf); |
241 | |
242 | printf("'%s%srelations.mem' - %9"PRIu64" Bytes\n",prefix?prefix:"",prefix?"-":"",(uint64_t)buf.st_size); |
243 | printf("%s\n",RFC822Date(buf.st_mtime)); |
244 | printf("\n"); |
245 | |
246 | if(errorlogs_filename) |
247 | { |
248 | stat(errorlogs_filename,&buf); |
249 | |
250 | printf("'%s%serrorlogs.mem' - %9"PRIu64" Bytes\n",prefix?prefix:"",prefix?"-":"",(uint64_t)buf.st_size); |
251 | printf("%s\n",RFC822Date(buf.st_mtime)); |
252 | printf("\n"); |
253 | } |
254 | |
255 | /* Examine the nodes */ |
256 | |
257 | printf("Nodes\n"); |
258 | printf("-----\n"); |
259 | printf("\n"); |
260 | |
261 | printf("sizeof(Node) =%9zu Bytes\n",sizeof(Node)); |
262 | printf("Number =%9"Pindex_t"\n",OSMNodes->file.number); |
263 | printf("Number(super)=%9"Pindex_t"\n",OSMNodes->file.snumber); |
264 | printf("\n"); |
265 | |
266 | printf("Lat bins= %4d\n",(int)OSMNodes->file.latbins); |
267 | printf("Lon bins= %4d\n",(int)OSMNodes->file.lonbins); |
268 | printf("\n"); |
269 | |
270 | printf("Lat zero=%5d (%8.4f deg)\n",(int)OSMNodes->file.latzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->file.latzero)))); |
271 | printf("Lon zero=%5d (%8.4f deg)\n",(int)OSMNodes->file.lonzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->file.lonzero)))); |
272 | |
273 | /* Examine the segments */ |
274 | |
275 | printf("\n"); |
276 | printf("Segments\n"); |
277 | printf("--------\n"); |
278 | printf("\n"); |
279 | |
280 | printf("sizeof(Segment)=%9zu Bytes\n",sizeof(Segment)); |
281 | printf("Number(total) =%9"Pindex_t"\n",OSMSegments->file.number); |
282 | printf("Number(super) =%9"Pindex_t"\n",OSMSegments->file.snumber); |
283 | printf("Number(normal) =%9"Pindex_t"\n",OSMSegments->file.nnumber); |
284 | |
285 | /* Examine the ways */ |
286 | |
287 | printf("\n"); |
288 | printf("Ways\n"); |
289 | printf("----\n"); |
290 | printf("\n"); |
291 | |
292 | printf("sizeof(Way)=%9zu Bytes\n",sizeof(Way)); |
293 | printf("Number =%9"Pindex_t"\n",OSMWays->file.number); |
294 | printf("\n"); |
295 | |
296 | stat(ways_filename,&buf); |
297 | printf("Total names=%9zu Bytes\n",(size_t)buf.st_size-sizeof(Ways)-OSMWays->file.number*sizeof(Way)); |
298 | printf("\n"); |
299 | |
300 | printf("Included highways : %s\n",HighwaysNameList(OSMWays->file.highways)); |
301 | printf("Included transports: %s\n",TransportsNameList(OSMWays->file.transports)); |
302 | printf("Included properties: %s\n",PropertiesNameList(OSMWays->file.properties)); |
303 | |
304 | /* Examine the relations */ |
305 | |
306 | printf("\n"); |
307 | printf("Relations\n"); |
308 | printf("---------\n"); |
309 | printf("\n"); |
310 | |
311 | printf("sizeof(TurnRelation)=%9zu Bytes\n",sizeof(TurnRelation)); |
312 | printf("Number =%9"Pindex_t"\n",OSMRelations->file.trnumber); |
313 | |
314 | if(errorlogs_filename) |
315 | { |
316 | printf("\n"); |
317 | printf("Error Logs\n"); |
318 | printf("----------\n"); |
319 | printf("\n"); |
320 | |
321 | printf("Number(total) =%9"Pindex_t"\n",OSMErrorLogs->file.number); |
322 | printf("Number(geographical) =%9"Pindex_t"\n",OSMErrorLogs->file.number_geo); |
323 | printf("Number(non-geographical)=%9"Pindex_t"\n",OSMErrorLogs->file.number_nongeo); |
324 | |
325 | printf("\n"); |
326 | stat(errorlogs_filename,&buf); |
327 | #if !SLIM |
328 | printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(OSMErrorLogs->strings-(char*)OSMErrorLogs->data)); |
329 | #else |
330 | printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(size_t)OSMErrorLogs->stringsoffset); |
331 | #endif |
332 | } |
333 | } |
334 | |
335 | /* Print out internal data (in plain text format) */ |
336 | |
337 | if(option_dump) |
338 | { |
339 | index_t item; |
340 | |
341 | for(arg=1;arg<argc;arg++) |
342 | if(!strcmp(argv[arg],"--node=all")) |
343 | { |
344 | for(item=0;item<OSMNodes->file.number;item++) |
345 | print_node(OSMNodes,item); |
346 | } |
347 | else if(!strncmp(argv[arg],"--node=",7)) |
348 | { |
349 | item=atoi(&argv[arg][7]); |
350 | |
351 | if(item<OSMNodes->file.number) |
352 | print_node(OSMNodes,item); |
353 | else |
354 | printf("Invalid node number; minimum=0, maximum=%"Pindex_t".\n",OSMNodes->file.number-1); |
355 | } |
356 | else if(!strcmp(argv[arg],"--segment=all")) |
357 | { |
358 | for(item=0;item<OSMSegments->file.number;item++) |
359 | print_segment(OSMSegments,item); |
360 | } |
361 | else if(!strncmp(argv[arg],"--segment=",10)) |
362 | { |
363 | item=atoi(&argv[arg][10]); |
364 | |
365 | if(item<OSMSegments->file.number) |
366 | print_segment(OSMSegments,item); |
367 | else |
368 | printf("Invalid segment number; minimum=0, maximum=%"Pindex_t".\n",OSMSegments->file.number-1); |
369 | } |
370 | else if(!strcmp(argv[arg],"--way=all")) |
371 | { |
372 | for(item=0;item<OSMWays->file.number;item++) |
373 | print_way(OSMWays,item); |
374 | } |
375 | else if(!strncmp(argv[arg],"--way=",6)) |
376 | { |
377 | item=atoi(&argv[arg][6]); |
378 | |
379 | if(item<OSMWays->file.number) |
380 | print_way(OSMWays,item); |
381 | else |
382 | printf("Invalid way number; minimum=0, maximum=%"Pindex_t".\n",OSMWays->file.number-1); |
383 | } |
384 | else if(!strcmp(argv[arg],"--turn-relation=all")) |
385 | { |
386 | for(item=0;item<OSMRelations->file.trnumber;item++) |
387 | print_turn_relation(OSMRelations,item,OSMSegments,OSMNodes); |
388 | } |
389 | else if(!strncmp(argv[arg],"--turn-relation=",16)) |
390 | { |
391 | item=atoi(&argv[arg][16]); |
392 | |
393 | if(item<OSMRelations->file.trnumber) |
394 | print_turn_relation(OSMRelations,item,OSMSegments,OSMNodes); |
395 | else |
396 | printf("Invalid turn relation number; minimum=0, maximum=%"Pindex_t".\n",OSMRelations->file.trnumber-1); |
397 | } |
398 | else if(!strcmp(argv[arg],"--errorlog=all")) |
399 | { |
400 | for(item=0;item<OSMErrorLogs->file.number;item++) |
401 | print_errorlog(OSMErrorLogs,item); |
402 | } |
403 | else if(!strncmp(argv[arg],"--errorlog=",11)) |
404 | { |
405 | item=atoi(&argv[arg][11]); |
406 | |
407 | if(item<OSMErrorLogs->file.number) |
408 | print_errorlog(OSMErrorLogs,item); |
409 | else |
410 | printf("Invalid error log number; minimum=0, maximum=%"Pindex_t".\n",OSMErrorLogs->file.number-1); |
411 | } |
412 | } |
413 | |
414 | /* Print out internal data (in OSM XML format) */ |
415 | |
416 | if(option_dump_osm) |
417 | { |
418 | if(coordcount>0 && coordcount!=4) |
419 | print_usage(0,NULL,"The --dump-osm option must have all of --latmin, --latmax, --lonmin, --lonmax or none.\n"); |
420 | |
421 | print_head_osm(coordcount,latmin,latmax,lonmin,lonmax); |
422 | |
423 | if(coordcount) |
424 | print_region_osm(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,option_no_super); |
425 | else |
426 | { |
427 | index_t item; |
428 | |
429 | for(item=0;item<OSMNodes->file.number;item++) |
430 | print_node_osm(OSMNodes,item); |
431 | |
432 | for(item=0;item<OSMSegments->file.number;item++) |
433 | if(!option_no_super || IsNormalSegment(LookupSegment(OSMSegments,item,1))) |
434 | print_segment_osm(OSMSegments,item,OSMWays); |
435 | |
436 | for(item=0;item<OSMRelations->file.trnumber;item++) |
437 | print_turn_relation_osm(OSMRelations,item,OSMSegments,OSMNodes); |
438 | } |
439 | |
440 | print_tail_osm(); |
441 | } |
442 | |
443 | /* Print out internal data (in HTML format for the visualiser) */ |
444 | |
445 | if(option_dump_visualiser) |
446 | { |
447 | index_t item; |
448 | |
449 | if(!option_data) |
450 | print_usage(0,NULL,"The --dump-visualiser option must have --data.\n"); |
451 | |
452 | for(arg=1;arg<argc;arg++) |
453 | if(!strncmp(argv[arg],"--data=node",11)) |
454 | { |
455 | item=atoi(&argv[arg][11]); |
456 | |
457 | if(item<OSMNodes->file.number) |
458 | print_node_visualiser(OSMNodes,item); |
459 | else |
460 | printf("Invalid node number; minimum=0, maximum=%"Pindex_t".\n",OSMNodes->file.number-1); |
461 | } |
462 | else if(!strncmp(argv[arg],"--data=segment",14)) |
463 | { |
464 | item=atoi(&argv[arg][14]); |
465 | |
466 | if(item<OSMSegments->file.number) |
467 | print_segment_visualiser(OSMSegments,item,OSMWays); |
468 | else |
469 | printf("Invalid segment number; minimum=0, maximum=%"Pindex_t".\n",OSMSegments->file.number-1); |
470 | } |
471 | else if(!strncmp(argv[arg],"--data=turn-relation",20)) |
472 | { |
473 | item=atoi(&argv[arg][20]); |
474 | |
475 | if(item<OSMRelations->file.trnumber) |
476 | print_turn_relation_visualiser(OSMRelations,item,OSMSegments,OSMNodes); |
477 | else |
478 | printf("Invalid turn relation number; minimum=0, maximum=%"Pindex_t".\n",OSMRelations->file.trnumber-1); |
479 | } |
480 | else if(!strncmp(argv[arg],"--data=errorlog",15)) |
481 | { |
482 | item=atoi(&argv[arg][15]); |
483 | |
484 | if(item<OSMErrorLogs->file.number) |
485 | print_errorlog_visualiser(OSMErrorLogs,item); |
486 | else |
487 | printf("Invalid error log number; minimum=0, maximum=%"Pindex_t".\n",OSMErrorLogs->file.number-1); |
488 | } |
489 | } |
490 | |
491 | exit(EXIT_SUCCESS); |
492 | } |
493 | |
494 | |
495 | /*++++++++++++++++++++++++++++++++++++++ |
496 | Print out the contents of a node from the routing database (as plain text). |
497 | |
498 | Nodes *nodes The set of nodes to use. |
499 | |
500 | index_t item The node index to print. |
501 | ++++++++++++++++++++++++++++++++++++++*/ |
502 | |
503 | static void print_node(Nodes *nodes,index_t item) |
504 | { |
505 | Node *nodep=LookupNode(nodes,item,1); |
506 | double latitude,longitude; |
507 | |
508 | GetLatLong(nodes,item,nodep,&latitude,&longitude); |
509 | |
510 | printf("Node %"Pindex_t"\n",item); |
511 | printf(" firstseg=%"Pindex_t"\n",nodep->firstseg); |
512 | printf(" latoffset=%d lonoffset=%d (latitude=%.6f longitude=%.6f)\n",nodep->latoffset,nodep->lonoffset,radians_to_degrees(latitude),radians_to_degrees(longitude)); |
513 | printf(" allow=%02x (%s)\n",nodep->allow,TransportsNameList(nodep->allow)); |
514 | printf(" destination=%02x (%s)\n",nodep->destination,TransportsNameList(nodep->destination)); |
515 | if(IsSuperNode(nodep)) |
516 | printf(" Super-Node\n"); |
517 | if(nodep->flags & NODE_MINIRNDBT) |
518 | printf(" Mini-roundabout\n"); |
519 | } |
520 | |
521 | |
522 | /*++++++++++++++++++++++++++++++++++++++ |
523 | Print out the contents of a segment from the routing database (as plain text). |
524 | |
525 | Segments *segments The set of segments to use. |
526 | |
527 | index_t item The segment index to print. |
528 | ++++++++++++++++++++++++++++++++++++++*/ |
529 | |
530 | static void print_segment(Segments *segments,index_t item) |
531 | { |
532 | Segment *segmentp=LookupSegment(segments,item,1); |
533 | |
534 | printf("Segment %"Pindex_t"\n",item); |
535 | printf(" node1=%"Pindex_t" node2=%"Pindex_t"\n",segmentp->node1,segmentp->node2); |
536 | printf(" next2=%"Pindex_t"\n",segmentp->next2); |
537 | printf(" way=%"Pindex_t"\n",segmentp->way); |
538 | printf(" distance=%d (%.3f km)\n",DISTANCE(segmentp->distance),distance_to_km(DISTANCE(segmentp->distance))); |
539 | if(IsSuperSegment(segmentp) && IsNormalSegment(segmentp)) |
540 | printf(" Super-Segment AND normal Segment\n"); |
541 | else if(IsSuperSegment(segmentp) && !IsNormalSegment(segmentp)) |
542 | printf(" Super-Segment\n"); |
543 | if(IsOnewayTo(segmentp,segmentp->node1)) |
544 | printf(" One-Way from node2 to node1\n"); |
545 | if(IsOnewayTo(segmentp,segmentp->node2)) |
546 | printf(" One-Way from node1 to node2\n"); |
547 | } |
548 | |
549 | |
550 | /*++++++++++++++++++++++++++++++++++++++ |
551 | Print out the contents of a way from the routing database (as plain text). |
552 | |
553 | Ways *ways The set of ways to use. |
554 | |
555 | index_t item The way index to print. |
556 | ++++++++++++++++++++++++++++++++++++++*/ |
557 | |
558 | static void print_way(Ways *ways,index_t item) |
559 | { |
560 | Way *wayp=LookupWay(ways,item,1); |
561 | char *name=WayName(ways,wayp); |
562 | |
563 | printf("Way %"Pindex_t"\n",item); |
564 | if(*name) |
565 | printf(" name=%s\n",name); |
566 | printf(" type=%02x (%s%s%s%s)\n",wayp->type, |
567 | HighwayName(HIGHWAY(wayp->type)), |
568 | wayp->type&Highway_OneWay?",One-Way":"", |
569 | wayp->type&Highway_CycleBothWays?",Cycle-Both-Ways":"", |
570 | wayp->type&Highway_Roundabout?",Roundabout":""); |
571 | printf(" allow=%02x (%s)\n",wayp->allow,TransportsNameList(wayp->allow)); |
572 | printf(" destination=%02x (%s)\n",wayp->destination,TransportsNameList(wayp->destination)); |
573 | if(wayp->props) |
574 | printf(" props=%02x (%s)\n",wayp->props,PropertiesNameList(wayp->props)); |
575 | if(wayp->speed) |
576 | printf(" speed=%d (%d km/hr)\n",wayp->speed,speed_to_kph(wayp->speed)); |
577 | if(wayp->weight) |
578 | printf(" weight=%d (%.1f tonnes)\n",wayp->weight,weight_to_tonnes(wayp->weight)); |
579 | if(wayp->height) |
580 | printf(" height=%d (%.1f m)\n",wayp->height,height_to_metres(wayp->height)); |
581 | if(wayp->width) |
582 | printf(" width=%d (%.1f m)\n",wayp->width,width_to_metres(wayp->width)); |
583 | if(wayp->length) |
584 | printf(" length=%d (%.1f m)\n",wayp->length,length_to_metres(wayp->length)); |
585 | } |
586 | |
587 | |
588 | /*++++++++++++++++++++++++++++++++++++++ |
589 | Print out the contents of a turn relation from the routing database (as plain text). |
590 | |
591 | Relations *relations The set of relations to use. |
592 | |
593 | index_t item The turn relation index to print. |
594 | |
595 | Segments *segments The set of segments to use. |
596 | |
597 | Nodes *nodes The set of nodes to use. |
598 | ++++++++++++++++++++++++++++++++++++++*/ |
599 | |
600 | static void print_turn_relation(Relations *relations,index_t item,Segments *segments,Nodes *nodes) |
601 | { |
602 | Segment *segmentp; |
603 | TurnRelation *relationp=LookupTurnRelation(relations,item,1); |
604 | Node *nodep=LookupNode(nodes,relationp->via,1); |
605 | index_t from_way=NO_WAY,to_way=NO_WAY; |
606 | index_t from_node=NO_NODE,to_node=NO_NODE; |
607 | |
608 | segmentp=FirstSegment(segments,nodep,1); |
609 | |
610 | do |
611 | { |
612 | index_t seg=IndexSegment(segments,segmentp); |
613 | |
614 | if(seg==relationp->from) |
615 | { |
616 | from_node=OtherNode(segmentp,relationp->via); |
617 | from_way=segmentp->way; |
618 | } |
619 | |
620 | if(seg==relationp->to) |
621 | { |
622 | to_node=OtherNode(segmentp,relationp->via); |
623 | to_way=segmentp->way; |
624 | } |
625 | |
626 | segmentp=NextSegment(segments,segmentp,relationp->via); |
627 | } |
628 | while(segmentp); |
629 | |
630 | printf("Relation %"Pindex_t"\n",item); |
631 | printf(" from=%"Pindex_t" (segment) = %"Pindex_t" (way) = %"Pindex_t" (node)\n",relationp->from,from_way,from_node); |
632 | printf(" via=%"Pindex_t" (node)\n",relationp->via); |
633 | printf(" to=%"Pindex_t" (segment) = %"Pindex_t" (way) = %"Pindex_t" (node)\n",relationp->to,to_way,to_node); |
634 | if(relationp->except) |
635 | printf(" except=%02x (%s)\n",relationp->except,TransportsNameList(relationp->except)); |
636 | } |
637 | |
638 | |
639 | /*++++++++++++++++++++++++++++++++++++++ |
640 | Print out the contents of an error log from the routing database (as plain text). |
641 | |
642 | ErrorLogs *errorlogs The set of error logs to use. |
643 | |
644 | index_t item The error log index to print. |
645 | ++++++++++++++++++++++++++++++++++++++*/ |
646 | |
647 | static void print_errorlog(ErrorLogs *errorlogs,index_t item) |
648 | { |
649 | ErrorLog *errorlogp=LookupErrorLog(errorlogs,item,1); |
650 | |
651 | printf("Error Log %"Pindex_t"\n",item); |
652 | |
653 | if(item<errorlogs->file.number_geo) |
654 | { |
655 | double latitude,longitude; |
656 | |
657 | GetErrorLogLatLong(errorlogs,item,errorlogp,&latitude,&longitude); |
658 | |
659 | printf(" latoffset=%d lonoffset=%d (latitude=%.6f longitude=%.6f)\n",errorlogp->latoffset,errorlogp->lonoffset,radians_to_degrees(latitude),radians_to_degrees(longitude)); |
660 | } |
661 | else |
662 | printf(" No geographical information\n"); |
663 | |
664 | printf(" '%s'\n",LookupErrorLogString(errorlogs,item)); |
665 | } |
666 | |
667 | |
668 | /*++++++++++++++++++++++++++++++++++++++ |
669 | Print out a header in OSM XML format. |
670 | |
671 | int coordcount If true then include a bounding box. |
672 | |
673 | double latmin The minimum latitude. |
674 | |
675 | double latmax The maximum latitude. |
676 | |
677 | double lonmin The minimum longitude. |
678 | |
679 | double lonmax The maximum longitude. |
680 | ++++++++++++++++++++++++++++++++++++++*/ |
681 | |
682 | static void print_head_osm(int coordcount,double latmin,double latmax,double lonmin,double lonmax) |
683 | { |
684 | printf("<?xml version='1.0' encoding='UTF-8'?>\n"); |
685 | printf("<osm version='0.6' generator='Routino'>\n"); |
686 | |
687 | if(coordcount) |
688 | printf(" <bounds minlat='%.6f' maxlat='%.6f' minlon='%.6f' maxlon='%.6f' />\n", |
689 | radians_to_degrees(latmin),radians_to_degrees(latmax),radians_to_degrees(lonmin),radians_to_degrees(lonmax)); |
690 | } |
691 | |
692 | |
693 | /*++++++++++++++++++++++++++++++++++++++ |
694 | Print a region of the database in OSM XML format. |
695 | |
696 | Nodes *nodes The set of nodes to use. |
697 | |
698 | Segments *segments The set of segments to use. |
699 | |
700 | Ways *ways The set of ways to use. |
701 | |
702 | Relations *relations The set of relations to use. |
703 | |
704 | double latmin The minimum latitude. |
705 | |
706 | double latmax The maximum latitude. |
707 | |
708 | double lonmin The minimum longitude. |
709 | |
710 | double lonmax The maximum longitude. |
711 | |
712 | int option_no_super The option to print no super-segments. |
713 | ++++++++++++++++++++++++++++++++++++++*/ |
714 | |
715 | static void print_region_osm(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations, |
716 | double latmin,double latmax,double lonmin,double lonmax,int option_no_super) |
717 | { |
718 | ll_bin_t latminbin=latlong_to_bin(radians_to_latlong(latmin))-nodes->file.latzero; |
719 | ll_bin_t latmaxbin=latlong_to_bin(radians_to_latlong(latmax))-nodes->file.latzero; |
720 | ll_bin_t lonminbin=latlong_to_bin(radians_to_latlong(lonmin))-nodes->file.lonzero; |
721 | ll_bin_t lonmaxbin=latlong_to_bin(radians_to_latlong(lonmax))-nodes->file.lonzero; |
722 | ll_bin_t latb,lonb; |
723 | index_t item,index1,index2; |
724 | |
725 | if(latminbin<0) latminbin=0; |
726 | if(latmaxbin>nodes->file.latbins) latmaxbin=nodes->file.latbins-1; |
727 | if(lonminbin<0) lonminbin=0; |
728 | if(lonmaxbin>nodes->file.lonbins) lonmaxbin=nodes->file.lonbins-1; |
729 | |
730 | /* Loop through all of the nodes. */ |
731 | |
732 | for(latb=latminbin;latb<=latmaxbin;latb++) |
733 | for(lonb=lonminbin;lonb<=lonmaxbin;lonb++) |
734 | { |
735 | ll_bin2_t llbin=lonb*nodes->file.latbins+latb; |
736 | |
737 | if(llbin<0 || llbin>(nodes->file.latbins*nodes->file.lonbins)) |
738 | continue; |
739 | |
740 | index1=LookupNodeOffset(nodes,llbin); |
741 | index2=LookupNodeOffset(nodes,llbin+1); |
742 | |
743 | for(item=index1;item<index2;item++) |
744 | { |
745 | Node *nodep=LookupNode(nodes,item,1); |
746 | double lat=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(nodep->latoffset)); |
747 | double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(nodep->lonoffset)); |
748 | |
749 | if(lat>latmin && lat<latmax && lon>lonmin && lon<lonmax) |
750 | { |
751 | Segment *segmentp; |
752 | |
753 | print_node_osm(nodes,item); |
754 | |
755 | segmentp=FirstSegment(segments,nodep,1); |
756 | |
757 | while(segmentp) |
758 | { |
759 | double olat,olon; |
760 | index_t oitem=OtherNode(segmentp,item); |
761 | |
762 | GetLatLong(nodes,oitem,NULL,&olat,&olon); |
763 | |
764 | if(olat>latmin && olat<latmax && olon>lonmin && olon<lonmax) |
765 | if(item>oitem) |
766 | if(!option_no_super || IsNormalSegment(segmentp)) |
767 | print_segment_osm(segments,IndexSegment(segments,segmentp),ways); |
768 | |
769 | segmentp=NextSegment(segments,segmentp,item); |
770 | } |
771 | |
772 | if(IsTurnRestrictedNode(nodep)) |
773 | { |
774 | index_t relindex=FindFirstTurnRelation1(relations,item); |
775 | |
776 | while(relindex!=NO_RELATION) |
777 | { |
778 | print_turn_relation_osm(relations,relindex,segments,nodes); |
779 | |
780 | relindex=FindNextTurnRelation1(relations,relindex); |
781 | } |
782 | } |
783 | } |
784 | } |
785 | } |
786 | } |
787 | |
788 | |
789 | /*++++++++++++++++++++++++++++++++++++++ |
790 | Print out the contents of a node from the routing database (in OSM XML format). |
791 | |
792 | Nodes *nodes The set of nodes to use. |
793 | |
794 | index_t item The node index to print. |
795 | ++++++++++++++++++++++++++++++++++++++*/ |
796 | |
797 | static void print_node_osm(Nodes *nodes,index_t item) |
798 | { |
799 | Node *nodep=LookupNode(nodes,item,1); |
800 | double latitude,longitude; |
801 | int i; |
802 | |
803 | GetLatLong(nodes,item,nodep,&latitude,&longitude); |
804 | |
805 | if(nodep->allow==Transports_ALL && nodep->destination==Transports_None && nodep->flags==0) |
806 | printf(" <node id='%"Pindex_t"' lat='%.7f' lon='%.7f' version='1' />\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude)); |
807 | else |
808 | { |
809 | printf(" <node id='%"Pindex_t"' lat='%.7f' lon='%.7f' version='1'>\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude)); |
810 | |
811 | if(nodep->flags & NODE_SUPER) |
812 | printf(" <tag k='routino:super' v='yes' />\n"); |
813 | |
814 | if(nodep->flags & NODE_UTURN) |
815 | printf(" <tag k='routino:uturn' v='yes' />\n"); |
816 | |
817 | if(nodep->flags & NODE_MINIRNDBT) |
818 | printf(" <tag k='junction' v='roundabout' />\n"); |
819 | |
820 | if(nodep->flags & NODE_TURNRSTRCT) |
821 | printf(" <tag k='routino:turnrestriction' v='yes' />\n"); |
822 | |
823 | for(i=1;i<Transport_Count;i++) |
824 | { |
825 | if(nodep->destination & TRANSPORTS(i)) |
826 | printf(" <tag k='%s' v='destination' />\n",TransportName(i)); |
827 | else if(!(nodep->allow & TRANSPORTS(i))) |
828 | printf(" <tag k='%s' v='no' />\n",TransportName(i)); |
829 | } |
830 | |
831 | printf(" </node>\n"); |
832 | } |
833 | } |
834 | |
835 | |
836 | /*++++++++++++++++++++++++++++++++++++++ |
837 | Print out the contents of a segment from the routing database (as a way in OSM XML format). |
838 | |
839 | Segments *segments The set of segments to use. |
840 | |
841 | index_t item The segment index to print. |
842 | |
843 | Ways *ways The set of ways to use. |
844 | ++++++++++++++++++++++++++++++++++++++*/ |
845 | |
846 | static void print_segment_osm(Segments *segments,index_t item,Ways *ways) |
847 | { |
848 | Segment *segmentp=LookupSegment(segments,item,1); |
849 | Way *wayp=LookupWay(ways,segmentp->way,1); |
850 | char *name=WayName(ways,wayp); |
851 | int i; |
852 | |
853 | printf(" <way id='%"Pindex_t"' version='1'>\n",item+1); |
854 | |
855 | if(IsOnewayTo(segmentp,segmentp->node1)) |
856 | { |
857 | printf(" <nd ref='%"Pindex_t"' />\n",segmentp->node2+1); |
858 | printf(" <nd ref='%"Pindex_t"' />\n",segmentp->node1+1); |
859 | } |
860 | else |
861 | { |
862 | printf(" <nd ref='%"Pindex_t"' />\n",segmentp->node1+1); |
863 | printf(" <nd ref='%"Pindex_t"' />\n",segmentp->node2+1); |
864 | } |
865 | |
866 | if(IsSuperSegment(segmentp)) |
867 | printf(" <tag k='routino:super' v='yes' />\n"); |
868 | if(IsNormalSegment(segmentp)) |
869 | printf(" <tag k='routino:normal' v='yes' />\n"); |
870 | |
871 | printf(" <tag k='routino:distance' v='%.3f' />\n",distance_to_km(DISTANCE(segmentp->distance))); |
872 | |
873 | if(wayp->type & Highway_OneWay) |
874 | printf(" <tag k='oneway' v='yes' />\n"); |
875 | |
876 | if(wayp->type & Highway_CycleBothWays) |
877 | printf(" <tag k='cyclebothways' v='yes' />\n"); |
878 | |
879 | if(wayp->type & Highway_Roundabout) |
880 | printf(" <tag k='roundabout' v='yes' />\n"); |
881 | |
882 | printf(" <tag k='highway' v='%s' />\n",HighwayName(HIGHWAY(wayp->type))); |
883 | |
884 | if(IsNormalSegment(segmentp) && *name) |
885 | printf(" <tag k='name' v='%s' />\n",ParseXML_Encode_Safe_XML(name)); |
886 | |
887 | for(i=1;i<Transport_Count;i++) |
888 | { |
889 | if(wayp->destination & TRANSPORTS(i)) |
890 | printf(" <tag k='%s' v='destination' />\n",TransportName(i)); |
891 | else if(wayp->allow & TRANSPORTS(i)) |
892 | printf(" <tag k='%s' v='yes' />\n",TransportName(i)); |
893 | } |
894 | |
895 | for(i=1;i<Property_Count;i++) |
896 | if(wayp->props & PROPERTIES(i)) |
897 | printf(" <tag k='%s' v='yes' />\n",PropertyName(i)); |
898 | |
899 | if(wayp->speed) |
900 | printf(" <tag k='maxspeed' v='%d' />\n",speed_to_kph(wayp->speed)); |
901 | |
902 | if(wayp->weight) |
903 | printf(" <tag k='maxweight' v='%.1f' />\n",weight_to_tonnes(wayp->weight)); |
904 | if(wayp->height) |
905 | printf(" <tag k='maxheight' v='%.1f' />\n",height_to_metres(wayp->height)); |
906 | if(wayp->width) |
907 | printf(" <tag k='maxwidth' v='%.1f' />\n",width_to_metres(wayp->width)); |
908 | if(wayp->length) |
909 | printf(" <tag k='maxlength' v='%.1f' />\n",length_to_metres(wayp->length)); |
910 | |
911 | printf(" </way>\n"); |
912 | } |
913 | |
914 | |
915 | /*++++++++++++++++++++++++++++++++++++++ |
916 | Print out the contents of a turn relation from the routing database (in OSM XML format). |
917 | |
918 | Relations *relations The set of relations to use. |
919 | |
920 | index_t item The relation index to print. |
921 | |
922 | Segments *segments The set of segments to use. |
923 | |
924 | Nodes *nodes The set of nodes to use. |
925 | ++++++++++++++++++++++++++++++++++++++*/ |
926 | |
927 | static void print_turn_relation_osm(Relations *relations,index_t item,Segments *segments,Nodes *nodes) |
928 | { |
929 | TurnRelation *relationp=LookupTurnRelation(relations,item,1); |
930 | |
931 | Segment *segmentp_from=LookupSegment(segments,relationp->from,1); |
932 | Segment *segmentp_to =LookupSegment(segments,relationp->to ,2); |
933 | |
934 | double angle=TurnAngle(nodes,segmentp_from,segmentp_to,relationp->via); |
935 | |
936 | char *restriction; |
937 | |
938 | if(angle>150 || angle<-150) |
939 | restriction="no_u_turn"; |
940 | else if(angle>30) |
941 | restriction="no_right_turn"; |
942 | else if(angle<-30) |
943 | restriction="no_left_turn"; |
944 | else |
945 | restriction="no_straight_on"; |
946 | |
947 | printf(" <relation id='%"Pindex_t"' version='1'>\n",item+1); |
948 | printf(" <tag k='type' v='restriction' />\n"); |
949 | printf(" <tag k='restriction' v='%s'/>\n",restriction); |
950 | |
951 | if(relationp->except) |
952 | printf(" <tag k='except' v='%s' />\n",TransportsNameList(relationp->except)); |
953 | |
954 | printf(" <member type='way' ref='%"Pindex_t"' role='from' />\n",relationp->from+1); |
955 | printf(" <member type='node' ref='%"Pindex_t"' role='via' />\n",relationp->via+1); |
956 | printf(" <member type='way' ref='%"Pindex_t"' role='to' />\n",relationp->to+1); |
957 | |
958 | printf(" </relation>\n"); |
959 | } |
960 | |
961 | |
962 | /*++++++++++++++++++++++++++++++++++++++ |
963 | Print out a tail in OSM XML format. |
964 | ++++++++++++++++++++++++++++++++++++++*/ |
965 | |
966 | static void print_tail_osm(void) |
967 | { |
968 | printf("</osm>\n"); |
969 | } |
970 | |
971 | |
972 | /*++++++++++++++++++++++++++++++++++++++ |
973 | Print out the contents of a node from the routing database (in visualiser format). |
974 | |
975 | Nodes *nodes The set of nodes to use. |
976 | |
977 | index_t item The node index to print. |
978 | ++++++++++++++++++++++++++++++++++++++*/ |
979 | |
980 | static void print_node_visualiser(Nodes *nodes,index_t item) |
981 | { |
982 | Node *nodep=LookupNode(nodes,item,1); |
983 | double latitude,longitude; |
984 | int i; |
985 | |
986 | GetLatLong(nodes,item,nodep,&latitude,&longitude); |
987 | |
988 | if(nodep->allow==Transports_ALL && nodep->destination==Transports_None && nodep->flags==0) |
989 | printf("<routino:node id='%"Pindex_t"' lat='%.7f' lon='%.7f' />\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude)); |
990 | else |
991 | { |
992 | printf("<routino:node id='%"Pindex_t"' lat='%.7f' lon='%.7f'>\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude)); |
993 | |
994 | if(nodep->flags & NODE_SUPER) |
995 | printf(" <tag k='routino:super' v='yes' />\n"); |
996 | |
997 | if(nodep->flags & NODE_UTURN) |
998 | printf(" <tag k='routino:uturn' v='yes' />\n"); |
999 | |
1000 | if(nodep->flags & NODE_MINIRNDBT) |
1001 | printf(" <tag k='junction' v='roundabout' />\n"); |
1002 | |
1003 | if(nodep->flags & NODE_TURNRSTRCT) |
1004 | printf(" <tag k='routino:turnrestriction' v='yes' />\n"); |
1005 | |
1006 | for(i=1;i<Transport_Count;i++) |
1007 | { |
1008 | if(nodep->destination & TRANSPORTS(i)) |
1009 | printf(" <tag k='%s' v='destination' />\n",TransportName(i)); |
1010 | else if(!(nodep->allow & TRANSPORTS(i))) |
1011 | printf(" <tag k='%s' v='no' />\n",TransportName(i)); |
1012 | } |
1013 | |
1014 | printf("</routino:node>\n"); |
1015 | } |
1016 | } |
1017 | |
1018 | |
1019 | /*++++++++++++++++++++++++++++++++++++++ |
1020 | Print out the contents of a segment from the routing database (as a way in visualiser format). |
1021 | |
1022 | Segments *segments The set of segments to use. |
1023 | |
1024 | index_t item The segment index to print. |
1025 | |
1026 | Ways *ways The set of ways to use. |
1027 | ++++++++++++++++++++++++++++++++++++++*/ |
1028 | |
1029 | static void print_segment_visualiser(Segments *segments,index_t item,Ways *ways) |
1030 | { |
1031 | Segment *segmentp=LookupSegment(segments,item,1); |
1032 | Way *wayp=LookupWay(ways,segmentp->way,1); |
1033 | char *name=WayName(ways,wayp); |
1034 | int i; |
1035 | |
1036 | printf("<routino:way id='%"Pindex_t"'>\n",item+1); |
1037 | |
1038 | if(IsOnewayTo(segmentp,segmentp->node1)) |
1039 | { |
1040 | printf(" <nd ref='%"Pindex_t"' />\n",segmentp->node2+1); |
1041 | printf(" <nd ref='%"Pindex_t"' />\n",segmentp->node1+1); |
1042 | } |
1043 | else |
1044 | { |
1045 | printf(" <nd ref='%"Pindex_t"' />\n",segmentp->node1+1); |
1046 | printf(" <nd ref='%"Pindex_t"' />\n",segmentp->node2+1); |
1047 | } |
1048 | |
1049 | if(IsSuperSegment(segmentp)) |
1050 | printf(" <tag k='routino:super' v='yes' />\n"); |
1051 | if(IsNormalSegment(segmentp)) |
1052 | printf(" <tag k='routino:normal' v='yes' />\n"); |
1053 | |
1054 | printf(" <tag k='routino:distance' v='%.3f km' />\n",distance_to_km(DISTANCE(segmentp->distance))); |
1055 | |
1056 | if(wayp->type & Highway_OneWay) |
1057 | printf(" <tag k='oneway' v='yes' />\n"); |
1058 | |
1059 | if(wayp->type & Highway_CycleBothWays) |
1060 | printf(" <tag k='cyclebothways' v='yes' />\n"); |
1061 | |
1062 | if(wayp->type & Highway_Roundabout) |
1063 | printf(" <tag k='roundabout' v='yes' />\n"); |
1064 | |
1065 | printf(" <tag k='highway' v='%s' />\n",HighwayName(HIGHWAY(wayp->type))); |
1066 | |
1067 | if(IsNormalSegment(segmentp) && *name) |
1068 | printf(" <tag k='name' v='%s' />\n",ParseXML_Encode_Safe_XML(name)); |
1069 | |
1070 | for(i=1;i<Transport_Count;i++) |
1071 | if(wayp->destination & TRANSPORTS(i)) |
1072 | printf(" <tag k='%s' v='destination' />\n",TransportName(i)); |
1073 | else if(wayp->allow & TRANSPORTS(i)) |
1074 | printf(" <tag k='%s' v='yes' />\n",TransportName(i)); |
1075 | |
1076 | for(i=1;i<Property_Count;i++) |
1077 | if(wayp->props & PROPERTIES(i)) |
1078 | printf(" <tag k='%s' v='yes' />\n",PropertyName(i)); |
1079 | |
1080 | if(wayp->speed) |
1081 | printf(" <tag k='maxspeed' v='%d kph' />\n",speed_to_kph(wayp->speed)); |
1082 | |
1083 | if(wayp->weight) |
1084 | printf(" <tag k='maxweight' v='%.1f t' />\n",weight_to_tonnes(wayp->weight)); |
1085 | if(wayp->height) |
1086 | printf(" <tag k='maxheight' v='%.1f m' />\n",height_to_metres(wayp->height)); |
1087 | if(wayp->width) |
1088 | printf(" <tag k='maxwidth' v='%.1f m' />\n",width_to_metres(wayp->width)); |
1089 | if(wayp->length) |
1090 | printf(" <tag k='maxlength' v='%.1f m' />\n",length_to_metres(wayp->length)); |
1091 | |
1092 | printf("</routino:way>\n"); |
1093 | } |
1094 | |
1095 | |
1096 | /*++++++++++++++++++++++++++++++++++++++ |
1097 | Print out the contents of a turn relation from the routing database (in visualiser format). |
1098 | |
1099 | Relations *relations The set of relations to use. |
1100 | |
1101 | index_t item The relation index to print. |
1102 | |
1103 | Segments *segments The set of segments to use. |
1104 | |
1105 | Nodes *nodes The set of nodes to use. |
1106 | ++++++++++++++++++++++++++++++++++++++*/ |
1107 | |
1108 | static void print_turn_relation_visualiser(Relations *relations,index_t item,Segments *segments,Nodes *nodes) |
1109 | { |
1110 | TurnRelation *relationp=LookupTurnRelation(relations,item,1); |
1111 | |
1112 | Segment *segmentp_from=LookupSegment(segments,relationp->from,1); |
1113 | Segment *segmentp_to =LookupSegment(segments,relationp->to ,2); |
1114 | |
1115 | double angle=TurnAngle(nodes,segmentp_from,segmentp_to,relationp->via); |
1116 | |
1117 | char *restriction; |
1118 | |
1119 | if(angle>150 || angle<-150) |
1120 | restriction="no_u_turn"; |
1121 | else if(angle>30) |
1122 | restriction="no_right_turn"; |
1123 | else if(angle<-30) |
1124 | restriction="no_left_turn"; |
1125 | else |
1126 | restriction="no_straight_on"; |
1127 | |
1128 | printf("<routino:relation id='%"Pindex_t"'>\n",item+1); |
1129 | printf(" <tag k='type' v='restriction' />\n"); |
1130 | printf(" <tag k='restriction' v='%s'/>\n",restriction); |
1131 | |
1132 | if(relationp->except) |
1133 | printf(" <tag k='except' v='%s' />\n",TransportsNameList(relationp->except)); |
1134 | |
1135 | printf(" <member type='way' ref='%"Pindex_t"' role='from' />\n",relationp->from+1); |
1136 | printf(" <member type='node' ref='%"Pindex_t"' role='via' />\n",relationp->via+1); |
1137 | printf(" <member type='way' ref='%"Pindex_t"' role='to' />\n",relationp->to+1); |
1138 | |
1139 | printf("</routino:relation>\n"); |
1140 | } |
1141 | |
1142 | |
1143 | /*++++++++++++++++++++++++++++++++++++++ |
1144 | Print out an error log entry from the database (in visualiser format). |
1145 | |
1146 | ErrorLogs *errorlogs The set of error logs to use. |
1147 | |
1148 | index_t item The error log index to print. |
1149 | ++++++++++++++++++++++++++++++++++++++*/ |
1150 | |
1151 | static void print_errorlog_visualiser(ErrorLogs *errorlogs,index_t item) |
1152 | { |
1153 | char *string=LookupErrorLogString(errorlogs,item); |
1154 | |
1155 | printf("%s\n",ParseXML_Encode_Safe_XML(string)); |
1156 | } |
1157 | |
1158 | |
1159 | /*+ Conversion from time_t to date string (day of week). +*/ |
1160 | static const char* const weekdays[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; |
1161 | |
1162 | /*+ Conversion from time_t to date string (month of year). +*/ |
1163 | static const char* const months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; |
1164 | |
1165 | |
1166 | /*++++++++++++++++++++++++++++++++++++++ |
1167 | Convert the time into an RFC 822 compliant date. |
1168 | |
1169 | char *RFC822Date Returns a pointer to a fixed string containing the date. |
1170 | |
1171 | time_t t The time. |
1172 | ++++++++++++++++++++++++++++++++++++++*/ |
1173 | |
1174 | static char *RFC822Date(time_t t) |
1175 | { |
1176 | static char value[80]; /* static allocation of return value */ |
1177 | char weekday[4]; |
1178 | char month[4]; |
1179 | struct tm *tim; |
1180 | |
1181 | tim=gmtime(&t); |
1182 | |
1183 | strcpy(weekday,weekdays[tim->tm_wday]); |
1184 | strcpy(month,months[tim->tm_mon]); |
1185 | |
1186 | /* Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 */ |
1187 | |
1188 | sprintf(value,"%3s, %02d %3s %4d %02d:%02d:%02d %s", |
1189 | weekday, |
1190 | tim->tm_mday, |
1191 | month, |
1192 | tim->tm_year+1900, |
1193 | tim->tm_hour, |
1194 | tim->tm_min, |
1195 | tim->tm_sec, |
1196 | "GMT" |
1197 | ); |
1198 | |
1199 | return(value); |
1200 | } |
1201 | |
1202 | |
1203 | /*++++++++++++++++++++++++++++++++++++++ |
1204 | Print out the usage information. |
1205 | |
1206 | int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details. |
1207 | |
1208 | const char *argerr The argument that gave the error (if there is one). |
1209 | |
1210 | const char *err Other error message (if there is one). |
1211 | ++++++++++++++++++++++++++++++++++++++*/ |
1212 | |
1213 | static void print_usage(int detail,const char *argerr,const char *err) |
1214 | { |
1215 | if(detail<0) |
1216 | { |
1217 | fprintf(stderr, |
1218 | "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n" |
1219 | ); |
1220 | } |
1221 | |
1222 | if(detail>=0) |
1223 | { |
1224 | fprintf(stderr, |
1225 | "Usage: filedumper [--version]\n" |
1226 | " [--help]\n" |
1227 | " [--dir=<dirname>] [--prefix=<name>]\n" |
1228 | " [--statistics]\n" |
1229 | " [--visualiser --latmin=<latmin> --latmax=<latmax>\n" |
1230 | " --lonmin=<lonmin> --lonmax=<lonmax>\n" |
1231 | " --data=<data-type>]\n" |
1232 | " [--dump [--node=<node> ...]\n" |
1233 | " [--segment=<segment> ...]\n" |
1234 | " [--way=<way> ...]\n" |
1235 | " [--turn-relation=<rel> ...]\n" |
1236 | " [--errorlog=<number> ...]]\n" |
1237 | " [--dump-osm [--no-super]\n" |
1238 | " [--latmin=<latmin> --latmax=<latmax>\n" |
1239 | " --lonmin=<lonmin> --lonmax=<lonmax>]]\n" |
1240 | " [--dump-visualiser [--data=node<node>]\n" |
1241 | " [--data=segment<segment>]\n" |
1242 | " [--data=turn-relation<rel>]\n" |
1243 | " [--data=errorlog<number>]]\n"); |
1244 | |
1245 | if(argerr) |
1246 | fprintf(stderr, |
1247 | "\n" |
1248 | "Error with command line parameter: %s\n",argerr); |
1249 | |
1250 | if(err) |
1251 | fprintf(stderr, |
1252 | "\n" |
1253 | "Error: %s\n",err); |
1254 | } |
1255 | |
1256 | if(detail==1) |
1257 | fprintf(stderr, |
1258 | "\n" |
1259 | "--version Print the version of Routino.\n" |
1260 | "\n" |
1261 | "--help Prints this information.\n" |
1262 | "\n" |
1263 | "--dir=<dirname> The directory containing the routing database.\n" |
1264 | "--prefix=<name> The filename prefix for the routing database.\n" |
1265 | "\n" |
1266 | "--statistics Print statistics about the routing database.\n" |
1267 | "\n" |
1268 | "--visualiser Extract selected data from the routing database:\n" |
1269 | " --latmin=<latmin> * the minimum latitude (degrees N).\n" |
1270 | " --latmax=<latmax> * the maximum latitude (degrees N).\n" |
1271 | " --lonmin=<lonmin> * the minimum longitude (degrees E).\n" |
1272 | " --lonmax=<lonmax> * the maximum longitude (degrees E).\n" |
1273 | " --data=<data-type> * the type of data to select.\n" |
1274 | "\n" |
1275 | " <data-type> can be selected from:\n" |
1276 | " junctions = segment count at each junction.\n" |
1277 | " super = super-node and super-segments.\n" |
1278 | " waytype-* = segments of oneway, cyclebothways or roundabout type.\n" |
1279 | " highway-* = segments of the specified highway type.\n" |
1280 | " transport-* = segments allowing the specified transport type.\n" |
1281 | " destination-* = segments allowing the specified transport type to\n" |
1282 | " destinations only (i.e. first and last waypoint).\n" |
1283 | " barrier-* = nodes disallowing the specified transport type.\n" |
1284 | " turns = turn restrictions.\n" |
1285 | " speed = speed limits.\n" |
1286 | " weight = weight limits.\n" |
1287 | " height = height limits.\n" |
1288 | " width = width limits.\n" |
1289 | " length = length limits.\n" |
1290 | " property-* = segments with the specified property.\n" |
1291 | " errorlogs = errors logged during parsing.\n" |
1292 | "\n" |
1293 | "--dump Dump selected contents of the database.\n" |
1294 | " --node=<node> * the node with the selected index.\n" |
1295 | " --segment=<segment> * the segment with the selected index.\n" |
1296 | " --way=<way> * the way with the selected index.\n" |
1297 | " --turn-relation=<rel> * the turn relation with the selected index.\n" |
1298 | " --errorlog=<number> * the error log with the selected index.\n" |
1299 | " Use 'all' instead of a number to get all of them.\n" |
1300 | "\n" |
1301 | "--dump-osm Dump all or part of the database as an XML file.\n" |
1302 | " --no-super * exclude the super-segments.\n" |
1303 | " --latmin=<latmin> * the minimum latitude (degrees N).\n" |
1304 | " --latmax=<latmax> * the maximum latitude (degrees N).\n" |
1305 | " --lonmin=<lonmin> * the minimum longitude (degrees E).\n" |
1306 | " --lonmax=<lonmax> * the maximum longitude (degrees E).\n" |
1307 | "\n" |
1308 | "--dump-visualiser Dump selected contents of the database in HTML.\n" |
1309 | " --data=node<node> * the node with the selected index.\n" |
1310 | " --data=segment<segment> * the segment with the selected index.\n" |
1311 | " --data=turn-relation<rel> * the turn relation with the selected index.\n" |
1312 | " --data=errorlog<number> * the error log with the selected index.\n"); |
1313 | |
1314 | exit(!detail); |
1315 | } |
Properties
Name | Value |
---|---|
cvs:description | Test program for mmap files. |