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 214 - (hide annotations) (download) (as text)
Thu Jul 2 17:49:16 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 10766 byte(s)
Fix some gcc pedantic warnings.

1 amb 110 /***************************************
2 amb 214 $Header: /home/amb/CVS/routino/src/superx.c,v 1.18 2009-07-02 17:49:16 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 151 This file Copyright 2008,2009 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 <assert.h>
26     #include <stdlib.h>
27     #include <stdio.h>
28    
29     #include "results.h"
30     #include "nodesx.h"
31     #include "segmentsx.h"
32     #include "waysx.h"
33     #include "superx.h"
34    
35    
36     /*++++++++++++++++++++++++++++++++++++++
37     Select the super-segments from the list of segments.
38    
39     NodesX *nodesx The nodes.
40    
41     SegmentsX *segmentsx The segments.
42    
43     WaysX *waysx The ways.
44     ++++++++++++++++++++++++++++++++++++++*/
45    
46 amb 214 void ChooseSuperNodes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx)
47 amb 110 {
48 amb 214 index_t i;
49     int segcount=0,difference=0,nnodes=0;
50     node_t node=0;
51     WayX *wayx1;
52 amb 110
53 amb 213 assert(segmentsx->ndata); /* Must have ndata filled in */
54    
55 amb 110 /* Find super-nodes */
56    
57 amb 206 node=segmentsx->ndata[0]->node1;
58     wayx1=FindWayX(waysx,segmentsx->ndata[0]->way);
59 amb 110
60     for(i=0;i<segmentsx->number;i++)
61     {
62 amb 209 WayX *wayx2=FindWayX(waysx,segmentsx->ndata[i]->way);
63 amb 110
64 amb 209 if(segmentsx->ndata[i]->node1!=node)
65 amb 110 {
66     /* Store the node if there is a difference in the ways that could affect routing.
67     Store the node if it is not a dead-end and if it isn't just the middle of a way. */
68    
69     if(difference || segcount>2)
70     {
71 amb 212 NodeX **nodex=FindNodeX(nodesx,node);
72 amb 110
73 amb 212 (*nodex)->super++;
74 amb 110
75     nnodes++;
76     }
77    
78     segcount=1;
79     difference=0;
80    
81 amb 209 node=segmentsx->ndata[i]->node1;
82 amb 204 wayx1=wayx2;
83 amb 110 }
84     else /* Same starting node */
85     {
86 amb 204 if(WaysCompare(wayx2->way,wayx1->way))
87 amb 110 difference=1;
88    
89     segcount+=1;
90     }
91    
92     if(!((i+1)%10000))
93     {
94     printf("\rFinding Super-Nodes: Segments=%d Super-Nodes=%d",i+1,nnodes);
95     fflush(stdout);
96     }
97     }
98    
99     printf("\rFound Super-Nodes: Segments=%d Super-Nodes=%d \n",segmentsx->number,nnodes);
100     fflush(stdout);
101     }
102    
103    
104     /*++++++++++++++++++++++++++++++++++++++
105     Create the super-segments.
106    
107     SegmentsX *CreateSuperSegments Creates the super segments.
108    
109     NodesX *nodesx The nodes.
110    
111     SegmentsX *segmentsx The segments.
112    
113     WaysX *waysx The ways.
114    
115     int iteration The current super-node / super-segment iteration number.
116     ++++++++++++++++++++++++++++++++++++++*/
117    
118     SegmentsX *CreateSuperSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,int iteration)
119     {
120 amb 214 index_t i;
121 amb 110 SegmentsX *supersegmentsx;
122    
123 amb 213 assert(nodesx->idata); /* Must have idata filled in */
124    
125 amb 110 supersegmentsx=NewSegmentList();
126    
127     /* Create super-segments for each super-node. */
128    
129     for(i=0;i<nodesx->number;i++)
130     {
131 amb 212 if(nodesx->idata[i]->super>iteration)
132 amb 110 {
133     SegmentX **segmentx,**first;
134    
135 amb 212 segmentx=first=FindFirstSegmentX(segmentsx,nodesx->idata[i]->id);
136 amb 110
137     while(segmentx)
138     {
139 amb 204 WayX *wayx=FindWayX(waysx,(*segmentx)->way);
140 amb 110
141     /* Check that this type of way hasn't already been routed */
142    
143     if(segmentx!=first)
144     {
145     SegmentX **othersegmentx=first;
146    
147     while(othersegmentx && othersegmentx!=segmentx)
148     {
149 amb 204 WayX *otherwayx=FindWayX(waysx,(*othersegmentx)->way);
150 amb 110
151 amb 204 if(!WaysCompare(otherwayx->way,wayx->way))
152 amb 110 {
153 amb 204 wayx=NULL;
154 amb 110 break;
155     }
156    
157     othersegmentx=FindNextSegmentX(segmentsx,othersegmentx);
158     }
159     }
160    
161     /* Route the way and store the super-segments. */
162    
163 amb 204 if(wayx)
164 amb 110 {
165 amb 212 Results *results=FindRoutesWay(nodesx,segmentsx,waysx,nodesx->idata[i]->id,wayx->way,iteration);
166 amb 110 Result *result=FirstResult(results);
167    
168     while(result)
169     {
170 amb 212 NodeX **nodex=FindNodeX(nodesx,result->node);
171     WayX *wayx =FindWayX (waysx ,(*segmentx)->way);
172 amb 110
173 amb 212 if(result->node!=nodesx->idata[i]->id && (*nodex)->super>iteration)
174 amb 110 {
175 amb 203 if(wayx->way->type&Way_OneWay)
176 amb 110 {
177 amb 212 AppendSegment(supersegmentsx,wayx->id,nodesx->idata[i]->id,result->node,DISTANCE((distance_t)result->score)|ONEWAY_1TO2);
178 amb 110
179 amb 212 AppendSegment(supersegmentsx,wayx->id,result->node,nodesx->idata[i]->id,DISTANCE((distance_t)result->score)|ONEWAY_2TO1);
180 amb 110 }
181 amb 172 else
182 amb 212 AppendSegment(supersegmentsx,wayx->id,result->node,nodesx->idata[i]->id,DISTANCE((distance_t)result->score));
183 amb 110 }
184    
185     result=NextResult(results,result);
186     }
187    
188     FreeResultsList(results);
189     }
190    
191     segmentx=FindNextSegmentX(segmentsx,segmentx);
192     }
193     }
194    
195     if(!((i+1)%10000))
196     {
197     printf("\rCreating Super-Segments: Nodes=%d Super-Segments=%d",i+1,supersegmentsx->xnumber);
198     fflush(stdout);
199     }
200     }
201    
202     printf("\rCreated Super-Segments: Nodes=%d Super-Segments=%d \n",nodesx->number,supersegmentsx->xnumber);
203     fflush(stdout);
204    
205     /* Append the new supersegments onto the segments. */
206    
207     return(supersegmentsx);
208     }
209    
210    
211     /*++++++++++++++++++++++++++++++++++++++
212     Merge the super-segments into the segments.
213    
214     SegmentsX* segmentsx The set of segments to process.
215    
216     SegmentsX* supersegmentsx The set of super-segments to merge.
217     ++++++++++++++++++++++++++++++++++++++*/
218    
219     void MergeSuperSegments(SegmentsX* segmentsx,SegmentsX* supersegmentsx)
220     {
221 amb 214 index_t i,j,n;
222 amb 110
223     assert(segmentsx->sorted); /* Must be sorted */
224 amb 213 assert(segmentsx->ndata); /* Must have ndata filled in */
225 amb 110 assert(supersegmentsx->sorted); /* Must be sorted */
226 amb 213 assert(supersegmentsx->ndata); /* Must have ndata filled in */
227 amb 110
228     n=segmentsx->number;
229    
230     for(i=0,j=0;i<n;i++)
231     {
232     while(j<supersegmentsx->number)
233     {
234 amb 206 if(segmentsx->ndata[i]->node1==supersegmentsx->ndata[j]->node1 &&
235     segmentsx->ndata[i]->node2==supersegmentsx->ndata[j]->node2 &&
236 amb 209 segmentsx->ndata[i]->distance==supersegmentsx->ndata[j]->distance)
237 amb 110 {
238 amb 209 segmentsx->ndata[i]->distance|=SEGMENT_SUPER; /* mark as super-segment */
239 amb 206 supersegmentsx->ndata[j]=NULL;
240 amb 110 j++;
241     break;
242     }
243 amb 206 else if(segmentsx->ndata[i]->node1==supersegmentsx->ndata[j]->node1 &&
244     segmentsx->ndata[i]->node2==supersegmentsx->ndata[j]->node2)
245 amb 110 {
246 amb 209 supersegmentsx->ndata[j]->distance|=SEGMENT_SUPER; /* mark as super-segment */
247 amb 110 }
248 amb 206 else if(segmentsx->ndata[i]->node1==supersegmentsx->ndata[j]->node1 &&
249     segmentsx->ndata[i]->node2>supersegmentsx->ndata[j]->node2)
250 amb 110 {
251 amb 209 supersegmentsx->ndata[j]->distance|=SEGMENT_SUPER; /* mark as super-segment */
252 amb 110 }
253 amb 206 else if(segmentsx->ndata[i]->node1>supersegmentsx->ndata[j]->node1)
254 amb 110 {
255 amb 209 supersegmentsx->ndata[j]->distance|=SEGMENT_SUPER; /* mark as super-segment */
256 amb 110 }
257     else
258     break;
259    
260     j++;
261     }
262    
263 amb 209 segmentsx->ndata[i]->distance|=SEGMENT_NORMAL; /* mark as normal segment */
264 amb 208
265 amb 110 if(!((i+1)%10000))
266     {
267     printf("\rMerging Segments: Segments=%d Super-Segment=%d Total=%d",i+1,j+1,segmentsx->xnumber);
268     fflush(stdout);
269     }
270     }
271    
272 amb 139 for(j=0;j<supersegmentsx->number;j++)
273 amb 206 if(supersegmentsx->ndata[j])
274 amb 209 AppendSegment(segmentsx,supersegmentsx->ndata[j]->way,supersegmentsx->ndata[j]->node1,supersegmentsx->ndata[j]->node2,supersegmentsx->ndata[j]->distance);
275 amb 139
276 amb 110 printf("\rMerged Segments: Segments=%d Super-Segment=%d Total=%d \n",n,supersegmentsx->number,segmentsx->xnumber);
277     fflush(stdout);
278     }
279    
280    
281     /*++++++++++++++++++++++++++++++++++++++
282     Find all routes from a specified node to any node in the specified list that follows a certain type of way.
283    
284     Results *FindRoutesWay Returns a set of results.
285    
286     NodesX *nodesx The set of nodes to use.
287    
288     SegmentsX *segmentsx The set of segments to use.
289    
290     WaysX *waysx The set of ways to use.
291    
292     node_t start The start node.
293    
294 amb 203 Way *match The way that the route must match.
295 amb 110
296     int iteration The current super-node / super-segment iteration number.
297     ++++++++++++++++++++++++++++++++++++++*/
298    
299 amb 203 Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match,int iteration)
300 amb 110 {
301     Results *results;
302     index_t node1,node2;
303     Result *result1,*result2;
304 amb 212 NodeX **nodex;
305 amb 110 SegmentX **segmentx;
306 amb 204 WayX *wayx;
307 amb 110
308     /* Insert the first node into the queue */
309    
310     results=NewResultsList(8);
311    
312     result1=InsertResult(results,start);
313    
314 amb 166 ZeroResult(result1);
315 amb 110
316     insert_in_queue(result1);
317    
318     /* Loop across all nodes in the queue */
319    
320     while((result1=pop_from_queue()))
321     {
322     node1=result1->node;
323    
324     segmentx=FindFirstSegmentX(segmentsx,node1);
325    
326     while(segmentx)
327     {
328 amb 113 distance_t cumulative_distance;
329    
330 amb 209 if((*segmentx)->distance&ONEWAY_2TO1)
331 amb 110 goto endloop;
332    
333     node2=(*segmentx)->node2;
334    
335 amb 113 if(result1->prev==node2)
336 amb 110 goto endloop;
337    
338 amb 204 wayx=FindWayX(waysx,(*segmentx)->way);
339 amb 110
340 amb 204 if(WaysCompare(wayx->way,match))
341 amb 110 goto endloop;
342    
343 amb 209 cumulative_distance=(distance_t)result1->score+DISTANCE((*segmentx)->distance);
344 amb 110
345     result2=FindResult(results,node2);
346    
347     if(!result2) /* New end node */
348     {
349     result2=InsertResult(results,node2);
350 amb 113 result2->prev=node1;
351 amb 176 result2->next=NO_NODE;
352 amb 172 result2->score=cumulative_distance;
353 amb 166 result2->sortby=cumulative_distance;
354 amb 110
355     nodex=FindNodeX(nodesx,node2);
356    
357 amb 212 if((*nodex)->super<=iteration)
358 amb 110 insert_in_queue(result2);
359     }
360 amb 172 else if(cumulative_distance<result2->score)
361 amb 110 {
362 amb 166 result2->prev=node1;
363 amb 172 result2->score=cumulative_distance;
364 amb 166 result2->sortby=cumulative_distance;
365 amb 110
366 amb 166 nodex=FindNodeX(nodesx,node2);
367 amb 110
368 amb 212 if((*nodex)->super<=iteration)
369 amb 166 insert_in_queue(result2);
370 amb 110 }
371    
372     endloop:
373    
374     segmentx=FindNextSegmentX(segmentsx,segmentx);
375     }
376     }
377    
378     return(results);
379     }

Properties

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