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