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 279 - (hide annotations) (download) (as text)
Thu Oct 8 19:20:29 2009 UTC (15 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 19397 byte(s)
Replace node, segment and way indexes with a single index for a set of segments
containing the location of the first segment for each node.

1 amb 110 /***************************************
2 amb 279 $Header: /home/amb/CVS/routino/src/nodesx.c,v 1.45 2009-10-08 19:20:29 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 amb 279
95 amb 226 if(nodesx->idata)
96     free(nodesx->idata);
97    
98     if(nodesx->ndata)
99     free(nodesx->ndata);
100    
101 amb 257 if(nodesx->offsets)
102     free(nodesx->offsets);
103    
104 amb 226 free(nodesx);
105     }
106    
107    
108     /*++++++++++++++++++++++++++++++++++++++
109 amb 110 Save the node list to a file.
110    
111     NodesX* nodesx The set of nodes to save.
112    
113     const char *filename The name of the file to save.
114     ++++++++++++++++++++++++++++++++++++++*/
115    
116     void SaveNodeList(NodesX* nodesx,const char *filename)
117     {
118 amb 214 index_t i;
119 amb 110 int fd;
120 amb 243 Nodes *nodes;
121 amb 232 int super_number=0;
122 amb 110
123 amb 243 assert(nodesx->gdata); /* Must have gdata filled in => sorted geographically */
124     assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
125 amb 110
126 amb 227 printf("Writing Nodes: Nodes=0");
127     fflush(stdout);
128    
129 amb 219 for(i=0;i<nodesx->number;i++)
130 amb 232 if(nodesx->ndata[i].firstseg&NODE_SUPER)
131     super_number++;
132 amb 219
133 amb 110 /* Fill in a Nodes structure with the offset of the real data in the file after
134     the Node structure itself. */
135    
136 amb 243 nodes=calloc(1,sizeof(Nodes));
137    
138     assert(nodes); /* Check calloc() worked */
139    
140 amb 110 nodes->number=nodesx->number;
141 amb 232 nodes->snumber=super_number;
142 amb 110
143 amb 257 nodes->latbins=nodesx->latbins;
144     nodes->lonbins=nodesx->lonbins;
145 amb 110
146 amb 257 nodes->latzero=nodesx->latzero;
147     nodes->lonzero=nodesx->lonzero;
148 amb 110
149     nodes->data=NULL;
150 amb 232
151 amb 110 nodes->offsets=(void*)sizeof(Nodes);
152 amb 257 nodes->nodes=(void*)(sizeof(Nodes)+(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
153 amb 110
154     /* Write out the Nodes structure and then the real data. */
155    
156     fd=OpenFile(filename);
157    
158     WriteFile(fd,nodes,sizeof(Nodes));
159    
160 amb 257 WriteFile(fd,nodesx->offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
161 amb 110
162 amb 203 for(i=0;i<nodes->number;i++)
163 amb 132 {
164 amb 257 Node *node=&nodesx->ndata[nodesx->gdata[i]];
165 amb 110
166 amb 212 WriteFile(fd,node,sizeof(Node));
167    
168 amb 132 if(!((i+1)%10000))
169     {
170     printf("\rWriting Nodes: Nodes=%d",i+1);
171     fflush(stdout);
172     }
173     }
174    
175 amb 203 printf("\rWrote Nodes: Nodes=%d \n",nodes->number);
176 amb 132 fflush(stdout);
177    
178 amb 110 CloseFile(fd);
179    
180     /* Free the fake Nodes */
181    
182     free(nodes);
183     }
184    
185    
186     /*++++++++++++++++++++++++++++++++++++++
187 amb 252 Find a particular node index.
188 amb 110
189 amb 249 index_t IndexNodeX Returns the index of the extended node with the specified id.
190 amb 110
191     NodesX* nodesx The set of nodes to process.
192    
193     node_t id The node id to look for.
194     ++++++++++++++++++++++++++++++++++++++*/
195    
196 amb 249 index_t IndexNodeX(NodesX* nodesx,node_t id)
197 amb 110 {
198     int start=0;
199     int end=nodesx->number-1;
200     int mid;
201    
202 amb 243 assert(nodesx->idata); /* Must have idata filled in => sorted by id */
203 amb 110
204     /* Binary search - search key exact match only is required.
205     *
206     * # <- start | Check mid and move start or end if it doesn't match
207     * # |
208     * # | Since an exact match is wanted we can set end=mid-1
209     * # <- mid | or start=mid+1 because we know that mid doesn't match.
210     * # |
211     * # | Eventually either end=start or end=start+1 and one of
212     * # <- end | start or end is the wanted one.
213     */
214    
215 amb 252 if(end<start) /* There are no nodes */
216 amb 249 return(NO_NODE);
217 amb 252 else if(id<nodesx->idata[start]) /* Check key is not before start */
218 amb 249 return(NO_NODE);
219 amb 252 else if(id>nodesx->idata[end]) /* Check key is not after end */
220 amb 249 return(NO_NODE);
221 amb 110 else
222     {
223     do
224     {
225 amb 252 mid=(start+end)/2; /* Choose mid point */
226 amb 110
227 amb 252 if(nodesx->idata[mid]<id) /* Mid point is too low */
228 amb 110 start=mid+1;
229 amb 252 else if(nodesx->idata[mid]>id) /* Mid point is too high */
230 amb 110 end=mid-1;
231 amb 252 else /* Mid point is correct */
232 amb 249 return(mid);
233 amb 110 }
234     while((end-start)>1);
235    
236 amb 252 if(nodesx->idata[start]==id) /* Start is correct */
237 amb 249 return(start);
238 amb 110
239 amb 252 if(nodesx->idata[end]==id) /* End is correct */
240 amb 249 return(end);
241 amb 110 }
242    
243 amb 249 return(NO_NODE);
244 amb 110 }
245    
246    
247     /*++++++++++++++++++++++++++++++++++++++
248 amb 275 Lookup a particular node.
249    
250     NodeX *LookupNodeX Returns a pointer to the extended node with the specified id.
251    
252     NodesX* nodesx The set of nodes to process.
253    
254     index_t index The node index to look for.
255    
256     int position The position in the cache to use.
257     ++++++++++++++++++++++++++++++++++++++*/
258    
259     NodeX *LookupNodeX(NodesX* nodesx,index_t index,int position)
260     {
261     assert(index!=NO_NODE); /* Must be a valid node */
262    
263     if(option_slim)
264     {
265     SeekFile(nodesx->fd,index*sizeof(NodeX));
266    
267     ReadFile(nodesx->fd,&nodesx->cached[position-1],sizeof(NodeX));
268    
269     return(&nodesx->cached[position-1]);
270     }
271     else
272     {
273     return(&nodesx->xdata[index]);
274     }
275     }
276    
277    
278     /*++++++++++++++++++++++++++++++++++++++
279 amb 252 Append a node to a newly created node list (unsorted).
280 amb 243
281 amb 252 NodesX* nodesx The set of nodes to process.
282 amb 243
283 amb 252 node_t id The node identification.
284 amb 110
285 amb 252 double latitude The latitude of the node.
286 amb 110
287 amb 252 double longitude The longitude of the node.
288     ++++++++++++++++++++++++++++++++++++++*/
289 amb 110
290 amb 252 void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude)
291     {
292     NodeX nodex;
293 amb 249
294 amb 252 assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
295    
296     nodex.id=id;
297     nodex.latitude =radians_to_latlong(latitude);
298     nodex.longitude=radians_to_latlong(longitude);
299    
300     WriteFile(nodesx->fd,&nodex,sizeof(NodeX));
301    
302     nodesx->xnumber++;
303 amb 110 }
304    
305    
306 amb 271 /*+ A temporary file-local variable for use by the sort functions. +*/
307     static NodesX *sortnodesx;
308    
309    
310 amb 110 /*++++++++++++++++++++++++++++++++++++++
311 amb 263 Sort the node list (i.e. create the sortable indexes).
312 amb 110
313     NodesX* nodesx The set of nodes to process.
314     ++++++++++++++++++++++++++++++++++++++*/
315    
316 amb 263 void SortNodeList(NodesX* nodesx)
317 amb 110 {
318 amb 263 int fd;
319 amb 110
320 amb 263 /* Check the start conditions */
321    
322 amb 252 assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
323    
324 amb 263 /* Print the start message */
325    
326     printf("Sorting Nodes");
327 amb 227 fflush(stdout);
328 amb 132
329 amb 263 /* Close the files and re-open them (finished appending) */
330 amb 260
331     CloseFile(nodesx->fd);
332     nodesx->fd=ReOpenFile(nodesx->filename);
333    
334 amb 271 DeleteFile(nodesx->filename);
335    
336     fd=OpenFile(nodesx->filename);
337    
338 amb 252 /* Allocate the array of indexes */
339 amb 249
340 amb 252 nodesx->idata=(node_t*)malloc(nodesx->xnumber*sizeof(node_t));
341 amb 249
342 amb 252 assert(nodesx->idata); /* Check malloc() worked */
343 amb 249
344 amb 271 /* Sort by node indexes */
345 amb 249
346 amb 271 sortnodesx=nodesx;
347 amb 110
348 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);
349 amb 252
350 amb 260 /* Close the files and re-open them */
351    
352 amb 257 CloseFile(nodesx->fd);
353     CloseFile(fd);
354 amb 252
355 amb 257 nodesx->fd=ReOpenFile(nodesx->filename);
356 amb 252
357 amb 263 /* Print the final message */
358    
359 amb 273 printf("\rSorted Nodes: Nodes=%d Duplicates=%d\n",nodesx->xnumber,nodesx->xnumber-nodesx->number);
360 amb 263 fflush(stdout);
361 amb 110 }
362    
363    
364     /*++++++++++++++++++++++++++++++++++++++
365     Sort the nodes into id order.
366    
367     int sort_by_id Returns the comparison of the id fields.
368    
369 amb 271 NodeX *a The first extended node.
370 amb 110
371 amb 271 NodeX *b The second extended node.
372 amb 110 ++++++++++++++++++++++++++++++++++++++*/
373    
374 amb 271 static int sort_by_id(NodeX *a,NodeX *b)
375 amb 110 {
376 amb 271 node_t a_id=a->id;
377     node_t b_id=b->id;
378 amb 252
379     if(a_id<b_id)
380     return(-1);
381     else if(a_id>b_id)
382 amb 249 return(1);
383 amb 110 else
384 amb 252 return(0);
385 amb 110 }
386    
387    
388 amb 271 /*++++++++++++++++++++++++++++++++++++++
389     Index the nodes after sorting.
390 amb 252
391 amb 273 index_by_id Return 1 if the value is to be kept, otherwise zero.
392    
393 amb 271 NodeX *nodex The extended node.
394 amb 252
395 amb 271 index_t index The index of this node in the total.
396     ++++++++++++++++++++++++++++++++++++++*/
397    
398 amb 273 static int index_by_id(NodeX *nodex,index_t index)
399 amb 271 {
400 amb 273 if(index==0 || sortnodesx->idata[index-1]!=nodex->id)
401     {
402     sortnodesx->idata[index]=nodex->id;
403 amb 271
404 amb 273 sortnodesx->number++;
405    
406     return(1);
407     }
408    
409     return(0);
410 amb 271 }
411    
412    
413 amb 110 /*++++++++++++++++++++++++++++++++++++++
414 amb 212 Sort the node list geographically.
415    
416     NodesX* nodesx The set of nodes to process.
417     ++++++++++++++++++++++++++++++++++++++*/
418    
419     void SortNodeListGeographically(NodesX* nodesx)
420     {
421 amb 214 index_t i;
422 amb 257 ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin;
423     latlong_t lat_min,lat_max,lon_min,lon_max;
424     uint32_t latlonbin;
425 amb 212
426 amb 263 /* Check the start conditions */
427    
428 amb 279 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->ndata); /* Must not have ndata filled in => no real nodes */
655 amb 110
656 amb 275 /* Print the start message */
657    
658 amb 227 printf("Creating Real Nodes: Nodes=0");
659     fflush(stdout);
660    
661 amb 275 /* Map into memory */
662    
663     if(!option_slim)
664     nodesx->xdata=MapFile(nodesx->filename);
665    
666 amb 212 /* Allocate the memory */
667    
668     nodesx->ndata=(Node*)malloc(nodesx->number*sizeof(Node));
669    
670 amb 243 assert(nodesx->ndata); /* Check malloc() worked */
671    
672 amb 212 /* Loop through and allocate. */
673    
674 amb 110 for(i=0;i<nodesx->number;i++)
675     {
676 amb 275 NodeX *nodex=LookupNodeX(nodesx,i,1);
677 amb 208
678 amb 275 nodesx->ndata[i].latoffset=latlong_to_off(nodex->latitude);
679     nodesx->ndata[i].lonoffset=latlong_to_off(nodex->longitude);
680 amb 212 nodesx->ndata[i].firstseg=SEGMENT(NO_SEGMENT);
681    
682 amb 249 if(nodesx->super[i]==iteration)
683 amb 212 nodesx->ndata[i].firstseg|=NODE_SUPER;
684    
685 amb 110 if(!((i+1)%10000))
686     {
687 amb 212 printf("\rCreating Real Nodes: Nodes=%d",i+1);
688 amb 110 fflush(stdout);
689     }
690     }
691    
692 amb 275 /* Unmap from memory */
693    
694     if(!option_slim)
695     nodesx->xdata=UnmapFile(nodesx->filename);
696    
697     /* Print the final message */
698    
699 amb 212 printf("\rCreating Real Nodes: Nodes=%d \n",nodesx->number);
700 amb 110 fflush(stdout);
701     }
702    
703    
704     /*++++++++++++++++++++++++++++++++++++++
705     Assign the segment indexes to the nodes.
706    
707     NodesX *nodesx The list of nodes to process.
708    
709     SegmentsX* segmentsx The set of segments to use.
710     ++++++++++++++++++++++++++++++++++++++*/
711    
712 amb 209 void IndexNodes(NodesX *nodesx,SegmentsX *segmentsx)
713 amb 110 {
714 amb 214 index_t i;
715 amb 110
716 amb 275 /* Check the start conditions */
717    
718 amb 243 assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
719     assert(segmentsx->sdata); /* Must have sdata filled in => real segments exist */
720 amb 110
721 amb 275 /* Print the start message */
722    
723 amb 227 printf("Indexing Segments: Segments=0");
724     fflush(stdout);
725    
726 amb 275 /* Map into memory */
727    
728     if(!option_slim)
729     segmentsx->xdata=MapFile(segmentsx->filename);
730    
731 amb 110 /* Index the nodes */
732    
733     for(i=0;i<segmentsx->number;i++)
734     {
735 amb 275 SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
736 amb 257 node_t id1=segmentx->node1;
737     node_t id2=segmentx->node2;
738 amb 279 Node *node1=&nodesx->ndata[id1];
739     Node *node2=&nodesx->ndata[id2];
740 amb 110
741     /* Check node1 */
742    
743 amb 212 if(SEGMENT(node1->firstseg)==SEGMENT(NO_SEGMENT))
744 amb 110 {
745 amb 212 node1->firstseg^=SEGMENT(NO_SEGMENT);
746     node1->firstseg|=i;
747 amb 110 }
748     else
749     {
750 amb 212 index_t index=SEGMENT(node1->firstseg);
751 amb 110
752     do
753     {
754 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
755 amb 256
756 amb 257 if(segmentx->node1==id1)
757 amb 110 {
758 amb 209 index++;
759 amb 128
760 amb 256 if(index>=segmentsx->number)
761 amb 209 break;
762 amb 256
763 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
764 amb 256
765 amb 257 if(segmentx->node1!=id1)
766 amb 256 break;
767 amb 110 }
768     else
769     {
770 amb 209 if(segmentsx->sdata[index].next2==NO_NODE)
771 amb 110 {
772 amb 209 segmentsx->sdata[index].next2=i;
773     break;
774 amb 110 }
775     else
776 amb 209 index=segmentsx->sdata[index].next2;
777 amb 110 }
778     }
779 amb 209 while(1);
780 amb 110 }
781    
782     /* Check node2 */
783    
784 amb 212 if(SEGMENT(node2->firstseg)==SEGMENT(NO_SEGMENT))
785 amb 110 {
786 amb 212 node2->firstseg^=SEGMENT(NO_SEGMENT);
787     node2->firstseg|=i;
788 amb 110 }
789     else
790     {
791 amb 212 index_t index=SEGMENT(node2->firstseg);
792 amb 110
793     do
794     {
795 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
796 amb 256
797 amb 257 if(segmentx->node1==id2)
798 amb 110 {
799 amb 209 index++;
800 amb 128
801 amb 256 if(index>=segmentsx->number)
802 amb 209 break;
803 amb 256
804 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
805 amb 256
806 amb 257 if(segmentx->node1!=id2)
807 amb 256 break;
808 amb 110 }
809     else
810     {
811 amb 209 if(segmentsx->sdata[index].next2==NO_NODE)
812 amb 110 {
813 amb 209 segmentsx->sdata[index].next2=i;
814     break;
815 amb 110 }
816     else
817 amb 209 index=segmentsx->sdata[index].next2;
818 amb 110 }
819     }
820 amb 209 while(1);
821 amb 110 }
822    
823     if(!((i+1)%10000))
824     {
825     printf("\rIndexing Segments: Segments=%d",i+1);
826     fflush(stdout);
827     }
828     }
829    
830 amb 275 /* Unmap from memory */
831    
832     if(!option_slim)
833     segmentsx->xdata=UnmapFile(segmentsx->filename);
834    
835     /* Print the final message */
836    
837 amb 110 printf("\rIndexed Segments: Segments=%d \n",segmentsx->number);
838     fflush(stdout);
839     }

Properties

Name Value
cvs:description Extended nodes functions.