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 1380 - (show annotations) (download) (as text)
Tue Jun 4 19:03:55 2013 UTC (11 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 20680 byte(s)
Remember what types of transports we have so that we don't spend time pruning
for transport types we don't have.

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 waysx->knumber=waysx->number;
324
325 /* Close the files */
326
327 waysx->fd=CloseFile(waysx->fd);
328 CloseFile(fd);
329
330 /* Print the final message */
331
332 printf_last("Sorted Ways: Ways=%"Pindex_t" Duplicates=%"Pindex_t,xnumber,xnumber-waysx->number);
333 }
334
335
336 /*++++++++++++++++++++++++++++++++++++++
337 Sort the ways into id order.
338
339 int sort_by_id Returns the comparison of the id fields.
340
341 WayX *a The first extended way.
342
343 WayX *b The second extended way.
344 ++++++++++++++++++++++++++++++++++++++*/
345
346 static int sort_by_id(WayX *a,WayX *b)
347 {
348 way_t a_id=a->id;
349 way_t b_id=b->id;
350
351 if(a_id<b_id)
352 return(-1);
353 else if(a_id>b_id)
354 return(1);
355 else
356 return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */
357 }
358
359
360 /*++++++++++++++++++++++++++++++++++++++
361 Discard duplicate ways and create and index of ids.
362
363 int deduplicate_by_id Return 1 if the value is to be kept, otherwise 0.
364
365 WayX *wayx The extended way.
366
367 index_t index The number of sorted ways that have already been written to the output file.
368 ++++++++++++++++++++++++++++++++++++++*/
369
370 static int deduplicate_and_index_by_id(WayX *wayx,index_t index)
371 {
372 static way_t previd=NO_WAY_ID;
373
374 if(wayx->id!=previd)
375 {
376 previd=wayx->id;
377
378 if(wayx->way.type==WAY_DELETED)
379 return(0);
380 else
381 {
382 sortwaysx->idata[index]=wayx->id;
383
384 return(1);
385 }
386 }
387 else
388 return(0);
389 }
390
391
392 /*++++++++++++++++++++++++++++++++++++++
393 Split the ways into segments and way names.
394
395 WaysX *waysx The set of ways to process.
396
397 NodesX *nodesx The set of nodes to use.
398
399 int keep If set to 1 then keep the old data file otherwise delete it.
400 ++++++++++++++++++++++++++++++++++++++*/
401
402 SegmentsX *SplitWays(WaysX *waysx,NodesX *nodesx,int keep)
403 {
404 SegmentsX *segmentsx;
405 index_t i;
406 int fd,nfd;
407 char *name=NULL;
408 int namelen=0;
409
410 /* Print the start message */
411
412 printf_first("Splitting Ways: Ways=0 Segments=0");
413
414 segmentsx=NewSegmentList();
415
416 /* Re-open the file read-only and a new file writeable */
417
418 waysx->fd=ReOpenFile(waysx->filename_tmp);
419
420 if(keep)
421 RenameFile(waysx->filename_tmp,waysx->filename);
422 else
423 DeleteFile(waysx->filename_tmp);
424
425 fd=OpenFileNew(waysx->filename_tmp);
426
427 nfd=OpenFileNew(waysx->nfilename_tmp);
428
429 /* Loop through the ways and create the segments and way names */
430
431 for(i=0;i<waysx->number;i++)
432 {
433 WayX wayx;
434 FILESORT_VARINT size;
435 node_t node,prevnode=NO_NODE_ID;
436 index_t index,previndex=NO_NODE;
437
438 ReadFile(waysx->fd,&size,FILESORT_VARSIZE);
439
440 ReadFile(waysx->fd,&wayx,sizeof(WayX));
441
442 waysx->allow|=wayx.way.allow;
443
444 while(!ReadFile(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID)
445 {
446 index=IndexNodeX(nodesx,node);
447
448 if(prevnode==node)
449 {
450 logerror("Way %"Pway_t" contains node %"Pnode_t" that is connected to itself.\n",logerror_way(wayx.id),logerror_node(node));
451 }
452 else if(index==NO_NODE)
453 {
454 logerror("Way %"Pway_t" contains node %"Pnode_t" that does not exist in the Routino database.\n",logerror_way(wayx.id),logerror_node(node));
455 }
456 else if(previndex==NO_NODE)
457 ;
458 else
459 {
460 distance_t segment_flags=0;
461
462 if(wayx.way.type&Highway_OneWay)
463 segment_flags|=ONEWAY_1TO2;
464
465 if(wayx.way.type&Highway_Area)
466 segment_flags|=SEGMENT_AREA;
467
468 AppendSegmentList(segmentsx,i,previndex,index,segment_flags);
469 }
470
471 prevnode=node;
472 previndex=index;
473
474 size-=sizeof(node_t);
475 }
476
477 size-=sizeof(node_t)+sizeof(WayX);
478
479 if(namelen<size)
480 name=(char*)realloc((void*)name,namelen=size);
481
482 ReadFile(waysx->fd,name,size);
483
484 WriteFile(fd,&wayx,sizeof(WayX));
485
486 size+=sizeof(index_t);
487
488 WriteFile(nfd,&size,FILESORT_VARSIZE);
489 WriteFile(nfd,&i,sizeof(index_t));
490 WriteFile(nfd,name,size-sizeof(index_t));
491
492 if(!((i+1)%1000))
493 printf_middle("Splitting Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,i+1,segmentsx->number);
494 }
495
496 FinishSegmentList(segmentsx);
497
498 if(name) free(name);
499
500 /* Close the files */
501
502 waysx->fd=CloseFile(waysx->fd);
503 CloseFile(fd);
504
505 close(nfd);
506
507 /* Print the final message */
508
509 printf_last("Split Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,waysx->number,segmentsx->number);
510
511 return(segmentsx);
512 }
513
514
515
516 /*++++++++++++++++++++++++++++++++++++++
517 Sort the way names and assign the offsets to the ways.
518
519 WaysX *waysx The set of ways to process.
520 ++++++++++++++++++++++++++++++++++++++*/
521
522 void SortWayNames(WaysX *waysx)
523 {
524 index_t i;
525 int nfd;
526 char *names[2]={NULL,NULL};
527 int namelen[2]={0,0};
528 int nnames=0;
529 uint32_t lastlength=0;
530
531 /* Print the start message */
532
533 printf_first("Sorting Way Names");
534
535 /* Re-open the file read-only and new file writeable */
536
537 waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
538
539 DeleteFile(waysx->nfilename_tmp);
540
541 nfd=OpenFileNew(waysx->nfilename_tmp);
542
543 /* Sort the way names */
544
545 waysx->nlength=0;
546
547 filesort_vary(waysx->nfd,nfd,NULL,
548 (int (*)(const void*,const void*))sort_by_name,
549 NULL);
550
551 /* Close the files */
552
553 waysx->nfd=CloseFile(waysx->nfd);
554 CloseFile(nfd);
555
556 /* Print the final message */
557
558 printf_last("Sorted Way Names: Ways=%"Pindex_t,waysx->number);
559
560
561 #if !SLIM
562 waysx->data=MapFileWriteable(waysx->filename_tmp);
563 #else
564 waysx->fd=ReOpenFileWriteable(waysx->filename_tmp);
565 #endif
566
567 /* Print the start message */
568
569 printf_first("Updating Ways with Names: Ways=0 Names=0");
570
571 /* Re-open the file read-only and new file writeable */
572
573 waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
574
575 DeleteFile(waysx->nfilename_tmp);
576
577 nfd=OpenFileNew(waysx->nfilename_tmp);
578
579 /* Update the ways and de-duplicate the names */
580
581 for(i=0;i<waysx->number;i++)
582 {
583 WayX *wayx;
584 index_t index;
585 FILESORT_VARINT size;
586
587 ReadFile(waysx->nfd,&size,FILESORT_VARSIZE);
588
589 if(namelen[nnames%2]<size)
590 names[nnames%2]=(char*)realloc((void*)names[nnames%2],namelen[nnames%2]=size);
591
592 ReadFile(waysx->nfd,&index,sizeof(index_t));
593 ReadFile(waysx->nfd,names[nnames%2],size-sizeof(index_t));
594
595 if(nnames==0 || strcmp(names[0],names[1]))
596 {
597 WriteFile(nfd,names[nnames%2],size-sizeof(index_t));
598
599 lastlength=waysx->nlength;
600 waysx->nlength+=size-sizeof(index_t);
601
602 nnames++;
603 }
604
605 wayx=LookupWayX(waysx,index,1);
606
607 wayx->way.name=lastlength;
608
609 PutBackWayX(waysx,wayx);
610
611 if(!((i+1)%1000))
612 printf_middle("Updating Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,i+1,nnames);
613 }
614
615 if(names[0]) free(names[0]);
616 if(names[1]) free(names[1]);
617
618 /* Close the files */
619
620 waysx->nfd=CloseFile(waysx->nfd);
621 CloseFile(nfd);
622
623 /* Print the final message */
624
625 printf_last("Updated Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,waysx->number,nnames);
626
627
628 /* Unmap from memory / close the files */
629
630 #if !SLIM
631 waysx->data=UnmapFile(waysx->data);
632 #else
633 waysx->fd=CloseFile(waysx->fd);
634 #endif
635 }
636
637
638 /*++++++++++++++++++++++++++++++++++++++
639 Sort the ways into name order.
640
641 int sort_by_name Returns the comparison of the name fields.
642
643 char *a The first way name.
644
645 char *b The second way name.
646 ++++++++++++++++++++++++++++++++++++++*/
647
648 static int sort_by_name(char *a,char *b)
649 {
650 int compare;
651 char *a_name=a+sizeof(index_t);
652 char *b_name=b+sizeof(index_t);
653
654 compare=strcmp(a_name,b_name);
655
656 if(compare)
657 return(compare);
658 else
659 return(FILESORT_PRESERVE_ORDER(a,b));
660 }
661
662
663 /*++++++++++++++++++++++++++++++++++++++
664 Compact the way list, removing duplicated ways and unused ways.
665
666 WaysX *waysx The set of ways to process.
667
668 SegmentsX *segmentsx The set of segments to check.
669 ++++++++++++++++++++++++++++++++++++++*/
670
671 void CompactWayList(WaysX *waysx,SegmentsX *segmentsx)
672 {
673 int fd;
674 index_t cnumber;
675
676 if(waysx->number==0)
677 return;
678
679 /* Print the start message */
680
681 printf_first("Sorting Ways and Compacting");
682
683 /* Allocate the array of indexes */
684
685 waysx->cdata=(index_t*)malloc(waysx->number*sizeof(index_t));
686
687 logassert(waysx->cdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
688
689 /* Re-open the file read-only and a new file writeable */
690
691 waysx->fd=ReOpenFile(waysx->filename_tmp);
692
693 DeleteFile(waysx->filename_tmp);
694
695 fd=OpenFileNew(waysx->filename_tmp);
696
697 /* Sort the ways to allow compacting according to the properties */
698
699 sortwaysx=waysx;
700 sortsegmentsx=segmentsx;
701
702 cnumber=filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(void*,index_t))delete_unused,
703 (int (*)(const void*,const void*))sort_by_name_and_prop_and_id,
704 (int (*)(void*,index_t))deduplicate_and_index_by_compact_id);
705
706 /* Close the files */
707
708 waysx->fd=CloseFile(waysx->fd);
709 CloseFile(fd);
710
711 /* Print the final message */
712
713 printf_last("Sorted and Compacted Ways: Ways=%"Pindex_t" Unique=%"Pindex_t,waysx->number,cnumber);
714 waysx->number=cnumber;
715
716 free(segmentsx->usedway);
717 segmentsx->usedway=NULL;
718 }
719
720
721 /*++++++++++++++++++++++++++++++++++++++
722 Delete the ways that are no longer being used.
723
724 int delete_unused Return 1 if the value is to be kept, otherwise 0.
725
726 WayX *wayx The extended way.
727
728 index_t index The number of unsorted ways that have been read from the input file.
729 ++++++++++++++++++++++++++++++++++++++*/
730
731 static int delete_unused(WayX *wayx,index_t index)
732 {
733 if(sortsegmentsx && !IsBitSet(sortsegmentsx->usedway,index))
734 {
735 sortwaysx->cdata[index]=NO_WAY;
736
737 return(0);
738 }
739 else
740 {
741 wayx->id=index;
742
743 return(1);
744 }
745 }
746
747
748 /*++++++++++++++++++++++++++++++++++++++
749 Sort the ways into name, properties and id order.
750
751 int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields.
752
753 WayX *a The first extended Way.
754
755 WayX *b The second extended Way.
756 ++++++++++++++++++++++++++++++++++++++*/
757
758 static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
759 {
760 int compare;
761 index_t a_name=a->way.name;
762 index_t b_name=b->way.name;
763
764 if(a_name<b_name)
765 return(-1);
766 else if(a_name>b_name)
767 return(1);
768
769 compare=WaysCompare(&a->way,&b->way);
770
771 if(compare)
772 return(compare);
773
774 return(sort_by_id(a,b));
775 }
776
777
778 /*++++++++++++++++++++++++++++++++++++++
779 Create the index of compacted Way identifiers and ignore Ways with duplicated properties.
780
781 int deduplicate_and_index_by_compact_id Return 1 if the value is to be kept, otherwise 0.
782
783 WayX *wayx The extended way.
784
785 index_t index The number of sorted ways that have already been written to the output file.
786 ++++++++++++++++++++++++++++++++++++++*/
787
788 static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index)
789 {
790 static Way lastway;
791
792 if(index==0 || wayx->way.name!=lastway.name || WaysCompare(&lastway,&wayx->way))
793 {
794 lastway=wayx->way;
795
796 sortwaysx->cdata[wayx->id]=index;
797
798 wayx->id=index;
799
800 return(1);
801 }
802 else
803 {
804 sortwaysx->cdata[wayx->id]=index-1;
805
806 return(0);
807 }
808 }
809
810
811 /*++++++++++++++++++++++++++++++++++++++
812 Save the way list to a file.
813
814 WaysX *waysx The set of ways to save.
815
816 const char *filename The name of the file to save.
817 ++++++++++++++++++++++++++++++++++++++*/
818
819 void SaveWayList(WaysX *waysx,const char *filename)
820 {
821 index_t i;
822 int fd;
823 index_t position=0;
824 WayX wayx;
825 WaysFile waysfile={0};
826 highways_t highways=0;
827 transports_t allow=0;
828 properties_t props=0;
829
830 /* Print the start message */
831
832 printf_first("Writing Ways: Ways=0");
833
834 /* Re-open the files */
835
836 waysx->fd=ReOpenFile(waysx->filename_tmp);
837 waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
838
839 /* Write out the ways data */
840
841 fd=OpenFileNew(filename);
842
843 SeekFile(fd,sizeof(WaysFile));
844
845 for(i=0;i<waysx->number;i++)
846 {
847 ReadFile(waysx->fd,&wayx,sizeof(WayX));
848
849 highways|=HIGHWAYS(wayx.way.type);
850 allow |=wayx.way.allow;
851 props |=wayx.way.props;
852
853 WriteFile(fd,&wayx.way,sizeof(Way));
854
855 if(!((i+1)%1000))
856 printf_middle("Writing Ways: Ways=%"Pindex_t,i+1);
857 }
858
859 /* Write out the ways names */
860
861 SeekFile(fd,sizeof(WaysFile)+(off_t)waysx->number*sizeof(Way));
862
863 while(position<waysx->nlength)
864 {
865 size_t len=1024;
866 char temp[1024];
867
868 if((waysx->nlength-position)<1024)
869 len=waysx->nlength-position;
870
871 ReadFile(waysx->nfd,temp,len);
872
873 WriteFile(fd,temp,len);
874
875 position+=len;
876 }
877
878 /* Close the files */
879
880 waysx->fd=CloseFile(waysx->fd);
881 waysx->nfd=CloseFile(waysx->nfd);
882
883 /* Write out the header structure */
884
885 waysfile.number =waysx->number;
886
887 waysfile.highways=highways;
888 waysfile.allow =allow;
889 waysfile.props =props;
890
891 SeekFile(fd,0);
892 WriteFile(fd,&waysfile,sizeof(WaysFile));
893
894 CloseFile(fd);
895
896 /* Print the final message */
897
898 printf_last("Wrote Ways: Ways=%"Pindex_t,waysx->number);
899 }

Properties

Name Value
cvs:description Extended ways functions.