Routino SVN Repository Browser

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

ViewVC logotype

Annotation of /trunk/src/nodesx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (hide annotations) (download) (as text)
Sun Oct 4 15:52:47 2009 UTC (15 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 19133 byte(s)
Remove the duplicates when sorting.

1 amb 110 /***************************************
2 amb 273 $Header: /home/amb/CVS/routino/src/nodesx.c,v 1.43 2009-10-04 15:52:47 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 amb 249 #include <string.h>
29 amb 110
30     #include "types.h"
31     #include "functions.h"
32     #include "nodesx.h"
33     #include "segmentsx.h"
34 amb 204 #include "waysx.h"
35 amb 228 #include "segments.h"
36     #include "nodes.h"
37 amb 110
38    
39 amb 271 /* Constants */
40    
41     #define SORT_RAMSIZE (64*1024*1024)
42    
43 amb 252 /* Variables */
44 amb 110
45 amb 252 extern int option_slim;
46 amb 256 extern char *tmpdirname;
47 amb 110
48     /* Functions */
49    
50 amb 271 static int sort_by_id(NodeX *a,NodeX *b);
51 amb 273 static int index_by_id(NodeX *nodex,index_t index);
52 amb 271
53 amb 252 static int sort_by_lat_long(node_t *a,node_t *b);
54 amb 110
55    
56     /*++++++++++++++++++++++++++++++++++++++
57     Allocate a new node list.
58    
59     NodesX *NewNodeList Returns the node list.
60     ++++++++++++++++++++++++++++++++++++++*/
61    
62 amb 256 NodesX *NewNodeList(void)
63 amb 110 {
64     NodesX *nodesx;
65    
66 amb 213 nodesx=(NodesX*)calloc(1,sizeof(NodesX));
67 amb 110
68 amb 243 assert(nodesx); /* Check calloc() worked */
69    
70 amb 256 nodesx->filename=(char*)malloc(strlen(tmpdirname)+24);
71     sprintf(nodesx->filename,"%s/nodes.%p.tmp",tmpdirname,nodesx);
72 amb 216
73 amb 252 nodesx->fd=OpenFile(nodesx->filename);
74 amb 249
75 amb 110 return(nodesx);
76     }
77    
78    
79     /*++++++++++++++++++++++++++++++++++++++
80 amb 226 Free a node list.
81    
82     NodesX *nodesx The list to be freed.
83     ++++++++++++++++++++++++++++++++++++++*/
84    
85     void FreeNodeList(NodesX *nodesx)
86     {
87 amb 252 DeleteFile(nodesx->filename);
88 amb 226
89 amb 252 if(nodesx->xdata)
90 amb 257 UnmapFile(nodesx->filename);
91 amb 252
92 amb 226 if(nodesx->gdata)
93     free(nodesx->gdata);
94     if(nodesx->idata)
95     free(nodesx->idata);
96    
97     if(nodesx->ndata)
98     free(nodesx->ndata);
99    
100 amb 257 if(nodesx->offsets)
101     free(nodesx->offsets);
102    
103 amb 226 free(nodesx);
104     }
105    
106    
107     /*++++++++++++++++++++++++++++++++++++++
108 amb 110 Save the node list to a file.
109    
110     NodesX* nodesx The set of nodes to save.
111    
112     const char *filename The name of the file to save.
113     ++++++++++++++++++++++++++++++++++++++*/
114    
115     void SaveNodeList(NodesX* nodesx,const char *filename)
116     {
117 amb 214 index_t i;
118 amb 110 int fd;
119 amb 243 Nodes *nodes;
120 amb 232 int super_number=0;
121 amb 110
122 amb 243 assert(nodesx->gdata); /* Must have gdata filled in => sorted geographically */
123     assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
124 amb 110
125 amb 227 printf("Writing Nodes: Nodes=0");
126     fflush(stdout);
127    
128 amb 219 for(i=0;i<nodesx->number;i++)
129 amb 232 if(nodesx->ndata[i].firstseg&NODE_SUPER)
130     super_number++;
131 amb 219
132 amb 110 /* Fill in a Nodes structure with the offset of the real data in the file after
133     the Node structure itself. */
134    
135 amb 243 nodes=calloc(1,sizeof(Nodes));
136    
137     assert(nodes); /* Check calloc() worked */
138    
139 amb 110 nodes->number=nodesx->number;
140 amb 232 nodes->snumber=super_number;
141 amb 110
142 amb 257 nodes->latbins=nodesx->latbins;
143     nodes->lonbins=nodesx->lonbins;
144 amb 110
145 amb 257 nodes->latzero=nodesx->latzero;
146     nodes->lonzero=nodesx->lonzero;
147 amb 110
148     nodes->data=NULL;
149 amb 232
150 amb 110 nodes->offsets=(void*)sizeof(Nodes);
151 amb 257 nodes->nodes=(void*)(sizeof(Nodes)+(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
152 amb 110
153     /* Write out the Nodes structure and then the real data. */
154    
155     fd=OpenFile(filename);
156    
157     WriteFile(fd,nodes,sizeof(Nodes));
158    
159 amb 257 WriteFile(fd,nodesx->offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
160 amb 110
161 amb 203 for(i=0;i<nodes->number;i++)
162 amb 132 {
163 amb 257 Node *node=&nodesx->ndata[nodesx->gdata[i]];
164 amb 110
165 amb 212 WriteFile(fd,node,sizeof(Node));
166    
167 amb 132 if(!((i+1)%10000))
168     {
169     printf("\rWriting Nodes: Nodes=%d",i+1);
170     fflush(stdout);
171     }
172     }
173    
174 amb 203 printf("\rWrote Nodes: Nodes=%d \n",nodes->number);
175 amb 132 fflush(stdout);
176    
177 amb 110 CloseFile(fd);
178    
179     /* Free the fake Nodes */
180    
181     free(nodes);
182     }
183    
184    
185     /*++++++++++++++++++++++++++++++++++++++
186 amb 252 Find a particular node index.
187 amb 110
188 amb 249 index_t IndexNodeX Returns the index of the extended node with the specified id.
189 amb 110
190     NodesX* nodesx The set of nodes to process.
191    
192     node_t id The node id to look for.
193     ++++++++++++++++++++++++++++++++++++++*/
194    
195 amb 249 index_t IndexNodeX(NodesX* nodesx,node_t id)
196 amb 110 {
197     int start=0;
198     int end=nodesx->number-1;
199     int mid;
200    
201 amb 243 assert(nodesx->idata); /* Must have idata filled in => sorted by id */
202 amb 110
203     /* Binary search - search key exact match only is required.
204     *
205     * # <- start | Check mid and move start or end if it doesn't match
206     * # |
207     * # | Since an exact match is wanted we can set end=mid-1
208     * # <- mid | or start=mid+1 because we know that mid doesn't match.
209     * # |
210     * # | Eventually either end=start or end=start+1 and one of
211     * # <- end | start or end is the wanted one.
212     */
213    
214 amb 252 if(end<start) /* There are no nodes */
215 amb 249 return(NO_NODE);
216 amb 252 else if(id<nodesx->idata[start]) /* Check key is not before start */
217 amb 249 return(NO_NODE);
218 amb 252 else if(id>nodesx->idata[end]) /* Check key is not after end */
219 amb 249 return(NO_NODE);
220 amb 110 else
221     {
222     do
223     {
224 amb 252 mid=(start+end)/2; /* Choose mid point */
225 amb 110
226 amb 252 if(nodesx->idata[mid]<id) /* Mid point is too low */
227 amb 110 start=mid+1;
228 amb 252 else if(nodesx->idata[mid]>id) /* Mid point is too high */
229 amb 110 end=mid-1;
230 amb 252 else /* Mid point is correct */
231 amb 249 return(mid);
232 amb 110 }
233     while((end-start)>1);
234    
235 amb 252 if(nodesx->idata[start]==id) /* Start is correct */
236 amb 249 return(start);
237 amb 110
238 amb 252 if(nodesx->idata[end]==id) /* End is correct */
239 amb 249 return(end);
240 amb 110 }
241    
242 amb 249 return(NO_NODE);
243 amb 110 }
244    
245    
246     /*++++++++++++++++++++++++++++++++++++++
247 amb 252 Append a node to a newly created node list (unsorted).
248 amb 243
249 amb 252 NodesX* nodesx The set of nodes to process.
250 amb 243
251 amb 252 node_t id The node identification.
252 amb 110
253 amb 252 double latitude The latitude of the node.
254 amb 110
255 amb 252 double longitude The longitude of the node.
256     ++++++++++++++++++++++++++++++++++++++*/
257 amb 110
258 amb 252 void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude)
259     {
260     NodeX nodex;
261 amb 249
262 amb 252 assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
263    
264     nodex.id=id;
265     nodex.latitude =radians_to_latlong(latitude);
266     nodex.longitude=radians_to_latlong(longitude);
267    
268     WriteFile(nodesx->fd,&nodex,sizeof(NodeX));
269    
270     nodesx->xnumber++;
271 amb 110 }
272    
273    
274 amb 271 /*+ A temporary file-local variable for use by the sort functions. +*/
275     static NodesX *sortnodesx;
276    
277    
278 amb 110 /*++++++++++++++++++++++++++++++++++++++
279 amb 263 Sort the node list (i.e. create the sortable indexes).
280 amb 110
281     NodesX* nodesx The set of nodes to process.
282     ++++++++++++++++++++++++++++++++++++++*/
283    
284 amb 263 void SortNodeList(NodesX* nodesx)
285 amb 110 {
286 amb 263 int fd;
287 amb 110
288 amb 263 /* Check the start conditions */
289    
290 amb 252 assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
291    
292 amb 263 /* Print the start message */
293    
294     printf("Sorting Nodes");
295 amb 227 fflush(stdout);
296 amb 132
297 amb 263 /* Close the files and re-open them (finished appending) */
298 amb 260
299     CloseFile(nodesx->fd);
300     nodesx->fd=ReOpenFile(nodesx->filename);
301    
302 amb 271 DeleteFile(nodesx->filename);
303    
304     fd=OpenFile(nodesx->filename);
305    
306 amb 252 /* Allocate the array of indexes */
307 amb 249
308 amb 252 nodesx->idata=(node_t*)malloc(nodesx->xnumber*sizeof(node_t));
309 amb 249
310 amb 252 assert(nodesx->idata); /* Check malloc() worked */
311 amb 249
312 amb 271 /* Sort by node indexes */
313 amb 249
314 amb 271 sortnodesx=nodesx;
315 amb 110
316 amb 273 filesort(nodesx->fd,fd,sizeof(NodeX),SORT_RAMSIZE,(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))index_by_id);
317 amb 252
318 amb 260 /* Close the files and re-open them */
319    
320 amb 257 CloseFile(nodesx->fd);
321     CloseFile(fd);
322 amb 252
323 amb 257 nodesx->fd=ReOpenFile(nodesx->filename);
324 amb 252
325 amb 266 if(!option_slim)
326     nodesx->xdata=MapFile(nodesx->filename);
327    
328 amb 263 /* Print the final message */
329    
330 amb 273 printf("\rSorted Nodes: Nodes=%d Duplicates=%d\n",nodesx->xnumber,nodesx->xnumber-nodesx->number);
331 amb 263 fflush(stdout);
332 amb 110 }
333    
334    
335     /*++++++++++++++++++++++++++++++++++++++
336     Sort the nodes into id order.
337    
338     int sort_by_id Returns the comparison of the id fields.
339    
340 amb 271 NodeX *a The first extended node.
341 amb 110
342 amb 271 NodeX *b The second extended node.
343 amb 110 ++++++++++++++++++++++++++++++++++++++*/
344    
345 amb 271 static int sort_by_id(NodeX *a,NodeX *b)
346 amb 110 {
347 amb 271 node_t a_id=a->id;
348     node_t b_id=b->id;
349 amb 252
350     if(a_id<b_id)
351     return(-1);
352     else if(a_id>b_id)
353 amb 249 return(1);
354 amb 110 else
355 amb 252 return(0);
356 amb 110 }
357    
358    
359 amb 271 /*++++++++++++++++++++++++++++++++++++++
360     Index the nodes after sorting.
361 amb 252
362 amb 273 index_by_id Return 1 if the value is to be kept, otherwise zero.
363    
364 amb 271 NodeX *nodex The extended node.
365 amb 252
366 amb 271 index_t index The index of this node in the total.
367     ++++++++++++++++++++++++++++++++++++++*/
368    
369 amb 273 static int index_by_id(NodeX *nodex,index_t index)
370 amb 271 {
371 amb 273 if(index==0 || sortnodesx->idata[index-1]!=nodex->id)
372     {
373     sortnodesx->idata[index]=nodex->id;
374 amb 271
375 amb 273 sortnodesx->number++;
376    
377     return(1);
378     }
379    
380     return(0);
381 amb 271 }
382    
383    
384 amb 110 /*++++++++++++++++++++++++++++++++++++++
385 amb 212 Sort the node list geographically.
386    
387     NodesX* nodesx The set of nodes to process.
388     ++++++++++++++++++++++++++++++++++++++*/
389    
390     void SortNodeListGeographically(NodesX* nodesx)
391     {
392 amb 214 index_t i;
393 amb 257 ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin;
394     latlong_t lat_min,lat_max,lon_min,lon_max;
395     uint32_t latlonbin;
396 amb 212
397 amb 263 /* Check the start conditions */
398    
399 amb 243 assert(nodesx->idata); /* Must have idata filled in => sorted by id */
400     assert(!nodesx->gdata); /* Must not have gdata filled in => unsorted geographically */
401 amb 212
402 amb 263 if(option_slim)
403     nodesx->xdata=MapFile(nodesx->filename);
404    
405     /* Print the start message */
406    
407 amb 227 printf("Sorting Nodes Geographically");
408     fflush(stdout);
409 amb 212
410 amb 213 /* Allocate the array of pointers and sort them */
411 amb 212
412 amb 257 nodesx->gdata=(index_t*)malloc(nodesx->number*sizeof(index_t));
413 amb 212
414 amb 243 assert(nodesx->gdata); /* Check malloc() worked */
415    
416 amb 212 for(i=0;i<nodesx->number;i++)
417 amb 257 nodesx->gdata[i]=i;
418 amb 212
419 amb 252 sortnodesx=nodesx;
420 amb 212
421 amb 257 qsort(nodesx->gdata,nodesx->number,sizeof(index_t),(int (*)(const void*,const void*))sort_by_lat_long);
422 amb 252
423 amb 257 /* Work out the range of data */
424    
425     lat_min=radians_to_latlong( 2);
426     lat_max=radians_to_latlong(-2);
427     lon_min=radians_to_latlong( 4);
428     lon_max=radians_to_latlong(-4);
429    
430     for(i=0;i<nodesx->number;i++)
431     {
432     NodeX *nodex=&nodesx->xdata[i];
433    
434     if(nodex->latitude<lat_min)
435     lat_min=nodex->latitude;
436     if(nodex->latitude>lat_max)
437     lat_max=nodex->latitude;
438     if(nodex->longitude<lon_min)
439     lon_min=nodex->longitude;
440     if(nodex->longitude>lon_max)
441     lon_max=nodex->longitude;
442     }
443    
444 amb 263 /* Work out the number of bins */
445 amb 257
446     lat_min_bin=latlong_to_bin(lat_min);
447     lon_min_bin=latlong_to_bin(lon_min);
448     lat_max_bin=latlong_to_bin(lat_max);
449     lon_max_bin=latlong_to_bin(lon_max);
450    
451     nodesx->latbins=(lat_max_bin-lat_min_bin)+1;
452     nodesx->lonbins=(lon_max_bin-lon_min_bin)+1;
453    
454 amb 263 /* Work out the offsets */
455    
456 amb 257 nodesx->offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
457    
458     latlonbin=0;
459    
460     for(i=0;i<nodesx->number;i++)
461     {
462     NodeX *nodex=&nodesx->xdata[nodesx->gdata[i]];
463    
464     ll_bin_t latbin=latlong_to_bin(nodex->latitude )-lat_min_bin;
465     ll_bin_t lonbin=latlong_to_bin(nodex->longitude)-lon_min_bin;
466     int llbin=lonbin*nodesx->latbins+latbin;
467    
468     for(;latlonbin<=llbin;latlonbin++)
469     nodesx->offsets[latlonbin]=i;
470     }
471    
472     for(;latlonbin<=(nodesx->latbins*nodesx->lonbins);latlonbin++)
473     nodesx->offsets[latlonbin]=nodesx->number;
474    
475     nodesx->latzero=lat_min_bin;
476     nodesx->lonzero=lon_min_bin;
477    
478 amb 263 /* Print the final message */
479 amb 257
480 amb 227 printf("\rSorted Nodes Geographically \n");
481     fflush(stdout);
482 amb 212 }
483    
484    
485     /*++++++++++++++++++++++++++++++++++++++
486 amb 110 Sort the nodes into latitude and longitude order.
487    
488     int sort_by_lat_long Returns the comparison of the latitude and longitude fields.
489    
490 amb 257 index_t *a The first node id.
491 amb 110
492 amb 257 index_t *b The second node id.
493 amb 110 ++++++++++++++++++++++++++++++++++++++*/
494    
495 amb 257 static int sort_by_lat_long(index_t *a,index_t *b)
496 amb 110 {
497 amb 257 NodeX *nodex_a=&sortnodesx->xdata[*a];
498     NodeX *nodex_b=&sortnodesx->xdata[*b];
499 amb 110
500 amb 252 ll_bin_t a_lon=latlong_to_bin(nodex_a->longitude);
501     ll_bin_t b_lon=latlong_to_bin(nodex_b->longitude);
502    
503 amb 110 if(a_lon<b_lon)
504     return(-1);
505     else if(a_lon>b_lon)
506     return(1);
507     else
508     {
509 amb 252 ll_bin_t a_lat=latlong_to_bin(nodex_a->latitude);
510     ll_bin_t b_lat=latlong_to_bin(nodex_b->latitude);
511 amb 110
512     if(a_lat<b_lat)
513     return(-1);
514     else if(a_lat>b_lat)
515     return(1);
516     else
517     return(0);
518     }
519     }
520    
521    
522     /*++++++++++++++++++++++++++++++++++++++
523     Remove any nodes that are not part of a highway.
524    
525     NodesX *nodesx The complete node list.
526    
527     SegmentsX *segmentsx The list of segments.
528     ++++++++++++++++++++++++++++++++++++++*/
529    
530     void RemoveNonHighwayNodes(NodesX *nodesx,SegmentsX *segmentsx)
531     {
532 amb 263 NodeX nodex;
533 amb 273 int total=0,highway=0,nothighway=0;
534 amb 263 int fd;
535 amb 271 node_t previd=NO_NODE,*idata;
536 amb 110
537 amb 263 /* Check the start conditions */
538    
539 amb 249 assert(nodesx->idata); /* Must have idata filled in => data sorted */
540 amb 213
541 amb 263 /* Print the start message */
542    
543 amb 227 printf("Checking: Nodes=0");
544     fflush(stdout);
545    
546 amb 263 /* Modify the on-disk image */
547    
548 amb 266 if(!option_slim)
549     nodesx->xdata=UnmapFile(nodesx->filename);
550    
551     if(option_slim)
552     segmentsx->xdata=MapFile(segmentsx->filename);
553    
554 amb 263 DeleteFile(nodesx->filename);
555    
556     fd=OpenFile(nodesx->filename);
557     SeekFile(nodesx->fd,0);
558    
559     while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
560 amb 110 {
561 amb 273 if(!IndexFirstSegmentX(segmentsx,nodex.id))
562 amb 271 nothighway++;
563     else
564 amb 263 {
565     WriteFile(fd,&nodex,sizeof(NodeX));
566    
567     nodesx->idata[highway]=nodesx->idata[total];
568 amb 110 highway++;
569 amb 263 }
570 amb 110
571 amb 271 previd=nodex.id;
572    
573 amb 263 total++;
574    
575     if(!(total%10000))
576 amb 110 {
577 amb 273 printf("\rChecking: Nodes=%d Highway=%d not-Highway=%d",total,highway,nothighway);
578 amb 110 fflush(stdout);
579     }
580     }
581    
582 amb 263 /* Close the files and re-open them */
583    
584     CloseFile(nodesx->fd);
585     CloseFile(fd);
586    
587     nodesx->fd=ReOpenFile(nodesx->filename);
588    
589 amb 266 if(!option_slim)
590     nodesx->xdata=MapFile(nodesx->filename);
591    
592     if(option_slim)
593     segmentsx->xdata=UnmapFile(segmentsx->filename);
594    
595 amb 263 /* Allocate a smaller array for the node index (don't trust realloc to make it smaller) */
596    
597     idata=(node_t*)malloc(highway*sizeof(node_t));
598    
599     assert(idata); /* Check malloc() worked */
600    
601     memcpy(idata,nodesx->idata,highway*sizeof(node_t));
602    
603     free(nodesx->idata);
604    
605     nodesx->idata=idata;
606     nodesx->number=highway;
607    
608     /* Allocate and clear the super-node markers */
609    
610     nodesx->super=(uint8_t*)calloc(nodesx->number,sizeof(uint8_t));
611    
612     assert(nodesx->super); /* Check calloc() worked */
613    
614     /* Print the final message */
615    
616 amb 273 printf("\rChecked: Nodes=%d Highway=%d not-Highway=%d \n",total,highway,nothighway);
617 amb 110 fflush(stdout);
618     }
619    
620    
621     /*++++++++++++++++++++++++++++++++++++++
622 amb 212 Create the real node data.
623 amb 110
624 amb 212 NodesX *nodesx The set of nodes to use.
625 amb 110
626 amb 212 int iteration The final super-node iteration.
627 amb 110 ++++++++++++++++++++++++++++++++++++++*/
628    
629 amb 212 void CreateRealNodes(NodesX *nodesx,int iteration)
630 amb 110 {
631 amb 214 index_t i;
632 amb 110
633 amb 243 assert(nodesx->idata); /* Must have idata filled in => sorted by id */
634     assert(!nodesx->ndata); /* Must not have ndata filled in => no real nodes */
635 amb 110
636 amb 227 printf("Creating Real Nodes: Nodes=0");
637     fflush(stdout);
638    
639 amb 212 /* Allocate the memory */
640    
641     nodesx->ndata=(Node*)malloc(nodesx->number*sizeof(Node));
642    
643 amb 243 assert(nodesx->ndata); /* Check malloc() worked */
644    
645 amb 257 SeekFile(nodesx->fd,0);
646    
647 amb 212 /* Loop through and allocate. */
648    
649 amb 110 for(i=0;i<nodesx->number;i++)
650     {
651 amb 257 if(option_slim)
652     {
653     NodeX nodex;
654 amb 208
655 amb 257 ReadFile(nodesx->fd,&nodex,sizeof(NodeX));
656 amb 252
657 amb 257 nodesx->ndata[i].latoffset=latlong_to_off(nodex.latitude);
658     nodesx->ndata[i].lonoffset=latlong_to_off(nodex.longitude);
659     }
660     else
661     {
662     nodesx->ndata[i].latoffset=latlong_to_off(nodesx->xdata[i].latitude);
663     nodesx->ndata[i].lonoffset=latlong_to_off(nodesx->xdata[i].longitude);
664     }
665    
666 amb 212 nodesx->ndata[i].firstseg=SEGMENT(NO_SEGMENT);
667    
668 amb 249 if(nodesx->super[i]==iteration)
669 amb 212 nodesx->ndata[i].firstseg|=NODE_SUPER;
670    
671 amb 110 if(!((i+1)%10000))
672     {
673 amb 212 printf("\rCreating Real Nodes: Nodes=%d",i+1);
674 amb 110 fflush(stdout);
675     }
676     }
677    
678 amb 212 printf("\rCreating Real Nodes: Nodes=%d \n",nodesx->number);
679 amb 110 fflush(stdout);
680     }
681    
682    
683     /*++++++++++++++++++++++++++++++++++++++
684     Assign the segment indexes to the nodes.
685    
686     NodesX *nodesx The list of nodes to process.
687    
688     SegmentsX* segmentsx The set of segments to use.
689     ++++++++++++++++++++++++++++++++++++++*/
690    
691 amb 209 void IndexNodes(NodesX *nodesx,SegmentsX *segmentsx)
692 amb 110 {
693 amb 214 index_t i;
694 amb 110
695 amb 243 assert(nodesx->idata); /* Must have idata filled in => sorted */
696     assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
697     assert(segmentsx->n1data); /* Must have n1data filled in => sorted */
698     assert(segmentsx->sdata); /* Must have sdata filled in => real segments exist */
699 amb 110
700 amb 227 printf("Indexing Segments: Segments=0");
701     fflush(stdout);
702    
703 amb 110 /* Index the nodes */
704    
705     for(i=0;i<segmentsx->number;i++)
706     {
707 amb 257 SegmentX *segmentx=LookupSegmentX(segmentsx,segmentsx->n1data[i]);
708     node_t id1=segmentx->node1;
709     node_t id2=segmentx->node2;
710     Node *node1=&nodesx->ndata[IndexNodeX(nodesx,id1)];
711     Node *node2=&nodesx->ndata[IndexNodeX(nodesx,id2)];
712 amb 110
713     /* Check node1 */
714    
715 amb 212 if(SEGMENT(node1->firstseg)==SEGMENT(NO_SEGMENT))
716 amb 110 {
717 amb 212 node1->firstseg^=SEGMENT(NO_SEGMENT);
718     node1->firstseg|=i;
719 amb 110 }
720     else
721     {
722 amb 212 index_t index=SEGMENT(node1->firstseg);
723 amb 110
724     do
725     {
726 amb 257 segmentx=LookupSegmentX(segmentsx,segmentsx->n1data[index]);
727 amb 256
728 amb 257 if(segmentx->node1==id1)
729 amb 110 {
730 amb 209 index++;
731 amb 128
732 amb 256 if(index>=segmentsx->number)
733 amb 209 break;
734 amb 256
735 amb 257 segmentx=LookupSegmentX(segmentsx,segmentsx->n1data[index]);
736 amb 256
737 amb 257 if(segmentx->node1!=id1)
738 amb 256 break;
739 amb 110 }
740     else
741     {
742 amb 209 if(segmentsx->sdata[index].next2==NO_NODE)
743 amb 110 {
744 amb 209 segmentsx->sdata[index].next2=i;
745     break;
746 amb 110 }
747     else
748 amb 209 index=segmentsx->sdata[index].next2;
749 amb 110 }
750     }
751 amb 209 while(1);
752 amb 110 }
753    
754     /* Check node2 */
755    
756 amb 212 if(SEGMENT(node2->firstseg)==SEGMENT(NO_SEGMENT))
757 amb 110 {
758 amb 212 node2->firstseg^=SEGMENT(NO_SEGMENT);
759     node2->firstseg|=i;
760 amb 110 }
761     else
762     {
763 amb 212 index_t index=SEGMENT(node2->firstseg);
764 amb 110
765     do
766     {
767 amb 257 segmentx=LookupSegmentX(segmentsx,segmentsx->n1data[index]);
768 amb 256
769 amb 257 if(segmentx->node1==id2)
770 amb 110 {
771 amb 209 index++;
772 amb 128
773 amb 256 if(index>=segmentsx->number)
774 amb 209 break;
775 amb 256
776 amb 257 segmentx=LookupSegmentX(segmentsx,segmentsx->n1data[index]);
777 amb 256
778 amb 257 if(segmentx->node1!=id2)
779 amb 256 break;
780 amb 110 }
781     else
782     {
783 amb 209 if(segmentsx->sdata[index].next2==NO_NODE)
784 amb 110 {
785 amb 209 segmentsx->sdata[index].next2=i;
786     break;
787 amb 110 }
788     else
789 amb 209 index=segmentsx->sdata[index].next2;
790 amb 110 }
791     }
792 amb 209 while(1);
793 amb 110 }
794    
795     if(!((i+1)%10000))
796     {
797     printf("\rIndexing Segments: Segments=%d",i+1);
798     fflush(stdout);
799     }
800     }
801    
802     printf("\rIndexed Segments: Segments=%d \n",segmentsx->number);
803     fflush(stdout);
804     }

Properties

Name Value
cvs:description Extended nodes functions.