Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Annotation of /branches/MS-Windows/src/nodesx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1402 - (hide annotations) (download) (as text)
Wed Jun 19 18:58:05 2013 UTC (11 years, 9 months ago) by amb
Original Path: trunk/src/nodesx.c
File MIME type: text/x-csrc
File size: 20326 byte(s)
Use the buffered write functions when creating the nodes, segments, ways and
relation raw files.

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

Properties

Name Value
cvs:description Extended nodes functions.