Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/superx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 172 - (show annotations) (download) (as text)
Wed May 13 18:00:30 2009 UTC (15 years, 10 months ago) by amb
File MIME type: text/x-csrc
File size: 11054 byte(s)
Remove distance and duration from Result structure.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/superx.c,v 1.8 2009-05-13 18:00:30 amb Exp $
3
4 Super-Segment data type functions.
5
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008,2009 Andrew M. Bishop
9
10 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 ***************************************/
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 int segcount=0,difference=0,nnodes=0;
53 node_t node=0;
54 Way way;
55
56 /* Find super-nodes */
57
58 node=segmentsx->sdata[0]->node1;
59
60 for(i=0;i<segmentsx->number;i++)
61 {
62 SegmentX **segmentx=LookupSegmentX(segmentsx,i);
63 WayX *wayx=LookupWayX(waysx,(*segmentx)->segment.way);
64
65 if((*segmentx)->node1!=node)
66 {
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 NodeX *nodex=FindNodeX(nodesx,node);
73
74 nodex->super++;
75
76 nnodes++;
77 }
78
79 segcount=1;
80 difference=0;
81
82 node=(*segmentx)->node1;
83 way=wayx->way;
84 }
85 else /* Same starting node */
86 {
87 if(!WaysSame(&wayx->way,&way))
88 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 if(nodesx->gdata[i]->super>iteration)
131 {
132 SegmentX **segmentx,**first;
133
134 segmentx=first=FindFirstSegmentX(segmentsx,nodesx->gdata[i]->id);
135
136 while(segmentx)
137 {
138 WayX *wayx=LookupWayX(waysx,(*segmentx)->segment.way);
139
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 WayX *otherwayx=LookupWayX(waysx,(*othersegmentx)->segment.way);
149
150 if(WaysSame(&otherwayx->way,&wayx->way))
151 {
152 wayx=NULL;
153 break;
154 }
155
156 othersegmentx=FindNextSegmentX(segmentsx,othersegmentx);
157 }
158 }
159
160 /* Route the way and store the super-segments. */
161
162 if(wayx)
163 {
164 Results *results=FindRoutesWay(nodesx,segmentsx,waysx,nodesx->gdata[i]->id,wayx,iteration);
165 Result *result=FirstResult(results);
166
167 while(result)
168 {
169 NodeX *nodex=FindNodeX(nodesx,result->node);
170
171 if(result->node!=nodesx->gdata[i]->id && nodex->super>iteration)
172 {
173 Segment *supersegment=AppendSegment(supersegmentsx,nodesx->gdata[i]->id,result->node);
174
175 if(wayx->way.type&Way_OneWay)
176 {
177 supersegment->distance=ONEWAY_1TO2|(distance_t)result->score;
178 supersegment->way=IndexWayX(waysx,wayx);
179
180 supersegment=AppendSegment(supersegmentsx,result->node,nodesx->gdata[i]->id);
181
182 supersegment->distance=ONEWAY_2TO1|(distance_t)result->score;
183 supersegment->way=IndexWayX(waysx,wayx);
184 }
185 else
186 {
187 supersegment->distance=(distance_t)result->score;
188 supersegment->way=IndexWayX(waysx,wayx);
189 }
190 }
191
192 result=NextResult(results,result);
193 }
194
195 FreeResultsList(results);
196 }
197
198 segmentx=FindNextSegmentX(segmentsx,segmentx);
199 }
200 }
201
202 if(!((i+1)%10000))
203 {
204 printf("\rCreating Super-Segments: Nodes=%d Super-Segments=%d",i+1,supersegmentsx->xnumber);
205 fflush(stdout);
206 }
207 }
208
209 printf("\rCreated Super-Segments: Nodes=%d Super-Segments=%d \n",nodesx->number,supersegmentsx->xnumber);
210 fflush(stdout);
211
212 /* Append the new supersegments onto the segments. */
213
214 return(supersegmentsx);
215 }
216
217
218 /*++++++++++++++++++++++++++++++++++++++
219 Merge the super-segments into the segments.
220
221 SegmentsX* segmentsx The set of segments to process.
222
223 SegmentsX* supersegmentsx The set of super-segments to merge.
224 ++++++++++++++++++++++++++++++++++++++*/
225
226 void MergeSuperSegments(SegmentsX* segmentsx,SegmentsX* supersegmentsx)
227 {
228 int i,j,n;
229
230 assert(segmentsx->sorted); /* Must be sorted */
231 assert(supersegmentsx->sorted); /* Must be sorted */
232
233 n=segmentsx->number;
234
235 for(i=0,j=0;i<n;i++)
236 {
237 segmentsx->sdata[i]->segment.node1=SUPER_FLAG; /* mark as normal segment */
238
239 segmentsx->sdata[i]->segment.next2=~0;
240
241 while(j<supersegmentsx->number)
242 {
243 if(segmentsx->sdata[i]->node1==supersegmentsx->sdata[j]->node1 &&
244 segmentsx->sdata[i]->node2==supersegmentsx->sdata[j]->node2 &&
245 segmentsx->sdata[i]->segment.distance==supersegmentsx->sdata[j]->segment.distance)
246 {
247 segmentsx->sdata[i]->segment.node2=SUPER_FLAG; /* mark as super-segment */
248 supersegmentsx->sdata[j]=NULL;
249 j++;
250 break;
251 }
252 else if(segmentsx->sdata[i]->node1==supersegmentsx->sdata[j]->node1 &&
253 segmentsx->sdata[i]->node2==supersegmentsx->sdata[j]->node2)
254 {
255 supersegmentsx->sdata[j]->segment.node2=SUPER_FLAG; /* mark as super-segment */
256 supersegmentsx->sdata[j]->segment.next2=~0;
257 }
258 else if(segmentsx->sdata[i]->node1==supersegmentsx->sdata[j]->node1 &&
259 segmentsx->sdata[i]->node2>supersegmentsx->sdata[j]->node2)
260 {
261 supersegmentsx->sdata[j]->segment.node2=SUPER_FLAG; /* mark as super-segment */
262 supersegmentsx->sdata[j]->segment.next2=~0;
263 }
264 else if(segmentsx->sdata[i]->node1>supersegmentsx->sdata[j]->node1)
265 {
266 supersegmentsx->sdata[j]->segment.node2=SUPER_FLAG; /* mark as super-segment */
267 supersegmentsx->sdata[j]->segment.next2=~0;
268 }
269 else
270 break;
271
272 j++;
273 }
274
275 if(!((i+1)%10000))
276 {
277 printf("\rMerging Segments: Segments=%d Super-Segment=%d Total=%d",i+1,j+1,segmentsx->xnumber);
278 fflush(stdout);
279 }
280 }
281
282 for(j=0;j<supersegmentsx->number;j++)
283 if(supersegmentsx->sdata[j])
284 {
285 Segment *supersegment=AppendSegment(segmentsx,supersegmentsx->sdata[j]->node1,supersegmentsx->sdata[j]->node2);
286
287 *supersegment=supersegmentsx->sdata[j]->segment;
288 }
289
290 printf("\rMerged Segments: Segments=%d Super-Segment=%d Total=%d \n",n,supersegmentsx->number,segmentsx->xnumber);
291 fflush(stdout);
292 }
293
294
295 /*++++++++++++++++++++++++++++++++++++++
296 Find all routes from a specified node to any node in the specified list that follows a certain type of way.
297
298 Results *FindRoutesWay Returns a set of results.
299
300 NodesX *nodesx The set of nodes to use.
301
302 SegmentsX *segmentsx The set of segments to use.
303
304 WaysX *waysx The set of ways to use.
305
306 node_t start The start node.
307
308 WayX *match The way that the route must match.
309
310 int iteration The current super-node / super-segment iteration number.
311 ++++++++++++++++++++++++++++++++++++++*/
312
313 Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,WayX *match,int iteration)
314 {
315 Results *results;
316 index_t node1,node2;
317 Result *result1,*result2;
318 NodeX *nodex;
319 SegmentX **segmentx;
320 WayX *wayx;
321
322 /* Insert the first node into the queue */
323
324 results=NewResultsList(8);
325
326 result1=InsertResult(results,start);
327
328 ZeroResult(result1);
329
330 insert_in_queue(result1);
331
332 /* Loop across all nodes in the queue */
333
334 while((result1=pop_from_queue()))
335 {
336 node1=result1->node;
337
338 segmentx=FindFirstSegmentX(segmentsx,node1);
339
340 while(segmentx)
341 {
342 distance_t cumulative_distance;
343
344 if((*segmentx)->segment.distance&ONEWAY_2TO1)
345 goto endloop;
346
347 node2=(*segmentx)->node2;
348
349 if(result1->prev==node2)
350 goto endloop;
351
352 wayx=LookupWayX(waysx,(*segmentx)->segment.way);
353
354 if(!WaysSame(&wayx->way,&match->way))
355 goto endloop;
356
357 cumulative_distance=(distance_t)result1->score+DISTANCE((*segmentx)->segment.distance);
358
359 result2=FindResult(results,node2);
360
361 if(!result2) /* New end node */
362 {
363 result2=InsertResult(results,node2);
364 result2->prev=node1;
365 result2->next=0;
366 result2->score=cumulative_distance;
367 result2->sortby=cumulative_distance;
368
369 nodex=FindNodeX(nodesx,node2);
370
371 if(nodex->super<=iteration)
372 insert_in_queue(result2);
373 }
374 else if(cumulative_distance<result2->score)
375 {
376 result2->prev=node1;
377 result2->score=cumulative_distance;
378 result2->sortby=cumulative_distance;
379
380 nodex=FindNodeX(nodesx,node2);
381
382 if(nodex->super<=iteration)
383 insert_in_queue(result2);
384 }
385
386 endloop:
387
388 segmentx=FindNextSegmentX(segmentsx,segmentx);
389 }
390 }
391
392 return(results);
393 }

Properties

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