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/waysx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1348 - (show annotations) (download) (as text)
Mon May 27 18:29:44 2013 UTC (11 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 20258 byte(s)
Simplify the sorting of the way names (only sort the names, not all the ways
twice), merge the generating of segments and separation of way names.

1 /***************************************
2 Extended Way data type functions.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-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 <stdlib.h>
24 #include <string.h>
25
26 #include "types.h"
27 #include "ways.h"
28
29 #include "typesx.h"
30 #include "nodesx.h"
31 #include "segmentsx.h"
32 #include "waysx.h"
33
34 #include "files.h"
35 #include "logging.h"
36 #include "sorting.h"
37
38
39 /* Global variables */
40
41 /*+ The command line '--tmpdir' option or its default value. +*/
42 extern char *option_tmpdirname;
43
44 /* Local variables */
45
46 /*+ Temporary file-local variables for use by the sort functions. +*/
47 static WaysX *sortwaysx;
48 static SegmentsX *sortsegmentsx;
49
50 /* Local functions */
51
52 static int sort_by_id(WayX *a,WayX *b);
53 static int deduplicate_and_index_by_id(WayX *wayx,index_t index);
54
55 static int sort_by_name(char *a,char *b);
56
57 static int delete_unused(WayX *wayx,index_t index);
58 static int sort_by_name_and_prop_and_id(WayX *a,WayX *b);
59 static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index);
60
61
62 /*++++++++++++++++++++++++++++++++++++++
63 Allocate a new way list (create a new file or open an existing one).
64
65 WaysX *NewWayList Returns the way list.
66
67 int append Set to 1 if the file is to be opened for appending.
68
69 int readonly Set to 1 if the file is to be opened for reading.
70 ++++++++++++++++++++++++++++++++++++++*/
71
72 WaysX *NewWayList(int append,int readonly)
73 {
74 WaysX *waysx;
75
76 waysx=(WaysX*)calloc(1,sizeof(WaysX));
77
78 logassert(waysx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */
79
80 waysx->filename =(char*)malloc(strlen(option_tmpdirname)+32);
81 waysx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
82
83 sprintf(waysx->filename ,"%s/waysx.parsed.mem",option_tmpdirname);
84 sprintf(waysx->filename_tmp,"%s/waysx.%p.tmp" ,option_tmpdirname,(void*)waysx);
85
86 if(append || readonly)
87 if(ExistsFile(waysx->filename))
88 {
89 off_t size,position=0;
90 int fd;
91
92 size=SizeFile(waysx->filename);
93
94 fd=ReOpenFile(waysx->filename);
95
96 while(position<size)
97 {
98 FILESORT_VARINT waysize;
99
100 SeekReadFile(fd,&waysize,FILESORT_VARSIZE,position);
101
102 waysx->number++;
103
104 position+=waysize+FILESORT_VARSIZE;
105 }
106
107 CloseFile(fd);
108
109 RenameFile(waysx->filename,waysx->filename_tmp);
110 }
111
112 if(append)
113 waysx->fd=OpenFileAppend(waysx->filename_tmp);
114 else if(!readonly)
115 waysx->fd=OpenFileNew(waysx->filename_tmp);
116 else
117 waysx->fd=-1;
118
119 #if SLIM
120 waysx->cache=NewWayXCache();
121 #endif
122
123
124 waysx->nfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
125
126 sprintf(waysx->nfilename_tmp,"%s/waynames.%p.tmp",option_tmpdirname,(void*)waysx);
127
128 return(waysx);
129 }
130
131
132 /*++++++++++++++++++++++++++++++++++++++
133 Free a way list.
134
135 WaysX *waysx The set of ways to be freed.
136
137 int keep If set then the results file is to be kept.
138 ++++++++++++++++++++++++++++++++++++++*/
139
140 void FreeWayList(WaysX *waysx,int keep)
141 {
142 if(keep)
143 RenameFile(waysx->filename_tmp,waysx->filename);
144 else
145 DeleteFile(waysx->filename_tmp);
146
147 free(waysx->filename);
148 free(waysx->filename_tmp);
149
150 if(waysx->idata)
151 free(waysx->idata);
152
153 if(waysx->odata)
154 free(waysx->odata);
155
156 if(waysx->cdata)
157 free(waysx->cdata);
158
159 DeleteFile(waysx->nfilename_tmp);
160
161 free(waysx->nfilename_tmp);
162
163 #if SLIM
164 DeleteWayXCache(waysx->cache);
165 #endif
166
167 free(waysx);
168 }
169
170
171 /*++++++++++++++++++++++++++++++++++++++
172 Append a single way to an unsorted way list.
173
174 WaysX *waysx The set of ways to process.
175
176 way_t id The ID of the way.
177
178 Way *way The way data itself.
179
180 node_t *nodes The list of nodes for this way.
181
182 int nnodes The number of nodes for this way.
183
184 const char *name The name or reference of the way.
185 ++++++++++++++++++++++++++++++++++++++*/
186
187 void AppendWayList(WaysX *waysx,way_t id,Way *way,node_t *nodes,int nnodes,const char *name)
188 {
189 WayX wayx;
190 FILESORT_VARINT size;
191 node_t nonode=NO_NODE_ID;
192
193 wayx.id=id;
194 wayx.way=*way;
195
196 size=sizeof(WayX)+(nnodes+1)*sizeof(node_t)+strlen(name)+1;
197
198 WriteFile(waysx->fd,&size,FILESORT_VARSIZE);
199 WriteFile(waysx->fd,&wayx,sizeof(WayX));
200
201 WriteFile(waysx->fd,nodes ,nnodes*sizeof(node_t));
202 WriteFile(waysx->fd,&nonode, sizeof(node_t));
203
204 WriteFile(waysx->fd,name,strlen(name)+1);
205
206 waysx->number++;
207
208 logassert(waysx->number!=0,"Too many ways (change index_t to 64-bits?)"); /* Zero marks the high-water mark for ways. */
209 }
210
211
212 /*++++++++++++++++++++++++++++++++++++++
213 Finish appending ways and change the filename over.
214
215 WaysX *waysx The ways that have been appended.
216 ++++++++++++++++++++++++++++++++++++++*/
217
218 void FinishWayList(WaysX *waysx)
219 {
220 if(waysx->fd!=-1)
221 waysx->fd=CloseFile(waysx->fd);
222 }
223
224
225 /*++++++++++++++++++++++++++++++++++++++
226 Find a particular way index.
227
228 index_t IndexWayX Returns the index of the extended way with the specified id.
229
230 WaysX *waysx The set of ways to process.
231
232 way_t id The way id to look for.
233 ++++++++++++++++++++++++++++++++++++++*/
234
235 index_t IndexWayX(WaysX *waysx,way_t id)
236 {
237 index_t start=0;
238 index_t end=waysx->number-1;
239 index_t mid;
240
241 if(waysx->number==0) /* There are no ways */
242 return(NO_WAY);
243
244 if(id<waysx->idata[start]) /* Key is before start */
245 return(NO_WAY);
246
247 if(id>waysx->idata[end]) /* Key is after end */
248 return(NO_WAY);
249
250 /* Binary search - search key exact match only is required.
251 *
252 * # <- start | Check mid and move start or end if it doesn't match
253 * # |
254 * # | Since an exact match is wanted we can set end=mid-1
255 * # <- mid | or start=mid+1 because we know that mid doesn't match.
256 * # |
257 * # | Eventually either end=start or end=start+1 and one of
258 * # <- end | start or end is the wanted one.
259 */
260
261 do
262 {
263 mid=(start+end)/2; /* Choose mid point */
264
265 if(waysx->idata[mid]<id) /* Mid point is too low */
266 start=mid+1;
267 else if(waysx->idata[mid]>id) /* Mid point is too high */
268 end=mid?(mid-1):mid;
269 else /* Mid point is correct */
270 return(mid);
271 }
272 while((end-start)>1);
273
274 if(waysx->idata[start]==id) /* Start is correct */
275 return(start);
276
277 if(waysx->idata[end]==id) /* End is correct */
278 return(end);
279
280 return(NO_WAY);
281 }
282
283
284 /*++++++++++++++++++++++++++++++++++++++
285 Sort the list of ways.
286
287 WaysX *waysx The set of ways to process.
288 ++++++++++++++++++++++++++++++++++++++*/
289
290 void SortWayList(WaysX *waysx)
291 {
292 index_t xnumber;
293 int fd;
294
295 /* Print the start message */
296
297 printf_first("Sorting Ways");
298
299 /* Re-open the file read-only and a new file writeable */
300
301 waysx->fd=ReOpenFile(waysx->filename_tmp);
302
303 DeleteFile(waysx->filename_tmp);
304
305 fd=OpenFileNew(waysx->filename_tmp);
306
307 /* Allocate the array of indexes */
308
309 waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t));
310
311 logassert(waysx->idata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
312
313 /* Sort the ways by ID and index them */
314
315 sortwaysx=waysx;
316
317 xnumber=waysx->number;
318
319 waysx->number=filesort_vary(waysx->fd,fd,NULL,
320 (int (*)(const void*,const void*))sort_by_id,
321 (int (*)(void*,index_t))deduplicate_and_index_by_id);
322
323 /* Close the files */
324
325 waysx->fd=CloseFile(waysx->fd);
326 CloseFile(fd);
327
328 /* Print the final message */
329
330 printf_last("Sorted Ways: Ways=%"Pindex_t" Duplicates=%"Pindex_t,xnumber,xnumber-waysx->number);
331 }
332
333
334 /*++++++++++++++++++++++++++++++++++++++
335 Sort the ways into id order.
336
337 int sort_by_id Returns the comparison of the id fields.
338
339 WayX *a The first extended way.
340
341 WayX *b The second extended way.
342 ++++++++++++++++++++++++++++++++++++++*/
343
344 static int sort_by_id(WayX *a,WayX *b)
345 {
346 way_t a_id=a->id;
347 way_t b_id=b->id;
348
349 if(a_id<b_id)
350 return(-1);
351 else if(a_id>b_id)
352 return(1);
353 else
354 return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */
355 }
356
357
358 /*++++++++++++++++++++++++++++++++++++++
359 Discard duplicate ways and create and index of ids.
360
361 int deduplicate_by_id Return 1 if the value is to be kept, otherwise 0.
362
363 WayX *wayx The extended way.
364
365 index_t index The number of sorted ways that have already been written to the output file.
366 ++++++++++++++++++++++++++++++++++++++*/
367
368 static int deduplicate_and_index_by_id(WayX *wayx,index_t index)
369 {
370 static way_t previd=NO_WAY_ID;
371
372 if(wayx->id!=previd)
373 {
374 previd=wayx->id;
375
376 if(wayx->way.type==WAY_DELETED)
377 return(0);
378 else
379 {
380 sortwaysx->idata[index]=wayx->id;
381
382 return(1);
383 }
384 }
385 else
386 return(0);
387 }
388
389
390 /*++++++++++++++++++++++++++++++++++++++
391 Split the ways into segments and way names.
392
393 WaysX *waysx The set of ways to process.
394
395 int keep If set to 1 then keep the old data file otherwise delete it.
396 ++++++++++++++++++++++++++++++++++++++*/
397
398 SegmentsX *SplitWays(WaysX *waysx,int keep)
399 {
400 SegmentsX *segmentsx;
401 index_t i;
402 int fd,nfd;
403 char *name=NULL;
404 int namelen=0;
405
406 /* Print the start message */
407
408 printf_first("Splitting Ways: Ways=0 Segments=0");
409
410 segmentsx=NewSegmentList();
411
412 /* Re-open the file read-only and a new file writeable */
413
414 waysx->fd=ReOpenFile(waysx->filename_tmp);
415
416 if(keep)
417 RenameFile(waysx->filename_tmp,waysx->filename);
418 else
419 DeleteFile(waysx->filename_tmp);
420
421 waysx->knumber=waysx->number;
422
423 fd=OpenFileNew(waysx->filename_tmp);
424
425 nfd=OpenFileNew(waysx->nfilename_tmp);
426
427 /* Loop through the ways and create the segments and way names */
428
429 for(i=0;i<waysx->number;i++)
430 {
431 WayX wayx;
432 FILESORT_VARINT size;
433 node_t node,prevnode=NO_NODE_ID;
434
435 ReadFile(waysx->fd,&size,FILESORT_VARSIZE);
436
437 ReadFile(waysx->fd,&wayx,sizeof(WayX));
438
439 while(!ReadFile(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID)
440 {
441 if(prevnode==NO_NODE_ID)
442 ;
443 else if(prevnode==node)
444 logerror("Node %"Pnode_t" in way %"Pway_t" is connected to itself.\n",logerror_node(node),logerror_way(wayx.id));
445 else
446 {
447 distance_t segment_flags=0;
448
449 if(wayx.way.type&Highway_OneWay)
450 segment_flags|=ONEWAY_1TO2;
451
452 if(wayx.way.type&Highway_Area)
453 segment_flags|=SEGMENT_AREA;
454
455 AppendSegmentList(segmentsx,wayx.id,prevnode,node,segment_flags);
456 }
457
458 prevnode=node;
459
460 size-=sizeof(node_t);
461 }
462
463 size-=sizeof(node_t)+sizeof(WayX);
464
465 if(namelen<size)
466 name=(char*)realloc((void*)name,namelen=size);
467
468 ReadFile(waysx->fd,name,size);
469
470 WriteFile(fd,&wayx,sizeof(WayX));
471
472 size+=sizeof(index_t);
473
474 WriteFile(nfd,&size,FILESORT_VARSIZE);
475 WriteFile(nfd,&i,sizeof(index_t));
476 WriteFile(nfd,name,size-sizeof(index_t));
477
478 if(!((i+1)%1000))
479 printf_middle("Splitting Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,i+1,segmentsx->number);
480 }
481
482 FinishSegmentList(segmentsx);
483
484 if(name) free(name);
485
486 /* Close the files */
487
488 waysx->fd=CloseFile(waysx->fd);
489 CloseFile(fd);
490
491 close(nfd);
492
493 /* Print the final message */
494
495 printf_last("Splitting Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,waysx->number,segmentsx->number);
496
497 return(segmentsx);
498 }
499
500
501
502 /*++++++++++++++++++++++++++++++++++++++
503 Sort the way names and assign the offsets to the ways.
504
505 WaysX *waysx The set of ways to process.
506 ++++++++++++++++++++++++++++++++++++++*/
507
508 void SortWayNames(WaysX *waysx)
509 {
510 index_t i;
511 int nfd;
512 char *names[2]={NULL,NULL};
513 int namelen[2]={0,0};
514 int nnames=0;
515 uint32_t lastlength=0;
516
517 /* Print the start message */
518
519 printf_first("Sorting Way Names");
520
521 /* Re-open the file read-only and new file writeable */
522
523 waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
524
525 DeleteFile(waysx->nfilename_tmp);
526
527 nfd=OpenFileNew(waysx->nfilename_tmp);
528
529 /* Sort the way names */
530
531 waysx->nlength=0;
532
533 filesort_vary(waysx->nfd,nfd,NULL,
534 (int (*)(const void*,const void*))sort_by_name,
535 NULL);
536
537 /* Close the files */
538
539 waysx->nfd=CloseFile(waysx->nfd);
540 CloseFile(nfd);
541
542 /* Print the final message */
543
544 printf_last("Sorted Way Names: Ways=%"Pindex_t,waysx->number);
545
546
547 #if !SLIM
548 waysx->data=MapFileWriteable(waysx->filename_tmp);
549 #else
550 waysx->fd=ReOpenFileWriteable(waysx->filename_tmp);
551 #endif
552
553 /* Print the start message */
554
555 printf_first("Updating Ways with Names: Ways=0 Names=0");
556
557 /* Re-open the file read-only and new file writeable */
558
559 waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
560
561 DeleteFile(waysx->nfilename_tmp);
562
563 nfd=OpenFileNew(waysx->nfilename_tmp);
564
565 /* Copy from the single file into two files */
566
567 for(i=0;i<waysx->number;i++)
568 {
569 WayX *wayx;
570 index_t index;
571 FILESORT_VARINT size;
572
573 ReadFile(waysx->nfd,&size,FILESORT_VARSIZE);
574
575 if(namelen[nnames%2]<size)
576 names[nnames%2]=(char*)realloc((void*)names[nnames%2],namelen[nnames%2]=size);
577
578 ReadFile(waysx->nfd,&index,sizeof(index_t));
579 ReadFile(waysx->nfd,names[nnames%2],size-sizeof(index_t));
580
581 if(nnames==0 || strcmp(names[0],names[1]))
582 {
583 WriteFile(nfd,names[nnames%2],size-sizeof(index_t));
584
585 lastlength=waysx->nlength;
586 waysx->nlength+=size-sizeof(index_t);
587
588 nnames++;
589 }
590
591 wayx=LookupWayX(waysx,index,1);
592
593 wayx->way.name=lastlength;
594
595 PutBackWayX(waysx,wayx);
596
597 if(!((i+1)%1000))
598 printf_middle("Updating Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,i+1,nnames);
599 }
600
601 if(names[0]) free(names[0]);
602 if(names[1]) free(names[1]);
603
604 /* Close the files */
605
606 waysx->nfd=CloseFile(waysx->nfd);
607 CloseFile(nfd);
608
609 /* Print the final message */
610
611 printf_last("Updated Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,waysx->number,nnames);
612
613
614 /* Unmap from memory / close the files */
615
616 #if !SLIM
617 waysx->data=UnmapFile(waysx->data);
618 #else
619 waysx->fd=CloseFile(waysx->fd);
620 #endif
621 }
622
623
624 /*++++++++++++++++++++++++++++++++++++++
625 Sort the ways into name order.
626
627 int sort_by_name Returns the comparison of the name fields.
628
629 char *a The first way name.
630
631 char *b The second way name.
632 ++++++++++++++++++++++++++++++++++++++*/
633
634 static int sort_by_name(char *a,char *b)
635 {
636 int compare;
637 char *a_name=a+sizeof(index_t);
638 char *b_name=b+sizeof(index_t);
639
640 compare=strcmp(a_name,b_name);
641
642 if(compare)
643 return(compare);
644 else
645 return(FILESORT_PRESERVE_ORDER(a,b));
646 }
647
648
649 /*++++++++++++++++++++++++++++++++++++++
650 Compact the way list, removing duplicated ways and unused ways.
651
652 WaysX *waysx The set of ways to process.
653
654 SegmentsX *segmentsx The set of segments to check.
655 ++++++++++++++++++++++++++++++++++++++*/
656
657 void CompactWayList(WaysX *waysx,SegmentsX *segmentsx)
658 {
659 int fd;
660 index_t cnumber;
661
662 if(waysx->number==0)
663 return;
664
665 /* Print the start message */
666
667 printf_first("Sorting Ways and Compacting");
668
669 /* Allocate the array of indexes */
670
671 waysx->cdata=(index_t*)malloc(waysx->number*sizeof(index_t));
672
673 logassert(waysx->cdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
674
675 /* Re-open the file read-only and a new file writeable */
676
677 waysx->fd=ReOpenFile(waysx->filename_tmp);
678
679 DeleteFile(waysx->filename_tmp);
680
681 fd=OpenFileNew(waysx->filename_tmp);
682
683 /* Sort the ways to allow compacting according to the properties */
684
685 sortwaysx=waysx;
686 sortsegmentsx=segmentsx;
687
688 cnumber=filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(void*,index_t))delete_unused,
689 (int (*)(const void*,const void*))sort_by_name_and_prop_and_id,
690 (int (*)(void*,index_t))deduplicate_and_index_by_compact_id);
691
692 /* Close the files */
693
694 waysx->fd=CloseFile(waysx->fd);
695 CloseFile(fd);
696
697 /* Print the final message */
698
699 printf_last("Sorted and Compacted Ways: Ways=%"Pindex_t" Unique=%"Pindex_t,waysx->number,cnumber);
700 waysx->number=cnumber;
701
702 free(segmentsx->usedway);
703 segmentsx->usedway=NULL;
704 }
705
706
707 /*++++++++++++++++++++++++++++++++++++++
708 Delete the ways that are no longer being used.
709
710 int delete_unused Return 1 if the value is to be kept, otherwise 0.
711
712 WayX *wayx The extended way.
713
714 index_t index The number of unsorted ways that have been read from the input file.
715 ++++++++++++++++++++++++++++++++++++++*/
716
717 static int delete_unused(WayX *wayx,index_t index)
718 {
719 if(sortsegmentsx && !IsBitSet(sortsegmentsx->usedway,index))
720 {
721 sortwaysx->cdata[index]=NO_WAY;
722
723 return(0);
724 }
725 else
726 {
727 wayx->id=index;
728
729 return(1);
730 }
731 }
732
733
734 /*++++++++++++++++++++++++++++++++++++++
735 Sort the ways into name, properties and id order.
736
737 int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields.
738
739 WayX *a The first extended Way.
740
741 WayX *b The second extended Way.
742 ++++++++++++++++++++++++++++++++++++++*/
743
744 static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
745 {
746 int compare;
747 index_t a_name=a->way.name;
748 index_t b_name=b->way.name;
749
750 if(a_name<b_name)
751 return(-1);
752 else if(a_name>b_name)
753 return(1);
754
755 compare=WaysCompare(&a->way,&b->way);
756
757 if(compare)
758 return(compare);
759
760 return(sort_by_id(a,b));
761 }
762
763
764 /*++++++++++++++++++++++++++++++++++++++
765 Create the index of compacted Way identifiers and ignore Ways with duplicated properties.
766
767 int deduplicate_and_index_by_compact_id Return 1 if the value is to be kept, otherwise 0.
768
769 WayX *wayx The extended way.
770
771 index_t index The number of sorted ways that have already been written to the output file.
772 ++++++++++++++++++++++++++++++++++++++*/
773
774 static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index)
775 {
776 static Way lastway;
777
778 if(index==0 || wayx->way.name!=lastway.name || WaysCompare(&lastway,&wayx->way))
779 {
780 lastway=wayx->way;
781
782 sortwaysx->cdata[wayx->id]=index;
783
784 wayx->id=index;
785
786 return(1);
787 }
788 else
789 {
790 sortwaysx->cdata[wayx->id]=index-1;
791
792 return(0);
793 }
794 }
795
796
797 /*++++++++++++++++++++++++++++++++++++++
798 Save the way list to a file.
799
800 WaysX *waysx The set of ways to save.
801
802 const char *filename The name of the file to save.
803 ++++++++++++++++++++++++++++++++++++++*/
804
805 void SaveWayList(WaysX *waysx,const char *filename)
806 {
807 index_t i;
808 int fd;
809 index_t position=0;
810 WayX wayx;
811 WaysFile waysfile={0};
812 highways_t highways=0;
813 transports_t allow=0;
814 properties_t props=0;
815
816 /* Print the start message */
817
818 printf_first("Writing Ways: Ways=0");
819
820 /* Re-open the files */
821
822 waysx->fd=ReOpenFile(waysx->filename_tmp);
823 waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
824
825 /* Write out the ways data */
826
827 fd=OpenFileNew(filename);
828
829 SeekFile(fd,sizeof(WaysFile));
830
831 for(i=0;i<waysx->number;i++)
832 {
833 ReadFile(waysx->fd,&wayx,sizeof(WayX));
834
835 highways|=HIGHWAYS(wayx.way.type);
836 allow |=wayx.way.allow;
837 props |=wayx.way.props;
838
839 WriteFile(fd,&wayx.way,sizeof(Way));
840
841 if(!((i+1)%1000))
842 printf_middle("Writing Ways: Ways=%"Pindex_t,i+1);
843 }
844
845 /* Write out the ways names */
846
847 SeekFile(fd,sizeof(WaysFile)+(off_t)waysx->number*sizeof(Way));
848
849 while(position<waysx->nlength)
850 {
851 size_t len=1024;
852 char temp[1024];
853
854 if((waysx->nlength-position)<1024)
855 len=waysx->nlength-position;
856
857 ReadFile(waysx->nfd,temp,len);
858
859 WriteFile(fd,temp,len);
860
861 position+=len;
862 }
863
864 /* Close the files */
865
866 waysx->fd=CloseFile(waysx->fd);
867 waysx->nfd=CloseFile(waysx->nfd);
868
869 /* Write out the header structure */
870
871 waysfile.number =waysx->number;
872
873 waysfile.highways=highways;
874 waysfile.allow =allow;
875 waysfile.props =props;
876
877 SeekFile(fd,0);
878 WriteFile(fd,&waysfile,sizeof(WaysFile));
879
880 CloseFile(fd);
881
882 /* Print the final message */
883
884 printf_last("Wrote Ways: Ways=%"Pindex_t,waysx->number);
885 }

Properties

Name Value
cvs:description Extended ways functions.