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 1784 - (show annotations) (download) (as text)
Sat Aug 15 13:08:37 2015 UTC (9 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 21507 byte(s)
Merge libroutino branch back into the trunk.

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

Properties

Name Value
cvs:description Extended ways functions.