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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1098 - (hide annotations) (download) (as text)
Sat Oct 20 12:52:01 2012 UTC (12 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 14900 byte(s)
Delete the pruned nodes before searching for super-nodes etc.

1 amb 110 /***************************************
2     Super-Segment data type functions.
3 amb 151
4     Part of the Routino routing software.
5 amb 110 ******************/ /******************
6 amb 947 This file Copyright 2008-2012 Andrew M. Bishop
7 amb 110
8 amb 151 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 amb 110 ***************************************/
21    
22    
23 amb 776 #include <assert.h>
24 amb 110 #include <stdlib.h>
25    
26 amb 955 #include "types.h"
27     #include "segments.h"
28 amb 449 #include "ways.h"
29    
30 amb 955 #include "typesx.h"
31 amb 110 #include "nodesx.h"
32     #include "segmentsx.h"
33     #include "waysx.h"
34     #include "superx.h"
35    
36 amb 449 #include "files.h"
37 amb 519 #include "logging.h"
38 amb 449 #include "results.h"
39 amb 110
40 amb 449
41 amb 680 /* Local functions */
42 amb 228
43 amb 653 static Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match);
44 amb 228
45    
46 amb 110 /*++++++++++++++++++++++++++++++++++++++
47 amb 680 Select the super-nodes from the list of nodes.
48 amb 110
49 amb 680 NodesX *nodesx The set of nodes to use.
50 amb 110
51 amb 680 SegmentsX *segmentsx The set of segments to use.
52 amb 110
53 amb 680 WaysX *waysx The set of ways to use.
54 amb 110 ++++++++++++++++++++++++++++++++++++++*/
55    
56 amb 653 void ChooseSuperNodes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx)
57 amb 110 {
58 amb 214 index_t i;
59 amb 780 index_t nnodes=0;
60 amb 110
61 amb 510 if(nodesx->number==0 || segmentsx->number==0 || waysx->number==0)
62 amb 508 return;
63    
64 amb 275 /* Print the start message */
65    
66 amb 519 printf_first("Finding Super-Nodes: Nodes=0 Super-Nodes=0");
67 amb 227
68 amb 947 /* Allocate and set the super-node markers */
69    
70     if(!nodesx->super)
71     {
72 amb 950 nodesx->super=AllocBitMask(nodesx->number);
73 amb 947
74 amb 950 assert(nodesx->super); /* Check AllocBitMask() worked */
75 amb 947
76 amb 1089 SetAllBits(nodesx->super,nodesx->number);
77 amb 947 }
78    
79 amb 555 /* Map into memory / open the files */
80 amb 275
81 amb 452 #if !SLIM
82 amb 651 nodesx->data=MapFile(nodesx->filename);
83     segmentsx->data=MapFile(segmentsx->filename);
84     waysx->data=MapFile(waysx->filename);
85 amb 555 #else
86     nodesx->fd=ReOpenFile(nodesx->filename);
87     segmentsx->fd=ReOpenFile(segmentsx->filename);
88     waysx->fd=ReOpenFile(waysx->filename);
89 amb 452 #endif
90 amb 257
91 amb 110 /* Find super-nodes */
92    
93 amb 229 for(i=0;i<nodesx->number;i++)
94 amb 110 {
95 amb 654 if(IsBitSet(nodesx->super,i))
96 amb 652 {
97     int issuper=0;
98     NodeX *nodex=LookupNodeX(nodesx,i,1);
99 amb 110
100 amb 1098 if(nodex->flags&(NODE_TURNRSTRCT|NODE_TURNRSTRCT2))
101 amb 652 issuper=1;
102     else
103     {
104     int count=0,j;
105 amb 759 Way segmentway[MAX_SEG_PER_NODE];
106     int segmentweight[MAX_SEG_PER_NODE];
107 amb 652 SegmentX *segmentx=FirstSegmentX(segmentsx,i,1);
108 amb 229
109 amb 652 while(segmentx)
110     {
111     WayX *wayx=LookupWayX(waysx,segmentx->way,1);
112     int nsegments;
113 amb 110
114 amb 652 /* Segments that are loops count twice */
115 amb 641
116 amb 759 assert(count<MAX_SEG_PER_NODE); /* Only a limited amount of information stored. */
117 amb 469
118 amb 652 if(segmentx->node1==segmentx->node2)
119     segmentweight[count]=2;
120     else
121     segmentweight[count]=1;
122 amb 469
123 amb 652 segmentway[count]=wayx->way;
124 amb 643
125 amb 1069 /* If the node allows less traffic types than any connecting way then it is super if it allows anything */
126 amb 110
127 amb 1069 if((wayx->way.allow&nodex->allow)!=wayx->way.allow && nodex->allow!=Transports_None)
128 amb 652 {
129     issuper=1;
130     break;
131     }
132    
133     nsegments=segmentweight[count];
134    
135     for(j=0;j<count;j++)
136     if(wayx->way.allow & segmentway[j].allow)
137 amb 643 {
138 amb 652 /* If two ways are different in any attribute and there is a type of traffic that can use both then it is super */
139 amb 110
140 amb 652 if(WaysCompare(&segmentway[j],&wayx->way))
141     {
142     issuper=1;
143     break;
144     }
145 amb 434
146 amb 652 /* If there are two other segments that can be used by the same types of traffic as this one then it is super */
147 amb 110
148 amb 652 nsegments+=segmentweight[j];
149     if(nsegments>2)
150     {
151     issuper=1;
152     break;
153     }
154     }
155 amb 643
156 amb 652 if(issuper)
157     break;
158 amb 110
159 amb 943 segmentx=NextSegmentX(segmentsx,segmentx,i);
160 amb 110
161 amb 652 count++;
162     }
163     }
164 amb 434
165 amb 652 /* Mark the node as super if it is. */
166    
167     if(issuper)
168     nnodes++;
169 amb 653 else
170 amb 654 ClearBit(nodesx->super,i);
171 amb 110 }
172    
173     if(!((i+1)%10000))
174 amb 790 printf_middle("Finding Super-Nodes: Nodes=%"Pindex_t" Super-Nodes=%"Pindex_t,i+1,nnodes);
175 amb 110 }
176    
177 amb 555 /* Unmap from memory / close the files */
178 amb 275
179 amb 452 #if !SLIM
180 amb 651 nodesx->data=UnmapFile(nodesx->filename);
181     segmentsx->data=UnmapFile(segmentsx->filename);
182     waysx->data=UnmapFile(waysx->filename);
183 amb 555 #else
184 amb 612 nodesx->fd=CloseFile(nodesx->fd);
185     segmentsx->fd=CloseFile(segmentsx->fd);
186     waysx->fd=CloseFile(waysx->fd);
187 amb 452 #endif
188 amb 275
189     /* Print the final message */
190    
191 amb 790 printf_last("Found Super-Nodes: Nodes=%"Pindex_t" Super-Nodes=%"Pindex_t,nodesx->number,nnodes);
192 amb 110 }
193    
194    
195     /*++++++++++++++++++++++++++++++++++++++
196 amb 680 Create the super-segments from the existing segments.
197 amb 110
198 amb 680 SegmentsX *CreateSuperSegments Returns the new super segments.
199 amb 110
200 amb 680 NodesX *nodesx The set of nodes to use.
201 amb 110
202 amb 680 SegmentsX *segmentsx The set of segments to use.
203 amb 110
204 amb 680 WaysX *waysx The set of ways to use.
205 amb 110 ++++++++++++++++++++++++++++++++++++++*/
206    
207 amb 653 SegmentsX *CreateSuperSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx)
208 amb 110 {
209 amb 214 index_t i;
210 amb 110 SegmentsX *supersegmentsx;
211 amb 780 index_t sn=0,ss=0;
212 amb 110
213 amb 508 supersegmentsx=NewSegmentList(0);
214    
215 amb 510 if(segmentsx->number==0 || waysx->number==0)
216 amb 508 return(supersegmentsx);
217    
218 amb 275 /* Print the start message */
219    
220 amb 519 printf_first("Creating Super-Segments: Super-Nodes=0 Super-Segments=0");
221 amb 227
222 amb 555 /* Map into memory / open the files */
223 amb 275
224 amb 452 #if !SLIM
225 amb 1071 nodesx->data=MapFile(nodesx->filename);
226 amb 651 segmentsx->data=MapFile(segmentsx->filename);
227     waysx->data=MapFile(waysx->filename);
228 amb 555 #else
229 amb 1071 nodesx->fd=ReOpenFile(nodesx->filename);
230 amb 555 segmentsx->fd=ReOpenFile(segmentsx->filename);
231     waysx->fd=ReOpenFile(waysx->filename);
232 amb 452 #endif
233 amb 257
234 amb 275 /* Create super-segments for each super-node. */
235    
236 amb 110 for(i=0;i<nodesx->number;i++)
237     {
238 amb 654 if(IsBitSet(nodesx->super,i))
239 amb 110 {
240 amb 643 SegmentX *segmentx;
241 amb 652 int count=0,match;
242 amb 759 Way prevway[MAX_SEG_PER_NODE];
243 amb 110
244 amb 646 segmentx=FirstSegmentX(segmentsx,i,1);
245 amb 110
246 amb 643 while(segmentx)
247 amb 110 {
248 amb 279 WayX *wayx=LookupWayX(waysx,segmentx->way,1);
249 amb 110
250     /* Check that this type of way hasn't already been routed */
251    
252 amb 643 match=0;
253    
254 amb 652 if(count>0)
255 amb 110 {
256 amb 643 int j;
257 amb 110
258 amb 652 for(j=0;j<count;j++)
259 amb 643 if(!WaysCompare(&prevway[j],&wayx->way))
260 amb 110 {
261 amb 643 match=1;
262 amb 110 break;
263     }
264     }
265    
266 amb 759 assert(count<MAX_SEG_PER_NODE); /* Only a limited amount of history stored. */
267 amb 643
268 amb 652 prevway[count++]=wayx->way;
269 amb 643
270 amb 110 /* Route the way and store the super-segments. */
271    
272 amb 643 if(!match)
273 amb 110 {
274 amb 653 Results *results=FindRoutesWay(nodesx,segmentsx,waysx,i,&wayx->way);
275 amb 110 Result *result=FirstResult(results);
276    
277     while(result)
278     {
279 amb 654 if(IsBitSet(nodesx->super,result->node) && result->segment!=NO_SEGMENT)
280 amb 110 {
281 amb 641 if(wayx->way.type&Way_OneWay && result->node!=i)
282 amb 279 AppendSegment(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score)|ONEWAY_1TO2);
283 amb 172 else
284 amb 279 AppendSegment(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score));
285 amb 216
286 amb 229 ss++;
287 amb 110 }
288    
289     result=NextResult(results,result);
290     }
291    
292     FreeResultsList(results);
293     }
294    
295 amb 943 segmentx=NextSegmentX(segmentsx,segmentx,i);
296 amb 110 }
297 amb 227
298     sn++;
299 amb 110
300 amb 229 if(!(sn%10000))
301 amb 790 printf_middle("Creating Super-Segments: Super-Nodes=%"Pindex_t" Super-Segments=%"Pindex_t,sn,ss);
302 amb 110 }
303     }
304    
305 amb 555 /* Unmap from memory / close the files */
306 amb 275
307 amb 452 #if !SLIM
308 amb 1071 nodesx->data=UnmapFile(nodesx->filename);
309 amb 651 segmentsx->data=UnmapFile(segmentsx->filename);
310     waysx->data=UnmapFile(waysx->filename);
311 amb 555 #else
312 amb 1071 nodesx->fd=CloseFile(nodesx->fd);
313 amb 612 segmentsx->fd=CloseFile(segmentsx->fd);
314     waysx->fd=CloseFile(waysx->fd);
315 amb 452 #endif
316 amb 275
317     /* Print the final message */
318    
319 amb 790 printf_last("Created Super-Segments: Super-Nodes=%"Pindex_t" Super-Segments=%"Pindex_t,sn,ss);
320 amb 110
321     return(supersegmentsx);
322     }
323    
324    
325     /*++++++++++++++++++++++++++++++++++++++
326 amb 256 Merge the segments and super-segments into a new segment list.
327 amb 110
328 amb 681 SegmentsX *MergeSuperSegments Returns a new set of merged segments.
329 amb 256
330 amb 681 SegmentsX *segmentsx The set of segments to use.
331 amb 110
332 amb 681 SegmentsX *supersegmentsx The set of super-segments to use.
333 amb 110 ++++++++++++++++++++++++++++++++++++++*/
334    
335 amb 681 SegmentsX *MergeSuperSegments(SegmentsX *segmentsx,SegmentsX *supersegmentsx)
336 amb 110 {
337 amb 216 index_t i,j;
338 amb 780 index_t merged=0,added=0;
339 amb 681 SegmentsX *mergedsegmentsx;
340 amb 110
341 amb 508 mergedsegmentsx=NewSegmentList(0);
342    
343 amb 550 if(segmentsx->number==0)
344 amb 508 return(mergedsegmentsx);
345    
346 amb 275 /* Print the start message */
347    
348 amb 761 printf_first("Merging Segments: Segments=0 Super=0 Merged=0 Added=0");
349 amb 227
350 amb 555 /* Map into memory / open the files */
351 amb 275
352 amb 452 #if !SLIM
353 amb 651 segmentsx->data=MapFile(segmentsx->filename);
354 amb 550 if(supersegmentsx->number>0)
355 amb 651 supersegmentsx->data=MapFile(supersegmentsx->filename);
356 amb 555 #else
357     segmentsx->fd=ReOpenFile(segmentsx->filename);
358     if(supersegmentsx->number>0)
359     supersegmentsx->fd=ReOpenFile(supersegmentsx->filename);
360 amb 452 #endif
361 amb 275
362     /* Loop through and create a new list of combined segments */
363    
364 amb 216 for(i=0,j=0;i<segmentsx->number;i++)
365 amb 110 {
366 amb 256 int super=0;
367 amb 275 SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
368 amb 256
369 amb 110 while(j<supersegmentsx->number)
370     {
371 amb 275 SegmentX *supersegmentx=LookupSegmentX(supersegmentsx,j,1);
372 amb 256
373     if(segmentx->node1 ==supersegmentx->node1 &&
374     segmentx->node2 ==supersegmentx->node2 &&
375     segmentx->distance==supersegmentx->distance)
376 amb 110 {
377 amb 780 merged++;
378 amb 257 j++;
379 amb 256 /* mark as super-segment and normal segment */
380     super=1;
381 amb 110 break;
382     }
383 amb 256 else if((segmentx->node1==supersegmentx->node1 &&
384     segmentx->node2==supersegmentx->node2) ||
385     (segmentx->node1==supersegmentx->node1 &&
386     segmentx->node2>supersegmentx->node2) ||
387     (segmentx->node1>supersegmentx->node1))
388 amb 110 {
389 amb 256 /* mark as super-segment */
390     AppendSegment(mergedsegmentsx,supersegmentx->way,supersegmentx->node1,supersegmentx->node2,supersegmentx->distance|SEGMENT_SUPER);
391 amb 780 added++;
392 amb 216 j++;
393 amb 110 }
394     else
395 amb 257 {
396     /* mark as normal segment */
397 amb 110 break;
398 amb 257 }
399 amb 110 }
400    
401 amb 256 if(super)
402     AppendSegment(mergedsegmentsx,segmentx->way,segmentx->node1,segmentx->node2,segmentx->distance|SEGMENT_SUPER|SEGMENT_NORMAL);
403     else
404     AppendSegment(mergedsegmentsx,segmentx->way,segmentx->node1,segmentx->node2,segmentx->distance|SEGMENT_NORMAL);
405 amb 208
406 amb 110 if(!((i+1)%10000))
407 amb 790 printf_middle("Merging Segments: Segments=%"Pindex_t" Super=%"Pindex_t" Merged=%"Pindex_t" Added=%"Pindex_t,i+1,j,merged,added);
408 amb 110 }
409    
410 amb 555 /* Unmap from memory / close the files */
411 amb 275
412 amb 452 #if !SLIM
413 amb 651 segmentsx->data=UnmapFile(segmentsx->filename);
414 amb 550 if(supersegmentsx->number>0)
415 amb 651 supersegmentsx->data=UnmapFile(supersegmentsx->filename);
416 amb 555 #else
417 amb 612 segmentsx->fd=CloseFile(segmentsx->fd);
418 amb 555 if(supersegmentsx->number>0)
419 amb 612 supersegmentsx->fd=CloseFile(supersegmentsx->fd);
420 amb 452 #endif
421 amb 275
422     /* Print the final message */
423    
424 amb 790 printf_last("Merged Segments: Segments=%"Pindex_t" Super=%"Pindex_t" Merged=%"Pindex_t" Added=%"Pindex_t,segmentsx->number,supersegmentsx->number,merged,added);
425 amb 256
426     return(mergedsegmentsx);
427 amb 110 }
428    
429    
430     /*++++++++++++++++++++++++++++++++++++++
431 amb 680 Find all routes from a specified super-node to any other super-node that follows a certain type of way.
432 amb 110
433     Results *FindRoutesWay Returns a set of results.
434    
435     NodesX *nodesx The set of nodes to use.
436    
437     SegmentsX *segmentsx The set of segments to use.
438    
439     WaysX *waysx The set of ways to use.
440    
441     node_t start The start node.
442    
443 amb 680 Way *match A template for the type of way that the route must follow.
444 amb 110 ++++++++++++++++++++++++++++++++++++++*/
445    
446 amb 653 static Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match)
447 amb 110 {
448     Results *results;
449 amb 236 Queue *queue;
450 amb 110 Result *result1,*result2;
451 amb 204 WayX *wayx;
452 amb 110
453     /* Insert the first node into the queue */
454    
455 amb 1066 results=NewResultsList(64);
456 amb 110
457 amb 236 queue=NewQueueList();
458    
459 amb 605 result1=InsertResult(results,start,NO_SEGMENT);
460 amb 110
461 amb 236 InsertInQueue(queue,result1);
462 amb 110
463     /* Loop across all nodes in the queue */
464    
465 amb 236 while((result1=PopFromQueue(queue)))
466 amb 110 {
467 amb 785 index_t node1;
468 amb 643 SegmentX *segmentx;
469    
470 amb 110 node1=result1->node;
471    
472 amb 646 segmentx=FirstSegmentX(segmentsx,node1,2); /* position 1 is already used */
473 amb 110
474 amb 643 while(segmentx)
475 amb 110 {
476 amb 1071 NodeX *node2x;
477 amb 643 index_t node2,seg2;
478 amb 113 distance_t cumulative_distance;
479    
480 amb 680 /* must not be one-way against the direction of travel */
481 amb 647 if(IsOnewayTo(segmentx,node1))
482     goto endloop;
483 amb 110
484 amb 643 seg2=IndexSegmentX(segmentsx,segmentx);
485    
486 amb 680 /* must not be a u-turn */
487 amb 656 if(result1->segment==seg2)
488 amb 110 goto endloop;
489    
490 amb 890 wayx=LookupWayX(waysx,segmentx->way,2); /* position 1 is already used */
491 amb 110
492 amb 680 /* must be the right type of way */
493 amb 262 if(WaysCompare(&wayx->way,match))
494 amb 110 goto endloop;
495    
496 amb 1071 node2=OtherNode(segmentx,node1);
497    
498     node2x=LookupNodeX(nodesx,node2,2); /* position 1 is already used */
499    
500     /* Don't route beyond a node with no access */
501     if(node2x->allow==Transports_None)
502     goto endloop;
503    
504 amb 256 cumulative_distance=(distance_t)result1->score+DISTANCE(segmentx->distance);
505 amb 110
506 amb 642 result2=FindResult(results,node2,seg2);
507 amb 110
508     if(!result2) /* New end node */
509     {
510 amb 642 result2=InsertResult(results,node2,seg2);
511 amb 605 result2->prev=result1;
512 amb 172 result2->score=cumulative_distance;
513 amb 166 result2->sortby=cumulative_distance;
514 amb 110
515 amb 680 /* don't route beyond a super-node. */
516 amb 654 if(!IsBitSet(nodesx->super,node2))
517 amb 236 InsertInQueue(queue,result2);
518 amb 110 }
519 amb 172 else if(cumulative_distance<result2->score)
520 amb 110 {
521 amb 605 result2->prev=result1;
522 amb 172 result2->score=cumulative_distance;
523 amb 166 result2->sortby=cumulative_distance;
524 amb 110
525 amb 680 /* don't route beyond a super-node. */
526 amb 654 if(!IsBitSet(nodesx->super,node2))
527 amb 236 InsertInQueue(queue,result2);
528 amb 110 }
529    
530     endloop:
531    
532 amb 943 segmentx=NextSegmentX(segmentsx,segmentx,node1);
533 amb 110 }
534     }
535    
536 amb 236 FreeQueueList(queue);
537    
538 amb 110 return(results);
539     }

Properties

Name Value
cvs:description Super-nodes and super-segments functions.