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 510 - (hide annotations) (download) (as text)
Sat Oct 9 14:14:42 2010 UTC (14 years, 6 months ago) by amb
File MIME type: text/x-csrc
File size: 12674 byte(s)
Fix previous check-in on this set of files.

1 amb 110 /***************************************
2 amb 510 $Header: /home/amb/CVS/routino/src/superx.c,v 1.44 2010-10-09 14:14:42 amb Exp $
3 amb 110
4     Super-Segment data type functions.
5 amb 151
6     Part of the Routino routing software.
7 amb 110 ******************/ /******************
8 amb 326 This file Copyright 2008-2010 Andrew M. Bishop
9 amb 110
10 amb 151 This program is free software: you can redistribute it and/or modify
11     it under the terms of the GNU Affero General Public License as published by
12     the Free Software Foundation, either version 3 of the License, or
13     (at your option) any later version.
14    
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     GNU Affero General Public License for more details.
19    
20     You should have received a copy of the GNU Affero General Public License
21     along with this program. If not, see <http://www.gnu.org/licenses/>.
22 amb 110 ***************************************/
23    
24    
25     #include <stdlib.h>
26     #include <stdio.h>
27    
28 amb 449 #include "ways.h"
29    
30 amb 110 #include "nodesx.h"
31     #include "segmentsx.h"
32     #include "waysx.h"
33     #include "superx.h"
34    
35 amb 449 #include "files.h"
36     #include "results.h"
37 amb 110
38 amb 449
39 amb 228 /* Local Functions */
40    
41     static Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match,int iteration);
42    
43    
44 amb 110 /*++++++++++++++++++++++++++++++++++++++
45     Select the super-segments from the list of segments.
46    
47     NodesX *nodesx The nodes.
48    
49     SegmentsX *segmentsx The segments.
50    
51     WaysX *waysx The ways.
52     ++++++++++++++++++++++++++++++++++++++*/
53    
54 amb 214 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 231 printf("Finding Super-Nodes: Nodes=0 Super-Nodes=0");
65 amb 227 fflush(stdout);
66    
67 amb 275 /* Map into memory */
68    
69 amb 452 #if !SLIM
70 amb 469 nodesx->xdata=MapFile(nodesx->filename);
71 amb 452 segmentsx->xdata=MapFile(segmentsx->filename);
72     waysx->xdata=MapFile(waysx->filename);
73     #endif
74 amb 257
75 amb 110 /* Find super-nodes */
76    
77 amb 229 for(i=0;i<nodesx->number;i++)
78 amb 110 {
79 amb 469 NodeX *nodex=LookupNodeX(nodesx,i,1);
80 amb 434 int difference=0;
81     index_t index1,index2;
82 amb 110
83 amb 434 index1=IndexFirstSegmentX(segmentsx,i);
84 amb 229
85 amb 434 while(index1!=NO_SEGMENT)
86 amb 110 {
87 amb 434 SegmentX *segmentx1=LookupSegmentX(segmentsx,index1,1);
88 amb 279 WayX *wayx1=LookupWayX(waysx,segmentx1->way,1);
89 amb 110
90 amb 434 index1=IndexNextSegmentX(segmentsx,index1,i);
91     index2=index1;
92 amb 229
93 amb 469 /* If the node allows less traffic types than any connecting way ... */
94    
95     if((wayx1->way.allow&nodex->allow)!=wayx1->way.allow)
96     {
97     difference=1;
98     break;
99     }
100    
101 amb 434 while(index2!=NO_SEGMENT)
102 amb 110 {
103 amb 434 SegmentX *segmentx2=LookupSegmentX(segmentsx,index2,2);
104 amb 279 WayX *wayx2=LookupWayX(waysx,segmentx2->way,2);
105 amb 110
106 amb 469 /* If the ways are different in any attribute and there is a type of traffic that can use both ... */
107 amb 110
108 amb 434 if(WaysCompare(&wayx1->way,&wayx2->way))
109     if(wayx1->way.allow & wayx2->way.allow)
110     {
111     difference=1;
112     break;
113     }
114    
115     index2=IndexNextSegmentX(segmentsx,index2,i);
116 amb 110 }
117    
118 amb 434 if(difference)
119     break;
120     }
121 amb 110
122 amb 434 /* Store the node if there is a difference in the connected ways that could affect routing. */
123 amb 110
124 amb 434 if(difference)
125     {
126     nodesx->super[i]++;
127    
128     nnodes++;
129 amb 110 }
130    
131     if(!((i+1)%10000))
132     {
133 amb 231 printf("\rFinding Super-Nodes: Nodes=%d Super-Nodes=%d",i+1,nnodes);
134 amb 110 fflush(stdout);
135     }
136     }
137    
138 amb 275 /* Unmap from memory */
139    
140 amb 452 #if !SLIM
141 amb 469 nodesx->xdata=UnmapFile(nodesx->filename);
142 amb 452 segmentsx->xdata=UnmapFile(segmentsx->filename);
143     waysx->xdata=UnmapFile(waysx->filename);
144     #endif
145 amb 275
146     /* Print the final message */
147    
148 amb 231 printf("\rFound Super-Nodes: Nodes=%d Super-Nodes=%d \n",nodesx->number,nnodes);
149 amb 110 fflush(stdout);
150     }
151    
152    
153     /*++++++++++++++++++++++++++++++++++++++
154     Create the super-segments.
155    
156     SegmentsX *CreateSuperSegments Creates the super segments.
157    
158     NodesX *nodesx The nodes.
159    
160     SegmentsX *segmentsx The segments.
161    
162     WaysX *waysx The ways.
163    
164     int iteration The current super-node / super-segment iteration number.
165     ++++++++++++++++++++++++++++++++++++++*/
166    
167     SegmentsX *CreateSuperSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,int iteration)
168     {
169 amb 214 index_t i;
170 amb 110 SegmentsX *supersegmentsx;
171 amb 227 int sn=0,ss=0;
172 amb 110
173 amb 508 supersegmentsx=NewSegmentList(0);
174    
175 amb 510 if(segmentsx->number==0 || waysx->number==0)
176 amb 508 return(supersegmentsx);
177    
178 amb 275 /* Print the start message */
179    
180 amb 227 printf("Creating Super-Segments: Super-Nodes=0 Super-Segments=0");
181     fflush(stdout);
182    
183 amb 275 /* Map into memory */
184    
185 amb 452 #if !SLIM
186     segmentsx->xdata=MapFile(segmentsx->filename);
187     waysx->xdata=MapFile(waysx->filename);
188     #endif
189 amb 257
190 amb 275 /* Create super-segments for each super-node. */
191    
192 amb 110 for(i=0;i<nodesx->number;i++)
193     {
194 amb 249 if(nodesx->super[i]>iteration)
195 amb 110 {
196 amb 275 index_t index,first;
197 amb 110
198 amb 279 index=first=IndexFirstSegmentX(segmentsx,i);
199 amb 110
200 amb 275 while(index!=NO_SEGMENT)
201 amb 110 {
202 amb 275 SegmentX *segmentx=LookupSegmentX(segmentsx,index,1);
203 amb 279 WayX *wayx=LookupWayX(waysx,segmentx->way,1);
204 amb 110
205     /* Check that this type of way hasn't already been routed */
206    
207 amb 256 if(index!=first)
208 amb 110 {
209 amb 275 index_t otherindex=first;
210 amb 110
211 amb 275 while(otherindex!=NO_SEGMENT && otherindex!=index)
212 amb 110 {
213 amb 275 SegmentX *othersegmentx=LookupSegmentX(segmentsx,otherindex,2);
214 amb 279 WayX *otherwayx=LookupWayX(waysx,othersegmentx->way,2);
215 amb 110
216 amb 262 if(!WaysCompare(&otherwayx->way,&wayx->way))
217 amb 110 {
218 amb 204 wayx=NULL;
219 amb 110 break;
220     }
221    
222 amb 279 otherindex=IndexNextSegmentX(segmentsx,otherindex,i);
223 amb 110 }
224     }
225    
226     /* Route the way and store the super-segments. */
227    
228 amb 204 if(wayx)
229 amb 110 {
230 amb 279 Results *results=FindRoutesWay(nodesx,segmentsx,waysx,i,&wayx->way,iteration);
231 amb 110 Result *result=FirstResult(results);
232    
233     while(result)
234     {
235 amb 279 if(result->node!=i && nodesx->super[result->node]>iteration)
236 amb 110 {
237 amb 262 if(wayx->way.type&Way_OneWay)
238 amb 277 {
239 amb 279 AppendSegment(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score)|ONEWAY_1TO2);
240     AppendSegment(supersegmentsx,segmentx->way,result->node,i,DISTANCE((distance_t)result->score)|ONEWAY_2TO1);
241 amb 277 }
242 amb 172 else
243 amb 279 AppendSegment(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score));
244 amb 216
245 amb 229 ss++;
246 amb 110 }
247    
248     result=NextResult(results,result);
249     }
250    
251     FreeResultsList(results);
252     }
253    
254 amb 279 index=IndexNextSegmentX(segmentsx,index,i);
255 amb 110 }
256 amb 227
257     sn++;
258 amb 110
259 amb 229 if(!(sn%10000))
260     {
261     printf("\rCreating Super-Segments: Super-Nodes=%d Super-Segments=%d",sn,ss);
262     fflush(stdout);
263     }
264 amb 110 }
265     }
266    
267 amb 275 /* Unmap from memory */
268    
269 amb 452 #if !SLIM
270     segmentsx->xdata=UnmapFile(segmentsx->filename);
271     waysx->xdata=UnmapFile(waysx->filename);
272     #endif
273 amb 275
274     /* Print the final message */
275    
276 amb 227 printf("\rCreated Super-Segments: Super-Nodes=%d Super-Segments=%d \n",sn,ss);
277 amb 110 fflush(stdout);
278    
279     return(supersegmentsx);
280     }
281    
282    
283     /*++++++++++++++++++++++++++++++++++++++
284 amb 256 Merge the segments and super-segments into a new segment list.
285 amb 110
286 amb 256 SegmentsX* MergeSuperSegments Returns a new set of merged segments.
287    
288 amb 110 SegmentsX* segmentsx The set of segments to process.
289    
290     SegmentsX* supersegmentsx The set of super-segments to merge.
291     ++++++++++++++++++++++++++++++++++++++*/
292    
293 amb 256 SegmentsX *MergeSuperSegments(SegmentsX* segmentsx,SegmentsX* supersegmentsx)
294 amb 110 {
295 amb 216 index_t i,j;
296     int m=0,a=0;
297 amb 256 SegmentsX* mergedsegmentsx;
298 amb 110
299 amb 508 mergedsegmentsx=NewSegmentList(0);
300    
301 amb 510 if(segmentsx->number==0 || supersegmentsx->number==0)
302 amb 508 return(mergedsegmentsx);
303    
304 amb 275 /* Print the start message */
305    
306 amb 227 printf("Merging: Segments=0 Super-Segments=0 Merged=0 Added=0");
307     fflush(stdout);
308    
309 amb 275 /* Map into memory */
310    
311 amb 452 #if !SLIM
312     segmentsx->xdata=MapFile(segmentsx->filename);
313     supersegmentsx->xdata=MapFile(supersegmentsx->filename);
314     #endif
315 amb 275
316     /* Loop through and create a new list of combined segments */
317    
318 amb 216 for(i=0,j=0;i<segmentsx->number;i++)
319 amb 110 {
320 amb 256 int super=0;
321 amb 275 SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
322 amb 256
323 amb 110 while(j<supersegmentsx->number)
324     {
325 amb 275 SegmentX *supersegmentx=LookupSegmentX(supersegmentsx,j,1);
326 amb 256
327     if(segmentx->node1 ==supersegmentx->node1 &&
328     segmentx->node2 ==supersegmentx->node2 &&
329     segmentx->distance==supersegmentx->distance)
330 amb 110 {
331 amb 257 m++;
332     j++;
333 amb 256 /* mark as super-segment and normal segment */
334     super=1;
335 amb 110 break;
336     }
337 amb 256 else if((segmentx->node1==supersegmentx->node1 &&
338     segmentx->node2==supersegmentx->node2) ||
339     (segmentx->node1==supersegmentx->node1 &&
340     segmentx->node2>supersegmentx->node2) ||
341     (segmentx->node1>supersegmentx->node1))
342 amb 110 {
343 amb 256 /* mark as super-segment */
344     AppendSegment(mergedsegmentsx,supersegmentx->way,supersegmentx->node1,supersegmentx->node2,supersegmentx->distance|SEGMENT_SUPER);
345 amb 216 a++;
346     j++;
347 amb 110 }
348     else
349 amb 257 {
350     /* mark as normal segment */
351 amb 110 break;
352 amb 257 }
353 amb 110 }
354    
355 amb 256 if(super)
356     AppendSegment(mergedsegmentsx,segmentx->way,segmentx->node1,segmentx->node2,segmentx->distance|SEGMENT_SUPER|SEGMENT_NORMAL);
357     else
358     AppendSegment(mergedsegmentsx,segmentx->way,segmentx->node1,segmentx->node2,segmentx->distance|SEGMENT_NORMAL);
359 amb 208
360 amb 110 if(!((i+1)%10000))
361     {
362 amb 216 printf("\rMerging: Segments=%d Super-Segments=%d Merged=%d Added=%d",i+1,j,m,a);
363 amb 110 fflush(stdout);
364     }
365     }
366    
367 amb 275 /* Unmap from memory */
368    
369 amb 452 #if !SLIM
370     segmentsx->xdata=UnmapFile(segmentsx->filename);
371     supersegmentsx->xdata=UnmapFile(supersegmentsx->filename);
372     #endif
373 amb 275
374     /* Print the final message */
375    
376 amb 216 printf("\rMerged: Segments=%d Super-Segments=%d Merged=%d Added=%d \n",segmentsx->number,supersegmentsx->number,m,a);
377 amb 110 fflush(stdout);
378 amb 256
379     return(mergedsegmentsx);
380 amb 110 }
381    
382    
383     /*++++++++++++++++++++++++++++++++++++++
384     Find all routes from a specified node to any node in the specified list that follows a certain type of way.
385    
386     Results *FindRoutesWay Returns a set of results.
387    
388     NodesX *nodesx The set of nodes to use.
389    
390     SegmentsX *segmentsx The set of segments to use.
391    
392     WaysX *waysx The set of ways to use.
393    
394     node_t start The start node.
395    
396 amb 203 Way *match The way that the route must match.
397 amb 110
398     int iteration The current super-node / super-segment iteration number.
399     ++++++++++++++++++++++++++++++++++++++*/
400    
401 amb 228 static Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match,int iteration)
402 amb 110 {
403     Results *results;
404 amb 236 Queue *queue;
405 amb 110 index_t node1,node2;
406     Result *result1,*result2;
407 amb 275 index_t index;
408 amb 204 WayX *wayx;
409 amb 110
410     /* Insert the first node into the queue */
411    
412     results=NewResultsList(8);
413    
414 amb 236 queue=NewQueueList();
415    
416 amb 110 result1=InsertResult(results,start);
417    
418 amb 166 ZeroResult(result1);
419 amb 110
420 amb 236 InsertInQueue(queue,result1);
421 amb 110
422     /* Loop across all nodes in the queue */
423    
424 amb 236 while((result1=PopFromQueue(queue)))
425 amb 110 {
426     node1=result1->node;
427    
428 amb 256 index=IndexFirstSegmentX(segmentsx,node1);
429 amb 110
430 amb 275 while(index!=NO_SEGMENT)
431 amb 110 {
432 amb 279 SegmentX *segmentx=LookupSegmentX(segmentsx,index,2); /* must use 2 here */
433 amb 113 distance_t cumulative_distance;
434    
435 amb 275 if(segmentx->distance&ONEWAY_2TO1)
436     goto endloop;
437 amb 110
438 amb 275 node2=segmentx->node2;
439 amb 110
440 amb 113 if(result1->prev==node2)
441 amb 110 goto endloop;
442    
443 amb 279 wayx=LookupWayX(waysx,segmentx->way,2);
444 amb 110
445 amb 262 if(WaysCompare(&wayx->way,match))
446 amb 110 goto endloop;
447    
448 amb 256 cumulative_distance=(distance_t)result1->score+DISTANCE(segmentx->distance);
449 amb 110
450     result2=FindResult(results,node2);
451    
452     if(!result2) /* New end node */
453     {
454     result2=InsertResult(results,node2);
455 amb 113 result2->prev=node1;
456 amb 176 result2->next=NO_NODE;
457 amb 172 result2->score=cumulative_distance;
458 amb 166 result2->sortby=cumulative_distance;
459 amb 110
460 amb 279 if(nodesx->super[node2]<=iteration)
461 amb 236 InsertInQueue(queue,result2);
462 amb 110 }
463 amb 172 else if(cumulative_distance<result2->score)
464 amb 110 {
465 amb 166 result2->prev=node1;
466 amb 172 result2->score=cumulative_distance;
467 amb 166 result2->sortby=cumulative_distance;
468 amb 110
469 amb 279 if(nodesx->super[node2]<=iteration)
470 amb 236 InsertInQueue(queue,result2);
471 amb 110 }
472    
473     endloop:
474    
475 amb 279 index=IndexNextSegmentX(segmentsx,index,node1);
476 amb 110 }
477     }
478    
479 amb 236 FreeQueueList(queue);
480    
481 amb 110 return(results);
482     }

Properties

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