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 1409 - (show annotations) (download) (as text)
Fri Jun 21 14:53:01 2013 UTC (11 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 21038 byte(s)
Use the new buffered functions in the filesort functions.

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

Properties

Name Value
cvs:description Extended ways functions.