Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/nodesx.c
Parent Directory
|
Revision Log
Revision 229 -
(hide annotations)
(download)
(as text)
Sun Jul 19 12:54:07 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 16375 byte(s)
Sun Jul 19 12:54:07 2009 UTC (15 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 16375 byte(s)
Store only one copy of each segment but index once for each direction.
1 | amb | 110 | /*************************************** |
2 | amb | 229 | $Header: /home/amb/CVS/routino/src/nodesx.c,v 1.27 2009-07-19 12:54:07 amb Exp $ |
3 | amb | 110 | |
4 | Extented Node 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 <stdlib.h> | ||
27 | #include <stdio.h> | ||
28 | |||
29 | #include "types.h" | ||
30 | #include "functions.h" | ||
31 | #include "nodesx.h" | ||
32 | #include "segmentsx.h" | ||
33 | amb | 204 | #include "waysx.h" |
34 | amb | 228 | #include "segments.h" |
35 | #include "nodes.h" | ||
36 | amb | 110 | |
37 | |||
38 | /* Constants */ | ||
39 | |||
40 | amb | 216 | /*+ The array size increment for NodesX (UK is ~10.3M raw nodes, this is ~78 increments). +*/ |
41 | #define INCREMENT_NODESX (128*1024) | ||
42 | amb | 110 | |
43 | |||
44 | /* Functions */ | ||
45 | |||
46 | static int sort_by_id(NodeX **a,NodeX **b); | ||
47 | static int sort_by_lat_long(NodeX **a,NodeX **b); | ||
48 | |||
49 | |||
50 | /*++++++++++++++++++++++++++++++++++++++ | ||
51 | Allocate a new node list. | ||
52 | |||
53 | NodesX *NewNodeList Returns the node list. | ||
54 | ++++++++++++++++++++++++++++++++++++++*/ | ||
55 | |||
56 | NodesX *NewNodeList(void) | ||
57 | { | ||
58 | NodesX *nodesx; | ||
59 | |||
60 | amb | 213 | nodesx=(NodesX*)calloc(1,sizeof(NodesX)); |
61 | amb | 110 | |
62 | amb | 216 | nodesx->row=-1; |
63 | |||
64 | amb | 110 | return(nodesx); |
65 | } | ||
66 | |||
67 | |||
68 | /*++++++++++++++++++++++++++++++++++++++ | ||
69 | amb | 226 | Free a node list. |
70 | |||
71 | NodesX *nodesx The list to be freed. | ||
72 | ++++++++++++++++++++++++++++++++++++++*/ | ||
73 | |||
74 | void FreeNodeList(NodesX *nodesx) | ||
75 | { | ||
76 | if(nodesx->xdata) | ||
77 | { | ||
78 | int i; | ||
79 | for(i=0;i<=nodesx->row;i++) | ||
80 | free(nodesx->xdata[i]); | ||
81 | free(nodesx->xdata); | ||
82 | } | ||
83 | |||
84 | if(nodesx->gdata) | ||
85 | free(nodesx->gdata); | ||
86 | if(nodesx->idata) | ||
87 | free(nodesx->idata); | ||
88 | |||
89 | if(nodesx->ndata) | ||
90 | free(nodesx->ndata); | ||
91 | |||
92 | free(nodesx); | ||
93 | } | ||
94 | |||
95 | |||
96 | /*++++++++++++++++++++++++++++++++++++++ | ||
97 | amb | 110 | Save the node list to a file. |
98 | |||
99 | NodesX* nodesx The set of nodes to save. | ||
100 | |||
101 | const char *filename The name of the file to save. | ||
102 | ++++++++++++++++++++++++++++++++++++++*/ | ||
103 | |||
104 | void SaveNodeList(NodesX* nodesx,const char *filename) | ||
105 | { | ||
106 | amb | 214 | index_t i; |
107 | amb | 110 | int fd; |
108 | Nodes *nodes=calloc(1,sizeof(Nodes)); | ||
109 | index_t *offsets; | ||
110 | amb | 219 | ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin; |
111 | latlong_t lat_min,lat_max,lon_min,lon_max; | ||
112 | amb | 110 | int latbins,lonbins,latlonbin; |
113 | |||
114 | assert(nodesx->sorted); /* Must be sorted */ | ||
115 | amb | 213 | assert(nodesx->gdata); /* Must have gdata filled in */ |
116 | assert(nodesx->ndata); /* Must have ndata filled in */ | ||
117 | amb | 110 | |
118 | amb | 227 | printf("Writing Nodes: Nodes=0"); |
119 | fflush(stdout); | ||
120 | |||
121 | amb | 219 | /* Work out the range of data */ |
122 | |||
123 | lat_min=radians_to_latlong( 2); | ||
124 | lat_max=radians_to_latlong(-2); | ||
125 | lon_min=radians_to_latlong( 4); | ||
126 | lon_max=radians_to_latlong(-4); | ||
127 | |||
128 | for(i=0;i<nodesx->number;i++) | ||
129 | { | ||
130 | amb | 223 | if(nodesx->idata[i]->latitude<lat_min) |
131 | lat_min=nodesx->idata[i]->latitude; | ||
132 | if(nodesx->idata[i]->latitude>lat_max) | ||
133 | lat_max=nodesx->idata[i]->latitude; | ||
134 | if(nodesx->idata[i]->longitude<lon_min) | ||
135 | lon_min=nodesx->idata[i]->longitude; | ||
136 | if(nodesx->idata[i]->longitude>lon_max) | ||
137 | lon_max=nodesx->idata[i]->longitude; | ||
138 | amb | 219 | } |
139 | |||
140 | amb | 118 | /* Work out the offsets */ |
141 | amb | 110 | |
142 | amb | 219 | lat_min_bin=latlong_to_bin(lat_min); |
143 | lon_min_bin=latlong_to_bin(lon_min); | ||
144 | lat_max_bin=latlong_to_bin(lat_max); | ||
145 | lon_max_bin=latlong_to_bin(lon_max); | ||
146 | amb | 110 | |
147 | amb | 219 | latbins=(lat_max_bin-lat_min_bin)+1; |
148 | lonbins=(lon_max_bin-lon_min_bin)+1; | ||
149 | amb | 110 | |
150 | amb | 216 | offsets=(index_t*)malloc((latbins*lonbins+1)*sizeof(index_t)); |
151 | amb | 110 | |
152 | latlonbin=0; | ||
153 | |||
154 | for(i=0;i<nodesx->number;i++) | ||
155 | { | ||
156 | amb | 223 | ll_bin_t latbin=latlong_to_bin(nodesx->gdata[i]->latitude )-lat_min_bin; |
157 | ll_bin_t lonbin=latlong_to_bin(nodesx->gdata[i]->longitude)-lon_min_bin; | ||
158 | amb | 110 | int llbin=lonbin*latbins+latbin; |
159 | |||
160 | for(;latlonbin<=llbin;latlonbin++) | ||
161 | offsets[latlonbin]=i; | ||
162 | } | ||
163 | |||
164 | for(;latlonbin<=(latbins*lonbins);latlonbin++) | ||
165 | offsets[latlonbin]=nodesx->number; | ||
166 | |||
167 | /* Fill in a Nodes structure with the offset of the real data in the file after | ||
168 | the Node structure itself. */ | ||
169 | |||
170 | nodes->number=nodesx->number; | ||
171 | |||
172 | nodes->latbins=latbins; | ||
173 | nodes->lonbins=lonbins; | ||
174 | |||
175 | amb | 223 | nodes->latzero=lat_min_bin; |
176 | nodes->lonzero=lon_min_bin; | ||
177 | amb | 110 | |
178 | nodes->data=NULL; | ||
179 | nodes->offsets=(void*)sizeof(Nodes); | ||
180 | amb | 214 | nodes->nodes=(void*)(sizeof(Nodes)+(latbins*lonbins+1)*sizeof(index_t)); |
181 | amb | 110 | |
182 | /* Write out the Nodes structure and then the real data. */ | ||
183 | |||
184 | fd=OpenFile(filename); | ||
185 | |||
186 | WriteFile(fd,nodes,sizeof(Nodes)); | ||
187 | |||
188 | WriteFile(fd,offsets,(latbins*lonbins+1)*sizeof(index_t)); | ||
189 | |||
190 | amb | 203 | for(i=0;i<nodes->number;i++) |
191 | amb | 132 | { |
192 | amb | 212 | NodeX **nodex=FindNodeX(nodesx,nodesx->gdata[i]->id); |
193 | Node *node =&nodesx->ndata[nodex-nodesx->idata]; | ||
194 | amb | 110 | |
195 | amb | 212 | WriteFile(fd,node,sizeof(Node)); |
196 | |||
197 | amb | 132 | if(!((i+1)%10000)) |
198 | { | ||
199 | printf("\rWriting Nodes: Nodes=%d",i+1); | ||
200 | fflush(stdout); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | amb | 203 | printf("\rWrote Nodes: Nodes=%d \n",nodes->number); |
205 | amb | 132 | fflush(stdout); |
206 | |||
207 | amb | 110 | CloseFile(fd); |
208 | |||
209 | /* Free the fake Nodes */ | ||
210 | |||
211 | free(nodes); | ||
212 | free(offsets); | ||
213 | } | ||
214 | |||
215 | |||
216 | /*++++++++++++++++++++++++++++++++++++++ | ||
217 | Find a particular node. | ||
218 | |||
219 | amb | 212 | NodeX **FindNodeX Returns a pointer to the extended node with the specified id. |
220 | amb | 110 | |
221 | NodesX* nodesx The set of nodes to process. | ||
222 | |||
223 | node_t id The node id to look for. | ||
224 | ++++++++++++++++++++++++++++++++++++++*/ | ||
225 | |||
226 | amb | 212 | NodeX **FindNodeX(NodesX* nodesx,node_t id) |
227 | amb | 110 | { |
228 | int start=0; | ||
229 | int end=nodesx->number-1; | ||
230 | int mid; | ||
231 | |||
232 | assert(nodesx->sorted); /* Must be sorted */ | ||
233 | amb | 213 | assert(nodesx->idata); /* Must have idata filled in */ |
234 | amb | 110 | |
235 | /* Binary search - search key exact match only is required. | ||
236 | * | ||
237 | * # <- start | Check mid and move start or end if it doesn't match | ||
238 | * # | | ||
239 | * # | Since an exact match is wanted we can set end=mid-1 | ||
240 | * # <- mid | or start=mid+1 because we know that mid doesn't match. | ||
241 | * # | | ||
242 | * # | Eventually either end=start or end=start+1 and one of | ||
243 | * # <- end | start or end is the wanted one. | ||
244 | */ | ||
245 | |||
246 | if(end<start) /* There are no nodes */ | ||
247 | amb | 194 | return(NULL); |
248 | amb | 110 | else if(id<nodesx->idata[start]->id) /* Check key is not before start */ |
249 | amb | 194 | return(NULL); |
250 | amb | 110 | else if(id>nodesx->idata[end]->id) /* Check key is not after end */ |
251 | amb | 194 | return(NULL); |
252 | amb | 110 | else |
253 | { | ||
254 | do | ||
255 | { | ||
256 | mid=(start+end)/2; /* Choose mid point */ | ||
257 | |||
258 | if(nodesx->idata[mid]->id<id) /* Mid point is too low */ | ||
259 | start=mid+1; | ||
260 | else if(nodesx->idata[mid]->id>id) /* Mid point is too high */ | ||
261 | end=mid-1; | ||
262 | else /* Mid point is correct */ | ||
263 | amb | 212 | return(&nodesx->idata[mid]); |
264 | amb | 110 | } |
265 | while((end-start)>1); | ||
266 | |||
267 | if(nodesx->idata[start]->id==id) /* Start is correct */ | ||
268 | amb | 212 | return(&nodesx->idata[start]); |
269 | amb | 110 | |
270 | if(nodesx->idata[end]->id==id) /* End is correct */ | ||
271 | amb | 212 | return(&nodesx->idata[end]); |
272 | amb | 110 | } |
273 | |||
274 | return(NULL); | ||
275 | } | ||
276 | |||
277 | |||
278 | /*++++++++++++++++++++++++++++++++++++++ | ||
279 | Append a node to a newly created node list (unsorted). | ||
280 | |||
281 | NodesX* nodesx The set of nodes to process. | ||
282 | |||
283 | node_t id The node identification. | ||
284 | |||
285 | amb | 219 | double latitude The latitude of the node. |
286 | amb | 110 | |
287 | amb | 219 | double longitude The longitude of the node. |
288 | amb | 110 | ++++++++++++++++++++++++++++++++++++++*/ |
289 | |||
290 | amb | 219 | void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude) |
291 | amb | 110 | { |
292 | /* Check that the array has enough space. */ | ||
293 | |||
294 | amb | 216 | if(nodesx->row==-1 || nodesx->col==INCREMENT_NODESX) |
295 | amb | 110 | { |
296 | amb | 216 | nodesx->row++; |
297 | nodesx->col=0; | ||
298 | amb | 110 | |
299 | amb | 216 | if((nodesx->row%16)==0) |
300 | nodesx->xdata=(NodeX**)realloc((void*)nodesx->xdata,(nodesx->row+16)*sizeof(NodeX*)); | ||
301 | |||
302 | nodesx->xdata[nodesx->row]=(NodeX*)malloc(INCREMENT_NODESX*sizeof(NodeX)); | ||
303 | amb | 110 | } |
304 | |||
305 | /* Insert the node */ | ||
306 | |||
307 | amb | 216 | nodesx->xdata[nodesx->row][nodesx->col].id=id; |
308 | nodesx->xdata[nodesx->row][nodesx->col].super=0; | ||
309 | amb | 223 | nodesx->xdata[nodesx->row][nodesx->col].latitude =radians_to_latlong(latitude); |
310 | nodesx->xdata[nodesx->row][nodesx->col].longitude=radians_to_latlong(longitude); | ||
311 | amb | 110 | |
312 | amb | 216 | nodesx->col++; |
313 | amb | 110 | |
314 | nodesx->sorted=0; | ||
315 | } | ||
316 | |||
317 | |||
318 | /*++++++++++++++++++++++++++++++++++++++ | ||
319 | Sort the node list. | ||
320 | |||
321 | NodesX* nodesx The set of nodes to process. | ||
322 | ++++++++++++++++++++++++++++++++++++++*/ | ||
323 | |||
324 | void SortNodeList(NodesX* nodesx) | ||
325 | { | ||
326 | amb | 214 | index_t i; |
327 | amb | 144 | int duplicate; |
328 | amb | 110 | |
329 | amb | 213 | assert(nodesx->xdata); /* Must have xdata filled in */ |
330 | |||
331 | amb | 227 | printf("Sorting Nodes"); |
332 | fflush(stdout); | ||
333 | amb | 132 | |
334 | amb | 213 | /* Allocate the array of pointers and sort them */ |
335 | amb | 110 | |
336 | amb | 216 | nodesx->idata=(NodeX**)realloc(nodesx->idata,(nodesx->row*INCREMENT_NODESX+nodesx->col)*sizeof(NodeX*)); |
337 | amb | 110 | |
338 | amb | 213 | do |
339 | { | ||
340 | nodesx->number=0; | ||
341 | amb | 144 | |
342 | amb | 216 | for(i=0;i<(nodesx->row*INCREMENT_NODESX+nodesx->col);i++) |
343 | if(nodesx->xdata[i/INCREMENT_NODESX][i%INCREMENT_NODESX].id!=NO_NODE) | ||
344 | amb | 213 | { |
345 | amb | 216 | nodesx->idata[nodesx->number]=&nodesx->xdata[i/INCREMENT_NODESX][i%INCREMENT_NODESX]; |
346 | amb | 213 | nodesx->number++; |
347 | } | ||
348 | amb | 110 | |
349 | amb | 213 | qsort(nodesx->idata,nodesx->number,sizeof(NodeX*),(int (*)(const void*,const void*))sort_by_id); |
350 | amb | 110 | |
351 | amb | 213 | duplicate=0; |
352 | amb | 144 | |
353 | amb | 213 | for(i=1;i<nodesx->number;i++) |
354 | amb | 144 | { |
355 | amb | 213 | if(nodesx->idata[i]->id==nodesx->idata[i-1]->id && |
356 | nodesx->idata[i]->id!=NO_NODE) | ||
357 | { | ||
358 | nodesx->idata[i-1]->id=NO_NODE; | ||
359 | duplicate++; | ||
360 | } | ||
361 | amb | 144 | } |
362 | |||
363 | amb | 213 | if(duplicate) |
364 | amb | 227 | { |
365 | printf(" - %d duplicates found; trying again.\nSorting Nodes",duplicate); | ||
366 | fflush(stdout); | ||
367 | } | ||
368 | amb | 144 | } |
369 | amb | 213 | while(duplicate); |
370 | amb | 144 | |
371 | amb | 227 | printf("\rSorted Nodes \n"); |
372 | fflush(stdout); | ||
373 | amb | 213 | |
374 | nodesx->sorted=1; | ||
375 | amb | 110 | } |
376 | |||
377 | |||
378 | /*++++++++++++++++++++++++++++++++++++++ | ||
379 | Sort the nodes into id order. | ||
380 | |||
381 | int sort_by_id Returns the comparison of the id fields. | ||
382 | |||
383 | NodeX **a The first Node. | ||
384 | |||
385 | NodeX **b The second Node. | ||
386 | ++++++++++++++++++++++++++++++++++++++*/ | ||
387 | |||
388 | static int sort_by_id(NodeX **a,NodeX **b) | ||
389 | { | ||
390 | node_t a_id=(*a)->id; | ||
391 | node_t b_id=(*b)->id; | ||
392 | |||
393 | if(a_id<b_id) | ||
394 | return(-1); | ||
395 | amb | 144 | else if(a_id>b_id) |
396 | return(1); | ||
397 | amb | 110 | else |
398 | amb | 144 | return(0); |
399 | amb | 110 | } |
400 | |||
401 | |||
402 | /*++++++++++++++++++++++++++++++++++++++ | ||
403 | amb | 212 | Sort the node list geographically. |
404 | |||
405 | NodesX* nodesx The set of nodes to process. | ||
406 | ++++++++++++++++++++++++++++++++++++++*/ | ||
407 | |||
408 | void SortNodeListGeographically(NodesX* nodesx) | ||
409 | { | ||
410 | amb | 214 | index_t i; |
411 | amb | 212 | |
412 | amb | 213 | assert(nodesx->idata); /* Must have idata filled in */ |
413 | amb | 212 | |
414 | amb | 227 | printf("Sorting Nodes Geographically"); |
415 | fflush(stdout); | ||
416 | amb | 212 | |
417 | amb | 213 | /* Allocate the array of pointers and sort them */ |
418 | amb | 212 | |
419 | nodesx->gdata=(NodeX**)malloc(nodesx->number*sizeof(NodeX*)); | ||
420 | |||
421 | for(i=0;i<nodesx->number;i++) | ||
422 | nodesx->gdata[i]=nodesx->idata[i]; | ||
423 | |||
424 | qsort(nodesx->gdata,nodesx->number,sizeof(NodeX*),(int (*)(const void*,const void*))sort_by_lat_long); | ||
425 | |||
426 | amb | 227 | printf("\rSorted Nodes Geographically \n"); |
427 | fflush(stdout); | ||
428 | amb | 212 | } |
429 | |||
430 | |||
431 | /*++++++++++++++++++++++++++++++++++++++ | ||
432 | amb | 110 | Sort the nodes into latitude and longitude order. |
433 | |||
434 | int sort_by_lat_long Returns the comparison of the latitude and longitude fields. | ||
435 | |||
436 | NodeX **a The first Node. | ||
437 | |||
438 | NodeX **b The second Node. | ||
439 | ++++++++++++++++++++++++++++++++++++++*/ | ||
440 | |||
441 | static int sort_by_lat_long(NodeX **a,NodeX **b) | ||
442 | { | ||
443 | amb | 223 | ll_bin_t a_lon=latlong_to_bin((*a)->longitude); |
444 | ll_bin_t b_lon=latlong_to_bin((*b)->longitude); | ||
445 | amb | 110 | |
446 | if(a_lon<b_lon) | ||
447 | return(-1); | ||
448 | else if(a_lon>b_lon) | ||
449 | return(1); | ||
450 | else | ||
451 | { | ||
452 | amb | 223 | ll_bin_t a_lat=latlong_to_bin((*a)->latitude); |
453 | ll_bin_t b_lat=latlong_to_bin((*b)->latitude); | ||
454 | amb | 110 | |
455 | if(a_lat<b_lat) | ||
456 | return(-1); | ||
457 | else if(a_lat>b_lat) | ||
458 | return(1); | ||
459 | else | ||
460 | return(0); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | |||
465 | /*++++++++++++++++++++++++++++++++++++++ | ||
466 | Remove any nodes that are not part of a highway. | ||
467 | |||
468 | NodesX *nodesx The complete node list. | ||
469 | |||
470 | SegmentsX *segmentsx The list of segments. | ||
471 | ++++++++++++++++++++++++++++++++++++++*/ | ||
472 | |||
473 | void RemoveNonHighwayNodes(NodesX *nodesx,SegmentsX *segmentsx) | ||
474 | { | ||
475 | amb | 214 | index_t i; |
476 | amb | 110 | int highway=0,nothighway=0; |
477 | |||
478 | amb | 213 | assert(nodesx->xdata); /* Must have xdata filled in */ |
479 | |||
480 | amb | 227 | printf("Checking: Nodes=0"); |
481 | fflush(stdout); | ||
482 | |||
483 | amb | 216 | for(i=0;i<(nodesx->row*INCREMENT_NODESX+nodesx->col);i++) |
484 | amb | 110 | { |
485 | amb | 216 | if(FindFirstSegmentX(segmentsx,nodesx->xdata[i/INCREMENT_NODESX][i%INCREMENT_NODESX].id)) |
486 | amb | 110 | highway++; |
487 | else | ||
488 | { | ||
489 | amb | 216 | nodesx->xdata[i/INCREMENT_NODESX][i%INCREMENT_NODESX].id=NO_NODE; |
490 | amb | 110 | nothighway++; |
491 | } | ||
492 | |||
493 | if(!((i+1)%10000)) | ||
494 | { | ||
495 | printf("\rChecking: Nodes=%d Highway=%d not-Highway=%d",i+1,highway,nothighway); | ||
496 | fflush(stdout); | ||
497 | } | ||
498 | } | ||
499 | |||
500 | amb | 216 | printf("\rChecked: Nodes=%d Highway=%d not-Highway=%d \n",i,highway,nothighway); |
501 | amb | 110 | fflush(stdout); |
502 | amb | 213 | |
503 | nodesx->sorted=0; | ||
504 | amb | 110 | } |
505 | |||
506 | |||
507 | /*++++++++++++++++++++++++++++++++++++++ | ||
508 | amb | 212 | Create the real node data. |
509 | amb | 110 | |
510 | amb | 212 | NodesX *nodesx The set of nodes to use. |
511 | amb | 110 | |
512 | amb | 212 | int iteration The final super-node iteration. |
513 | amb | 110 | ++++++++++++++++++++++++++++++++++++++*/ |
514 | |||
515 | amb | 212 | void CreateRealNodes(NodesX *nodesx,int iteration) |
516 | amb | 110 | { |
517 | amb | 214 | index_t i; |
518 | amb | 110 | |
519 | amb | 213 | assert(nodesx->gdata); /* Must have gdata filled in */ |
520 | amb | 110 | |
521 | amb | 227 | printf("Creating Real Nodes: Nodes=0"); |
522 | fflush(stdout); | ||
523 | |||
524 | amb | 212 | /* Allocate the memory */ |
525 | |||
526 | nodesx->ndata=(Node*)malloc(nodesx->number*sizeof(Node)); | ||
527 | |||
528 | /* Loop through and allocate. */ | ||
529 | |||
530 | amb | 110 | for(i=0;i<nodesx->number;i++) |
531 | { | ||
532 | amb | 223 | nodesx->ndata[i].latoffset=latlong_to_off(nodesx->idata[i]->latitude); |
533 | nodesx->ndata[i].lonoffset=latlong_to_off(nodesx->idata[i]->longitude); | ||
534 | amb | 208 | |
535 | amb | 212 | nodesx->ndata[i].firstseg=SEGMENT(NO_SEGMENT); |
536 | |||
537 | if(nodesx->idata[i]->super==iteration) | ||
538 | nodesx->ndata[i].firstseg|=NODE_SUPER; | ||
539 | |||
540 | amb | 110 | if(!((i+1)%10000)) |
541 | { | ||
542 | amb | 212 | printf("\rCreating Real Nodes: Nodes=%d",i+1); |
543 | amb | 110 | fflush(stdout); |
544 | } | ||
545 | } | ||
546 | |||
547 | amb | 212 | printf("\rCreating Real Nodes: Nodes=%d \n",nodesx->number); |
548 | amb | 110 | fflush(stdout); |
549 | } | ||
550 | |||
551 | |||
552 | /*++++++++++++++++++++++++++++++++++++++ | ||
553 | Assign the segment indexes to the nodes. | ||
554 | |||
555 | NodesX *nodesx The list of nodes to process. | ||
556 | |||
557 | SegmentsX* segmentsx The set of segments to use. | ||
558 | ++++++++++++++++++++++++++++++++++++++*/ | ||
559 | |||
560 | amb | 209 | void IndexNodes(NodesX *nodesx,SegmentsX *segmentsx) |
561 | amb | 110 | { |
562 | amb | 214 | index_t i; |
563 | amb | 110 | |
564 | assert(nodesx->sorted); /* Must be sorted */ | ||
565 | amb | 213 | assert(nodesx->idata); /* Must have idata filled in */ |
566 | assert(nodesx->ndata); /* Must have ndata filled in */ | ||
567 | amb | 110 | assert(segmentsx->sorted); /* Must be sorted */ |
568 | amb | 229 | assert(segmentsx->n1data); /* Must have n1data filled in */ |
569 | amb | 213 | assert(segmentsx->sdata); /* Must have sdata filled in */ |
570 | amb | 110 | |
571 | amb | 227 | printf("Indexing Segments: Segments=0"); |
572 | fflush(stdout); | ||
573 | |||
574 | amb | 110 | /* Index the nodes */ |
575 | |||
576 | for(i=0;i<segmentsx->number;i++) | ||
577 | { | ||
578 | amb | 229 | NodeX **nodex1=FindNodeX(nodesx,segmentsx->n1data[i]->node1); |
579 | NodeX **nodex2=FindNodeX(nodesx,segmentsx->n1data[i]->node2); | ||
580 | amb | 212 | Node *node1=&nodesx->ndata[nodex1-nodesx->idata]; |
581 | Node *node2=&nodesx->ndata[nodex2-nodesx->idata]; | ||
582 | amb | 110 | |
583 | /* Check node1 */ | ||
584 | |||
585 | amb | 212 | if(SEGMENT(node1->firstseg)==SEGMENT(NO_SEGMENT)) |
586 | amb | 110 | { |
587 | amb | 212 | node1->firstseg^=SEGMENT(NO_SEGMENT); |
588 | node1->firstseg|=i; | ||
589 | amb | 110 | } |
590 | else | ||
591 | { | ||
592 | amb | 212 | index_t index=SEGMENT(node1->firstseg); |
593 | amb | 110 | |
594 | do | ||
595 | { | ||
596 | amb | 229 | if(segmentsx->n1data[index]->node1==segmentsx->n1data[i]->node1) |
597 | amb | 110 | { |
598 | amb | 209 | index++; |
599 | amb | 128 | |
600 | amb | 229 | if(index>=segmentsx->number || segmentsx->n1data[index]->node1!=segmentsx->n1data[i]->node1) |
601 | amb | 209 | break; |
602 | amb | 110 | } |
603 | else | ||
604 | { | ||
605 | amb | 209 | if(segmentsx->sdata[index].next2==NO_NODE) |
606 | amb | 110 | { |
607 | amb | 209 | segmentsx->sdata[index].next2=i; |
608 | break; | ||
609 | amb | 110 | } |
610 | else | ||
611 | amb | 209 | index=segmentsx->sdata[index].next2; |
612 | amb | 110 | } |
613 | } | ||
614 | amb | 209 | while(1); |
615 | amb | 110 | } |
616 | |||
617 | /* Check node2 */ | ||
618 | |||
619 | amb | 212 | if(SEGMENT(node2->firstseg)==SEGMENT(NO_SEGMENT)) |
620 | amb | 110 | { |
621 | amb | 212 | node2->firstseg^=SEGMENT(NO_SEGMENT); |
622 | node2->firstseg|=i; | ||
623 | amb | 110 | } |
624 | else | ||
625 | { | ||
626 | amb | 212 | index_t index=SEGMENT(node2->firstseg); |
627 | amb | 110 | |
628 | do | ||
629 | { | ||
630 | amb | 229 | if(segmentsx->n1data[index]->node1==segmentsx->n1data[i]->node2) |
631 | amb | 110 | { |
632 | amb | 209 | index++; |
633 | amb | 128 | |
634 | amb | 229 | if(index>=segmentsx->number || segmentsx->n1data[index]->node1!=segmentsx->n1data[i]->node2) |
635 | amb | 209 | break; |
636 | amb | 110 | } |
637 | else | ||
638 | { | ||
639 | amb | 209 | if(segmentsx->sdata[index].next2==NO_NODE) |
640 | amb | 110 | { |
641 | amb | 209 | segmentsx->sdata[index].next2=i; |
642 | break; | ||
643 | amb | 110 | } |
644 | else | ||
645 | amb | 209 | index=segmentsx->sdata[index].next2; |
646 | amb | 110 | } |
647 | } | ||
648 | amb | 209 | while(1); |
649 | amb | 110 | } |
650 | |||
651 | if(!((i+1)%10000)) | ||
652 | { | ||
653 | printf("\rIndexing Segments: Segments=%d",i+1); | ||
654 | fflush(stdout); | ||
655 | } | ||
656 | } | ||
657 | |||
658 | printf("\rIndexed Segments: Segments=%d \n",segmentsx->number); | ||
659 | fflush(stdout); | ||
660 | } |
Properties
Name | Value |
---|---|
cvs:description | Extended nodes functions. |