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 651 - (hide annotations) (download) (as text)
Sun Feb 27 16:31:34 2011 UTC (14 years ago) by amb
File MIME type: text/x-csrc
File size: 26464 byte(s)
Rename the xdata and xcached members of the nodesx, segmentsx and waysx
structures.

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