Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/superx.c
Parent Directory
|
Revision Log
Revision 289 -
(show annotations)
(download)
(as text)
Thu Oct 22 18:17:51 2009 UTC (15 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 12353 byte(s)
Thu Oct 22 18:17:51 2009 UTC (15 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 12353 byte(s)
Added some missing comments and corrected some existing ones.
1 | /*************************************** |
2 | $Header: /home/amb/CVS/routino/src/superx.c,v 1.36 2009-10-22 18:17:51 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 <stdlib.h> |
27 | #include <stdio.h> |
28 | |
29 | #include "results.h" |
30 | #include "functions.h" |
31 | #include "nodesx.h" |
32 | #include "segmentsx.h" |
33 | #include "waysx.h" |
34 | #include "superx.h" |
35 | #include "ways.h" |
36 | |
37 | |
38 | /* Variables */ |
39 | |
40 | /*+ The command line '--slim' option. +*/ |
41 | extern int option_slim; |
42 | |
43 | /* Local Functions */ |
44 | |
45 | static Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match,int iteration); |
46 | |
47 | |
48 | /*++++++++++++++++++++++++++++++++++++++ |
49 | Select the super-segments from the list of segments. |
50 | |
51 | NodesX *nodesx The nodes. |
52 | |
53 | SegmentsX *segmentsx The segments. |
54 | |
55 | WaysX *waysx The ways. |
56 | ++++++++++++++++++++++++++++++++++++++*/ |
57 | |
58 | void ChooseSuperNodes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx) |
59 | { |
60 | index_t i; |
61 | int nnodes=0; |
62 | |
63 | /* Check the start conditions */ |
64 | |
65 | assert(segmentsx->firstnode); /* Must have firstnode filled in => segments are updated */ |
66 | |
67 | /* Print the start message */ |
68 | |
69 | printf("Finding Super-Nodes: Nodes=0 Super-Nodes=0"); |
70 | fflush(stdout); |
71 | |
72 | /* Map into memory */ |
73 | |
74 | if(!option_slim) |
75 | { |
76 | segmentsx->xdata=MapFile(segmentsx->filename); |
77 | waysx->xdata=MapFile(waysx->filename); |
78 | } |
79 | |
80 | /* Find super-nodes */ |
81 | |
82 | for(i=0;i<nodesx->number;i++) |
83 | { |
84 | int difference=0; |
85 | index_t index; |
86 | |
87 | index=IndexFirstSegmentX(segmentsx,i); |
88 | |
89 | if(index!=NO_SEGMENT) |
90 | { |
91 | SegmentX *segmentx1=LookupSegmentX(segmentsx,index,1); |
92 | WayX *wayx1=LookupWayX(waysx,segmentx1->way,1); |
93 | |
94 | index=IndexNextSegmentX(segmentsx,index,i); |
95 | |
96 | if(index!=NO_SEGMENT) |
97 | { |
98 | SegmentX *segmentx2=LookupSegmentX(segmentsx,index,2); |
99 | WayX *wayx2=LookupWayX(waysx,segmentx2->way,2); |
100 | |
101 | if(WaysCompare(&wayx2->way,&wayx1->way)) |
102 | difference=1; |
103 | |
104 | index=IndexNextSegmentX(segmentsx,index,i); |
105 | } |
106 | |
107 | /* Store the node if there is a difference in the first two ways that could affect routing. |
108 | Store the node if it has at least three segments. */ |
109 | |
110 | if(difference || index!=NO_SEGMENT) |
111 | { |
112 | nodesx->super[i]++; |
113 | |
114 | nnodes++; |
115 | } |
116 | } |
117 | |
118 | if(!((i+1)%10000)) |
119 | { |
120 | printf("\rFinding Super-Nodes: Nodes=%d Super-Nodes=%d",i+1,nnodes); |
121 | fflush(stdout); |
122 | } |
123 | } |
124 | |
125 | /* Unmap from memory */ |
126 | |
127 | if(!option_slim) |
128 | { |
129 | segmentsx->xdata=UnmapFile(segmentsx->filename); |
130 | waysx->xdata=UnmapFile(waysx->filename); |
131 | } |
132 | |
133 | /* Print the final message */ |
134 | |
135 | printf("\rFound Super-Nodes: Nodes=%d Super-Nodes=%d \n",nodesx->number,nnodes); |
136 | fflush(stdout); |
137 | } |
138 | |
139 | |
140 | /*++++++++++++++++++++++++++++++++++++++ |
141 | Create the super-segments. |
142 | |
143 | SegmentsX *CreateSuperSegments Creates the super segments. |
144 | |
145 | NodesX *nodesx The nodes. |
146 | |
147 | SegmentsX *segmentsx The segments. |
148 | |
149 | WaysX *waysx The ways. |
150 | |
151 | int iteration The current super-node / super-segment iteration number. |
152 | ++++++++++++++++++++++++++++++++++++++*/ |
153 | |
154 | SegmentsX *CreateSuperSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,int iteration) |
155 | { |
156 | index_t i; |
157 | SegmentsX *supersegmentsx; |
158 | int sn=0,ss=0; |
159 | |
160 | /* Check the start conditions */ |
161 | |
162 | assert(segmentsx->firstnode); /* Must have firstnode filled in => segments are updated */ |
163 | |
164 | /* Print the start message */ |
165 | |
166 | printf("Creating Super-Segments: Super-Nodes=0 Super-Segments=0"); |
167 | fflush(stdout); |
168 | |
169 | /* Map into memory */ |
170 | |
171 | if(!option_slim) |
172 | { |
173 | segmentsx->xdata=MapFile(segmentsx->filename); |
174 | waysx->xdata=MapFile(waysx->filename); |
175 | } |
176 | |
177 | /* Create super-segments for each super-node. */ |
178 | |
179 | supersegmentsx=NewSegmentList(); |
180 | |
181 | for(i=0;i<nodesx->number;i++) |
182 | { |
183 | if(nodesx->super[i]>iteration) |
184 | { |
185 | index_t index,first; |
186 | |
187 | index=first=IndexFirstSegmentX(segmentsx,i); |
188 | |
189 | while(index!=NO_SEGMENT) |
190 | { |
191 | SegmentX *segmentx=LookupSegmentX(segmentsx,index,1); |
192 | WayX *wayx=LookupWayX(waysx,segmentx->way,1); |
193 | |
194 | /* Check that this type of way hasn't already been routed */ |
195 | |
196 | if(index!=first) |
197 | { |
198 | index_t otherindex=first; |
199 | |
200 | while(otherindex!=NO_SEGMENT && otherindex!=index) |
201 | { |
202 | SegmentX *othersegmentx=LookupSegmentX(segmentsx,otherindex,2); |
203 | WayX *otherwayx=LookupWayX(waysx,othersegmentx->way,2); |
204 | |
205 | if(!WaysCompare(&otherwayx->way,&wayx->way)) |
206 | { |
207 | wayx=NULL; |
208 | break; |
209 | } |
210 | |
211 | otherindex=IndexNextSegmentX(segmentsx,otherindex,i); |
212 | } |
213 | } |
214 | |
215 | /* Route the way and store the super-segments. */ |
216 | |
217 | if(wayx) |
218 | { |
219 | Results *results=FindRoutesWay(nodesx,segmentsx,waysx,i,&wayx->way,iteration); |
220 | Result *result=FirstResult(results); |
221 | |
222 | while(result) |
223 | { |
224 | if(result->node!=i && nodesx->super[result->node]>iteration) |
225 | { |
226 | if(wayx->way.type&Way_OneWay) |
227 | { |
228 | AppendSegment(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score)|ONEWAY_1TO2); |
229 | AppendSegment(supersegmentsx,segmentx->way,result->node,i,DISTANCE((distance_t)result->score)|ONEWAY_2TO1); |
230 | } |
231 | else |
232 | AppendSegment(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score)); |
233 | |
234 | ss++; |
235 | } |
236 | |
237 | result=NextResult(results,result); |
238 | } |
239 | |
240 | FreeResultsList(results); |
241 | } |
242 | |
243 | index=IndexNextSegmentX(segmentsx,index,i); |
244 | } |
245 | |
246 | sn++; |
247 | |
248 | if(!(sn%10000)) |
249 | { |
250 | printf("\rCreating Super-Segments: Super-Nodes=%d Super-Segments=%d",sn,ss); |
251 | fflush(stdout); |
252 | } |
253 | } |
254 | } |
255 | |
256 | /* Unmap from memory */ |
257 | |
258 | if(!option_slim) |
259 | { |
260 | segmentsx->xdata=UnmapFile(segmentsx->filename); |
261 | waysx->xdata=UnmapFile(waysx->filename); |
262 | } |
263 | |
264 | /* Print the final message */ |
265 | |
266 | printf("\rCreated Super-Segments: Super-Nodes=%d Super-Segments=%d \n",sn,ss); |
267 | fflush(stdout); |
268 | |
269 | return(supersegmentsx); |
270 | } |
271 | |
272 | |
273 | /*++++++++++++++++++++++++++++++++++++++ |
274 | Merge the segments and super-segments into a new segment list. |
275 | |
276 | SegmentsX* MergeSuperSegments Returns a new set of merged segments. |
277 | |
278 | SegmentsX* segmentsx The set of segments to process. |
279 | |
280 | SegmentsX* supersegmentsx The set of super-segments to merge. |
281 | ++++++++++++++++++++++++++++++++++++++*/ |
282 | |
283 | SegmentsX *MergeSuperSegments(SegmentsX* segmentsx,SegmentsX* supersegmentsx) |
284 | { |
285 | index_t i,j; |
286 | int m=0,a=0; |
287 | SegmentsX* mergedsegmentsx; |
288 | |
289 | /* Print the start message */ |
290 | |
291 | printf("Merging: Segments=0 Super-Segments=0 Merged=0 Added=0"); |
292 | fflush(stdout); |
293 | |
294 | /* Map into memory */ |
295 | |
296 | if(!option_slim) |
297 | { |
298 | segmentsx->xdata=MapFile(segmentsx->filename); |
299 | supersegmentsx->xdata=MapFile(supersegmentsx->filename); |
300 | } |
301 | |
302 | /* Loop through and create a new list of combined segments */ |
303 | |
304 | mergedsegmentsx=NewSegmentList(); |
305 | |
306 | for(i=0,j=0;i<segmentsx->number;i++) |
307 | { |
308 | int super=0; |
309 | SegmentX *segmentx=LookupSegmentX(segmentsx,i,1); |
310 | |
311 | while(j<supersegmentsx->number) |
312 | { |
313 | SegmentX *supersegmentx=LookupSegmentX(supersegmentsx,j,1); |
314 | |
315 | if(segmentx->node1 ==supersegmentx->node1 && |
316 | segmentx->node2 ==supersegmentx->node2 && |
317 | segmentx->distance==supersegmentx->distance) |
318 | { |
319 | m++; |
320 | j++; |
321 | /* mark as super-segment and normal segment */ |
322 | super=1; |
323 | break; |
324 | } |
325 | else if((segmentx->node1==supersegmentx->node1 && |
326 | segmentx->node2==supersegmentx->node2) || |
327 | (segmentx->node1==supersegmentx->node1 && |
328 | segmentx->node2>supersegmentx->node2) || |
329 | (segmentx->node1>supersegmentx->node1)) |
330 | { |
331 | /* mark as super-segment */ |
332 | AppendSegment(mergedsegmentsx,supersegmentx->way,supersegmentx->node1,supersegmentx->node2,supersegmentx->distance|SEGMENT_SUPER); |
333 | a++; |
334 | j++; |
335 | } |
336 | else |
337 | { |
338 | /* mark as normal segment */ |
339 | break; |
340 | } |
341 | } |
342 | |
343 | if(super) |
344 | AppendSegment(mergedsegmentsx,segmentx->way,segmentx->node1,segmentx->node2,segmentx->distance|SEGMENT_SUPER|SEGMENT_NORMAL); |
345 | else |
346 | AppendSegment(mergedsegmentsx,segmentx->way,segmentx->node1,segmentx->node2,segmentx->distance|SEGMENT_NORMAL); |
347 | |
348 | if(!((i+1)%10000)) |
349 | { |
350 | printf("\rMerging: Segments=%d Super-Segments=%d Merged=%d Added=%d",i+1,j,m,a); |
351 | fflush(stdout); |
352 | } |
353 | } |
354 | |
355 | /* Unmap from memory */ |
356 | |
357 | if(!option_slim) |
358 | { |
359 | segmentsx->xdata=UnmapFile(segmentsx->filename); |
360 | supersegmentsx->xdata=UnmapFile(supersegmentsx->filename); |
361 | } |
362 | |
363 | /* Print the final message */ |
364 | |
365 | printf("\rMerged: Segments=%d Super-Segments=%d Merged=%d Added=%d \n",segmentsx->number,supersegmentsx->number,m,a); |
366 | fflush(stdout); |
367 | |
368 | return(mergedsegmentsx); |
369 | } |
370 | |
371 | |
372 | /*++++++++++++++++++++++++++++++++++++++ |
373 | Find all routes from a specified node to any node in the specified list that follows a certain type of way. |
374 | |
375 | Results *FindRoutesWay Returns a set of results. |
376 | |
377 | NodesX *nodesx The set of nodes to use. |
378 | |
379 | SegmentsX *segmentsx The set of segments to use. |
380 | |
381 | WaysX *waysx The set of ways to use. |
382 | |
383 | node_t start The start node. |
384 | |
385 | Way *match The way that the route must match. |
386 | |
387 | int iteration The current super-node / super-segment iteration number. |
388 | ++++++++++++++++++++++++++++++++++++++*/ |
389 | |
390 | static Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match,int iteration) |
391 | { |
392 | Results *results; |
393 | Queue *queue; |
394 | index_t node1,node2; |
395 | Result *result1,*result2; |
396 | index_t index; |
397 | WayX *wayx; |
398 | |
399 | /* Insert the first node into the queue */ |
400 | |
401 | results=NewResultsList(8); |
402 | |
403 | queue=NewQueueList(); |
404 | |
405 | result1=InsertResult(results,start); |
406 | |
407 | ZeroResult(result1); |
408 | |
409 | InsertInQueue(queue,result1); |
410 | |
411 | /* Loop across all nodes in the queue */ |
412 | |
413 | while((result1=PopFromQueue(queue))) |
414 | { |
415 | node1=result1->node; |
416 | |
417 | index=IndexFirstSegmentX(segmentsx,node1); |
418 | |
419 | while(index!=NO_SEGMENT) |
420 | { |
421 | SegmentX *segmentx=LookupSegmentX(segmentsx,index,2); /* must use 2 here */ |
422 | distance_t cumulative_distance; |
423 | |
424 | if(segmentx->distance&ONEWAY_2TO1) |
425 | goto endloop; |
426 | |
427 | node2=segmentx->node2; |
428 | |
429 | if(result1->prev==node2) |
430 | goto endloop; |
431 | |
432 | wayx=LookupWayX(waysx,segmentx->way,2); |
433 | |
434 | if(WaysCompare(&wayx->way,match)) |
435 | goto endloop; |
436 | |
437 | cumulative_distance=(distance_t)result1->score+DISTANCE(segmentx->distance); |
438 | |
439 | result2=FindResult(results,node2); |
440 | |
441 | if(!result2) /* New end node */ |
442 | { |
443 | result2=InsertResult(results,node2); |
444 | result2->prev=node1; |
445 | result2->next=NO_NODE; |
446 | result2->score=cumulative_distance; |
447 | result2->sortby=cumulative_distance; |
448 | |
449 | if(nodesx->super[node2]<=iteration) |
450 | InsertInQueue(queue,result2); |
451 | } |
452 | else if(cumulative_distance<result2->score) |
453 | { |
454 | result2->prev=node1; |
455 | result2->score=cumulative_distance; |
456 | result2->sortby=cumulative_distance; |
457 | |
458 | if(nodesx->super[node2]<=iteration) |
459 | InsertInQueue(queue,result2); |
460 | } |
461 | |
462 | endloop: |
463 | |
464 | index=IndexNextSegmentX(segmentsx,index,node1); |
465 | } |
466 | } |
467 | |
468 | FreeQueueList(queue); |
469 | |
470 | return(results); |
471 | } |
Properties
Name | Value |
---|---|
cvs:description | Super-nodes and super-segments functions. |