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/relationsx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 646 - (show annotations) (download) (as text)
Sat Feb 26 19:44:56 2011 UTC (14 years ago) by amb
File MIME type: text/x-csrc
File size: 26416 byte(s)
Remove a pair of functions that are no longer used and rename the other pair.

1 /***************************************
2 Extended Relation data type functions.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2010-2011 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 <assert.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <sys/stat.h>
28
29 #include "types.h"
30 #include "relations.h"
31
32 #include "nodesx.h"
33 #include "segmentsx.h"
34 #include "waysx.h"
35 #include "relationsx.h"
36
37 #include "files.h"
38 #include "logging.h"
39 #include "sorting.h"
40
41
42 /* Functions */
43
44 static int sort_by_id(TurnRestrictRelX *a,TurnRestrictRelX *b);
45 static int deduplicate_by_id(TurnRestrictRelX *relationx,index_t index);
46
47 static int sort_by_via(TurnRestrictRelX *a,TurnRestrictRelX *b);
48
49
50 /* Variables */
51
52 /*+ The command line '--tmpdir' option or its default value. +*/
53 extern char *option_tmpdirname;
54
55 static RelationsX* sortrelationsx;
56
57
58 /*++++++++++++++++++++++++++++++++++++++
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
75 /* Route Relations */
76
77 relationsx->rfilename=(char*)malloc(strlen(option_tmpdirname)+32);
78
79 if(append)
80 sprintf(relationsx->rfilename,"%s/relationsx.route.input.tmp",option_tmpdirname);
81 else
82 sprintf(relationsx->rfilename,"%s/relationsx.route.%p.tmp",option_tmpdirname,relationsx);
83
84 if(append)
85 {
86 off_t size,position=0;
87
88 relationsx->rfd=OpenFileAppend(relationsx->rfilename);
89
90 size=SizeFile(relationsx->rfilename);
91
92 while(position<size)
93 {
94 FILESORT_VARINT relationsize;
95
96 SeekFile(relationsx->rfd,position);
97 ReadFile(relationsx->rfd,&relationsize,FILESORT_VARSIZE);
98
99 relationsx->rxnumber++;
100 position+=relationsize+FILESORT_VARSIZE;
101 }
102
103 SeekFile(relationsx->rfd,size);
104 }
105 else
106 relationsx->rfd=OpenFileNew(relationsx->rfilename);
107
108
109 /* Turn Restriction Relations */
110
111 relationsx->trfilename=(char*)malloc(strlen(option_tmpdirname)+32);
112
113 if(append)
114 sprintf(relationsx->trfilename,"%s/relationsx.turn.input.tmp",option_tmpdirname);
115 else
116 sprintf(relationsx->trfilename,"%s/relationsx.turn.%p.tmp",option_tmpdirname,relationsx);
117
118 if(append)
119 {
120 off_t size;
121
122 relationsx->trfd=OpenFileAppend(relationsx->trfilename);
123
124 size=SizeFile(relationsx->trfilename);
125
126 relationsx->trxnumber=size/sizeof(TurnRestrictRelX);
127 }
128 else
129 relationsx->trfd=OpenFileNew(relationsx->trfilename);
130
131 return(relationsx);
132 }
133
134
135 /*++++++++++++++++++++++++++++++++++++++
136 Free a relation list.
137
138 RelationsX *relationsx The list to be freed.
139
140 int keep Set to 1 if the file is to be kept.
141 ++++++++++++++++++++++++++++++++++++++*/
142
143 void FreeRelationList(RelationsX *relationsx,int keep)
144 {
145 /* Route relations */
146
147 if(!keep)
148 DeleteFile(relationsx->rfilename);
149
150 free(relationsx->rfilename);
151
152
153 /* Turn Restriction relations */
154
155 if(!keep)
156 DeleteFile(relationsx->trfilename);
157
158 free(relationsx->trfilename);
159
160 free(relationsx);
161 }
162
163
164 /*++++++++++++++++++++++++++++++++++++++
165 Append a single relation to an unsorted route relation list.
166
167 RelationsX* relationsx The set of relations to process.
168
169 relation_t id The ID of the relation.
170
171 transports_t routes The types of routes that this relation is for.
172
173 way_t *ways The array of ways that are members of the relation.
174
175 int nways The number of ways that are members of the relation.
176
177 relation_t *relations The array of relations that are members of the relation.
178
179 int nrelations The number of relations that are members of the relation.
180 ++++++++++++++++++++++++++++++++++++++*/
181
182 void AppendRouteRelation(RelationsX* relationsx,relation_t id,
183 transports_t routes,
184 way_t *ways,int nways,
185 relation_t *relations,int nrelations)
186 {
187 RouteRelX relationx;
188 FILESORT_VARINT size;
189 way_t zeroway=0;
190 relation_t zerorelation=0;
191
192 relationx.id=id;
193 relationx.routes=routes;
194
195 size=sizeof(RouteRelX)+(nways+1)*sizeof(way_t)+(nrelations+1)*sizeof(relation_t);
196
197 WriteFile(relationsx->rfd,&size,FILESORT_VARSIZE);
198 WriteFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
199
200 WriteFile(relationsx->rfd,ways ,nways*sizeof(way_t));
201 WriteFile(relationsx->rfd,&zeroway, sizeof(way_t));
202
203 WriteFile(relationsx->rfd,relations ,nrelations*sizeof(relation_t));
204 WriteFile(relationsx->rfd,&zerorelation, sizeof(relation_t));
205
206 relationsx->rxnumber++;
207
208 assert(!(relationsx->rxnumber==0)); /* Zero marks the high-water mark for relations. */
209 }
210
211
212 /*++++++++++++++++++++++++++++++++++++++
213 Append a single relation to an unsorted turn restriction relation list.
214
215 RelationsX* relationsx The set of relations to process.
216
217 relation_t id The ID of the relation.
218
219 way_t from The way that the turn restriction starts from.
220
221 way_t to The way that the restriction finished on.
222
223 node_t via The node that the turn restriction passes through.
224
225 TurnRestriction restriction The type of restriction.
226
227 transports_t except The set of transports allowed to bypass the restriction.
228 ++++++++++++++++++++++++++++++++++++++*/
229
230 void AppendTurnRestrictRelation(RelationsX* relationsx,relation_t id,
231 way_t from,way_t to,node_t via,
232 TurnRestriction restriction,transports_t except)
233 {
234 TurnRestrictRelX relationx;
235
236 relationx.id=id;
237 relationx.from=from;
238 relationx.to=to;
239 relationx.via=via;
240 relationx.restrict=restriction;
241 relationx.except=except;
242
243 WriteFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX));
244
245 relationsx->trxnumber++;
246
247 assert(!(relationsx->trxnumber==0)); /* Zero marks the high-water mark for relations. */
248 }
249
250
251 /*++++++++++++++++++++++++++++++++++++++
252 Sort the list of relations.
253
254 RelationsX* relationsx The set of relations to process.
255 ++++++++++++++++++++++++++++++++++++++*/
256
257 void SortRelationList(RelationsX* relationsx)
258 {
259 /* Close the files (finished appending) */
260
261 relationsx->rfd=CloseFile(relationsx->rfd);
262
263 relationsx->trfd=CloseFile(relationsx->trfd);
264
265
266 /* Route Relations */
267
268
269 /* Turn Restriction Relations. */
270
271 if(relationsx->trxnumber)
272 {
273 int trfd;
274
275 /* Print the start message */
276
277 printf_first("Sorting Turn Restriction Relations");
278
279 /* Re-open the file read-only and a new file writeable */
280
281 relationsx->trfd=ReOpenFile(relationsx->trfilename);
282
283 DeleteFile(relationsx->trfilename);
284
285 trfd=OpenFileNew(relationsx->trfilename);
286
287 /* Sort the relations */
288
289 sortrelationsx=relationsx;
290
291 filesort_fixed(relationsx->trfd,trfd,sizeof(TurnRestrictRelX),(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))deduplicate_by_id);
292
293 /* Close the files */
294
295 relationsx->trfd=CloseFile(relationsx->trfd);
296 CloseFile(trfd);
297
298 /* Print the final message */
299
300 printf_last("Sorted Relations: Relations=%d Duplicates=%d",relationsx->trxnumber,relationsx->trxnumber-relationsx->trnumber);
301 }
302 }
303
304
305 /*++++++++++++++++++++++++++++++++++++++
306 Sort the turn restriction relations into id order.
307
308 int sort_by_id Returns the comparison of the id fields.
309
310 TurnRestrictRelX *a The first extended relation.
311
312 TurnRestrictRelX *b The second extended relation.
313 ++++++++++++++++++++++++++++++++++++++*/
314
315 static int sort_by_id(TurnRestrictRelX *a,TurnRestrictRelX *b)
316 {
317 relation_t a_id=a->id;
318 relation_t b_id=b->id;
319
320 if(a_id<b_id)
321 return(-1);
322 else if(a_id>b_id)
323 return(1);
324 else
325 return(0);
326 }
327
328
329 /*++++++++++++++++++++++++++++++++++++++
330 Deduplicate the extended relations using the id after sorting.
331
332 int deduplicate_by_id Return 1 if the value is to be kept, otherwise zero.
333
334 TurnRestrictRelX *relationx The extended relation.
335
336 index_t index The index of this relation in the total.
337 ++++++++++++++++++++++++++++++++++++++*/
338
339 static int deduplicate_by_id(TurnRestrictRelX *relationx,index_t index)
340 {
341 static relation_t previd;
342
343 if(index==0 || relationx->id!=previd)
344 {
345 previd=relationx->id;
346
347 sortrelationsx->trnumber++;
348
349 return(1);
350 }
351
352 return(0);
353 }
354
355
356 /*++++++++++++++++++++++++++++++++++++++
357 Sort the list of turn relations.
358
359 RelationsX* relationsx The set of relations to process.
360 ++++++++++++++++++++++++++++++++++++++*/
361
362 void SortTurnRelationList(RelationsX* relationsx)
363 {
364 int trfd;
365
366 if(relationsx->trnumber==0)
367 return;
368
369 /* Print the start message */
370
371 printf_first("Sorting Turn Restriction Relations");
372
373 /* Re-open the file read-only and a new file writeable */
374
375 relationsx->trfd=ReOpenFile(relationsx->trfilename);
376
377 DeleteFile(relationsx->trfilename);
378
379 trfd=OpenFileNew(relationsx->trfilename);
380
381 /* Sort the relations */
382
383 filesort_fixed(relationsx->trfd,trfd,sizeof(TurnRestrictRelX),(int (*)(const void*,const void*))sort_by_via,NULL);
384
385 /* Close the files */
386
387 relationsx->trfd=CloseFile(relationsx->trfd);
388 CloseFile(trfd);
389
390 /* Print the final message */
391
392 printf_last("Sorted Relations: Relations=%d",relationsx->trnumber);
393 }
394
395
396 /*++++++++++++++++++++++++++++++++++++++
397 Sort the turn restriction relations into via node order.
398
399 int sort_by_via Returns the comparison of the via fields.
400
401 TurnRestrictRelX *a The first extended relation.
402
403 TurnRestrictRelX *b The second extended relation.
404 ++++++++++++++++++++++++++++++++++++++*/
405
406 static int sort_by_via(TurnRestrictRelX *a,TurnRestrictRelX *b)
407 {
408 node_t a_id=a->via;
409 node_t b_id=b->via;
410
411 if(a_id<b_id)
412 return(-1);
413 else if(a_id>b_id)
414 return(1);
415 else
416 {
417 node_t a_id=a->from;
418 node_t b_id=b->from;
419
420 if(a_id<b_id)
421 return(-1);
422 else if(a_id>b_id)
423 return(1);
424 else
425 {
426 node_t a_id=a->to;
427 node_t b_id=b->to;
428
429 if(a_id<b_id)
430 return(-1);
431 else if(a_id>b_id)
432 return(1);
433 else
434 return(0);
435 }
436 }
437 }
438
439
440 /*++++++++++++++++++++++++++++++++++++++
441 Process the route relations and apply the information to the ways.
442
443 RelationsX *relationsx The set of relations to process.
444
445 WaysX *waysx The set of ways to update.
446 ++++++++++++++++++++++++++++++++++++++*/
447
448 void ProcessRouteRelations(RelationsX *relationsx,WaysX *waysx)
449 {
450 RouteRelX *unmatched=NULL,*lastunmatched=NULL;
451 int nunmatched=0,lastnunmatched=0,iteration=0;
452
453 if(waysx->number==0)
454 return;
455
456 /* Map into memory / open the files */
457
458 #if !SLIM
459 waysx->xdata=MapFileWriteable(waysx->filename);
460 #else
461 waysx->fd=ReOpenFileWriteable(waysx->filename);
462 #endif
463
464 /* Re-open the file read-only */
465
466 relationsx->rfd=ReOpenFile(relationsx->rfilename);
467
468 /* Read through the file. */
469
470 do
471 {
472 int ways=0,relations=0;
473 int i;
474
475 SeekFile(relationsx->rfd,0);
476
477 /* Print the start message */
478
479 printf_first("Processing Route Relations: Iteration=%d Relations=0 Modified Ways=0",iteration);
480
481 for(i=0;i<relationsx->rxnumber;i++)
482 {
483 FILESORT_VARINT size;
484 RouteRelX relationx;
485 way_t wayid;
486 relation_t relationid;
487 transports_t routes=Transports_None;
488
489 /* Read each route relation */
490
491 ReadFile(relationsx->rfd,&size,FILESORT_VARSIZE);
492 ReadFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
493
494 /* Decide what type of route it is */
495
496 if(iteration==0)
497 {
498 relations++;
499 routes=relationx.routes;
500 }
501 else
502 {
503 int j;
504
505 for(j=0;j<lastnunmatched;j++)
506 if(lastunmatched[j].id==relationx.id)
507 {
508 relations++;
509
510 if((lastunmatched[j].routes|relationx.routes)==relationx.routes)
511 routes=0; /* Nothing new to add */
512 else
513 routes=lastunmatched[j].routes;
514 break;
515 }
516 }
517
518 /* Loop through the ways */
519
520 do
521 {
522 ReadFile(relationsx->rfd,&wayid,sizeof(way_t));
523
524 /* Update the ways that are listed for the relation */
525
526 if(wayid && routes)
527 {
528 index_t way=IndexWayX(waysx,wayid);
529
530 if(way!=NO_WAY)
531 {
532 WayX *wayx=LookupWayX(waysx,way,1);
533
534 if(routes&Transports_Foot)
535 wayx->way.props|=Properties_FootRoute;
536
537 if(routes&Transports_Bicycle)
538 wayx->way.props|=Properties_BicycleRoute;
539
540 PutBackWayX(waysx,way,1);
541
542 ways++;
543 }
544 }
545 }
546 while(wayid);
547
548 /* Loop through the relations */
549
550 do
551 {
552 ReadFile(relationsx->rfd,&relationid,sizeof(relation_t));
553
554 /* Add the relations that are listed for this relation to the list for next time */
555
556 if(relationid && routes && relationid!=relationx.id)
557 {
558 if(nunmatched%256==0)
559 unmatched=(RouteRelX*)realloc((void*)unmatched,(nunmatched+256)*sizeof(RouteRelX));
560
561 unmatched[nunmatched].id=relationid;
562 unmatched[nunmatched].routes=routes;
563
564 nunmatched++;
565 }
566 }
567 while(relationid);
568
569 if(!((i+1)%10000))
570 printf_middle("Processing Route Relations: Iteration=%d Relations=%d Modified Ways=%d",iteration,relations,ways);
571 }
572
573 if(lastunmatched)
574 free(lastunmatched);
575
576 lastunmatched=unmatched;
577 lastnunmatched=nunmatched;
578
579 unmatched=NULL;
580 nunmatched=0;
581
582 /* Print the final message */
583
584 printf_last("Processed Route Relations: Iteration=%d Relations=%d Modified Ways=%d",iteration,relations,ways);
585 }
586 while(lastnunmatched && ++iteration<5);
587
588 if(lastunmatched)
589 free(lastunmatched);
590
591 /* Close the file */
592
593 relationsx->rfd=CloseFile(relationsx->rfd);
594
595 /* Unmap from memory / close the files */
596
597 #if !SLIM
598 waysx->xdata=UnmapFile(waysx->filename);
599 #else
600 waysx->fd=CloseFile(waysx->fd);
601 #endif
602 }
603
604
605 /*++++++++++++++++++++++++++++++++++++++
606 Process the turn relations (first part) to update them with the node/way information.
607
608 RelationsX *relationsx The set of relations to process.
609
610 NodesX *nodesx The set of nodes to process.
611
612 WaysX *waysx The set of ways to process.
613 ++++++++++++++++++++++++++++++++++++++*/
614
615 void ProcessTurnRelations1(RelationsX *relationsx,NodesX *nodesx,WaysX *waysx)
616 {
617 int i,trfd;
618
619 /* Print the start message */
620
621 printf_first("Processing Turn Restriction Relations (1): Turn Relations=0");
622
623 /* Re-open the file read-only and a new file writeable */
624
625 relationsx->trfd=ReOpenFile(relationsx->trfilename);
626
627 DeleteFile(relationsx->trfilename);
628
629 trfd=OpenFileNew(relationsx->trfilename);
630
631 /* Process all of the relations */
632
633 for(i=0;i<relationsx->trnumber;i++)
634 {
635 TurnRestrictRelX relationx;
636
637 ReadFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX));
638
639 relationx.via =IndexNodeX(nodesx,relationx.via);
640 relationx.from=IndexWayX(waysx,relationx.from);
641 relationx.to =IndexWayX(waysx,relationx.to);
642
643 WriteFile(trfd,&relationx,sizeof(TurnRestrictRelX));
644
645 if(!((i+1)%10000))
646 printf_middle("Processing Turn Restriction Relations (1): Turn Relations=%d",i+1);
647 }
648
649 /* Close the files */
650
651 relationsx->trfd=CloseFile(relationsx->trfd);
652 CloseFile(trfd);
653
654 /* Print the final message */
655
656 printf_last("Processed Turn Restriction Relations (1): Turn Relations=%d",relationsx->trnumber);
657 }
658
659
660 /*++++++++++++++++++++++++++++++++++++++
661 Process the turn relations (second part) to convert them to nodes.
662
663 RelationsX *relationsx The set of relations to process.
664
665 NodesX *nodesx The set of nodes to process.
666
667 SegmentsX *segmentsx The set of segments to process.
668
669 WaysX *waysx The set of ways to process.
670 ++++++++++++++++++++++++++++++++++++++*/
671
672 void ProcessTurnRelations2(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx)
673 {
674 TurnRestrictRelX relationx;
675 int trfd;
676 int total=0;
677
678 if(nodesx->number==0 || segmentsx->number==0)
679 return;
680
681 /* Print the start message */
682
683 printf_first("Processing Turn Restriction Relations (2): Turn Relations=0");
684
685 /* Map into memory / open the files */
686
687 #if !SLIM
688 nodesx->xdata=MapFileWriteable(nodesx->filename);
689 segmentsx->xdata=MapFile(segmentsx->filename);
690 #else
691 nodesx->fd=ReOpenFileWriteable(nodesx->filename);
692 segmentsx->fd=ReOpenFile(segmentsx->filename);
693 #endif
694
695 /* Re-open the file read-only and a new file writeable */
696
697 relationsx->trfd=ReOpenFile(relationsx->trfilename);
698
699 DeleteFile(relationsx->trfilename);
700
701 trfd=OpenFileNew(relationsx->trfilename);
702
703 /* Process all of the relations */
704
705 while(!ReadFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX)))
706 {
707 NodeX *nodex;
708 SegmentX *segmentx;
709
710 if(relationx.restrict==TurnRestrict_no_right_turn ||
711 relationx.restrict==TurnRestrict_no_left_turn ||
712 relationx.restrict==TurnRestrict_no_u_turn ||
713 relationx.restrict==TurnRestrict_no_straight_on)
714 {
715 node_t node_from=NO_NODE,node_to=NO_NODE;
716
717 /* Find the segments that join the node 'via' */
718
719 segmentx=FirstSegmentX(segmentsx,relationx.via,1);
720
721 do
722 {
723 if(segmentx->way==relationx.from)
724 {
725 if(node_from!=NO_NODE) /* Only one segment can be on the 'from' way */
726 goto endloop;
727
728 node_from=OtherNode(segmentx,relationx.via);
729 }
730
731 if(segmentx->way==relationx.to)
732 {
733 if(node_to!=NO_NODE) /* Only one segment can be on the 'to' way */
734 goto endloop;
735
736 node_to=OtherNode(segmentx,relationx.via);
737 }
738
739 segmentx=NextSegmentX(segmentsx,segmentx,relationx.via,1);
740 }
741 while(segmentx);
742
743 if(node_to==NO_NODE || node_from==NO_NODE) /* Not enough segments for the selected ways */
744 goto endloop;
745
746 /* Write the results */
747
748 relationx.from=node_from;
749 relationx.to =node_to;
750
751 WriteFile(trfd,&relationx,sizeof(TurnRestrictRelX));
752
753 total++;
754
755 if(!(total%10000))
756 printf_middle("Processing Turn Restriction Relations (2): Turn Relations=%d New=%d",total,total-relationsx->trnumber);
757 }
758 else
759 {
760 node_t node_from=NO_NODE,node_to[8];
761 int nnodes_to=0,i;
762
763 /* Find the segments that join the node 'via' */
764
765 segmentx=FirstSegmentX(segmentsx,relationx.via,1);
766
767 do
768 {
769 if(segmentx->way==relationx.from)
770 {
771 if(node_from!=NO_NODE) /* Only one segment can be on the 'from' way */
772 goto endloop;
773
774 node_from=OtherNode(segmentx,relationx.via);
775 }
776
777 if(segmentx->way!=relationx.to)
778 {
779 if(nnodes_to==8) /* Too many segments (arbitrary choice) */
780 goto endloop;
781
782 node_to[nnodes_to++]=OtherNode(segmentx,relationx.via);
783 }
784
785 segmentx=NextSegmentX(segmentsx,segmentx,relationx.via,1);
786 }
787 while(segmentx);
788
789 if(nnodes_to==0 || node_from==NO_NODE) /* Not enough segments for the selected ways */
790 goto endloop;
791
792 /* Write the results */
793
794 for(i=0;i<nnodes_to;i++)
795 {
796 if(node_to[i]==node_from)
797 continue;
798
799 relationx.from=node_from;
800 relationx.to =node_to[i];
801
802 WriteFile(trfd,&relationx,sizeof(TurnRestrictRelX));
803
804 total++;
805
806 if(!(total%10000))
807 printf_middle("Processing Turn Restriction Relations (2): Turn Relations=%d New=%d",total,total-relationsx->trnumber);
808 }
809 }
810
811 /* Force super nodes on via node and adjacent nodes */
812
813 nodex=LookupNodeX(nodesx,relationx.via,1);
814 nodex->flags|=NODE_TURNRSTRCT;
815 PutBackNodeX(nodesx,relationx.via,1);
816
817 segmentx=FirstSegmentX(segmentsx,relationx.via,1);
818
819 do
820 {
821 index_t othernode=OtherNode(segmentx,relationx.via);
822
823 nodex=LookupNodeX(nodesx,othernode,1);
824 nodex->flags|=NODE_TURNRSTRCT2;
825 PutBackNodeX(nodesx,othernode,1);
826
827 segmentx=NextSegmentX(segmentsx,segmentx,relationx.via,1);
828 }
829 while(segmentx);
830
831 endloop: ;
832 }
833
834 /* Close the files */
835
836 relationsx->trfd=CloseFile(relationsx->trfd);
837 CloseFile(trfd);
838
839 /* Unmap from memory / close the files */
840
841 #if !SLIM
842 nodesx->xdata=UnmapFile(nodesx->filename);
843 segmentsx->xdata=UnmapFile(segmentsx->filename);
844 #else
845 nodesx->fd=CloseFile(nodesx->fd);
846 segmentsx->fd=CloseFile(segmentsx->fd);
847 #endif
848
849 /* Print the final message */
850
851 printf_last("Processed Turn Restriction Relations (2): Turn Relations=%d New=%d",total,total-relationsx->trnumber);
852
853 relationsx->trnumber=total;
854 }
855
856
857 /*++++++++++++++++++++++++++++++++++++++
858 Process the turn relations (third part) to update them with the re-ordered node information.
859
860 RelationsX *relationsx The set of relations to process.
861
862 SegmentsX *segmentsx The set of segments to process.
863 ++++++++++++++++++++++++++++++++++++++*/
864
865 void ProcessTurnRelations3(RelationsX *relationsx,SegmentsX *segmentsx)
866 {
867 int trfd;
868 int i;
869
870 if(segmentsx->number==0)
871 return;
872
873 /* Print the start message */
874
875 printf_first("Processing Turn Restriction Relations (3): Turn Relations=0");
876
877 /* Map into memory / open the files */
878
879 #if !SLIM
880 segmentsx->xdata=MapFile(segmentsx->filename);
881 #else
882 segmentsx->fd=ReOpenFile(segmentsx->filename);
883 #endif
884
885 /* Re-open the file read-only and a new file writeable */
886
887 relationsx->trfd=ReOpenFile(relationsx->trfilename);
888
889 DeleteFile(relationsx->trfilename);
890
891 trfd=OpenFileNew(relationsx->trfilename);
892
893 /* Process all of the relations */
894
895 for(i=0;i<relationsx->trnumber;i++)
896 {
897 TurnRestrictRelX relationx;
898 SegmentX *segmentx;
899 index_t from_node,via_node,to_node;
900
901 ReadFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX));
902
903 from_node=relationx.from;
904 via_node =relationx.via;
905 to_node =relationx.to;
906
907 segmentx=FirstSegmentX(segmentsx,relationx.via,1);
908
909 do
910 {
911 if(OtherNode(segmentx,relationx.via)==from_node)
912 relationx.from=IndexSegmentX(segmentsx,segmentx);
913
914 if(OtherNode(segmentx,relationx.via)==to_node)
915 relationx.to=IndexSegmentX(segmentsx,segmentx);
916
917 segmentx=NextSegmentX(segmentsx,segmentx,relationx.via,1);
918 }
919 while(segmentx);
920
921 WriteFile(trfd,&relationx,sizeof(TurnRestrictRelX));
922
923 if(!(relationsx->trnumber%10000))
924 printf_middle("Processing Turn Restriction Relations (3): Turn Relations=%d",relationsx->trnumber);
925 }
926
927 /* Close the files */
928
929 relationsx->trfd=CloseFile(relationsx->trfd);
930 CloseFile(trfd);
931
932 /* Unmap from memory / close the files */
933
934 #if !SLIM
935 segmentsx->xdata=UnmapFile(segmentsx->filename);
936 #else
937 segmentsx->fd=CloseFile(segmentsx->fd);
938 #endif
939
940 /* Print the final message */
941
942 printf_last("Processed Turn Restriction Relations (3): Turn Relations=%d",relationsx->trnumber);
943 }
944
945
946 /*++++++++++++++++++++++++++++++++++++++
947 Update the node indexes after geographical sorting.
948
949 RelationsX *relationsx The set of relations to process.
950
951 NodesX *nodesx The set of nodes to use.
952 ++++++++++++++++++++++++++++++++++++++*/
953
954 void UpdateTurnRelations(RelationsX *relationsx,NodesX *nodesx)
955 {
956 int trfd;
957 int i;
958
959 /* Print the start message */
960
961 printf_first("Updating Turn Restriction Relations: Turn Relations=0");
962
963 /* Re-open the file read-only and a new file writeable */
964
965 relationsx->trfd=ReOpenFile(relationsx->trfilename);
966
967 DeleteFile(relationsx->trfilename);
968
969 trfd=OpenFileNew(relationsx->trfilename);
970
971 /* Process all of the relations */
972
973 for(i=0;i<relationsx->trnumber;i++)
974 {
975 TurnRestrictRelX relationx;
976
977 ReadFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX));
978
979 relationx.via=nodesx->gdata[relationx.via];
980
981 WriteFile(trfd,&relationx,sizeof(TurnRestrictRelX));
982
983 if(!(relationsx->trnumber%10000))
984 printf_middle("Updating Turn Restriction Relations: Turn Relations=%d",relationsx->trnumber);
985 }
986
987 /* Close the files */
988
989 relationsx->trfd=CloseFile(relationsx->trfd);
990 CloseFile(trfd);
991
992 /* Print the final message */
993
994 printf_last("Updated Turn Restriction Relations: Turn Relations=%d",relationsx->trnumber);
995 }
996
997
998 /*++++++++++++++++++++++++++++++++++++++
999 Save the relation list to a file.
1000
1001 RelationsX* relationsx The set of relations to save.
1002
1003 const char *filename The name of the file to save.
1004 ++++++++++++++++++++++++++++++++++++++*/
1005
1006 void SaveRelationList(RelationsX* relationsx,const char *filename)
1007 {
1008 index_t i;
1009 int fd;
1010 RelationsFile relationsfile={0};
1011
1012 /* Print the start message */
1013
1014 printf_first("Writing Relations: Turn Relations=0");
1015
1016 /* Re-open the file read-only */
1017
1018 relationsx->trfd=ReOpenFile(relationsx->trfilename);
1019
1020 /* Write out the relations data */
1021
1022 fd=OpenFileNew(filename);
1023
1024 SeekFile(fd,sizeof(RelationsFile));
1025
1026 for(i=0;i<relationsx->trnumber;i++)
1027 {
1028 TurnRestrictRelX relationx;
1029 TurnRelation relation;
1030
1031 ReadFile(relationsx->trfd,&relationx,sizeof(TurnRestrictRelX));
1032
1033 relation.from=relationx.from;
1034 relation.via=relationx.via;
1035 relation.to=relationx.to;
1036 relation.except=relationx.except;
1037
1038 WriteFile(fd,&relation,sizeof(TurnRelation));
1039
1040 if(!((i+1)%10000))
1041 printf_middle("Writing Relations: Turn Relations=%d",i+1);
1042 }
1043
1044 /* Write out the header structure */
1045
1046 relationsfile.trnumber=relationsx->trnumber;
1047
1048 SeekFile(fd,0);
1049 WriteFile(fd,&relationsfile,sizeof(RelationsFile));
1050
1051 CloseFile(fd);
1052
1053 /* Close the file */
1054
1055 relationsx->trfd=CloseFile(relationsx->trfd);
1056
1057 /* Print the final message */
1058
1059 printf_last("Wrote Relations: Turn Relations=%d",relationsx->trnumber);
1060 }