Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/errorlogx.c
Parent Directory
|
Revision Log
Revision 1320 -
(show annotations)
(download)
(as text)
Tue May 14 18:57:52 2013 UTC (11 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 13090 byte(s)
Tue May 14 18:57:52 2013 UTC (11 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 13090 byte(s)
Copy errorlogx.h to errorlog.h and create errorlog.c so that they mirror the nodes.h and nodes.c filenames. Add functions to read in a set of error logs from a file.
1 | /*************************************** |
2 | Error log processing functions. |
3 | |
4 | Part of the Routino routing software. |
5 | ******************/ /****************** |
6 | This file Copyright 2013 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 "typesx.h" |
24 | #include "nodesx.h" |
25 | #include "waysx.h" |
26 | #include "relationsx.h" |
27 | |
28 | #include "errorlogx.h" |
29 | #include "errorlog.h" |
30 | |
31 | #include "files.h" |
32 | #include "sorting.h" |
33 | |
34 | |
35 | /* Local variables */ |
36 | |
37 | /*+ The name of the error log file. +*/ |
38 | extern char *errorlogfilename; |
39 | |
40 | /*+ The name of the binary error log file. +*/ |
41 | extern char *errorbinfilename; |
42 | |
43 | |
44 | /* Local functions */ |
45 | |
46 | static void reindex_nodes(NodesX *nodesx); |
47 | static void reindex_ways(WaysX *waysx); |
48 | static void reindex_relations(RelationsX *relationsx); |
49 | static int sort_by_lat_long(ErrorLogX *a,ErrorLogX *b); |
50 | |
51 | |
52 | /*++++++++++++++++++++++++++++++++++++++ |
53 | Process the binary error log. |
54 | |
55 | NodesX *nodesx The set of nodes. |
56 | |
57 | WaysX *waysx The set of ways. |
58 | |
59 | RelationsX *relationsx The set of relations. |
60 | ++++++++++++++++++++++++++++++++++++++*/ |
61 | |
62 | void ProcessErrorLogs(NodesX *nodesx,WaysX *waysx,RelationsX *relationsx) |
63 | { |
64 | int oldfd,newfd; |
65 | uint32_t offset=0; |
66 | int nerrorlogobjects=0; |
67 | int finished; |
68 | ErrorLogObject errorlogobjects[8]; |
69 | index_t number; |
70 | |
71 | /* Re-index the nodes, ways and relations */ |
72 | |
73 | printf_first("Re-indexing the Nodes, Ways and Relations: Nodes=0 Ways=0 Relations=0"); |
74 | |
75 | reindex_nodes(nodesx); |
76 | |
77 | printf_middle("Re-indexing the Nodes, Ways and Relations: Nodes=%"Pindex_t" Ways=0 Relations=0",nodesx->number); |
78 | |
79 | reindex_ways(waysx); |
80 | |
81 | printf_middle("Re-indexing the Nodes, Ways and Relations: Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=0",nodesx->number,waysx->number); |
82 | |
83 | reindex_relations(relationsx); |
84 | |
85 | printf_last("Re-indexed the Nodes, Ways and Relations: Nodes=%"Pindex_t" Ways=%"Pindex_t" Relations=%"Pindex_t,nodesx->number,waysx->number,relationsx->trnumber); |
86 | |
87 | |
88 | /* Print the start message */ |
89 | |
90 | printf_first("Calculating Coordinates: Errors=0"); |
91 | |
92 | /* Map into memory / open the files */ |
93 | |
94 | #if !SLIM |
95 | nodesx->data=MapFile(nodesx->filename); |
96 | waysx->data=MapFile(waysx->filename); |
97 | #else |
98 | nodesx->fd=ReOpenFile(nodesx->filename); |
99 | waysx->fd=ReOpenFile(waysx->filename); |
100 | |
101 | InvalidateNodeXCache(nodesx->cache); |
102 | InvalidateWayXCache(waysx->cache); |
103 | #endif |
104 | |
105 | /* Open the binary log file read-only and a new file writeable */ |
106 | |
107 | oldfd=ReOpenFile(errorbinfilename); |
108 | |
109 | DeleteFile(errorbinfilename); |
110 | |
111 | newfd=OpenFileNew(errorbinfilename); |
112 | |
113 | /* Loop through the file and merge the raw data into coordinates */ |
114 | |
115 | number=0; |
116 | |
117 | do |
118 | { |
119 | ErrorLogObject errorlogobject; |
120 | |
121 | finished=ReadFile(oldfd,&errorlogobject,sizeof(ErrorLogObject)); |
122 | |
123 | if(finished) |
124 | errorlogobject.offset=SizeFile(errorlogfilename); |
125 | |
126 | if(offset!=errorlogobject.offset) |
127 | { |
128 | ErrorLogX errorlogx; |
129 | int i; |
130 | latlong_t latitude=NO_LATLONG,longitude=NO_LATLONG; |
131 | |
132 | /* Calculate suitable coordinates */ |
133 | |
134 | for(i=0;i<nerrorlogobjects;i++) |
135 | { |
136 | if(((errorlogobjects[i].type_id>>56)&0xff)=='N') |
137 | { |
138 | index_t node=IndexNodeX(nodesx,errorlogobjects[i].type_id&(uint64_t)0x00ffffffffffffff); |
139 | |
140 | if(node!=NO_NODE) |
141 | { |
142 | NodeX *nodex=LookupNodeX(nodesx,node,1); |
143 | |
144 | latitude =nodex->latitude; |
145 | longitude=nodex->longitude; |
146 | } |
147 | } |
148 | } |
149 | |
150 | /* Write to file */ |
151 | |
152 | errorlogx.offset=offset; |
153 | errorlogx.length=errorlogobject.offset-offset; |
154 | |
155 | errorlogx.latitude =latitude; |
156 | errorlogx.longitude=longitude; |
157 | |
158 | // printf("errorlogx.lat=%ld (%f) .lon=%ld (%f)\n",errorlogx.latitude,radians_to_degrees(latlong_to_radians(errorlogx.latitude)),errorlogx.longitude,radians_to_degrees(latlong_to_radians(errorlogx.longitude))); |
159 | |
160 | WriteFile(newfd,&errorlogx,sizeof(ErrorLogX)); |
161 | |
162 | number++; |
163 | |
164 | offset=errorlogobject.offset; |
165 | nerrorlogobjects=0; |
166 | |
167 | if(!(number%10000)) |
168 | printf_middle("Calculating Coordinates: Errors=%"Pindex_t,number); |
169 | } |
170 | |
171 | /* Store for later */ |
172 | |
173 | logassert(nerrorlogobjects<8,"Too many error log objects for one error message."); /* Only a limited amount of information stored. */ |
174 | |
175 | errorlogobjects[nerrorlogobjects]=errorlogobject; |
176 | |
177 | nerrorlogobjects++; |
178 | } |
179 | while(!finished); |
180 | |
181 | /* Unmap from memory / close the files */ |
182 | |
183 | #if !SLIM |
184 | nodesx->data=UnmapFile(nodesx->data); |
185 | waysx->data=UnmapFile(waysx->data); |
186 | #else |
187 | nodesx->fd=CloseFile(nodesx->fd); |
188 | waysx->fd=CloseFile(waysx->fd); |
189 | #endif |
190 | |
191 | CloseFile(oldfd); |
192 | CloseFile(newfd); |
193 | |
194 | /* Print the final message */ |
195 | |
196 | printf_last("Calculated Coordinates: Errors=%"Pindex_t,number); |
197 | } |
198 | |
199 | |
200 | /*++++++++++++++++++++++++++++++++++++++ |
201 | Re-index the nodes that were kept. |
202 | |
203 | NodesX *nodesx The set of nodes to process (contains the filename and number of nodes). |
204 | ++++++++++++++++++++++++++++++++++++++*/ |
205 | |
206 | static void reindex_nodes(NodesX *nodesx) |
207 | { |
208 | int fd; |
209 | index_t index=0; |
210 | NodeX nodex; |
211 | |
212 | nodesx->number=nodesx->knumber; |
213 | |
214 | nodesx->idata=(node_t*)malloc(nodesx->number*sizeof(node_t)); |
215 | |
216 | /* Get the node id for each node in the file. */ |
217 | |
218 | fd=ReOpenFile(nodesx->filename); |
219 | |
220 | while(!ReadFile(fd,&nodex,sizeof(NodeX))) |
221 | { |
222 | nodesx->idata[index]=nodex.id; |
223 | |
224 | index++; |
225 | } |
226 | |
227 | CloseFile(fd); |
228 | } |
229 | |
230 | |
231 | /*++++++++++++++++++++++++++++++++++++++ |
232 | Re-index the ways that were kept. |
233 | |
234 | WaysX *waysx The set of ways to process (contains the filename and number of ways). |
235 | ++++++++++++++++++++++++++++++++++++++*/ |
236 | |
237 | static void reindex_ways(WaysX *waysx) |
238 | { |
239 | int fd; |
240 | off_t size,position=0; |
241 | index_t index=0; |
242 | WayX wayx; |
243 | |
244 | waysx->number=waysx->knumber; |
245 | |
246 | waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t)); |
247 | waysx->odata=(off_t*)malloc(waysx->number*sizeof(off_t)); |
248 | |
249 | /* Get the way id and the offset for each way in the file */ |
250 | |
251 | size=SizeFile(waysx->filename); |
252 | |
253 | fd=ReOpenFile(waysx->filename); |
254 | |
255 | while(position<size) |
256 | { |
257 | FILESORT_VARINT waysize; |
258 | |
259 | SeekReadFile(fd,&waysize,FILESORT_VARSIZE,position); |
260 | ReadFile(fd,&wayx,sizeof(WayX)); |
261 | |
262 | waysx->idata[index]=wayx.id; |
263 | waysx->odata[index]=position; |
264 | |
265 | index++; |
266 | |
267 | position+=waysize+FILESORT_VARSIZE; |
268 | } |
269 | |
270 | CloseFile(fd); |
271 | } |
272 | |
273 | |
274 | /*++++++++++++++++++++++++++++++++++++++ |
275 | Re-index the relations that were kept. |
276 | |
277 | RelationsX *relationsx The set of relations to process (contains the filename and number of relations). |
278 | ++++++++++++++++++++++++++++++++++++++*/ |
279 | |
280 | static void reindex_relations(RelationsX *relationsx) |
281 | { |
282 | } |
283 | |
284 | |
285 | /*++++++++++++++++++++++++++++++++++++++ |
286 | Sort the error logs geographically. |
287 | ++++++++++++++++++++++++++++++++++++++*/ |
288 | |
289 | void SortErrorLogsGeographically(void) |
290 | { |
291 | int oldfd,newfd; |
292 | |
293 | /* Print the start message */ |
294 | |
295 | printf_first("Sorting Errors Geographically"); |
296 | |
297 | /* Re-open the file read-only and a new file writeable */ |
298 | |
299 | oldfd=ReOpenFile(errorbinfilename); |
300 | |
301 | DeleteFile(errorbinfilename); |
302 | |
303 | newfd=OpenFileNew(errorbinfilename); |
304 | |
305 | /* Sort errors geographically */ |
306 | |
307 | filesort_fixed(oldfd,newfd,sizeof(ErrorLogX),NULL, |
308 | (int (*)(const void*,const void*))sort_by_lat_long, |
309 | NULL); |
310 | |
311 | /* Close the files */ |
312 | |
313 | CloseFile(oldfd); |
314 | CloseFile(newfd); |
315 | |
316 | /* Print the final message */ |
317 | |
318 | printf_last("Sorted Errors Geographically"); |
319 | } |
320 | |
321 | |
322 | /*++++++++++++++++++++++++++++++++++++++ |
323 | Sort the errors into latitude and longitude order (first by longitude bin |
324 | number, then by latitude bin number and then by exact longitude and then by |
325 | exact latitude). |
326 | |
327 | int sort_by_lat_long Returns the comparison of the latitude and longitude fields. |
328 | |
329 | ErrorLogX *a The first error location. |
330 | |
331 | ErrorLogX *b The second error location. |
332 | ++++++++++++++++++++++++++++++++++++++*/ |
333 | |
334 | static int sort_by_lat_long(ErrorLogX *a,ErrorLogX *b) |
335 | { |
336 | ll_bin_t a_lon=latlong_to_bin(a->longitude); |
337 | ll_bin_t b_lon=latlong_to_bin(b->longitude); |
338 | |
339 | if(a_lon<b_lon) |
340 | return(-1); |
341 | else if(a_lon>b_lon) |
342 | return(1); |
343 | else |
344 | { |
345 | ll_bin_t a_lat=latlong_to_bin(a->latitude); |
346 | ll_bin_t b_lat=latlong_to_bin(b->latitude); |
347 | |
348 | if(a_lat<b_lat) |
349 | return(-1); |
350 | else if(a_lat>b_lat) |
351 | return(1); |
352 | else |
353 | { |
354 | if(a->longitude<b->longitude) |
355 | return(-1); |
356 | else if(a->longitude>b->longitude) |
357 | return(1); |
358 | else |
359 | { |
360 | if(a->latitude<b->latitude) |
361 | return(-1); |
362 | else if(a->latitude>b->latitude) |
363 | return(1); |
364 | } |
365 | |
366 | return(FILESORT_PRESERVE_ORDER(a,b)); |
367 | } |
368 | } |
369 | } |
370 | |
371 | |
372 | /*++++++++++++++++++++++++++++++++++++++ |
373 | Save the binary error log. |
374 | |
375 | NodesX *nodesx The set of nodes to copy some data from. |
376 | |
377 | char *filename The name of the final file to write. |
378 | ++++++++++++++++++++++++++++++++++++++*/ |
379 | |
380 | void SaveErrorLogs(NodesX *nodesx,char *filename) |
381 | { |
382 | ErrorLogsFile errorlogsfile; |
383 | ErrorLogX errorlogx; |
384 | int oldfd,newfd; |
385 | ll_bin2_t latlonbin=0,maxlatlonbins; |
386 | index_t *offsets; |
387 | index_t number=0,number_geo=0,number_nongeo=0; |
388 | off_t size; |
389 | |
390 | /* Print the start message */ |
391 | |
392 | printf_first("Writing Errors: Geographical=0 Non-geographical=0"); |
393 | |
394 | /* Allocate the memory for the geographical offsets array */ |
395 | |
396 | offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t)); |
397 | |
398 | logassert(offsets,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ |
399 | |
400 | latlonbin=0; |
401 | |
402 | /* Re-open the file */ |
403 | |
404 | oldfd=ReOpenFile(errorbinfilename); |
405 | |
406 | newfd=OpenFileNew(filename); |
407 | |
408 | /* Write out the geographical errors */ |
409 | |
410 | SeekFile(newfd,sizeof(ErrorLogsFile)+(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t)); |
411 | |
412 | while(!ReadFile(oldfd,&errorlogx,sizeof(ErrorLogX))) |
413 | { |
414 | ErrorLog errorlog={0}; |
415 | ll_bin_t latbin,lonbin; |
416 | ll_bin2_t llbin; |
417 | |
418 | if(errorlogx.latitude==NO_LATLONG) |
419 | continue; |
420 | |
421 | /* Create the ErrorLog */ |
422 | |
423 | errorlog.latoffset=latlong_to_off(errorlogx.latitude); |
424 | errorlog.lonoffset=latlong_to_off(errorlogx.longitude); |
425 | |
426 | errorlog.offset=errorlogx.offset; |
427 | errorlog.length=errorlogx.length; |
428 | |
429 | /* Work out the offsets */ |
430 | |
431 | latbin=latlong_to_bin(errorlogx.latitude )-nodesx->latzero; |
432 | lonbin=latlong_to_bin(errorlogx.longitude)-nodesx->lonzero; |
433 | llbin=lonbin*nodesx->latbins+latbin; |
434 | |
435 | for(;latlonbin<=llbin;latlonbin++) |
436 | offsets[latlonbin]=number_geo; |
437 | |
438 | /* Write the data */ |
439 | |
440 | WriteFile(newfd,&errorlog,sizeof(ErrorLog)); |
441 | |
442 | number_geo++; |
443 | number++; |
444 | |
445 | if(!(number%10000)) |
446 | printf_middle("Writing Errors: Geographical=%"Pindex_t" Non-geographical=%"Pindex_t,number_geo,number_nongeo); |
447 | } |
448 | |
449 | /* Write out the non-geographical errors */ |
450 | |
451 | SeekFile(oldfd,0); |
452 | |
453 | while(!ReadFile(oldfd,&errorlogx,sizeof(ErrorLogX))) |
454 | { |
455 | ErrorLog errorlog={0}; |
456 | |
457 | if(errorlogx.latitude!=NO_LATLONG) |
458 | continue; |
459 | |
460 | /* Create the ErrorLog */ |
461 | |
462 | errorlog.latoffset=0; |
463 | errorlog.lonoffset=0; |
464 | |
465 | errorlog.offset=errorlogx.offset; |
466 | errorlog.length=errorlogx.length; |
467 | |
468 | /* Write the data */ |
469 | |
470 | WriteFile(newfd,&errorlog,sizeof(ErrorLog)); |
471 | |
472 | number_nongeo++; |
473 | number++; |
474 | |
475 | if(!(number%10000)) |
476 | printf_middle("Writing Errors: Geographical=%"Pindex_t" Non-geographical=%"Pindex_t,number_geo,number_nongeo); |
477 | } |
478 | |
479 | /* Close the input file */ |
480 | |
481 | CloseFile(oldfd); |
482 | |
483 | DeleteFile(errorbinfilename); |
484 | |
485 | /* Append the text from the log file */ |
486 | |
487 | size=SizeFile(errorlogfilename); |
488 | |
489 | oldfd=ReOpenFile(errorlogfilename); |
490 | |
491 | while(size) |
492 | { |
493 | char *buffer[4096]; |
494 | off_t chunksize=(size>sizeof(buffer)?sizeof(buffer):size); |
495 | |
496 | ReadFile(oldfd,buffer,chunksize); |
497 | |
498 | WriteFile(newfd,buffer,chunksize); |
499 | |
500 | size-=chunksize; |
501 | } |
502 | |
503 | CloseFile(oldfd); |
504 | |
505 | /* Finish off the offset indexing and write them out */ |
506 | |
507 | maxlatlonbins=nodesx->latbins*nodesx->lonbins; |
508 | |
509 | for(;latlonbin<=maxlatlonbins;latlonbin++) |
510 | offsets[latlonbin]=number_geo; |
511 | |
512 | SeekFile(newfd,sizeof(ErrorLogsFile)); |
513 | WriteFile(newfd,offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t)); |
514 | |
515 | free(offsets); |
516 | |
517 | /* Write out the header structure */ |
518 | |
519 | errorlogsfile.number =number; |
520 | errorlogsfile.number_geo =number_geo; |
521 | errorlogsfile.number_nongeo=number_nongeo; |
522 | |
523 | errorlogsfile.latbins=nodesx->latbins; |
524 | errorlogsfile.lonbins=nodesx->lonbins; |
525 | |
526 | errorlogsfile.latzero=nodesx->latzero; |
527 | errorlogsfile.lonzero=nodesx->lonzero; |
528 | |
529 | SeekFile(newfd,0); |
530 | WriteFile(newfd,&errorlogsfile,sizeof(ErrorLogsFile)); |
531 | |
532 | CloseFile(newfd); |
533 | |
534 | /* Print the final message */ |
535 | |
536 | printf_last("Wrote Errors: Geographical=%"Pindex_t" Non-geographical=%"Pindex_t,number_geo,number_nongeo); |
537 | } |