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 1414 - (show annotations) (download) (as text)
Sat Jun 22 18:49:33 2013 UTC (11 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 21043 byte(s)
Use SlimMapFile() and SlimUnmapFile() as the function names for the slim mode of
operation to open and close the files (to hide the fact that they are files
being opened for reading or writing unbuffered).

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=SlimMapFileWriteable(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=SlimUnmapFile(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.