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 560 - (hide annotations) (download) (as text)
Tue Dec 21 14:54:27 2010 UTC (14 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 13290 byte(s)
Update the nodes to force a super-node where there is a turn restriction.

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

Properties

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