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 1171 - (hide annotations) (download) (as text)
Tue Nov 27 19:19:01 2012 UTC (12 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 18684 byte(s)
Don't log an error for duplicated nodes, ways or relations because it can only
occur when applying changes or if using multiple geographically overlapping
files and neither is a data error.

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

Properties

Name Value
cvs:description Extended nodes functions.