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 761 - (hide annotations) (download) (as text)
Fri Jun 3 18:42:06 2011 UTC (13 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 14011 byte(s)
Shorten the messages when running to avoid going beyond 80 characters.

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

Properties

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