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 275 - (hide annotations) (download) (as text)
Wed Oct 7 18:03:48 2009 UTC (15 years, 6 months ago) by amb
File MIME type: text/x-csrc
File size: 19675 byte(s)
Go back to the version 1.1 method of having each segment listed twice.  This
simplifies the lookup of first/next segments at no in-RAM index cost and now
that slim mode has sorting of file contents the balance has tipped back.

1 amb 110 /***************************************
2 amb 275 $Header: /home/amb/CVS/routino/src/nodesx.c,v 1.44 2009-10-07 18:03:48 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 275 Lookup a particular node.
248    
249     NodeX *LookupNodeX Returns a pointer to the extended node with the specified id.
250    
251     NodesX* nodesx The set of nodes to process.
252    
253     index_t index The node index to look for.
254    
255     int position The position in the cache to use.
256     ++++++++++++++++++++++++++++++++++++++*/
257    
258     NodeX *LookupNodeX(NodesX* nodesx,index_t index,int position)
259     {
260     assert(index!=NO_NODE); /* Must be a valid node */
261    
262     if(option_slim)
263     {
264     SeekFile(nodesx->fd,index*sizeof(NodeX));
265    
266     ReadFile(nodesx->fd,&nodesx->cached[position-1],sizeof(NodeX));
267    
268     return(&nodesx->cached[position-1]);
269     }
270     else
271     {
272     return(&nodesx->xdata[index]);
273     }
274     }
275    
276    
277     /*++++++++++++++++++++++++++++++++++++++
278 amb 252 Append a node to a newly created node list (unsorted).
279 amb 243
280 amb 252 NodesX* nodesx The set of nodes to process.
281 amb 243
282 amb 252 node_t id The node identification.
283 amb 110
284 amb 252 double latitude The latitude of the node.
285 amb 110
286 amb 252 double longitude The longitude of the node.
287     ++++++++++++++++++++++++++++++++++++++*/
288 amb 110
289 amb 252 void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude)
290     {
291     NodeX nodex;
292 amb 249
293 amb 252 assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
294    
295     nodex.id=id;
296     nodex.latitude =radians_to_latlong(latitude);
297     nodex.longitude=radians_to_latlong(longitude);
298    
299     WriteFile(nodesx->fd,&nodex,sizeof(NodeX));
300    
301     nodesx->xnumber++;
302 amb 110 }
303    
304    
305 amb 271 /*+ A temporary file-local variable for use by the sort functions. +*/
306     static NodesX *sortnodesx;
307    
308    
309 amb 110 /*++++++++++++++++++++++++++++++++++++++
310 amb 263 Sort the node list (i.e. create the sortable indexes).
311 amb 110
312     NodesX* nodesx The set of nodes to process.
313     ++++++++++++++++++++++++++++++++++++++*/
314    
315 amb 263 void SortNodeList(NodesX* nodesx)
316 amb 110 {
317 amb 263 int fd;
318 amb 110
319 amb 263 /* Check the start conditions */
320    
321 amb 252 assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
322    
323 amb 263 /* Print the start message */
324    
325     printf("Sorting Nodes");
326 amb 227 fflush(stdout);
327 amb 132
328 amb 263 /* Close the files and re-open them (finished appending) */
329 amb 260
330     CloseFile(nodesx->fd);
331     nodesx->fd=ReOpenFile(nodesx->filename);
332    
333 amb 271 DeleteFile(nodesx->filename);
334    
335     fd=OpenFile(nodesx->filename);
336    
337 amb 252 /* Allocate the array of indexes */
338 amb 249
339 amb 252 nodesx->idata=(node_t*)malloc(nodesx->xnumber*sizeof(node_t));
340 amb 249
341 amb 252 assert(nodesx->idata); /* Check malloc() worked */
342 amb 249
343 amb 271 /* Sort by node indexes */
344 amb 249
345 amb 271 sortnodesx=nodesx;
346 amb 110
347 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);
348 amb 252
349 amb 260 /* Close the files and re-open them */
350    
351 amb 257 CloseFile(nodesx->fd);
352     CloseFile(fd);
353 amb 252
354 amb 257 nodesx->fd=ReOpenFile(nodesx->filename);
355 amb 252
356 amb 263 /* Print the final message */
357    
358 amb 273 printf("\rSorted Nodes: Nodes=%d Duplicates=%d\n",nodesx->xnumber,nodesx->xnumber-nodesx->number);
359 amb 263 fflush(stdout);
360 amb 110 }
361    
362    
363     /*++++++++++++++++++++++++++++++++++++++
364     Sort the nodes into id order.
365    
366     int sort_by_id Returns the comparison of the id fields.
367    
368 amb 271 NodeX *a The first extended node.
369 amb 110
370 amb 271 NodeX *b The second extended node.
371 amb 110 ++++++++++++++++++++++++++++++++++++++*/
372    
373 amb 271 static int sort_by_id(NodeX *a,NodeX *b)
374 amb 110 {
375 amb 271 node_t a_id=a->id;
376     node_t b_id=b->id;
377 amb 252
378     if(a_id<b_id)
379     return(-1);
380     else if(a_id>b_id)
381 amb 249 return(1);
382 amb 110 else
383 amb 252 return(0);
384 amb 110 }
385    
386    
387 amb 271 /*++++++++++++++++++++++++++++++++++++++
388     Index the nodes after sorting.
389 amb 252
390 amb 273 index_by_id Return 1 if the value is to be kept, otherwise zero.
391    
392 amb 271 NodeX *nodex The extended node.
393 amb 252
394 amb 271 index_t index The index of this node in the total.
395     ++++++++++++++++++++++++++++++++++++++*/
396    
397 amb 273 static int index_by_id(NodeX *nodex,index_t index)
398 amb 271 {
399 amb 273 if(index==0 || sortnodesx->idata[index-1]!=nodex->id)
400     {
401     sortnodesx->idata[index]=nodex->id;
402 amb 271
403 amb 273 sortnodesx->number++;
404    
405     return(1);
406     }
407    
408     return(0);
409 amb 271 }
410    
411    
412 amb 110 /*++++++++++++++++++++++++++++++++++++++
413 amb 212 Sort the node list geographically.
414    
415     NodesX* nodesx The set of nodes to process.
416     ++++++++++++++++++++++++++++++++++++++*/
417    
418     void SortNodeListGeographically(NodesX* nodesx)
419     {
420 amb 214 index_t i;
421 amb 257 ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin;
422     latlong_t lat_min,lat_max,lon_min,lon_max;
423     uint32_t latlonbin;
424 amb 212
425 amb 263 /* Check the start conditions */
426    
427 amb 243 assert(nodesx->idata); /* Must have idata filled in => sorted by id */
428     assert(!nodesx->gdata); /* Must not have gdata filled in => unsorted geographically */
429 amb 212
430 amb 263 /* Print the start message */
431    
432 amb 227 printf("Sorting Nodes Geographically");
433     fflush(stdout);
434 amb 212
435 amb 275 /* Map into memory */
436    
437     // FIXME
438     nodesx->xdata=MapFile(nodesx->filename);
439    
440 amb 213 /* Allocate the array of pointers and sort them */
441 amb 212
442 amb 257 nodesx->gdata=(index_t*)malloc(nodesx->number*sizeof(index_t));
443 amb 212
444 amb 243 assert(nodesx->gdata); /* Check malloc() worked */
445    
446 amb 212 for(i=0;i<nodesx->number;i++)
447 amb 257 nodesx->gdata[i]=i;
448 amb 212
449 amb 252 sortnodesx=nodesx;
450 amb 212
451 amb 257 qsort(nodesx->gdata,nodesx->number,sizeof(index_t),(int (*)(const void*,const void*))sort_by_lat_long);
452 amb 252
453 amb 257 /* Work out the range of data */
454    
455     lat_min=radians_to_latlong( 2);
456     lat_max=radians_to_latlong(-2);
457     lon_min=radians_to_latlong( 4);
458     lon_max=radians_to_latlong(-4);
459    
460     for(i=0;i<nodesx->number;i++)
461     {
462     NodeX *nodex=&nodesx->xdata[i];
463    
464     if(nodex->latitude<lat_min)
465     lat_min=nodex->latitude;
466     if(nodex->latitude>lat_max)
467     lat_max=nodex->latitude;
468     if(nodex->longitude<lon_min)
469     lon_min=nodex->longitude;
470     if(nodex->longitude>lon_max)
471     lon_max=nodex->longitude;
472     }
473    
474 amb 263 /* Work out the number of bins */
475 amb 257
476     lat_min_bin=latlong_to_bin(lat_min);
477     lon_min_bin=latlong_to_bin(lon_min);
478     lat_max_bin=latlong_to_bin(lat_max);
479     lon_max_bin=latlong_to_bin(lon_max);
480    
481     nodesx->latbins=(lat_max_bin-lat_min_bin)+1;
482     nodesx->lonbins=(lon_max_bin-lon_min_bin)+1;
483    
484 amb 263 /* Work out the offsets */
485    
486 amb 257 nodesx->offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
487    
488     latlonbin=0;
489    
490     for(i=0;i<nodesx->number;i++)
491     {
492     NodeX *nodex=&nodesx->xdata[nodesx->gdata[i]];
493    
494     ll_bin_t latbin=latlong_to_bin(nodex->latitude )-lat_min_bin;
495     ll_bin_t lonbin=latlong_to_bin(nodex->longitude)-lon_min_bin;
496     int llbin=lonbin*nodesx->latbins+latbin;
497    
498     for(;latlonbin<=llbin;latlonbin++)
499     nodesx->offsets[latlonbin]=i;
500     }
501    
502     for(;latlonbin<=(nodesx->latbins*nodesx->lonbins);latlonbin++)
503     nodesx->offsets[latlonbin]=nodesx->number;
504    
505     nodesx->latzero=lat_min_bin;
506     nodesx->lonzero=lon_min_bin;
507    
508 amb 275 // FIXME
509     nodesx->xdata=UnmapFile(nodesx->filename);
510    
511 amb 263 /* Print the final message */
512 amb 257
513 amb 227 printf("\rSorted Nodes Geographically \n");
514     fflush(stdout);
515 amb 212 }
516    
517    
518     /*++++++++++++++++++++++++++++++++++++++
519 amb 110 Sort the nodes into latitude and longitude order.
520    
521     int sort_by_lat_long Returns the comparison of the latitude and longitude fields.
522    
523 amb 257 index_t *a The first node id.
524 amb 110
525 amb 257 index_t *b The second node id.
526 amb 110 ++++++++++++++++++++++++++++++++++++++*/
527    
528 amb 257 static int sort_by_lat_long(index_t *a,index_t *b)
529 amb 110 {
530 amb 257 NodeX *nodex_a=&sortnodesx->xdata[*a];
531     NodeX *nodex_b=&sortnodesx->xdata[*b];
532 amb 110
533 amb 252 ll_bin_t a_lon=latlong_to_bin(nodex_a->longitude);
534     ll_bin_t b_lon=latlong_to_bin(nodex_b->longitude);
535    
536 amb 110 if(a_lon<b_lon)
537     return(-1);
538     else if(a_lon>b_lon)
539     return(1);
540     else
541     {
542 amb 252 ll_bin_t a_lat=latlong_to_bin(nodex_a->latitude);
543     ll_bin_t b_lat=latlong_to_bin(nodex_b->latitude);
544 amb 110
545     if(a_lat<b_lat)
546     return(-1);
547     else if(a_lat>b_lat)
548     return(1);
549     else
550     return(0);
551     }
552     }
553    
554    
555     /*++++++++++++++++++++++++++++++++++++++
556     Remove any nodes that are not part of a highway.
557    
558     NodesX *nodesx The complete node list.
559    
560     SegmentsX *segmentsx The list of segments.
561     ++++++++++++++++++++++++++++++++++++++*/
562    
563     void RemoveNonHighwayNodes(NodesX *nodesx,SegmentsX *segmentsx)
564     {
565 amb 263 NodeX nodex;
566 amb 273 int total=0,highway=0,nothighway=0;
567 amb 263 int fd;
568 amb 275 node_t *idata;
569 amb 110
570 amb 263 /* Check the start conditions */
571    
572 amb 249 assert(nodesx->idata); /* Must have idata filled in => data sorted */
573 amb 213
574 amb 263 /* Print the start message */
575    
576 amb 227 printf("Checking: Nodes=0");
577     fflush(stdout);
578    
579 amb 263 /* Modify the on-disk image */
580    
581     DeleteFile(nodesx->filename);
582    
583     fd=OpenFile(nodesx->filename);
584     SeekFile(nodesx->fd,0);
585    
586     while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
587 amb 110 {
588 amb 275 if(IndexFirstSegmentX(segmentsx,nodex.id)==NO_SEGMENT)
589 amb 271 nothighway++;
590     else
591 amb 263 {
592     WriteFile(fd,&nodex,sizeof(NodeX));
593    
594     nodesx->idata[highway]=nodesx->idata[total];
595 amb 110 highway++;
596 amb 263 }
597 amb 110
598 amb 263 total++;
599    
600     if(!(total%10000))
601 amb 110 {
602 amb 273 printf("\rChecking: Nodes=%d Highway=%d not-Highway=%d",total,highway,nothighway);
603 amb 110 fflush(stdout);
604     }
605     }
606    
607 amb 263 /* Close the files and re-open them */
608    
609     CloseFile(nodesx->fd);
610     CloseFile(fd);
611    
612     nodesx->fd=ReOpenFile(nodesx->filename);
613    
614     /* Allocate a smaller array for the node index (don't trust realloc to make it smaller) */
615    
616     idata=(node_t*)malloc(highway*sizeof(node_t));
617    
618     assert(idata); /* Check malloc() worked */
619    
620     memcpy(idata,nodesx->idata,highway*sizeof(node_t));
621    
622     free(nodesx->idata);
623    
624     nodesx->idata=idata;
625     nodesx->number=highway;
626    
627     /* Allocate and clear the super-node markers */
628    
629     nodesx->super=(uint8_t*)calloc(nodesx->number,sizeof(uint8_t));
630    
631     assert(nodesx->super); /* Check calloc() worked */
632    
633     /* Print the final message */
634    
635 amb 273 printf("\rChecked: Nodes=%d Highway=%d not-Highway=%d \n",total,highway,nothighway);
636 amb 110 fflush(stdout);
637     }
638    
639    
640     /*++++++++++++++++++++++++++++++++++++++
641 amb 212 Create the real node data.
642 amb 110
643 amb 212 NodesX *nodesx The set of nodes to use.
644 amb 110
645 amb 212 int iteration The final super-node iteration.
646 amb 110 ++++++++++++++++++++++++++++++++++++++*/
647    
648 amb 212 void CreateRealNodes(NodesX *nodesx,int iteration)
649 amb 110 {
650 amb 214 index_t i;
651 amb 110
652 amb 275 /* Check the start conditions */
653    
654 amb 243 assert(nodesx->idata); /* Must have idata filled in => sorted by id */
655     assert(!nodesx->ndata); /* Must not have ndata filled in => no real nodes */
656 amb 110
657 amb 275 /* Print the start message */
658    
659 amb 227 printf("Creating Real Nodes: Nodes=0");
660     fflush(stdout);
661    
662 amb 275 /* Map into memory */
663    
664     if(!option_slim)
665     nodesx->xdata=MapFile(nodesx->filename);
666    
667 amb 212 /* Allocate the memory */
668    
669     nodesx->ndata=(Node*)malloc(nodesx->number*sizeof(Node));
670    
671 amb 243 assert(nodesx->ndata); /* Check malloc() worked */
672    
673 amb 212 /* Loop through and allocate. */
674    
675 amb 110 for(i=0;i<nodesx->number;i++)
676     {
677 amb 275 NodeX *nodex=LookupNodeX(nodesx,i,1);
678 amb 208
679 amb 275 nodesx->ndata[i].latoffset=latlong_to_off(nodex->latitude);
680     nodesx->ndata[i].lonoffset=latlong_to_off(nodex->longitude);
681 amb 212 nodesx->ndata[i].firstseg=SEGMENT(NO_SEGMENT);
682    
683 amb 249 if(nodesx->super[i]==iteration)
684 amb 212 nodesx->ndata[i].firstseg|=NODE_SUPER;
685    
686 amb 110 if(!((i+1)%10000))
687     {
688 amb 212 printf("\rCreating Real Nodes: Nodes=%d",i+1);
689 amb 110 fflush(stdout);
690     }
691     }
692    
693 amb 275 /* Unmap from memory */
694    
695     if(!option_slim)
696     nodesx->xdata=UnmapFile(nodesx->filename);
697    
698     /* Print the final message */
699    
700 amb 212 printf("\rCreating Real Nodes: Nodes=%d \n",nodesx->number);
701 amb 110 fflush(stdout);
702     }
703    
704    
705     /*++++++++++++++++++++++++++++++++++++++
706     Assign the segment indexes to the nodes.
707    
708     NodesX *nodesx The list of nodes to process.
709    
710     SegmentsX* segmentsx The set of segments to use.
711     ++++++++++++++++++++++++++++++++++++++*/
712    
713 amb 209 void IndexNodes(NodesX *nodesx,SegmentsX *segmentsx)
714 amb 110 {
715 amb 214 index_t i;
716 amb 110
717 amb 275 /* Check the start conditions */
718    
719 amb 243 assert(nodesx->idata); /* Must have idata filled in => sorted */
720     assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
721     assert(segmentsx->sdata); /* Must have sdata filled in => real segments exist */
722 amb 110
723 amb 275 /* Print the start message */
724    
725 amb 227 printf("Indexing Segments: Segments=0");
726     fflush(stdout);
727    
728 amb 275 /* Map into memory */
729    
730     if(!option_slim)
731     segmentsx->xdata=MapFile(segmentsx->filename);
732    
733 amb 110 /* Index the nodes */
734    
735     for(i=0;i<segmentsx->number;i++)
736     {
737 amb 275 SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
738 amb 257 node_t id1=segmentx->node1;
739     node_t id2=segmentx->node2;
740     Node *node1=&nodesx->ndata[IndexNodeX(nodesx,id1)];
741     Node *node2=&nodesx->ndata[IndexNodeX(nodesx,id2)];
742 amb 110
743     /* Check node1 */
744    
745 amb 212 if(SEGMENT(node1->firstseg)==SEGMENT(NO_SEGMENT))
746 amb 110 {
747 amb 212 node1->firstseg^=SEGMENT(NO_SEGMENT);
748     node1->firstseg|=i;
749 amb 110 }
750     else
751     {
752 amb 212 index_t index=SEGMENT(node1->firstseg);
753 amb 110
754     do
755     {
756 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
757 amb 256
758 amb 257 if(segmentx->node1==id1)
759 amb 110 {
760 amb 209 index++;
761 amb 128
762 amb 256 if(index>=segmentsx->number)
763 amb 209 break;
764 amb 256
765 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
766 amb 256
767 amb 257 if(segmentx->node1!=id1)
768 amb 256 break;
769 amb 110 }
770     else
771     {
772 amb 209 if(segmentsx->sdata[index].next2==NO_NODE)
773 amb 110 {
774 amb 209 segmentsx->sdata[index].next2=i;
775     break;
776 amb 110 }
777     else
778 amb 209 index=segmentsx->sdata[index].next2;
779 amb 110 }
780     }
781 amb 209 while(1);
782 amb 110 }
783    
784     /* Check node2 */
785    
786 amb 212 if(SEGMENT(node2->firstseg)==SEGMENT(NO_SEGMENT))
787 amb 110 {
788 amb 212 node2->firstseg^=SEGMENT(NO_SEGMENT);
789     node2->firstseg|=i;
790 amb 110 }
791     else
792     {
793 amb 212 index_t index=SEGMENT(node2->firstseg);
794 amb 110
795     do
796     {
797 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
798 amb 256
799 amb 257 if(segmentx->node1==id2)
800 amb 110 {
801 amb 209 index++;
802 amb 128
803 amb 256 if(index>=segmentsx->number)
804 amb 209 break;
805 amb 256
806 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
807 amb 256
808 amb 257 if(segmentx->node1!=id2)
809 amb 256 break;
810 amb 110 }
811     else
812     {
813 amb 209 if(segmentsx->sdata[index].next2==NO_NODE)
814 amb 110 {
815 amb 209 segmentsx->sdata[index].next2=i;
816     break;
817 amb 110 }
818     else
819 amb 209 index=segmentsx->sdata[index].next2;
820 amb 110 }
821     }
822 amb 209 while(1);
823 amb 110 }
824    
825     if(!((i+1)%10000))
826     {
827     printf("\rIndexing Segments: Segments=%d",i+1);
828     fflush(stdout);
829     }
830     }
831    
832 amb 275 /* Unmap from memory */
833    
834     if(!option_slim)
835     segmentsx->xdata=UnmapFile(segmentsx->filename);
836    
837     /* Print the final message */
838    
839 amb 110 printf("\rIndexed Segments: Segments=%d \n",segmentsx->number);
840     fflush(stdout);
841     }

Properties

Name Value
cvs:description Extended nodes functions.