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 1151 - (hide annotations) (download) (as text)
Sun Nov 18 17:24:50 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 18610 byte(s)
Using --parse-only and --preserve must sort the data so that it is ready to
apply the changes.

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

Properties

Name Value
cvs:description Extended nodes functions.