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 212 - (hide annotations) (download) (as text)
Wed Jul 1 18:23:26 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 10597 byte(s)
Remove the Node structure from the NodeX structure to save memory.

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

Properties

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