Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Annotation of /trunk/src/relationsx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 557 - (hide annotations) (download) (as text)
Mon Dec 20 19:11:02 2010 UTC (14 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 21389 byte(s)
Make the PutBack*() functions be no-ops in slim mode and remove the
pre-processor guards from around the function calls.

1 amb 496 /***************************************
2 amb 557 $Header: /home/amb/CVS/routino/src/relationsx.c,v 1.18 2010-12-20 19:11:02 amb Exp $
3 amb 496
4     Extended Relation data type functions.
5    
6     Part of the Routino routing software.
7     ******************/ /******************
8     This file Copyright 2010 Andrew M. Bishop
9    
10     This program is free software: you can redistribute it and/or modify
11     it under the terms of the GNU Affero General Public License as published by
12     the Free Software Foundation, either version 3 of the License, or
13     (at your option) any later version.
14    
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     GNU Affero General Public License for more details.
19    
20     You should have received a copy of the GNU Affero General Public License
21     along with this program. If not, see <http://www.gnu.org/licenses/>.
22     ***************************************/
23    
24    
25     #include <assert.h>
26     #include <stdlib.h>
27     #include <stdio.h>
28     #include <string.h>
29     #include <sys/stat.h>
30    
31 amb 542 #include "types.h"
32     #include "relations.h"
33    
34     #include "nodesx.h"
35     #include "segmentsx.h"
36 amb 496 #include "waysx.h"
37     #include "relationsx.h"
38    
39     #include "files.h"
40 amb 519 #include "logging.h"
41 amb 532 #include "sorting.h"
42 amb 496
43    
44 amb 540 /* Functions */
45    
46     static int sort_by_via(TurnRestrictRelX *a,TurnRestrictRelX *b);
47     static int deduplicate_by_id(TurnRestrictRelX *relationx,index_t index);
48    
49    
50 amb 496 /* Variables */
51    
52     /*+ The command line '--tmpdir' option or its default value. +*/
53     extern char *option_tmpdirname;
54    
55 amb 540 static RelationsX* sortrelationsx;
56 amb 496
57 amb 540
58 amb 496 /*++++++++++++++++++++++++++++++++++++++
59     Allocate a new relation list (create a new file or open an existing one).
60    
61     RelationsX *NewRelationList Returns the relation list.
62    
63     int append Set to 1 if the file is to be opened for appending (now or later).
64     ++++++++++++++++++++++++++++++++++++++*/
65    
66     RelationsX *NewRelationList(int append)
67     {
68     RelationsX *relationsx;
69    
70     relationsx=(RelationsX*)calloc(1,sizeof(RelationsX));
71    
72     assert(relationsx); /* Check calloc() worked */
73    
74 amb 540 /* Route relations */
75    
76 amb 496 relationsx->rfilename=(char*)malloc(strlen(option_tmpdirname)+32);
77    
78     if(append)
79     sprintf(relationsx->rfilename,"%s/relationsx.route.input.tmp",option_tmpdirname);
80     else
81     sprintf(relationsx->rfilename,"%s/relationsx.route.%p.tmp",option_tmpdirname,relationsx);
82    
83     if(append)
84     {
85     off_t size,position=0;
86    
87 amb 505 relationsx->rfd=OpenFileAppend(relationsx->rfilename);
88 amb 496
89     size=SizeFile(relationsx->rfilename);
90    
91     while(position<size)
92     {
93     FILESORT_VARINT relationsize;
94    
95     SeekFile(relationsx->rfd,position);
96     ReadFile(relationsx->rfd,&relationsize,FILESORT_VARSIZE);
97    
98     relationsx->rxnumber++;
99     position+=relationsize+FILESORT_VARSIZE;
100     }
101    
102     SeekFile(relationsx->rfd,size);
103     }
104     else
105 amb 505 relationsx->rfd=OpenFileNew(relationsx->rfilename);
106 amb 496
107 amb 540 /* Turn Restriction relations */
108    
109     relationsx->trfilename=(char*)malloc(strlen(option_tmpdirname)+32);
110    
111     if(append)
112     sprintf(relationsx->trfilename,"%s/relationsx.turn.input.tmp",option_tmpdirname);
113     else
114     sprintf(relationsx->trfilename,"%s/relationsx.turn.%p.tmp",option_tmpdirname,relationsx);
115    
116     if(append)
117     {
118     off_t size;
119    
120     relationsx->trfd=OpenFileAppend(relationsx->trfilename);
121    
122     size=SizeFile(relationsx->trfilename);
123    
124     relationsx->trxnumber=size/sizeof(TurnRestrictRelX);
125     }
126     else
127     relationsx->trfd=OpenFileNew(relationsx->trfilename);
128    
129 amb 496 return(relationsx);
130     }
131    
132    
133     /*++++++++++++++++++++++++++++++++++++++
134     Free a relation list.
135    
136     RelationsX *relationsx The list to be freed.
137    
138     int keep Set to 1 if the file is to be kept.
139     ++++++++++++++++++++++++++++++++++++++*/
140    
141     void FreeRelationList(RelationsX *relationsx,int keep)
142     {
143 amb 540 /* Route relations */
144    
145 amb 496 if(!keep)
146     DeleteFile(relationsx->rfilename);
147    
148     free(relationsx->rfilename);
149    
150 amb 540 /* Turn Restriction relations */
151    
152     if(!keep)
153     DeleteFile(relationsx->trfilename);
154    
155     free(relationsx->trfilename);
156    
157 amb 496 free(relationsx);
158     }
159    
160    
161     /*++++++++++++++++++++++++++++++++++++++
162     Append a single relation to an unsorted route relation list.
163    
164     RelationsX* relationsx The set of relations to process.
165    
166     relation_t id The ID of the relation.
167    
168 amb 529 transports_t routes The types of routes that this relation is for.
169 amb 496
170     way_t *ways The array of ways that are members of the relation.
171    
172     int nways The number of ways that are members of the relation.
173    
174     relation_t *relations The array of relations that are members of the relation.
175    
176     int nrelations The number of relations that are members of the relation.
177     ++++++++++++++++++++++++++++++++++++++*/
178    
179 amb 540 void AppendRouteRelation(RelationsX* relationsx,relation_t id,
180     transports_t routes,
181 amb 496 way_t *ways,int nways,
182     relation_t *relations,int nrelations)
183     {
184     RouteRelX relationx;
185 amb 505 FILESORT_VARINT size;
186 amb 496 way_t zeroway=0;
187     relation_t zerorelation=0;
188    
189     relationx.id=id;
190     relationx.routes=routes;
191    
192     size=sizeof(RouteRelX)+(nways+1)*sizeof(way_t)+(nrelations+1)*sizeof(relation_t);
193    
194 amb 505 WriteFile(relationsx->rfd,&size,FILESORT_VARSIZE);
195 amb 496 WriteFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
196    
197     WriteFile(relationsx->rfd,ways ,nways*sizeof(way_t));
198     WriteFile(relationsx->rfd,&zeroway, sizeof(way_t));
199    
200     WriteFile(relationsx->rfd,relations ,nrelations*sizeof(relation_t));
201     WriteFile(relationsx->rfd,&zerorelation, sizeof(relation_t));
202    
203     relationsx->rxnumber++;
204    
205     assert(!(relationsx->rxnumber==0)); /* Zero marks the high-water mark for relations. */
206     }
207    
208    
209     /*++++++++++++++++++++++++++++++++++++++
210 amb 540 Append a single relation to an unsorted turn restriction relation list.
211    
212     RelationsX* relationsx The set of relations to process.
213    
214     relation_t id The ID of the relation.
215    
216     way_t from The way that the turn restriction starts from.
217    
218     way_t to The way that the restriction finished on.
219    
220     node_t via The node that the turn restriction passes through.
221    
222     TurnRestriction restriction The type of restriction.
223    
224     transports_t except The set of transports allowed to bypass the restriction.
225     ++++++++++++++++++++++++++++++++++++++*/
226    
227     void AppendTurnRestrictRelation(RelationsX* relationsx,relation_t id,
228     way_t from,way_t to,node_t via,
229     TurnRestriction restriction,transports_t except)
230     {
231     TurnRestrictRelX relationx;
232    
233     relationx.id=id;
234     relationx.from=from;
235     relationx.to=to;
236     relationx.via=via;
237     relationx.restrict=restriction;
238     relationx.except=except;
239    
240     WriteFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX));
241    
242     relationsx->trxnumber++;
243    
244     assert(!(relationsx->trxnumber==0)); /* Zero marks the high-water mark for relations. */
245     }
246    
247    
248     /*++++++++++++++++++++++++++++++++++++++
249 amb 496 Sort the list of relations.
250    
251     RelationsX* relationsx The set of relations to process.
252     ++++++++++++++++++++++++++++++++++++++*/
253    
254     void SortRelationList(RelationsX* relationsx)
255     {
256 amb 501 /* Don't need to sort route relations */
257 amb 540
258 amb 542
259 amb 551 /* Sort the turn restriction relations by via node. */
260 amb 540
261 amb 551 if(relationsx->trxnumber)
262     {
263     int trfd;
264 amb 540
265 amb 551 /* Print the start message */
266 amb 540
267 amb 551 printf_first("Sorting Turn Restriction Relations");
268 amb 540
269 amb 555 /* Close the file (finished appending) */
270 amb 540
271 amb 555 CloseFile(relationsx->trfd);
272    
273     /* Re-open the file read-only and a new file writeable */
274    
275     relationsx->trfd=ReOpenFile(relationsx->trfilename);
276    
277 amb 551 DeleteFile(relationsx->trfilename);
278 amb 540
279 amb 551 trfd=OpenFileNew(relationsx->trfilename);
280 amb 540
281 amb 551 /* Sort the relations */
282 amb 540
283 amb 551 sortrelationsx=relationsx;
284 amb 540
285 amb 551 filesort_fixed(relationsx->trfd,trfd,sizeof(TurnRestrictRelX),(int (*)(const void*,const void*))sort_by_via,(int (*)(void*,index_t))deduplicate_by_id);
286 amb 540
287 amb 555 /* Close the files */
288 amb 540
289 amb 551 CloseFile(relationsx->trfd);
290     CloseFile(trfd);
291 amb 540
292 amb 551 /* Print the final message */
293 amb 540
294 amb 551 printf_last("Sorted Relations: Relations=%d Duplicates=%d",relationsx->trxnumber,relationsx->trxnumber-relationsx->trnumber);
295     }
296 amb 496 }
297    
298    
299     /*++++++++++++++++++++++++++++++++++++++
300 amb 540 Sort the turn restriction relations into via node order.
301    
302     int sort_by_via Returns the comparison of the via fields.
303    
304     TurnRestrictRelX *a The first extended relation.
305    
306     TurnRestrictRelX *b The second extended relation.
307     ++++++++++++++++++++++++++++++++++++++*/
308    
309     static int sort_by_via(TurnRestrictRelX *a,TurnRestrictRelX *b)
310     {
311     node_t a_id=a->via;
312     node_t b_id=b->via;
313    
314     if(a_id<b_id)
315     return(-1);
316     else if(a_id>b_id)
317     return(1);
318     else
319     {
320     relation_t a_id=a->id;
321     relation_t b_id=b->id;
322    
323     if(a_id<b_id)
324     return(-1);
325     else if(a_id>b_id)
326     return(1);
327     else
328     return(0);
329     }
330     }
331    
332    
333     /*++++++++++++++++++++++++++++++++++++++
334     Deduplicate the extended relations using the id after sorting.
335    
336     int deduplicate_by_id Return 1 if the value is to be kept, otherwise zero.
337    
338     TurnRestrictRelX *relationx The extended relation.
339    
340     index_t index The index of this relation in the total.
341     ++++++++++++++++++++++++++++++++++++++*/
342    
343     static int deduplicate_by_id(TurnRestrictRelX *relationx,index_t index)
344     {
345     static relation_t previd;
346    
347     if(index==0 || relationx->id!=previd)
348     {
349     previd=relationx->id;
350    
351     sortrelationsx->trnumber++;
352    
353     return(1);
354     }
355    
356     return(0);
357     }
358    
359    
360     /*++++++++++++++++++++++++++++++++++++++
361 amb 496 Process the route relations and apply the information to the ways.
362    
363     RelationsX *relationsx The set of relations to process.
364    
365     WaysX *waysx The set of ways to update.
366     ++++++++++++++++++++++++++++++++++++++*/
367    
368     void ProcessRouteRelations(RelationsX *relationsx,WaysX *waysx)
369     {
370 amb 505 RouteRelX *unmatched=NULL,*lastunmatched=NULL;
371     int nunmatched=0,lastnunmatched=0,iteration=0;
372 amb 496
373 amb 510 if(waysx->number==0)
374 amb 508 return;
375    
376 amb 555 /* Map into memory / open the files */
377 amb 496
378 amb 505 #if !SLIM
379 amb 507 waysx->xdata=MapFileWriteable(waysx->filename);
380 amb 555 #else
381     waysx->fd=ReOpenFileWriteable(waysx->filename);
382 amb 505 #endif
383 amb 496
384 amb 555 /* Close the file (finished appending) */
385 amb 511
386 amb 555 CloseFile(relationsx->rfd);
387 amb 511
388 amb 555 /* Re-open the file read-only */
389 amb 548
390     relationsx->rfd=ReOpenFile(relationsx->rfilename);
391    
392 amb 542 /* Read through the file. */
393 amb 496
394 amb 505 do
395 amb 496 {
396 amb 522 int ways=0,relations=0;
397     int i;
398    
399 amb 505 SeekFile(relationsx->rfd,0);
400 amb 496
401 amb 505 /* Print the start message */
402 amb 496
403 amb 522 printf_first("Processing Route Relations: Iteration=%d Relations=0 Modified Ways=0",iteration);
404 amb 496
405 amb 505 for(i=0;i<relationsx->rxnumber;i++)
406 amb 496 {
407 amb 505 FILESORT_VARINT size;
408     RouteRelX relationx;
409     way_t wayid;
410     relation_t relationid;
411 amb 529 transports_t routes=Transports_None;
412 amb 496
413 amb 505 /* Read each route relation */
414 amb 496
415 amb 505 ReadFile(relationsx->rfd,&size,FILESORT_VARSIZE);
416     ReadFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
417 amb 496
418 amb 505 /* Decide what type of route it is */
419 amb 496
420 amb 505 if(iteration==0)
421 amb 522 {
422     relations++;
423 amb 505 routes=relationx.routes;
424 amb 522 }
425 amb 505 else
426 amb 506 {
427 amb 522 int j;
428    
429     for(j=0;j<lastnunmatched;j++)
430     if(lastunmatched[j].id==relationx.id)
431     {
432     relations++;
433    
434     if((lastunmatched[j].routes|relationx.routes)==relationx.routes)
435     routes=0; /* Nothing new to add */
436     else
437 amb 506 routes=lastunmatched[j].routes;
438 amb 522 break;
439     }
440 amb 506 }
441 amb 496
442 amb 505 /* Loop through the ways */
443    
444     do
445     {
446     ReadFile(relationsx->rfd,&wayid,sizeof(way_t));
447    
448     /* Update the ways that are listed for the relation */
449    
450     if(wayid && routes)
451     {
452 amb 506 index_t way=IndexWayX(waysx,wayid);
453 amb 505
454     if(way!=NO_WAY)
455     {
456     WayX *wayx=LookupWayX(waysx,way,1);
457    
458 amb 529 if(routes&Transports_Foot)
459 amb 505 wayx->way.props|=Properties_FootRoute;
460    
461 amb 529 if(routes&Transports_Bicycle)
462 amb 505 wayx->way.props|=Properties_BicycleRoute;
463    
464     PutBackWayX(waysx,way,1);
465 amb 522
466     ways++;
467 amb 505 }
468     }
469     }
470     while(wayid);
471    
472     /* Loop through the relations */
473    
474     do
475     {
476     ReadFile(relationsx->rfd,&relationid,sizeof(relation_t));
477    
478     /* Add the relations that are listed for this relation to the list for next time */
479    
480 amb 506 if(relationid && routes && relationid!=relationx.id)
481 amb 505 {
482     if(nunmatched%256==0)
483     unmatched=(RouteRelX*)realloc((void*)unmatched,(nunmatched+256)*sizeof(RouteRelX));
484    
485     unmatched[nunmatched].id=relationid;
486     unmatched[nunmatched].routes=routes;
487    
488     nunmatched++;
489     }
490     }
491     while(relationid);
492    
493     if(!((i+1)%10000))
494 amb 522 printf_middle("Processing Route Relations: Iteration=%d Relations=%d Modified Ways=%d",iteration,relations,ways);
495 amb 496 }
496    
497 amb 505 if(lastunmatched)
498     free(lastunmatched);
499    
500     lastunmatched=unmatched;
501     lastnunmatched=nunmatched;
502    
503     unmatched=NULL;
504     nunmatched=0;
505    
506     /* Print the final message */
507    
508 amb 522 printf_last("Processed Route Relations: Iteration=%d Relations=%d Modified Ways=%d",iteration,relations,ways);
509 amb 496 }
510 amb 505 while(lastnunmatched && ++iteration<5);
511 amb 496
512 amb 505 if(lastunmatched)
513     free(lastunmatched);
514    
515 amb 555 /* Close the file */
516    
517 amb 496 CloseFile(relationsx->rfd);
518    
519 amb 555 /* Unmap from memory / close the files */
520 amb 496
521 amb 505 #if !SLIM
522     waysx->xdata=UnmapFile(waysx->filename);
523 amb 555 #else
524 amb 511 CloseFile(waysx->fd);
525     #endif
526 amb 496 }
527 amb 542
528    
529     /*++++++++++++++++++++++++++++++++++++++
530     Process the turn relations (first part) to update them with the node information.
531    
532     RelationsX *relationsx The set of relations to process.
533    
534     NodesX *nodesx The set of nodes to process.
535    
536     SegmentsX *segmentsx The set of segments to process.
537    
538     WaysX *waysx The set of ways to process.
539     ++++++++++++++++++++++++++++++++++++++*/
540    
541     void ProcessTurnRelations1(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx)
542     {
543 amb 548 TurnRestrictRelX relationx;
544 amb 542 int trfd;
545    
546 amb 548 if(nodesx->number==0 || segmentsx->number==0)
547     return;
548    
549 amb 542 /* Print the start message */
550    
551     printf_first("Processing Turn Restriction Relations (1): Turn Relations=0");
552    
553 amb 555 /* Map into memory / open the files */
554 amb 548
555     #if !SLIM
556 amb 555 nodesx->xdata=MapFile(nodesx->filename);
557 amb 548 segmentsx->xdata=MapFile(segmentsx->filename);
558 amb 555 #else
559     nodesx->fd=ReOpenFile(nodesx->filename);
560     segmentsx->fd=ReOpenFile(segmentsx->filename);
561 amb 548 #endif
562    
563 amb 555 /* Close the file (finished appending) */
564 amb 548
565     CloseFile(relationsx->trfd);
566 amb 555
567     /* Re-open the file read-only and a new file writeable */
568    
569 amb 548 relationsx->trfd=ReOpenFile(relationsx->trfilename);
570    
571 amb 542 DeleteFile(relationsx->trfilename);
572    
573     trfd=OpenFileNew(relationsx->trfilename);
574    
575     /* Process all of the relations */
576    
577 amb 551 relationsx->trxnumber=0;
578 amb 548
579     while(!ReadFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX)))
580 amb 542 {
581 amb 548 if(relationx.restrict==TurnRestrict_no_right_turn ||
582     relationx.restrict==TurnRestrict_no_left_turn ||
583     relationx.restrict==TurnRestrict_no_u_turn ||
584     relationx.restrict==TurnRestrict_no_straight_on)
585     {
586 amb 551 index_t seg;
587     node_t node_from=NO_NODE,node_to=NO_NODE;
588 amb 542
589 amb 548 /* Find the segments that join the node 'via' */
590 amb 542
591 amb 548 seg=IndexFirstSegmentX1(segmentsx,relationx.via);
592 amb 542
593 amb 548 do
594     {
595     SegmentX *segx=LookupSegmentX(segmentsx,seg,1);
596 amb 542
597 amb 551 if(segx->way==relationx.from)
598 amb 548 {
599 amb 551 if(node_from!=NO_NODE) /* Only one segment can be on the 'from' way */
600     goto endloop;
601 amb 548
602 amb 551 node_from=segx->node2;
603 amb 548 }
604    
605 amb 551 if(segx->way==relationx.to)
606 amb 548 {
607 amb 551 if(node_to!=NO_NODE) /* Only one segment can be on the 'to' way */
608     goto endloop;
609 amb 548
610 amb 551 node_to=segx->node2;
611 amb 548 }
612    
613     seg=IndexNextSegmentX1(segmentsx,seg,relationx.via);
614     }
615     while(seg!=NO_SEGMENT);
616    
617 amb 551 if(node_to==NO_NODE || node_from==NO_NODE) /* Not enough segments for the selected ways */
618 amb 548 goto endloop;
619    
620 amb 551 /* Write the results */
621 amb 548
622 amb 551 relationx.from=IndexNodeX(nodesx,node_from);
623     relationx.to =IndexNodeX(nodesx,node_to);
624     relationx.via =IndexNodeX(nodesx,relationx.via);
625 amb 548
626 amb 551 WriteFile(trfd,&relationx,sizeof(TurnRestrictRelX));
627 amb 548
628 amb 551 relationsx->trxnumber++;
629 amb 548
630 amb 551 if(!(relationsx->trxnumber%10000))
631     printf_middle("Processing Turn Restriction Relations (1): Turn Relations=%d",relationsx->trxnumber);
632     }
633     else
634     {
635     index_t seg;
636     node_t node_from=NO_NODE,node_to[8];
637     int nnodes_to=0,i;
638 amb 548
639 amb 551 /* Find the segments that join the node 'via' */
640 amb 548
641 amb 551 seg=IndexFirstSegmentX1(segmentsx,relationx.via);
642 amb 548
643 amb 551 do
644     {
645     SegmentX *segx=LookupSegmentX(segmentsx,seg,1);
646 amb 548
647 amb 551 if(segx->way==relationx.from)
648     {
649     if(node_from!=NO_NODE) /* Only one segment can be on the 'from' way */
650 amb 548 goto endloop;
651    
652 amb 551 node_from=segx->node2;
653 amb 548 }
654 amb 551
655     if(segx->way!=relationx.to)
656     {
657     if(nnodes_to==8) /* Too many segments (arbitrary choice) */
658     goto endloop;
659    
660     node_to[nnodes_to++]=segx->node2;
661     }
662    
663     seg=IndexNextSegmentX1(segmentsx,seg,relationx.via);
664 amb 548 }
665 amb 551 while(seg!=NO_SEGMENT);
666 amb 548
667 amb 551 if(nnodes_to==0 || node_from==NO_NODE) /* Not enough segments for the selected ways */
668 amb 548 goto endloop;
669    
670     /* Write the results */
671    
672 amb 551 relationx.via=IndexNodeX(nodesx,relationx.via);
673 amb 548
674 amb 551 for(i=0;i<nnodes_to;i++)
675     {
676     if(node_to[i]==node_from)
677     continue;
678 amb 548
679 amb 551 relationx.from=IndexNodeX(nodesx,node_from);
680     relationx.to =IndexNodeX(nodesx,node_to[i]);
681 amb 548
682 amb 551 WriteFile(trfd,&relationx,sizeof(TurnRestrictRelX));
683 amb 548
684 amb 551 relationsx->trxnumber++;
685 amb 548
686 amb 551 if(!(relationsx->trxnumber%10000))
687     printf_middle("Processing Turn Restriction Relations (1): Turn Relations=%d",relationsx->trxnumber);
688     }
689 amb 548 }
690    
691     endloop: ;
692 amb 542 }
693    
694 amb 555 /* Close the files */
695 amb 542
696     CloseFile(relationsx->trfd);
697     CloseFile(trfd);
698    
699 amb 555 /* Unmap from memory / close the files */
700 amb 542
701 amb 548 #if !SLIM
702 amb 555 nodesx->xdata=UnmapFile(nodesx->filename);
703 amb 548 segmentsx->xdata=UnmapFile(segmentsx->filename);
704 amb 555 #else
705     CloseFile(nodesx->fd);
706     CloseFile(segmentsx->fd);
707 amb 548 #endif
708    
709 amb 542 /* Print the final message */
710    
711 amb 551 printf_last("Processing Turn Restriction Relations (1): Turn Relations=%d",relationsx->trxnumber);
712 amb 542 }
713    
714    
715     /*++++++++++++++++++++++++++++++++++++++
716     Process the turn relations (second part) to update them with the re-ordered node information.
717    
718     RelationsX *relationsx The set of relations to process.
719    
720     NodesX *nodesx The set of nodes to process.
721     ++++++++++++++++++++++++++++++++++++++*/
722    
723     void ProcessTurnRelations2(RelationsX *relationsx,NodesX *nodesx)
724     {
725 amb 551 return;
726    
727     TurnRestrictRelX relationx;
728 amb 542 int trfd;
729    
730 amb 551 if(nodesx->number==0)
731     return;
732    
733 amb 542 /* Print the start message */
734    
735     printf_first("Processing Turn Restriction Relations (2): Turn Relations=0");
736    
737 amb 555 /* Map into memory / open the files */
738 amb 542
739     #if !SLIM
740     nodesx->xdata=MapFile(nodesx->filename);
741 amb 555 #else
742     nodesx->fd=ReOpenFile(nodesx->filename);
743 amb 542 #endif
744    
745 amb 555 /* Re-open the file read-only and a new file writeable */
746 amb 542
747 amb 555 relationsx->trfd=ReOpenFile(relationsx->trfilename);
748    
749 amb 542 DeleteFile(relationsx->trfilename);
750    
751     trfd=OpenFileNew(relationsx->trfilename);
752    
753     /* Process all of the relations */
754    
755 amb 551 while(!ReadFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX)))
756 amb 542 {
757     NodeX *nodex;
758    
759     nodex=LookupNodeX(nodesx,relationx.from,1);
760     relationx.from=nodex->id;
761    
762     nodex=LookupNodeX(nodesx,relationx.via,1);
763     relationx.via=nodex->id;
764    
765     nodex=LookupNodeX(nodesx,relationx.to,1);
766     relationx.to=nodex->id;
767    
768     WriteFile(trfd,&relationx,sizeof(TurnRestrictRelX));
769    
770 amb 551 if(!(relationsx->trxnumber%10000))
771     printf_middle("Processing Turn Restriction Relations (2): Turn Relations=%d",relationsx->trxnumber);
772 amb 542 }
773    
774 amb 555 /* Close the files */
775 amb 542
776     CloseFile(relationsx->trfd);
777     CloseFile(trfd);
778    
779     /* Unmap from memory */
780    
781     #if !SLIM
782     nodesx->xdata=UnmapFile(nodesx->filename);
783 amb 555 #else
784     CloseFile(nodesx->fd);
785 amb 542 #endif
786    
787     /* Print the final message */
788    
789 amb 551 printf_last("Processing Turn Restriction Relations (2): Turn Relations=%d",relationsx->trxnumber);
790 amb 542 }
791    
792    
793     /*++++++++++++++++++++++++++++++++++++++
794     Save the relation list to a file.
795    
796     RelationsX* relationsx The set of relations to save.
797    
798     const char *filename The name of the file to save.
799     ++++++++++++++++++++++++++++++++++++++*/
800    
801     void SaveRelationList(RelationsX* relationsx,const char *filename)
802     {
803     index_t i;
804     int fd;
805     RelationsFile relationsfile={0};
806    
807     /* Print the start message */
808    
809     printf_first("Writing Relations: Turn Relations=0");
810    
811 amb 555 /* Re-open the file read-only and a new file writeable */
812    
813     relationsx->trfd=ReOpenFile(relationsx->trfilename);
814    
815 amb 542 /* Write out the relations data */
816    
817     fd=OpenFileNew(filename);
818    
819     SeekFile(fd,sizeof(RelationsFile));
820    
821     for(i=0;i<relationsx->trnumber;i++)
822     {
823     TurnRestrictRelX relationx;
824 amb 551 TurnRelation relation;
825 amb 542
826     ReadFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX));
827    
828 amb 551 relation.from=relationx.from;
829     relation.via=relationx.via;
830     relation.to=relationx.to;
831     relation.except=relationx.except;
832 amb 542
833 amb 551 WriteFile(fd,&relation,sizeof(TurnRelation));
834    
835 amb 542 if(!((i+1)%10000))
836     printf_middle("Writing Relations: Turn Relations=%d",i+1);
837     }
838    
839     /* Write out the header structure */
840    
841     relationsfile.trnumber=relationsx->trnumber;
842    
843     SeekFile(fd,0);
844     WriteFile(fd,&relationsfile,sizeof(RelationsFile));
845    
846     CloseFile(fd);
847    
848     /* Close the file */
849    
850     CloseFile(relationsx->trfd);
851    
852     /* Print the final message */
853    
854     printf_last("Wrote Relations: Turn Relations=%d",relationsx->trnumber);
855     }