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 776 - (hide annotations) (download) (as text)
Sat Jun 4 18:55:59 2011 UTC (13 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 14031 byte(s)
Add missing header file.

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

Properties

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