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 208 - (show annotations) (download) (as text)
Mon Jun 29 17:39:20 2009 UTC (15 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 11014 byte(s)
Move the super-segment and normal-segment flags from the nodes to the distance.
Remove the NODE() macro and rename SUPER_FLAG to NODE_SUPER.

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

Properties

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