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/supersegments.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 104 - (show annotations) (download) (as text)
Fri Feb 6 20:23:35 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 11273 byte(s)
Segments now not duplicated in database.
Routing with all nodes works, not with super-nodes.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/supersegments.c,v 1.27 2009-02-06 20:23:33 amb Exp $
3
4 Super-Segment data type functions.
5 ******************/ /******************
6 Written by Andrew M. Bishop
7
8 This file Copyright 2008,2009 Andrew M. Bishop
9 It may be distributed under the GNU Public License, version 2, or
10 any higher version. See section COPYING of the GNU Public license
11 for conditions under which this file may be redistributed.
12 ***************************************/
13
14
15 #include <assert.h>
16 #include <math.h>
17 #include <stdlib.h>
18
19 #include "results.h"
20 #include "nodes.h"
21 #include "ways.h"
22 #include "segments.h"
23 #include "functions.h"
24
25
26 /*++++++++++++++++++++++++++++++++++++++
27 Select the super-segments from the list of segments.
28
29 NodesX *nodesx The nodes.
30
31 SegmentsX *segmentsx The segments.
32
33 WaysX *waysx The ways.
34
35 int iteration The current super-node / super-segment iteration number.
36 ++++++++++++++++++++++++++++++++++++++*/
37
38 void ChooseSuperNodes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,int iteration)
39 {
40 int i;
41 int segcount=0,difference=0,nnodes=0;
42 node_t node=0;
43 speed_t limit=0;
44 waytype_t type=0;
45 wayallow_t allow=0;
46
47 /* Find super-nodes */
48
49 node=segmentsx->sdata[0]->node1;
50
51 for(i=0;i<segmentsx->number;i++)
52 {
53 SegmentX *segmentx=LookupSegmentX(segmentsx,i);
54 WayX *wayx=LookupWayX(waysx,segmentx->segment.way);
55
56 if(segmentx->node1!=node)
57 {
58 /* Store the node if there is a difference in the ways that could affect routing.
59 Store the node if it is not a dead-end and if it isn't just the middle of a way. */
60
61 if(difference || segcount>2)
62 {
63 NodeX *nodex=FindNodeX(nodesx,node);
64
65 nodex->super++;
66
67 nnodes++;
68 }
69
70 segcount=1;
71 difference=0;
72
73 node=segmentx->node1;
74 type=wayx->way.type;
75 limit=wayx->way.limit;
76 allow=wayx->way.allow;
77 }
78 else /* Same starting node */
79 {
80 if(wayx->way.type!=type)
81 difference=1;
82
83 if(wayx->way.limit!=limit)
84 difference=1;
85
86 if(wayx->way.allow!=allow)
87 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 int i;
121 SegmentsX *supersegmentsx;
122
123 supersegmentsx=NewSegmentList();
124
125 /* Create super-segments for each super-node. */
126
127 for(i=0;i<nodesx->number;i++)
128 {
129 if(nodesx->gdata[i]->super>iteration)
130 {
131 SegmentX **segmentx,**first;
132
133 segmentx=first=FindFirstSegmentX(segmentsx,nodesx->gdata[i]->id);
134
135 while(segmentx)
136 {
137 WayX *wayx=LookupWayX(waysx,(*segmentx)->segment.way);
138
139 /* Check that this type of way hasn't already been routed */
140
141 if(segmentx!=first)
142 {
143 SegmentX **othersegmentx=first;
144
145 while(othersegmentx && othersegmentx!=segmentx)
146 {
147 WayX *otherwayx=LookupWayX(waysx,(*othersegmentx)->segment.way);
148
149 if(otherwayx->way.type ==wayx->way.type &&
150 otherwayx->way.allow==wayx->way.allow &&
151 otherwayx->way.limit==wayx->way.limit)
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,iteration);
166 Result *result=FirstResult(results);
167
168 while(result)
169 {
170 NodeX *nodex=FindNodeX(nodesx,result->node);
171
172 if(result->node!=nodesx->gdata[i]->id && nodex->super>iteration)
173 {
174 Segment *supersegment=AppendSegment(supersegmentsx,nodesx->gdata[i]->id,result->node);
175
176 supersegment->distance=result->shortest.distance;
177 supersegment->way=IndexWayX(waysx,wayx);
178
179 if(wayx->way.type&Way_OneWay)
180 {
181 supersegment->distance=ONEWAY_1TO2|result->shortest.distance;
182
183 supersegment=AppendSegment(supersegmentsx,result->node,nodesx->gdata[i]->id);
184
185 supersegment->distance=ONEWAY_2TO1|result->shortest.distance;
186 supersegment->way=IndexWayX(waysx,wayx);
187 }
188 }
189
190 result=NextResult(results,result);
191 }
192
193 FreeResultsList(results);
194 }
195
196 segmentx=FindNextSegmentX(segmentsx,segmentx);
197 }
198 }
199
200 if(!((i+1)%10000))
201 {
202 printf("\rCreating Super-Segments: Nodes=%d Super-Segments=%d",i+1,supersegmentsx->number);
203 fflush(stdout);
204 }
205 }
206
207 printf("\rCreated Super-Segments: Nodes=%d Super-Segments=%d \n",nodesx->number,supersegmentsx->number);
208 fflush(stdout);
209
210 /* Append the new supersegments onto the segments. */
211
212 return(supersegmentsx);
213 }
214
215
216 /*++++++++++++++++++++++++++++++++++++++
217 Merge the super-segments into the segments.
218
219 SegmentsX* segmentsx The set of segments to process.
220
221 SegmentsX* supersegmentsx The set of super-segments to merge.
222 ++++++++++++++++++++++++++++++++++++++*/
223
224 void MergeSuperSegments(SegmentsX* segmentsx,SegmentsX* supersegmentsx)
225 {
226 int i,j,n;
227
228 assert(segmentsx->sorted); /* Must be sorted */
229 assert(supersegmentsx->sorted); /* Must be sorted */
230
231 n=segmentsx->number;
232
233 for(i=0,j=0;i<n;i++)
234 {
235 segmentsx->sdata[i]->segment.node1=SUPER_FLAG; /* mark as normal segment */
236
237 segmentsx->sdata[i]->segment.next1=~0;
238 segmentsx->sdata[i]->segment.next2=~0;
239
240 while(j<supersegmentsx->number)
241 {
242 if(segmentsx->sdata[i]->node1==supersegmentsx->sdata[j]->node1 &&
243 segmentsx->sdata[i]->node2==supersegmentsx->sdata[j]->node2 &&
244 segmentsx->sdata[i]->segment.distance==supersegmentsx->sdata[j]->segment.distance)
245 {
246 segmentsx->sdata[i]->segment.node2=SUPER_FLAG; /* mark as super-segment */
247 j++;
248 break;
249 }
250 else if(segmentsx->sdata[i]->node1==supersegmentsx->sdata[j]->node1 &&
251 segmentsx->sdata[i]->node2==supersegmentsx->sdata[j]->node2)
252 {
253 Segment *supersegment=AppendSegment(segmentsx,supersegmentsx->sdata[j]->node1,supersegmentsx->sdata[j]->node2);
254
255 *supersegment=supersegmentsx->sdata[j]->segment;
256 supersegment->node2=SUPER_FLAG; /* mark as super-segment */
257 supersegment->next1=~0;
258 supersegment->next2=~0;
259 }
260 else if(segmentsx->sdata[i]->node1==supersegmentsx->sdata[j]->node1 &&
261 segmentsx->sdata[i]->node2>supersegmentsx->sdata[j]->node2)
262 {
263 Segment *supersegment=AppendSegment(segmentsx,supersegmentsx->sdata[j]->node1,supersegmentsx->sdata[j]->node2);
264
265 *supersegment=supersegmentsx->sdata[j]->segment;
266 supersegment->node2=SUPER_FLAG; /* mark as super-segment */
267 supersegment->next1=~0;
268 supersegment->next2=~0;
269 }
270 else if(segmentsx->sdata[i]->node1>supersegmentsx->sdata[j]->node1)
271 {
272 Segment *supersegment=AppendSegment(segmentsx,supersegmentsx->sdata[j]->node1,supersegmentsx->sdata[j]->node2);
273
274 *supersegment=supersegmentsx->sdata[j]->segment;
275 supersegment->node2=SUPER_FLAG; /* mark as super-segment */
276 supersegment->next1=~0;
277 supersegment->next2=~0;
278 }
279 else
280 break;
281
282 j++;
283 }
284
285 if(!((i+1)%10000))
286 {
287 printf("\rMerging Segments: Segments=%d Super-Segment=%d Total=%d",i+1,j+1,segmentsx->number);
288 fflush(stdout);
289 }
290 }
291
292 printf("\rMerged Segments: Segments=%d Super-Segment=%d Total=%d \n",n,supersegmentsx->number,segmentsx->number);
293 fflush(stdout);
294 }
295
296
297 /*++++++++++++++++++++++++++++++++++++++
298 Find all routes from a specified node to any node in the specified list that follows a certain type of way.
299
300 Results *FindRoutesWay Returns a set of results.
301
302 NodesX *nodesx The set of nodes to use.
303
304 SegmentsX *segmentsx The set of segments to use.
305
306 WaysX *waysx The set of ways to use.
307
308 node_t start The start node.
309
310 WayX *match The way that the route must match.
311
312 int iteration The current super-node / super-segment iteration number.
313 ++++++++++++++++++++++++++++++++++++++*/
314
315 Results *FindRoutesWay(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,WayX *match,int iteration)
316 {
317 Results *results;
318 index_t node1,node2;
319 HalfResult shortest2;
320 Result *result1,*result2;
321 NodeX *nodex;
322 SegmentX **segmentx;
323 WayX *wayx;
324
325 /* Insert the first node into the queue */
326
327 results=NewResultsList(8);
328
329 result1=InsertResult(results,start);
330
331 result1->node=start;
332 result1->shortest.prev=0;
333 result1->shortest.next=0;
334 result1->shortest.distance=0;
335
336 insert_in_queue(result1);
337
338 /* Loop across all nodes in the queue */
339
340 while((result1=pop_from_queue()))
341 {
342 node1=result1->node;
343
344 segmentx=FindFirstSegmentX(segmentsx,node1);
345
346 while(segmentx)
347 {
348 if((*segmentx)->segment.distance&ONEWAY_2TO1)
349 goto endloop;
350
351 node2=(*segmentx)->node2;
352
353 if(result1->shortest.prev==node2)
354 goto endloop;
355
356 wayx=LookupWayX(waysx,(*segmentx)->segment.way);
357
358 if(wayx->way.type !=match->way.type ||
359 wayx->way.allow!=match->way.allow ||
360 wayx->way.limit!=match->way.limit)
361 goto endloop;
362
363 shortest2.distance=result1->shortest.distance+DISTANCE((*segmentx)->segment.distance);
364
365 result2=FindResult(results,node2);
366
367 if(!result2) /* New end node */
368 {
369 result2=InsertResult(results,node2);
370 result2->node=node2;
371 result2->shortest.prev=node1;
372 result2->shortest.next=0;
373 result2->shortest.distance=shortest2.distance;
374
375 nodex=FindNodeX(nodesx,node2);
376
377 if(nodex->super<=iteration)
378 insert_in_queue(result2);
379 }
380 else
381 {
382 if(shortest2.distance<result2->shortest.distance)
383 {
384 result2->shortest.prev=node1;
385 result2->shortest.distance=shortest2.distance;
386
387 nodex=FindNodeX(nodesx,node2);
388
389 if(nodex->super<=iteration)
390 insert_in_queue(result2);
391 }
392 }
393
394 endloop:
395
396 segmentx=FindNextSegmentX(segmentsx,segmentx);
397 }
398 }
399
400 return(results);
401 }

Properties

Name Value
cvs:description SuperSegments data type.