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 284 - (hide annotations) (download) (as text)
Mon Oct 12 17:35:26 2009 UTC (15 years, 6 months ago) by amb
File MIME type: text/x-csrc
File size: 20167 byte(s)
Rename the tmpdirname variable.

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

Properties

Name Value
cvs:description Extended nodes functions.