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 1062 - (hide annotations) (download) (as text)
Sun Sep 9 13:58:29 2012 UTC (12 years, 6 months ago) by amb
File MIME type: text/x-csrc
File size: 14521 byte(s)
Tiny optimisation to super-segment calculation.

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 950 SetAllBits1(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 949 if(IsPrunedNodeX(nodex))
101     issuper=0;
102     else if(nodex->flags&(NODE_TURNRSTRCT|NODE_TURNRSTRCT2))
103 amb 652 issuper=1;
104     else
105     {
106     int count=0,j;
107 amb 759 Way segmentway[MAX_SEG_PER_NODE];
108     int segmentweight[MAX_SEG_PER_NODE];
109 amb 652 SegmentX *segmentx=FirstSegmentX(segmentsx,i,1);
110 amb 229
111 amb 652 while(segmentx)
112     {
113     WayX *wayx=LookupWayX(waysx,segmentx->way,1);
114     int nsegments;
115 amb 110
116 amb 652 /* Segments that are loops count twice */
117 amb 641
118 amb 759 assert(count<MAX_SEG_PER_NODE); /* Only a limited amount of information stored. */
119 amb 469
120 amb 652 if(segmentx->node1==segmentx->node2)
121     segmentweight[count]=2;
122     else
123     segmentweight[count]=1;
124 amb 469
125 amb 652 segmentway[count]=wayx->way;
126 amb 643
127 amb 652 /* If the node allows less traffic types than any connecting way then it is super */
128 amb 110
129 amb 652 if((wayx->way.allow&nodex->allow)!=wayx->way.allow)
130     {
131     issuper=1;
132     break;
133     }
134    
135     nsegments=segmentweight[count];
136    
137     for(j=0;j<count;j++)
138     if(wayx->way.allow & segmentway[j].allow)
139 amb 643 {
140 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 */
141 amb 110
142 amb 652 if(WaysCompare(&segmentway[j],&wayx->way))
143     {
144     issuper=1;
145     break;
146     }
147 amb 434
148 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 */
149 amb 110
150 amb 652 nsegments+=segmentweight[j];
151     if(nsegments>2)
152     {
153     issuper=1;
154     break;
155     }
156     }
157 amb 643
158 amb 652 if(issuper)
159     break;
160 amb 110
161 amb 943 segmentx=NextSegmentX(segmentsx,segmentx,i);
162 amb 110
163 amb 652 count++;
164     }
165     }
166 amb 434
167 amb 652 /* Mark the node as super if it is. */
168    
169     if(issuper)
170     nnodes++;
171 amb 653 else
172 amb 654 ClearBit(nodesx->super,i);
173 amb 110 }
174    
175     if(!((i+1)%10000))
176 amb 790 printf_middle("Finding Super-Nodes: Nodes=%"Pindex_t" Super-Nodes=%"Pindex_t,i+1,nnodes);
177 amb 110 }
178    
179 amb 555 /* Unmap from memory / close the files */
180 amb 275
181 amb 452 #if !SLIM
182 amb 651 nodesx->data=UnmapFile(nodesx->filename);
183     segmentsx->data=UnmapFile(segmentsx->filename);
184     waysx->data=UnmapFile(waysx->filename);
185 amb 555 #else
186 amb 612 nodesx->fd=CloseFile(nodesx->fd);
187     segmentsx->fd=CloseFile(segmentsx->fd);
188     waysx->fd=CloseFile(waysx->fd);
189 amb 452 #endif
190 amb 275
191     /* Print the final message */
192    
193 amb 790 printf_last("Found Super-Nodes: Nodes=%"Pindex_t" Super-Nodes=%"Pindex_t,nodesx->number,nnodes);
194 amb 110 }
195    
196    
197     /*++++++++++++++++++++++++++++++++++++++
198 amb 680 Create the super-segments from the existing segments.
199 amb 110
200 amb 680 SegmentsX *CreateSuperSegments Returns the new super segments.
201 amb 110
202 amb 680 NodesX *nodesx The set of nodes to use.
203 amb 110
204 amb 680 SegmentsX *segmentsx The set of segments to use.
205 amb 110
206 amb 680 WaysX *waysx The set of ways to use.
207 amb 110 ++++++++++++++++++++++++++++++++++++++*/
208    
209 amb 653 SegmentsX *CreateSuperSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx)
210 amb 110 {
211 amb 214 index_t i;
212 amb 110 SegmentsX *supersegmentsx;
213 amb 780 index_t sn=0,ss=0;
214 amb 110
215 amb 508 supersegmentsx=NewSegmentList(0);
216    
217 amb 510 if(segmentsx->number==0 || waysx->number==0)
218 amb 508 return(supersegmentsx);
219    
220 amb 275 /* Print the start message */
221    
222 amb 519 printf_first("Creating Super-Segments: Super-Nodes=0 Super-Segments=0");
223 amb 227
224 amb 555 /* Map into memory / open the files */
225 amb 275
226 amb 452 #if !SLIM
227 amb 651 segmentsx->data=MapFile(segmentsx->filename);
228     waysx->data=MapFile(waysx->filename);
229 amb 555 #else
230     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 651 segmentsx->data=UnmapFile(segmentsx->filename);
309     waysx->data=UnmapFile(waysx->filename);
310 amb 555 #else
311 amb 612 segmentsx->fd=CloseFile(segmentsx->fd);
312     waysx->fd=CloseFile(waysx->fd);
313 amb 452 #endif
314 amb 275
315     /* Print the final message */
316    
317 amb 790 printf_last("Created Super-Segments: Super-Nodes=%"Pindex_t" Super-Segments=%"Pindex_t,sn,ss);
318 amb 110
319     return(supersegmentsx);
320     }
321    
322    
323     /*++++++++++++++++++++++++++++++++++++++
324 amb 256 Merge the segments and super-segments into a new segment list.
325 amb 110
326 amb 681 SegmentsX *MergeSuperSegments Returns a new set of merged segments.
327 amb 256
328 amb 681 SegmentsX *segmentsx The set of segments to use.
329 amb 110
330 amb 681 SegmentsX *supersegmentsx The set of super-segments to use.
331 amb 110 ++++++++++++++++++++++++++++++++++++++*/
332    
333 amb 681 SegmentsX *MergeSuperSegments(SegmentsX *segmentsx,SegmentsX *supersegmentsx)
334 amb 110 {
335 amb 216 index_t i,j;
336 amb 780 index_t merged=0,added=0;
337 amb 681 SegmentsX *mergedsegmentsx;
338 amb 110
339 amb 508 mergedsegmentsx=NewSegmentList(0);
340    
341 amb 550 if(segmentsx->number==0)
342 amb 508 return(mergedsegmentsx);
343    
344 amb 275 /* Print the start message */
345    
346 amb 761 printf_first("Merging Segments: Segments=0 Super=0 Merged=0 Added=0");
347 amb 227
348 amb 555 /* Map into memory / open the files */
349 amb 275
350 amb 452 #if !SLIM
351 amb 651 segmentsx->data=MapFile(segmentsx->filename);
352 amb 550 if(supersegmentsx->number>0)
353 amb 651 supersegmentsx->data=MapFile(supersegmentsx->filename);
354 amb 555 #else
355     segmentsx->fd=ReOpenFile(segmentsx->filename);
356     if(supersegmentsx->number>0)
357     supersegmentsx->fd=ReOpenFile(supersegmentsx->filename);
358 amb 452 #endif
359 amb 275
360     /* Loop through and create a new list of combined segments */
361    
362 amb 216 for(i=0,j=0;i<segmentsx->number;i++)
363 amb 110 {
364 amb 256 int super=0;
365 amb 275 SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
366 amb 256
367 amb 110 while(j<supersegmentsx->number)
368     {
369 amb 275 SegmentX *supersegmentx=LookupSegmentX(supersegmentsx,j,1);
370 amb 256
371     if(segmentx->node1 ==supersegmentx->node1 &&
372     segmentx->node2 ==supersegmentx->node2 &&
373     segmentx->distance==supersegmentx->distance)
374 amb 110 {
375 amb 780 merged++;
376 amb 257 j++;
377 amb 256 /* mark as super-segment and normal segment */
378     super=1;
379 amb 110 break;
380     }
381 amb 256 else if((segmentx->node1==supersegmentx->node1 &&
382     segmentx->node2==supersegmentx->node2) ||
383     (segmentx->node1==supersegmentx->node1 &&
384     segmentx->node2>supersegmentx->node2) ||
385     (segmentx->node1>supersegmentx->node1))
386 amb 110 {
387 amb 256 /* mark as super-segment */
388     AppendSegment(mergedsegmentsx,supersegmentx->way,supersegmentx->node1,supersegmentx->node2,supersegmentx->distance|SEGMENT_SUPER);
389 amb 780 added++;
390 amb 216 j++;
391 amb 110 }
392     else
393 amb 257 {
394     /* mark as normal segment */
395 amb 110 break;
396 amb 257 }
397 amb 110 }
398    
399 amb 256 if(super)
400     AppendSegment(mergedsegmentsx,segmentx->way,segmentx->node1,segmentx->node2,segmentx->distance|SEGMENT_SUPER|SEGMENT_NORMAL);
401     else
402     AppendSegment(mergedsegmentsx,segmentx->way,segmentx->node1,segmentx->node2,segmentx->distance|SEGMENT_NORMAL);
403 amb 208
404 amb 110 if(!((i+1)%10000))
405 amb 790 printf_middle("Merging Segments: Segments=%"Pindex_t" Super=%"Pindex_t" Merged=%"Pindex_t" Added=%"Pindex_t,i+1,j,merged,added);
406 amb 110 }
407    
408 amb 555 /* Unmap from memory / close the files */
409 amb 275
410 amb 452 #if !SLIM
411 amb 651 segmentsx->data=UnmapFile(segmentsx->filename);
412 amb 550 if(supersegmentsx->number>0)
413 amb 651 supersegmentsx->data=UnmapFile(supersegmentsx->filename);
414 amb 555 #else
415 amb 612 segmentsx->fd=CloseFile(segmentsx->fd);
416 amb 555 if(supersegmentsx->number>0)
417 amb 612 supersegmentsx->fd=CloseFile(supersegmentsx->fd);
418 amb 452 #endif
419 amb 275
420     /* Print the final message */
421    
422 amb 790 printf_last("Merged Segments: Segments=%"Pindex_t" Super=%"Pindex_t" Merged=%"Pindex_t" Added=%"Pindex_t,segmentsx->number,supersegmentsx->number,merged,added);
423 amb 256
424     return(mergedsegmentsx);
425 amb 110 }
426    
427    
428     /*++++++++++++++++++++++++++++++++++++++
429 amb 680 Find all routes from a specified super-node to any other super-node that follows a certain type of way.
430 amb 110
431     Results *FindRoutesWay Returns a set of results.
432    
433     NodesX *nodesx The set of nodes to use.
434    
435     SegmentsX *segmentsx The set of segments to use.
436    
437     WaysX *waysx The set of ways to use.
438    
439     node_t start The start node.
440    
441 amb 680 Way *match A template for the type of way that the route must follow.
442 amb 110 ++++++++++++++++++++++++++++++++++++++*/
443    
444 amb 653 static Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match)
445 amb 110 {
446     Results *results;
447 amb 236 Queue *queue;
448 amb 110 Result *result1,*result2;
449 amb 204 WayX *wayx;
450 amb 110
451     /* Insert the first node into the queue */
452    
453 amb 856 results=NewResultsList(4);
454 amb 110
455 amb 236 queue=NewQueueList();
456    
457 amb 605 result1=InsertResult(results,start,NO_SEGMENT);
458 amb 110
459 amb 236 InsertInQueue(queue,result1);
460 amb 110
461     /* Loop across all nodes in the queue */
462    
463 amb 236 while((result1=PopFromQueue(queue)))
464 amb 110 {
465 amb 785 index_t node1;
466 amb 643 SegmentX *segmentx;
467    
468 amb 110 node1=result1->node;
469    
470 amb 646 segmentx=FirstSegmentX(segmentsx,node1,2); /* position 1 is already used */
471 amb 110
472 amb 643 while(segmentx)
473 amb 110 {
474 amb 643 index_t node2,seg2;
475 amb 113 distance_t cumulative_distance;
476    
477 amb 680 /* must not be one-way against the direction of travel */
478 amb 647 if(IsOnewayTo(segmentx,node1))
479     goto endloop;
480 amb 110
481 amb 643 seg2=IndexSegmentX(segmentsx,segmentx);
482    
483 amb 680 /* must not be a u-turn */
484 amb 656 if(result1->segment==seg2)
485 amb 110 goto endloop;
486    
487 amb 890 wayx=LookupWayX(waysx,segmentx->way,2); /* position 1 is already used */
488 amb 110
489 amb 680 /* must be the right type of way */
490 amb 262 if(WaysCompare(&wayx->way,match))
491 amb 110 goto endloop;
492    
493 amb 256 cumulative_distance=(distance_t)result1->score+DISTANCE(segmentx->distance);
494 amb 110
495 amb 1062 node2=OtherNode(segmentx,node1);
496    
497 amb 642 result2=FindResult(results,node2,seg2);
498 amb 110
499     if(!result2) /* New end node */
500     {
501 amb 642 result2=InsertResult(results,node2,seg2);
502 amb 605 result2->prev=result1;
503 amb 172 result2->score=cumulative_distance;
504 amb 166 result2->sortby=cumulative_distance;
505 amb 110
506 amb 680 /* don't route beyond a super-node. */
507 amb 654 if(!IsBitSet(nodesx->super,node2))
508 amb 236 InsertInQueue(queue,result2);
509 amb 110 }
510 amb 172 else if(cumulative_distance<result2->score)
511 amb 110 {
512 amb 605 result2->prev=result1;
513 amb 172 result2->score=cumulative_distance;
514 amb 166 result2->sortby=cumulative_distance;
515 amb 110
516 amb 680 /* don't route beyond a super-node. */
517 amb 654 if(!IsBitSet(nodesx->super,node2))
518 amb 236 InsertInQueue(queue,result2);
519 amb 110 }
520    
521     endloop:
522    
523 amb 943 segmentx=NextSegmentX(segmentsx,segmentx,node1);
524 amb 110 }
525     }
526    
527 amb 236 FreeQueueList(queue);
528    
529 amb 110 return(results);
530     }

Properties

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