Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/errorlogx.c

Parent Directory Parent Directory | Revision Log 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)
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 }