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 1098 - (hide annotations) (download) (as text)
Sat Oct 20 12:52:01 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 18184 byte(s)
Delete the pruned nodes before searching for super-nodes etc.

1 amb 110 /***************************************
2     Extented Node data type functions.
3 amb 151
4     Part of the Routino routing software.
5 amb 110 ******************/ /******************
6 amb 947 This file Copyright 2008-2012 Andrew M. Bishop
7 amb 110
8 amb 151 This program is free software: you can redistribute it and/or modify
9     it under the terms of the GNU Affero General Public License as published by
10     the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12    
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU Affero General Public License for more details.
17    
18     You should have received a copy of the GNU Affero General Public License
19     along with this program. If not, see <http://www.gnu.org/licenses/>.
20 amb 110 ***************************************/
21    
22    
23     #include <assert.h>
24     #include <stdlib.h>
25 amb 249 #include <string.h>
26 amb 110
27     #include "types.h"
28 amb 449 #include "nodes.h"
29    
30 amb 955 #include "typesx.h"
31 amb 110 #include "nodesx.h"
32     #include "segmentsx.h"
33 amb 204 #include "waysx.h"
34 amb 110
35 amb 449 #include "files.h"
36 amb 519 #include "logging.h"
37 amb 532 #include "sorting.h"
38 amb 110
39 amb 449
40 amb 252 /* Variables */
41 amb 110
42 amb 289 /*+ The command line '--tmpdir' option or its default value. +*/
43 amb 284 extern char *option_tmpdirname;
44 amb 110
45 amb 284 /*+ A temporary file-local variable for use by the sort functions. +*/
46     static NodesX *sortnodesx;
47    
48 amb 110 /* Functions */
49    
50 amb 271 static int sort_by_id(NodeX *a,NodeX *b);
51 amb 680 static int deduplicate_and_index_by_id(NodeX *nodex,index_t index);
52 amb 271
53 amb 281 static int sort_by_lat_long(NodeX *a,NodeX *b);
54 amb 1098 static int index_by_lat_long(NodeX *nodex,index_t index);
55 amb 110
56    
57     /*++++++++++++++++++++++++++++++++++++++
58 amb 326 Allocate a new node list (create a new file or open an existing one).
59 amb 110
60 amb 680 NodesX *NewNodeList Returns a pointer to the node list.
61 amb 326
62     int append Set to 1 if the file is to be opened for appending (now or later).
63 amb 110 ++++++++++++++++++++++++++++++++++++++*/
64    
65 amb 326 NodesX *NewNodeList(int append)
66 amb 110 {
67     NodesX *nodesx;
68    
69 amb 213 nodesx=(NodesX*)calloc(1,sizeof(NodesX));
70 amb 110
71 amb 243 assert(nodesx); /* Check calloc() worked */
72    
73 amb 284 nodesx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
74 amb 216
75 amb 326 if(append)
76 amb 447 sprintf(nodesx->filename,"%s/nodesx.input.tmp",option_tmpdirname);
77 amb 326 else
78 amb 788 sprintf(nodesx->filename,"%s/nodesx.%p.tmp",option_tmpdirname,(void*)nodesx);
79 amb 249
80 amb 326 if(append)
81     {
82 amb 331 off_t size;
83 amb 326
84 amb 502 nodesx->fd=OpenFileAppend(nodesx->filename);
85 amb 326
86 amb 331 size=SizeFile(nodesx->filename);
87 amb 326
88 amb 650 nodesx->number=size/sizeof(NodeX);
89 amb 326 }
90     else
91 amb 502 nodesx->fd=OpenFileNew(nodesx->filename);
92 amb 326
93 amb 110 return(nodesx);
94     }
95    
96    
97     /*++++++++++++++++++++++++++++++++++++++
98 amb 226 Free a node list.
99    
100 amb 681 NodesX *nodesx The set of nodes to be freed.
101 amb 326
102 amb 680 int keep Set to 1 if the file is to be kept (for appending later).
103 amb 226 ++++++++++++++++++++++++++++++++++++++*/
104    
105 amb 326 void FreeNodeList(NodesX *nodesx,int keep)
106 amb 226 {
107 amb 326 if(!keep)
108     DeleteFile(nodesx->filename);
109    
110 amb 283 free(nodesx->filename);
111 amb 226
112     if(nodesx->idata)
113     free(nodesx->idata);
114    
115 amb 552 if(nodesx->gdata)
116     free(nodesx->gdata);
117 amb 226
118 amb 283 if(nodesx->super)
119     free(nodesx->super);
120    
121 amb 226 free(nodesx);
122     }
123    
124    
125     /*++++++++++++++++++++++++++++++++++++++
126 amb 493 Append a single node to an unsorted node list.
127 amb 243
128 amb 681 NodesX *nodesx The set of nodes to modify.
129 amb 243
130 amb 680 node_t id The node identifier from the original OSM data.
131 amb 110
132 amb 252 double latitude The latitude of the node.
133 amb 110
134 amb 252 double longitude The longitude of the node.
135 amb 469
136 amb 529 transports_t allow The allowed traffic types through the node.
137 amb 537
138 amb 538 uint16_t flags The flags to set for this node.
139 amb 252 ++++++++++++++++++++++++++++++++++++++*/
140 amb 110
141 amb 681 void AppendNode(NodesX *nodesx,node_t id,double latitude,double longitude,transports_t allow,uint16_t flags)
142 amb 252 {
143     NodeX nodex;
144 amb 249
145 amb 252 nodex.id=id;
146     nodex.latitude =radians_to_latlong(latitude);
147     nodex.longitude=radians_to_latlong(longitude);
148 amb 469 nodex.allow=allow;
149 amb 538 nodex.flags=flags;
150 amb 252
151     WriteFile(nodesx->fd,&nodex,sizeof(NodeX));
152    
153 amb 650 nodesx->number++;
154 amb 466
155 amb 650 assert(nodesx->number<NODE_FAKE); /* NODE_FAKE marks the high-water mark for real nodes. */
156 amb 110 }
157    
158    
159     /*++++++++++++++++++++++++++++++++++++++
160 amb 680 Sort the node list.
161 amb 110
162 amb 681 NodesX *nodesx The set of nodes to modify.
163 amb 110 ++++++++++++++++++++++++++++++++++++++*/
164    
165 amb 681 void SortNodeList(NodesX *nodesx)
166 amb 110 {
167 amb 263 int fd;
168 amb 650 index_t xnumber;
169 amb 110
170 amb 263 /* Print the start message */
171    
172 amb 519 printf_first("Sorting Nodes");
173 amb 132
174 amb 555 /* Close the file (finished appending) */
175 amb 260
176 amb 612 nodesx->fd=CloseFile(nodesx->fd);
177 amb 555
178     /* Re-open the file read-only and a new file writeable */
179    
180 amb 260 nodesx->fd=ReOpenFile(nodesx->filename);
181    
182 amb 271 DeleteFile(nodesx->filename);
183    
184 amb 502 fd=OpenFileNew(nodesx->filename);
185 amb 271
186 amb 252 /* Allocate the array of indexes */
187 amb 249
188 amb 650 nodesx->idata=(node_t*)malloc(nodesx->number*sizeof(node_t));
189 amb 249
190 amb 252 assert(nodesx->idata); /* Check malloc() worked */
191 amb 249
192 amb 1097 /* Sort the nodes by ID and index them */
193 amb 249
194 amb 650 xnumber=nodesx->number;
195     nodesx->number=0;
196    
197 amb 271 sortnodesx=nodesx;
198 amb 110
199 amb 948 nodesx->number=filesort_fixed(nodesx->fd,fd,sizeof(NodeX),(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))deduplicate_and_index_by_id);
200 amb 252
201 amb 555 /* Close the files */
202 amb 260
203 amb 612 nodesx->fd=CloseFile(nodesx->fd);
204 amb 257 CloseFile(fd);
205 amb 252
206 amb 263 /* Print the final message */
207    
208 amb 790 printf_last("Sorted Nodes: Nodes=%"Pindex_t" Duplicates=%"Pindex_t,xnumber,xnumber-nodesx->number);
209 amb 110 }
210    
211    
212     /*++++++++++++++++++++++++++++++++++++++
213     Sort the nodes into id order.
214    
215     int sort_by_id Returns the comparison of the id fields.
216    
217 amb 271 NodeX *a The first extended node.
218 amb 110
219 amb 271 NodeX *b The second extended node.
220 amb 110 ++++++++++++++++++++++++++++++++++++++*/
221    
222 amb 271 static int sort_by_id(NodeX *a,NodeX *b)
223 amb 110 {
224 amb 271 node_t a_id=a->id;
225     node_t b_id=b->id;
226 amb 252
227     if(a_id<b_id)
228     return(-1);
229     else if(a_id>b_id)
230 amb 249 return(1);
231 amb 110 else
232 amb 252 return(0);
233 amb 110 }
234    
235    
236 amb 271 /*++++++++++++++++++++++++++++++++++++++
237 amb 680 Create the index of identifiers and discard duplicate nodes.
238 amb 252
239 amb 680 int deduplicate_and_index_by_id Return 1 if the value is to be kept, otherwise 0.
240 amb 273
241 amb 271 NodeX *nodex The extended node.
242 amb 252
243 amb 271 index_t index The index of this node in the total.
244     ++++++++++++++++++++++++++++++++++++++*/
245    
246 amb 680 static int deduplicate_and_index_by_id(NodeX *nodex,index_t index)
247 amb 271 {
248 amb 273 if(index==0 || sortnodesx->idata[index-1]!=nodex->id)
249     {
250     sortnodesx->idata[index]=nodex->id;
251 amb 271
252 amb 273 return(1);
253     }
254 amb 812 else
255     {
256     logerror("Node %"Pnode_t" is duplicated\n",nodex->id);
257 amb 273
258 amb 812 return(0);
259     }
260 amb 271 }
261    
262    
263 amb 110 /*++++++++++++++++++++++++++++++++++++++
264 amb 212 Sort the node list geographically.
265    
266 amb 681 NodesX *nodesx The set of nodes to modify.
267 amb 212 ++++++++++++++++++++++++++++++++++++++*/
268    
269 amb 681 void SortNodeListGeographically(NodesX *nodesx)
270 amb 212 {
271 amb 281 int fd;
272 amb 949 index_t kept;
273 amb 212
274 amb 263 /* Print the start message */
275    
276 amb 949 printf_first("Sorting Nodes Geographically (Deleting Pruned)");
277 amb 212
278 amb 552 /* Allocate the memory for the geographical index array */
279    
280     nodesx->gdata=(index_t*)malloc(nodesx->number*sizeof(index_t));
281    
282     assert(nodesx->gdata); /* Check malloc() worked */
283    
284 amb 555 /* Re-open the file read-only and a new file writeable */
285 amb 212
286 amb 281 nodesx->fd=ReOpenFile(nodesx->filename);
287 amb 243
288 amb 281 DeleteFile(nodesx->filename);
289 amb 212
290 amb 502 fd=OpenFileNew(nodesx->filename);
291 amb 212
292 amb 1097 /* Sort nodes geographically and index them */
293 amb 252
294 amb 281 sortnodesx=nodesx;
295 amb 257
296 amb 1098 kept=filesort_fixed(nodesx->fd,fd,sizeof(NodeX),(int (*)(const void*,const void*))sort_by_lat_long,(int (*)(void*,index_t))index_by_lat_long);
297 amb 257
298 amb 555 /* Close the files */
299 amb 257
300 amb 612 nodesx->fd=CloseFile(nodesx->fd);
301 amb 281 CloseFile(fd);
302 amb 257
303 amb 263 /* Print the final message */
304 amb 257
305 amb 949 printf_last("Sorted Nodes Geographically: Nodes=%"Pindex_t" Deleted=%"Pindex_t,kept,nodesx->number-kept);
306     nodesx->number=kept;
307 amb 212 }
308    
309    
310     /*++++++++++++++++++++++++++++++++++++++
311 amb 680 Sort the nodes into latitude and longitude order (first by longitude bin
312     number, then by latitude bin number and then by exact longitude and then by
313     exact latitude).
314 amb 110
315     int sort_by_lat_long Returns the comparison of the latitude and longitude fields.
316    
317 amb 281 NodeX *a The first extended node.
318 amb 110
319 amb 281 NodeX *b The second extended node.
320 amb 110 ++++++++++++++++++++++++++++++++++++++*/
321    
322 amb 281 static int sort_by_lat_long(NodeX *a,NodeX *b)
323 amb 110 {
324 amb 1098 ll_bin_t a_lon=latlong_to_bin(a->longitude);
325     ll_bin_t b_lon=latlong_to_bin(b->longitude);
326 amb 110
327 amb 1098 if(a_lon<b_lon)
328     return(-1);
329     else if(a_lon>b_lon)
330 amb 949 return(1);
331 amb 110 else
332     {
333 amb 1098 ll_bin_t a_lat=latlong_to_bin(a->latitude);
334     ll_bin_t b_lat=latlong_to_bin(b->latitude);
335 amb 110
336 amb 1098 if(a_lat<b_lat)
337 amb 110 return(-1);
338 amb 1098 else if(a_lat>b_lat)
339 amb 110 return(1);
340     else
341 amb 281 {
342 amb 1098 if(a->longitude<b->longitude)
343 amb 281 return(-1);
344 amb 1098 else if(a->longitude>b->longitude)
345 amb 281 return(1);
346     else
347 amb 664 {
348 amb 1098 if(a->latitude<b->latitude)
349 amb 664 return(-1);
350 amb 1098 else if(a->latitude>b->latitude)
351 amb 664 return(1);
352 amb 1098 }
353 amb 949
354 amb 1098 return(0);
355 amb 281 }
356 amb 110 }
357     }
358    
359    
360     /*++++++++++++++++++++++++++++++++++++++
361 amb 1098 Create the index between the sorted and unsorted nodes.
362 amb 281
363 amb 1098 int index_by_lat_long Return 1 if the value is to be kept, otherwise 0.
364 amb 281
365     NodeX *nodex The extended node.
366    
367     index_t index The index of this node in the total.
368     ++++++++++++++++++++++++++++++++++++++*/
369    
370 amb 1098 static int index_by_lat_long(NodeX *nodex,index_t index)
371 amb 281 {
372 amb 552 /* Create the index from the previous sort to the current one */
373    
374     sortnodesx->gdata[nodex->id]=index;
375    
376 amb 281 return(1);
377     }
378    
379    
380     /*++++++++++++++++++++++++++++++++++++++
381 amb 285 Find a particular node index.
382    
383     index_t IndexNodeX Returns the index of the extended node with the specified id.
384    
385 amb 681 NodesX *nodesx The set of nodes to use.
386 amb 285
387     node_t id The node id to look for.
388     ++++++++++++++++++++++++++++++++++++++*/
389    
390 amb 681 index_t IndexNodeX(NodesX *nodesx,node_t id)
391 amb 285 {
392 amb 780 index_t start=0;
393     index_t end=nodesx->number-1;
394     index_t mid;
395 amb 285
396     /* Binary search - search key exact match only is required.
397     *
398     * # <- start | Check mid and move start or end if it doesn't match
399     * # |
400     * # | Since an exact match is wanted we can set end=mid-1
401     * # <- mid | or start=mid+1 because we know that mid doesn't match.
402     * # |
403     * # | Eventually either end=start or end=start+1 and one of
404     * # <- end | start or end is the wanted one.
405     */
406    
407     if(end<start) /* There are no nodes */
408     return(NO_NODE);
409     else if(id<nodesx->idata[start]) /* Check key is not before start */
410     return(NO_NODE);
411     else if(id>nodesx->idata[end]) /* Check key is not after end */
412     return(NO_NODE);
413     else
414     {
415     do
416     {
417     mid=(start+end)/2; /* Choose mid point */
418    
419     if(nodesx->idata[mid]<id) /* Mid point is too low */
420     start=mid+1;
421     else if(nodesx->idata[mid]>id) /* Mid point is too high */
422 amb 843 end=mid?(mid-1):mid;
423 amb 285 else /* Mid point is correct */
424     return(mid);
425     }
426     while((end-start)>1);
427    
428     if(nodesx->idata[start]==id) /* Start is correct */
429     return(start);
430    
431     if(nodesx->idata[end]==id) /* End is correct */
432     return(end);
433     }
434    
435     return(NO_NODE);
436     }
437    
438    
439     /*++++++++++++++++++++++++++++++++++++++
440 amb 110 Remove any nodes that are not part of a highway.
441    
442 amb 681 NodesX *nodesx The set of nodes to modify.
443 amb 110
444 amb 680 SegmentsX *segmentsx The set of segments to use.
445 amb 110 ++++++++++++++++++++++++++++++++++++++*/
446    
447     void RemoveNonHighwayNodes(NodesX *nodesx,SegmentsX *segmentsx)
448     {
449 amb 263 NodeX nodex;
450 amb 780 index_t total=0,highway=0,nothighway=0;
451 amb 263 int fd;
452 amb 110
453 amb 263 /* Print the start message */
454    
455 amb 627 printf_first("Checking Nodes: Nodes=0");
456 amb 227
457 amb 555 /* Re-open the file read-only and a new file writeable */
458 amb 263
459 amb 555 nodesx->fd=ReOpenFile(nodesx->filename);
460    
461 amb 263 DeleteFile(nodesx->filename);
462    
463 amb 502 fd=OpenFileNew(nodesx->filename);
464 amb 263
465 amb 555 /* Modify the on-disk image */
466    
467 amb 263 while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
468 amb 110 {
469 amb 655 if(!IsBitSet(segmentsx->usednode,total))
470 amb 271 nothighway++;
471     else
472 amb 263 {
473 amb 280 nodex.id=highway;
474 amb 1098 nodesx->idata[highway]=nodesx->idata[total];
475 amb 280
476 amb 263 WriteFile(fd,&nodex,sizeof(NodeX));
477    
478 amb 110 highway++;
479 amb 263 }
480 amb 110
481 amb 263 total++;
482    
483     if(!(total%10000))
484 amb 790 printf_middle("Checking Nodes: Nodes=%"Pindex_t" Highway=%"Pindex_t" not-Highway=%"Pindex_t,total,highway,nothighway);
485 amb 110 }
486    
487 amb 555 nodesx->number=highway;
488 amb 263
489 amb 555 /* Close the files */
490    
491 amb 612 nodesx->fd=CloseFile(nodesx->fd);
492 amb 263 CloseFile(fd);
493    
494 amb 643 /* Free the now-unneeded index */
495    
496     free(segmentsx->usednode);
497     segmentsx->usednode=NULL;
498    
499 amb 263 /* Print the final message */
500    
501 amb 790 printf_last("Checked Nodes: Nodes=%"Pindex_t" Highway=%"Pindex_t" not-Highway=%"Pindex_t,total,highway,nothighway);
502 amb 110 }
503    
504    
505     /*++++++++++++++++++++++++++++++++++++++
506 amb 1098 Remove any nodes that have been pruned.
507    
508     NodesX *nodesx The set of nodes to prune.
509    
510     SegmentsX *segmentsx The set of segments to use.
511     ++++++++++++++++++++++++++++++++++++++*/
512    
513     void RemovePrunedNodes(NodesX *nodesx,SegmentsX *segmentsx)
514     {
515     NodeX nodex;
516     index_t total=0,pruned=0,notpruned=0;
517     int fd;
518    
519     /* Print the start message */
520    
521     printf_first("Deleting Pruned Nodes: Nodes=0 Pruned=0");
522    
523     /* Allocate the array of indexes */
524    
525     nodesx->pdata=(index_t*)malloc(nodesx->number*sizeof(index_t));
526    
527     assert(nodesx->pdata); /* Check malloc() worked */
528    
529     /* Re-open the file read-only and a new file writeable */
530    
531     nodesx->fd=ReOpenFile(nodesx->filename);
532    
533     DeleteFile(nodesx->filename);
534    
535     fd=OpenFileNew(nodesx->filename);
536    
537     /* Modify the on-disk image */
538    
539     while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
540     {
541     if(segmentsx->firstnode[total]==NO_SEGMENT)
542     pruned++;
543     else
544     {
545     nodex.id=notpruned;
546     nodesx->pdata[total]=notpruned;
547    
548     WriteFile(fd,&nodex,sizeof(NodeX));
549    
550     notpruned++;
551     }
552    
553     total++;
554    
555     if(!(total%10000))
556     printf_middle("Deleting Pruned Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,total,pruned);
557     }
558    
559     nodesx->number=notpruned;
560    
561     /* Close the files */
562    
563     nodesx->fd=CloseFile(nodesx->fd);
564     CloseFile(fd);
565    
566     /* Print the final message */
567    
568     printf_last("Deleted Pruned Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,total,pruned);
569     }
570    
571    
572     /*++++++++++++++++++++++++++++++++++++++
573 amb 643 Insert the super-node flag and the first segment indexes after geographical sorting.
574 amb 110
575 amb 681 NodesX *nodesx The set of nodes to modify.
576 amb 110
577 amb 643 SegmentsX *segmentsx The set of segments to use.
578 amb 110 ++++++++++++++++++++++++++++++++++++++*/
579    
580 amb 653 void UpdateNodes(NodesX *nodesx,SegmentsX *segmentsx)
581 amb 110 {
582 amb 214 index_t i;
583 amb 643 int fd;
584 amb 1097 ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin;
585     latlong_t lat_min,lat_max,lon_min,lon_max;
586 amb 110
587 amb 275 /* Print the start message */
588    
589 amb 1097 printf_first("Updating Nodes: Nodes=0");
590 amb 227
591 amb 1097 /* While we are here we can work out the range of data */
592    
593     lat_min=radians_to_latlong( 2);
594     lat_max=radians_to_latlong(-2);
595     lon_min=radians_to_latlong( 4);
596     lon_max=radians_to_latlong(-4);
597    
598 amb 643 /* Re-open the file read-only and a new file writeable */
599 amb 275
600 amb 643 nodesx->fd=ReOpenFile(nodesx->filename);
601 amb 554
602 amb 643 DeleteFile(nodesx->filename);
603 amb 212
604 amb 643 fd=OpenFileNew(nodesx->filename);
605    
606     /* Modify the on-disk image */
607    
608 amb 110 for(i=0;i<nodesx->number;i++)
609     {
610 amb 643 NodeX nodex;
611 amb 208
612 amb 643 ReadFile(nodesx->fd,&nodex,sizeof(NodeX));
613 amb 212
614 amb 654 if(IsBitSet(nodesx->super,nodex.id))
615 amb 643 nodex.flags|=NODE_SUPER;
616 amb 212
617 amb 674 nodex.id=segmentsx->firstnode[nodesx->gdata[nodex.id]];
618 amb 448
619 amb 643 WriteFile(fd,&nodex,sizeof(NodeX));
620    
621 amb 1097 if(nodex.latitude<lat_min)
622     lat_min=nodex.latitude;
623     if(nodex.latitude>lat_max)
624     lat_max=nodex.latitude;
625     if(nodex.longitude<lon_min)
626     lon_min=nodex.longitude;
627     if(nodex.longitude>lon_max)
628     lon_max=nodex.longitude;
629    
630 amb 110 if(!((i+1)%10000))
631 amb 1097 printf_middle("Updating Nodes: Nodes=%"Pindex_t,i+1);
632 amb 110 }
633    
634 amb 643 /* Close the files */
635    
636     nodesx->fd=CloseFile(nodesx->fd);
637     CloseFile(fd);
638    
639 amb 947 /* Free the memory */
640    
641     free(nodesx->super);
642     nodesx->super=NULL;
643    
644 amb 1097 /* Work out the number of bins */
645    
646     lat_min_bin=latlong_to_bin(lat_min);
647     lon_min_bin=latlong_to_bin(lon_min);
648     lat_max_bin=latlong_to_bin(lat_max);
649     lon_max_bin=latlong_to_bin(lon_max);
650    
651     nodesx->latzero=lat_min_bin;
652     nodesx->lonzero=lon_min_bin;
653    
654     nodesx->latbins=(lat_max_bin-lat_min_bin)+1;
655     nodesx->lonbins=(lon_max_bin-lon_min_bin)+1;
656    
657 amb 275 /* Print the final message */
658    
659 amb 1097 printf_last("Updated Nodes: Nodes=%"Pindex_t,nodesx->number);
660 amb 110 }
661    
662    
663     /*++++++++++++++++++++++++++++++++++++++
664 amb 680 Save the final node list database to a file.
665 amb 285
666 amb 681 NodesX *nodesx The set of nodes to save.
667 amb 285
668     const char *filename The name of the file to save.
669     ++++++++++++++++++++++++++++++++++++++*/
670    
671 amb 681 void SaveNodeList(NodesX *nodesx,const char *filename)
672 amb 285 {
673     index_t i;
674     int fd;
675 amb 500 NodesFile nodesfile={0};
676 amb 780 index_t super_number=0;
677 amb 788 ll_bin2_t latlonbin=0,maxlatlonbins;
678 amb 780 index_t *offsets;
679 amb 285
680     /* Print the start message */
681    
682 amb 519 printf_first("Writing Nodes: Nodes=0");
683 amb 285
684 amb 553 /* Allocate the memory for the geographical offsets array */
685    
686     offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
687    
688     assert(offsets); /* Check malloc() worked */
689    
690     latlonbin=0;
691    
692 amb 556 /* Re-open the file */
693 amb 285
694 amb 555 nodesx->fd=ReOpenFile(nodesx->filename);
695 amb 285
696 amb 461 /* Write out the nodes data */
697 amb 285
698 amb 502 fd=OpenFileNew(filename);
699 amb 285
700 amb 553 SeekFile(fd,sizeof(NodesFile)+(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
701 amb 285
702 amb 461 for(i=0;i<nodesx->number;i++)
703 amb 285 {
704 amb 556 NodeX nodex;
705 amb 944 Node node={0};
706 amb 553 ll_bin_t latbin,lonbin;
707 amb 780 ll_bin2_t llbin;
708 amb 285
709 amb 556 ReadFile(nodesx->fd,&nodex,sizeof(NodeX));
710    
711 amb 553 /* Create the Node */
712    
713 amb 556 node.latoffset=latlong_to_off(nodex.latitude);
714     node.lonoffset=latlong_to_off(nodex.longitude);
715     node.firstseg=nodex.id;
716     node.allow=nodex.allow;
717     node.flags=nodex.flags;
718 amb 552
719     if(node.flags&NODE_SUPER)
720 amb 461 super_number++;
721    
722 amb 553 /* Work out the offsets */
723    
724 amb 556 latbin=latlong_to_bin(nodex.latitude )-nodesx->latzero;
725     lonbin=latlong_to_bin(nodex.longitude)-nodesx->lonzero;
726 amb 553 llbin=lonbin*nodesx->latbins+latbin;
727    
728     for(;latlonbin<=llbin;latlonbin++)
729     offsets[latlonbin]=i;
730    
731     /* Write the data */
732    
733 amb 552 WriteFile(fd,&node,sizeof(Node));
734 amb 285
735     if(!((i+1)%10000))
736 amb 790 printf_middle("Writing Nodes: Nodes=%"Pindex_t,i+1);
737 amb 285 }
738    
739 amb 556 /* Close the file */
740    
741 amb 612 nodesx->fd=CloseFile(nodesx->fd);
742 amb 556
743 amb 553 /* Finish off the offset indexing and write them out */
744    
745 amb 788 maxlatlonbins=nodesx->latbins*nodesx->lonbins;
746    
747     for(;latlonbin<=maxlatlonbins;latlonbin++)
748 amb 553 offsets[latlonbin]=nodesx->number;
749    
750     SeekFile(fd,sizeof(NodesFile));
751     WriteFile(fd,offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
752    
753 amb 795 free(offsets);
754    
755 amb 461 /* Write out the header structure */
756    
757     nodesfile.number=nodesx->number;
758     nodesfile.snumber=super_number;
759    
760     nodesfile.latbins=nodesx->latbins;
761     nodesfile.lonbins=nodesx->lonbins;
762    
763     nodesfile.latzero=nodesx->latzero;
764     nodesfile.lonzero=nodesx->lonzero;
765    
766     SeekFile(fd,0);
767     WriteFile(fd,&nodesfile,sizeof(NodesFile));
768    
769 amb 285 CloseFile(fd);
770    
771     /* Print the final message */
772    
773 amb 790 printf_last("Wrote Nodes: Nodes=%"Pindex_t,nodesx->number);
774 amb 285 }

Properties

Name Value
cvs:description Extended nodes functions.