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/segmentsx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 651 - (hide annotations) (download) (as text)
Sun Feb 27 16:31:34 2011 UTC (14 years ago) by amb
File MIME type: text/x-csrc
File size: 20233 byte(s)
Rename the xdata and xcached members of the nodesx, segmentsx and waysx
structures.

1 amb 110 /***************************************
2     Extended Segment data type functions.
3 amb 151
4     Part of the Routino routing software.
5 amb 110 ******************/ /******************
6 amb 602 This file Copyright 2008-2011 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 <math.h>
25     #include <stdlib.h>
26     #include <stdio.h>
27 amb 256 #include <string.h>
28 amb 326 #include <sys/stat.h>
29 amb 110
30     #include "types.h"
31 amb 228 #include "nodes.h"
32     #include "segments.h"
33     #include "ways.h"
34 amb 110
35 amb 449 #include "nodesx.h"
36     #include "segmentsx.h"
37     #include "waysx.h"
38 amb 110
39 amb 466 #include "types.h"
40    
41 amb 449 #include "files.h"
42 amb 519 #include "logging.h"
43 amb 532 #include "sorting.h"
44 amb 449
45    
46 amb 256 /* Variables */
47 amb 110
48 amb 289 /*+ The command line '--tmpdir' option or its default value. +*/
49 amb 284 extern char *option_tmpdirname;
50 amb 110
51 amb 228 /* Local Functions */
52 amb 110
53 amb 275 static int sort_by_id(SegmentX *a,SegmentX *b);
54    
55 amb 228 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2);
56 amb 110
57    
58     /*++++++++++++++++++++++++++++++++++++++
59 amb 326 Allocate a new segment list (create a new file or open an existing one).
60 amb 110
61     SegmentsX *NewSegmentList Returns the segment list.
62 amb 326
63     int append Set to 1 if the file is to be opened for appending (now or later).
64 amb 110 ++++++++++++++++++++++++++++++++++++++*/
65    
66 amb 326 SegmentsX *NewSegmentList(int append)
67 amb 110 {
68     SegmentsX *segmentsx;
69    
70 amb 213 segmentsx=(SegmentsX*)calloc(1,sizeof(SegmentsX));
71 amb 110
72 amb 243 assert(segmentsx); /* Check calloc() worked */
73    
74 amb 284 segmentsx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
75 amb 216
76 amb 326 if(append)
77 amb 447 sprintf(segmentsx->filename,"%s/segmentsx.input.tmp",option_tmpdirname);
78 amb 326 else
79 amb 447 sprintf(segmentsx->filename,"%s/segmentsx.%p.tmp",option_tmpdirname,segmentsx);
80 amb 256
81 amb 326 if(append)
82     {
83 amb 331 off_t size;
84 amb 326
85 amb 502 segmentsx->fd=OpenFileAppend(segmentsx->filename);
86 amb 326
87 amb 331 size=SizeFile(segmentsx->filename);
88 amb 326
89 amb 650 segmentsx->number=size/sizeof(SegmentX);
90 amb 326 }
91     else
92 amb 502 segmentsx->fd=OpenFileNew(segmentsx->filename);
93 amb 326
94 amb 110 return(segmentsx);
95     }
96    
97    
98     /*++++++++++++++++++++++++++++++++++++++
99 amb 226 Free a segment list.
100 amb 110
101     SegmentsX *segmentsx The list to be freed.
102 amb 326
103     int keep Set to 1 if the file is to be kept.
104 amb 110 ++++++++++++++++++++++++++++++++++++++*/
105    
106 amb 326 void FreeSegmentList(SegmentsX *segmentsx,int keep)
107 amb 110 {
108 amb 326 if(!keep)
109     DeleteFile(segmentsx->filename);
110    
111 amb 283 free(segmentsx->filename);
112 amb 256
113 amb 643 if(segmentsx->usednode)
114     free(segmentsx->usednode);
115    
116 amb 279 if(segmentsx->firstnode)
117     free(segmentsx->firstnode);
118    
119 amb 110 free(segmentsx);
120     }
121    
122    
123     /*++++++++++++++++++++++++++++++++++++++
124 amb 493 Append a single segment to an unsorted segment list.
125 amb 110
126 amb 285 SegmentsX* segmentsx The set of segments to process.
127 amb 110
128 amb 285 way_t way The way that the segment belongs to.
129    
130     node_t node1 The first node in the segment.
131    
132     node_t node2 The second node in the segment.
133    
134     distance_t distance The distance between the nodes (or just the flags).
135 amb 110 ++++++++++++++++++++++++++++++++++++++*/
136    
137 amb 285 void AppendSegment(SegmentsX* segmentsx,way_t way,node_t node1,node_t node2,distance_t distance)
138 amb 110 {
139 amb 285 SegmentX segmentx;
140 amb 110
141 amb 643 if(node1>node2)
142     {
143     node_t temp;
144    
145     temp=node1;
146     node1=node2;
147     node2=temp;
148    
149     if(distance&(ONEWAY_2TO1|ONEWAY_1TO2))
150     distance^=ONEWAY_2TO1|ONEWAY_1TO2;
151     }
152    
153 amb 285 segmentx.node1=node1;
154     segmentx.node2=node2;
155 amb 643 segmentx.next2=NO_SEGMENT;
156 amb 285 segmentx.way=way;
157     segmentx.distance=distance;
158 amb 110
159 amb 285 WriteFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
160 amb 281
161 amb 650 segmentsx->number++;
162 amb 466
163 amb 650 assert(segmentsx->number<SEGMENT_FAKE); /* SEGMENT_FAKE marks the high-water mark for real segments. */
164 amb 285 }
165 amb 227
166 amb 281
167 amb 285 /*++++++++++++++++++++++++++++++++++++++
168     Sort the segment list.
169 amb 232
170 amb 285 SegmentsX* segmentsx The set of segments to process.
171     ++++++++++++++++++++++++++++++++++++++*/
172 amb 110
173 amb 285 void SortSegmentList(SegmentsX* segmentsx)
174     {
175     int fd;
176 amb 243
177 amb 285 /* Print the start message */
178 amb 232
179 amb 519 printf_first("Sorting Segments");
180 amb 110
181 amb 555 /* Close the file (finished appending) */
182 amb 110
183 amb 612 segmentsx->fd=CloseFile(segmentsx->fd);
184 amb 555
185     /* Re-open the file read-only and a new file writeable */
186    
187 amb 285 segmentsx->fd=ReOpenFile(segmentsx->filename);
188 amb 110
189 amb 285 DeleteFile(segmentsx->filename);
190 amb 110
191 amb 502 fd=OpenFileNew(segmentsx->filename);
192 amb 110
193 amb 285 /* Sort by node indexes */
194 amb 132
195 amb 311 filesort_fixed(segmentsx->fd,fd,sizeof(SegmentX),(int (*)(const void*,const void*))sort_by_id,NULL);
196 amb 285
197 amb 555 /* Close the files */
198 amb 285
199 amb 612 segmentsx->fd=CloseFile(segmentsx->fd);
200 amb 281 CloseFile(fd);
201    
202     /* Print the final message */
203    
204 amb 650 printf_last("Sorted Segments: Segments=%d",segmentsx->number);
205 amb 110 }
206    
207    
208     /*++++++++++++++++++++++++++++++++++++++
209 amb 285 Sort the segments into id order (node1 then node2).
210 amb 110
211 amb 285 int sort_by_id Returns the comparison of the node fields.
212 amb 110
213 amb 285 SegmentX *a The first segment.
214 amb 110
215 amb 285 SegmentX *b The second segment.
216 amb 256 ++++++++++++++++++++++++++++++++++++++*/
217    
218 amb 285 static int sort_by_id(SegmentX *a,SegmentX *b)
219 amb 256 {
220 amb 285 node_t a_id1=a->node1;
221     node_t b_id1=b->node1;
222 amb 256
223 amb 285 if(a_id1<b_id1)
224     return(-1);
225     else if(a_id1>b_id1)
226     return(1);
227     else /* if(a_id1==b_id1) */
228 amb 256 {
229 amb 285 node_t a_id2=a->node2;
230     node_t b_id2=b->node2;
231 amb 256
232 amb 285 if(a_id2<b_id2)
233     return(-1);
234     else if(a_id2>b_id2)
235     return(1);
236     else
237     {
238     distance_t a_distance=a->distance;
239     distance_t b_distance=b->distance;
240 amb 256
241 amb 285 if(a_distance<b_distance)
242     return(-1);
243     else if(a_distance>b_distance)
244     return(1);
245     else
246     return(0);
247     }
248 amb 256 }
249     }
250    
251    
252     /*++++++++++++++++++++++++++++++++++++++
253 amb 643 Find the first extended segment with a particular starting node index.
254    
255 amb 646 SegmentX *FirstSegmentX Returns a pointer to the first extended segment with the specified id.
256 amb 544
257 amb 643 SegmentsX* segmentsx The set of extended segments to process.
258 amb 544
259 amb 643 index_t nodeindex The node index to look for.
260    
261     int position A flag to pass through.
262     ++++++++++++++++++++++++++++++++++++++*/
263    
264 amb 646 SegmentX *FirstSegmentX(SegmentsX* segmentsx,index_t nodeindex,int position)
265 amb 643 {
266     index_t index=segmentsx->firstnode[nodeindex];
267     SegmentX *segmentx;
268    
269     segmentx=LookupSegmentX(segmentsx,index,position);
270    
271     if(segmentx->node1!=nodeindex && segmentx->node2!=nodeindex)
272     return(NULL);
273    
274     return(segmentx);
275     }
276    
277    
278     /*++++++++++++++++++++++++++++++++++++++
279     Find the next segment with a particular starting node index.
280    
281 amb 646 SegmentX *NextSegmentX Returns a pointer to the next segment with the same id.
282 amb 643
283 amb 544 SegmentsX* segmentsx The set of segments to process.
284    
285 amb 643 SegmentX *segmentx The current segment.
286 amb 544
287 amb 643 index_t node The node index.
288    
289     int position A flag to pass through.
290 amb 110 ++++++++++++++++++++++++++++++++++++++*/
291    
292 amb 646 SegmentX *NextSegmentX(SegmentsX* segmentsx,SegmentX *segmentx,index_t node,int position)
293 amb 110 {
294 amb 643 if(segmentx->node1==node)
295     {
296     #if SLIM
297     index_t index=IndexSegmentX(segmentsx,segmentx);
298     index++;
299 amb 544
300 amb 643 if(index>=segmentsx->number)
301     return(NULL);
302     segmentx=LookupSegmentX(segmentsx,index,position);
303     if(segmentx->node1!=node)
304     return(NULL);
305     else
306     return(segmentx);
307     #else
308     segmentx++;
309     if(IndexSegmentX(segmentsx,segmentx)>=segmentsx->number || segmentx->node1!=node)
310     return(NULL);
311     else
312     return(segmentx);
313     #endif
314     }
315 amb 229 else
316 amb 643 {
317     if(segmentx->next2==NO_SEGMENT)
318     return(NULL);
319     else
320     return(LookupSegmentX(segmentsx,segmentx->next2,position));
321     }
322 amb 110 }
323    
324    
325     /*++++++++++++++++++++++++++++++++++++++
326 amb 275 Remove bad segments (duplicated, zero length or missing nodes).
327 amb 110
328 amb 195 NodesX *nodesx The nodes to check.
329    
330 amb 110 SegmentsX *segmentsx The segments to modify.
331     ++++++++++++++++++++++++++++++++++++++*/
332    
333 amb 204 void RemoveBadSegments(NodesX *nodesx,SegmentsX *segmentsx)
334 amb 110 {
335 amb 275 int duplicate=0,loop=0,missing=0,good=0,total=0;
336     SegmentX segmentx;
337     int fd;
338     node_t prevnode1=NO_NODE,prevnode2=NO_NODE;
339 amb 110
340 amb 275 /* Print the start message */
341    
342 amb 627 printf_first("Checking Segments: Segments=0 Duplicate=0 Loop=0 Missing-Node=0");
343 amb 227
344 amb 643 /* Allocate the array of node flags */
345    
346 amb 650 segmentsx->usednode=(char*)calloc(nodesx->number,sizeof(char));
347 amb 643
348     assert(segmentsx->usednode); /* Check malloc() worked */
349    
350 amb 555 /* Re-open the file read-only and a new file writeable */
351 amb 275
352 amb 555 segmentsx->fd=ReOpenFile(segmentsx->filename);
353    
354 amb 275 DeleteFile(segmentsx->filename);
355    
356 amb 502 fd=OpenFileNew(segmentsx->filename);
357 amb 275
358 amb 555 /* Modify the on-disk image */
359    
360 amb 275 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
361 amb 110 {
362 amb 643 index_t index1=IndexNodeX(nodesx,segmentx.node1);
363     index_t index2=IndexNodeX(nodesx,segmentx.node2);
364    
365 amb 275 if(prevnode1==segmentx.node1 && prevnode2==segmentx.node2)
366     duplicate++;
367     else if(segmentx.node1==segmentx.node2)
368 amb 257 loop++;
369 amb 643 else if(index1==NO_NODE || index2==NO_NODE)
370 amb 275 missing++;
371     else
372 amb 257 {
373 amb 275 WriteFile(fd,&segmentx,sizeof(SegmentX));
374    
375 amb 643 segmentsx->usednode[index1]=1;
376     segmentsx->usednode[index2]=1;
377    
378 amb 275 good++;
379    
380     prevnode1=segmentx.node1;
381     prevnode2=segmentx.node2;
382 amb 110 }
383    
384 amb 275 total++;
385 amb 256
386 amb 275 if(!(total%10000))
387 amb 627 printf_middle("Checking Segments: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d",total,duplicate,loop,missing);
388 amb 110 }
389    
390 amb 555 segmentsx->number=good;
391 amb 275
392 amb 555 /* Close the files */
393    
394 amb 612 segmentsx->fd=CloseFile(segmentsx->fd);
395 amb 275 CloseFile(fd);
396    
397     /* Print the final message */
398    
399 amb 627 printf_last("Checked Segments: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d",total,duplicate,loop,missing);
400 amb 110 }
401    
402    
403     /*++++++++++++++++++++++++++++++++++++++
404 amb 285 Measure the segments and replace node/way ids with indexes.
405 amb 110
406     SegmentsX* segmentsx The set of segments to process.
407    
408     NodesX *nodesx The list of nodes to use.
409 amb 279
410     WaysX *waysx The list of ways to use.
411 amb 110 ++++++++++++++++++++++++++++++++++++++*/
412    
413 amb 644 void MeasureSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
414 amb 110 {
415 amb 279 index_t index=0;
416 amb 643 int fd;
417 amb 256 SegmentX segmentx;
418 amb 110
419 amb 275 /* Print the start message */
420    
421 amb 519 printf_first("Measuring Segments: Segments=0");
422 amb 227
423 amb 555 /* Map into memory / open the file */
424 amb 257
425 amb 452 #if !SLIM
426 amb 651 nodesx->data=MapFile(nodesx->filename);
427 amb 555 #else
428     nodesx->fd=ReOpenFile(nodesx->filename);
429 amb 452 #endif
430 amb 258
431 amb 555 /* Re-open the file read-only and a new file writeable */
432 amb 275
433 amb 555 segmentsx->fd=ReOpenFile(segmentsx->filename);
434    
435 amb 256 DeleteFile(segmentsx->filename);
436    
437 amb 502 fd=OpenFileNew(segmentsx->filename);
438 amb 256
439 amb 555 /* Modify the on-disk image */
440    
441 amb 256 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
442 amb 110 {
443 amb 279 index_t node1=IndexNodeX(nodesx,segmentx.node1);
444     index_t node2=IndexNodeX(nodesx,segmentx.node2);
445     index_t way =IndexWayX (waysx ,segmentx.way);
446 amb 110
447 amb 279 NodeX *nodex1=LookupNodeX(nodesx,node1,1);
448     NodeX *nodex2=LookupNodeX(nodesx,node2,2);
449    
450     /* Replace the node and way ids with their indexes */
451    
452     segmentx.node1=node1;
453     segmentx.node2=node2;
454     segmentx.way =way;
455    
456 amb 275 /* Set the distance but preserve the ONEWAY_* flags */
457    
458     segmentx.distance|=DISTANCE(DistanceX(nodex1,nodex2));
459    
460 amb 279 /* Write the modified segment */
461    
462 amb 275 WriteFile(fd,&segmentx,sizeof(SegmentX));
463    
464 amb 279 index++;
465 amb 275
466 amb 279 if(!(index%10000))
467 amb 519 printf_middle("Measuring Segments: Segments=%d",index);
468 amb 275 }
469 amb 110
470 amb 555 /* Close the files */
471 amb 257
472 amb 612 segmentsx->fd=CloseFile(segmentsx->fd);
473 amb 275 CloseFile(fd);
474    
475 amb 280 /* Free the other now-unneeded indexes */
476 amb 279
477     free(nodesx->idata);
478     nodesx->idata=NULL;
479    
480     free(waysx->idata);
481     waysx->idata=NULL;
482    
483 amb 555 /* Unmap from memory / close the file */
484 amb 275
485 amb 452 #if !SLIM
486 amb 651 nodesx->data=UnmapFile(nodesx->filename);
487 amb 555 #else
488 amb 612 nodesx->fd=CloseFile(nodesx->fd);
489 amb 452 #endif
490 amb 275
491     /* Print the final message */
492    
493 amb 519 printf_last("Measured Segments: Segments=%d",segmentsx->number);
494 amb 275 }
495    
496    
497     /*++++++++++++++++++++++++++++++++++++++
498     Remove the duplicate segments.
499 amb 110
500     SegmentsX* segmentsx The set of segments to process.
501    
502 amb 279 NodesX *nodesx The list of nodes to use.
503    
504 amb 110 WaysX *waysx The list of ways to use.
505     ++++++++++++++++++++++++++++++++++++++*/
506    
507 amb 279 void DeduplicateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
508 amb 110 {
509 amb 275 int duplicate=0,good=0;
510     index_t firstindex=0,index=0;
511 amb 643 int fd;
512 amb 275 SegmentX prevsegmentx[16],segmentx;
513 amb 110
514 amb 275 /* Print the start message */
515    
516 amb 519 printf_first("Deduplicating Segments: Segments=0 Duplicate=0");
517 amb 227
518 amb 555 /* Map into memory / open the file */
519 amb 256
520 amb 452 #if !SLIM
521 amb 651 waysx->data=MapFile(waysx->filename);
522 amb 555 #else
523     waysx->fd=ReOpenFile(waysx->filename);
524 amb 452 #endif
525 amb 275
526 amb 555 /* Re-open the file read-only and a new file writeable */
527 amb 275
528 amb 555 segmentsx->fd=ReOpenFile(segmentsx->filename);
529    
530 amb 275 DeleteFile(segmentsx->filename);
531    
532 amb 502 fd=OpenFileNew(segmentsx->filename);
533 amb 275
534 amb 555 /* Modify the on-disk image */
535    
536 amb 275 while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
537 amb 110 {
538 amb 275 int isduplicate=0;
539 amb 256
540 amb 275 if(index && segmentx.node1==prevsegmentx[0].node1 &&
541     segmentx.node2==prevsegmentx[0].node2)
542 amb 110 {
543 amb 264 index_t previndex=firstindex;
544 amb 110
545 amb 275 while(previndex<index)
546 amb 110 {
547 amb 275 int offset=previndex-firstindex;
548    
549     if(DISTFLAG(segmentx.distance)==DISTFLAG(prevsegmentx[offset].distance))
550 amb 264 {
551 amb 279 WayX *wayx1=LookupWayX(waysx,prevsegmentx[offset].way,1);
552     WayX *wayx2=LookupWayX(waysx, segmentx .way,2);
553 amb 110
554 amb 275 if(!WaysCompare(&wayx1->way,&wayx2->way))
555 amb 264 {
556 amb 275 isduplicate=1;
557     break;
558 amb 264 }
559     }
560    
561     previndex++;
562 amb 110 }
563 amb 275
564     assert((index-firstindex)<(sizeof(prevsegmentx)/sizeof(prevsegmentx[0])));
565    
566     prevsegmentx[index-firstindex]=segmentx;
567 amb 110 }
568 amb 264 else
569     {
570 amb 275 firstindex=index;
571     prevsegmentx[0]=segmentx;
572 amb 264 }
573 amb 110
574 amb 640 if(isduplicate)
575     duplicate++;
576     else
577 amb 110 {
578 amb 275 WriteFile(fd,&segmentx,sizeof(SegmentX));
579    
580     good++;
581     }
582    
583     index++;
584    
585     if(!(index%10000))
586 amb 519 printf_middle("Deduplicating Segments: Segments=%d Duplicate=%d",index,duplicate);
587 amb 110 }
588    
589 amb 555 segmentsx->number=good;
590 amb 275
591 amb 555 /* Close the files */
592    
593 amb 612 segmentsx->fd=CloseFile(segmentsx->fd);
594 amb 275 CloseFile(fd);
595    
596 amb 555 /* Unmap from memory / close the file */
597 amb 275
598 amb 452 #if !SLIM
599 amb 651 waysx->data=UnmapFile(waysx->filename);
600 amb 555 #else
601 amb 612 waysx->fd=CloseFile(waysx->fd);
602 amb 452 #endif
603 amb 275
604     /* Print the final message */
605    
606 amb 640 printf_last("Deduplicated Segments: Segments=%d Duplicate=%d Unique=%d",index,duplicate,good);
607 amb 110 }
608    
609    
610     /*++++++++++++++++++++++++++++++++++++++
611 amb 643 Index the segments by creating the firstnode index and the segment next2 indexes.
612 amb 209
613 amb 643 SegmentsX* segmentsx The set of segments to process.
614 amb 209
615 amb 643 NodesX *nodesx The list of nodes to use.
616 amb 209 ++++++++++++++++++++++++++++++++++++++*/
617    
618 amb 643 void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
619 amb 209 {
620 amb 643 index_t index;
621     int i;
622 amb 209
623 amb 275 /* Print the start message */
624    
625 amb 643 printf_first("Indexing Segments: Segments=0");
626 amb 227
627 amb 643 /* Allocate the array of indexes */
628    
629     if(!segmentsx->firstnode)
630     {
631     segmentsx->firstnode=(index_t*)malloc((nodesx->number+1)*sizeof(index_t));
632    
633     assert(segmentsx->firstnode); /* Check malloc() worked */
634     }
635    
636     for(i=0;i<nodesx->number;i++)
637     segmentsx->firstnode[i]=NO_SEGMENT;
638    
639 amb 555 /* Map into memory / open the files */
640 amb 209
641 amb 452 #if !SLIM
642 amb 651 segmentsx->data=MapFileWriteable(segmentsx->filename);
643 amb 555 #else
644 amb 643 segmentsx->fd=ReOpenFileWriteable(segmentsx->filename);
645 amb 452 #endif
646 amb 275
647 amb 643 /* Read through the segments in reverse order */
648 amb 280
649 amb 643 for(index=segmentsx->number-1;index!=NO_SEGMENT;index--)
650 amb 209 {
651 amb 643 SegmentX *segmentx=LookupSegmentX(segmentsx,index,1);
652 amb 209
653 amb 643 if(segmentsx->firstnode[segmentx->node2]!=NO_SEGMENT)
654     {
655     segmentx->next2=segmentsx->firstnode[segmentx->node2];
656 amb 209
657 amb 643 PutBackSegmentX(segmentsx,index,1);
658     }
659 amb 448
660 amb 643 segmentsx->firstnode[segmentx->node1]=index;
661     segmentsx->firstnode[segmentx->node2]=index;
662 amb 558
663 amb 643 if(!(index%10000))
664     printf_middle("Indexing Segments: Segments=%d",segmentsx->number-index);
665 amb 209 }
666    
667 amb 555 /* Unmap from memory / close the files */
668 amb 275
669 amb 452 #if !SLIM
670 amb 651 segmentsx->data=UnmapFile(segmentsx->filename);
671 amb 555 #else
672 amb 643 segmentsx->fd=CloseFile(segmentsx->fd);
673 amb 452 #endif
674 amb 275
675 amb 643 /* Fix-up the firstnode index for the missing nodes */
676 amb 554
677 amb 643 segmentsx->firstnode[nodesx->number]=segmentsx->number;
678 amb 554
679 amb 643 for(i=nodesx->number-1;i>=0;i--)
680     if(segmentsx->firstnode[i]==NO_SEGMENT)
681     segmentsx->firstnode[i]=segmentsx->firstnode[i+1];
682    
683 amb 275 /* Print the final message */
684    
685 amb 643 printf_last("Indexed Segments: Segments=%d",segmentsx->number);
686 amb 209 }
687    
688    
689     /*++++++++++++++++++++++++++++++++++++++
690 amb 643 Update the segment indexes after geographical sorting.
691 amb 110
692 amb 643 SegmentsX *segmentsx The list of segments to update.
693 amb 110
694 amb 643 NodesX *nodesx The set of nodes to use.
695    
696     WaysX* waysx The set of ways to use.
697 amb 110 ++++++++++++++++++++++++++++++++++++++*/
698    
699 amb 644 void UpdateSegments(SegmentsX *segmentsx,NodesX *nodesx,WaysX *waysx)
700 amb 110 {
701 amb 214 index_t i;
702 amb 643 int fd;
703 amb 110
704 amb 275 /* Print the start message */
705    
706 amb 643 printf_first("Updating Super Segments: Segments=0");
707 amb 227
708 amb 555 /* Map into memory / open the files */
709 amb 275
710 amb 452 #if !SLIM
711 amb 651 waysx->data=MapFile(waysx->filename);
712 amb 555 #else
713 amb 643 waysx->fd=ReOpenFile(waysx->filename);
714 amb 452 #endif
715 amb 275
716 amb 643 /* Re-open the file read-only and a new file writeable */
717 amb 110
718 amb 643 segmentsx->fd=ReOpenFile(segmentsx->filename);
719 amb 110
720 amb 643 DeleteFile(segmentsx->filename);
721 amb 256
722 amb 643 fd=OpenFileNew(segmentsx->filename);
723 amb 110
724 amb 643 /* Modify the on-disk image */
725 amb 641
726 amb 643 for(i=0;i<segmentsx->number;i++)
727     {
728     SegmentX segmentx;
729     WayX *wayx;
730 amb 448
731 amb 643 ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
732 amb 128
733 amb 643 segmentx.node1=nodesx->gdata[segmentx.node1];
734     segmentx.node2=nodesx->gdata[segmentx.node2];
735 amb 256
736 amb 643 wayx=LookupWayX(waysx,segmentx.way,1);
737 amb 256
738 amb 643 segmentx.way=wayx->prop;
739 amb 110
740 amb 643 WriteFile(fd,&segmentx,sizeof(SegmentX));
741 amb 448
742 amb 110 if(!((i+1)%10000))
743 amb 643 printf_middle("Updating Super Segments: Segments=%d",i+1);
744 amb 110 }
745    
746 amb 643 /* Close the files */
747    
748     segmentsx->fd=CloseFile(segmentsx->fd);
749     CloseFile(fd);
750    
751 amb 555 /* Unmap from memory / close the files */
752 amb 275
753 amb 452 #if !SLIM
754 amb 651 waysx->data=UnmapFile(waysx->filename);
755 amb 555 #else
756 amb 643 waysx->fd=CloseFile(waysx->fd);
757 amb 452 #endif
758 amb 275
759     /* Print the final message */
760    
761 amb 643 printf_last("Updated Super Segments: Segments=%d",segmentsx->number);
762 amb 110 }
763    
764    
765     /*++++++++++++++++++++++++++++++++++++++
766 amb 285 Save the segment list to a file.
767    
768     SegmentsX* segmentsx The set of segments to save.
769    
770     const char *filename The name of the file to save.
771     ++++++++++++++++++++++++++++++++++++++*/
772    
773     void SaveSegmentList(SegmentsX* segmentsx,const char *filename)
774     {
775     index_t i;
776     int fd;
777 amb 500 SegmentsFile segmentsfile={0};
778 amb 285 int super_number=0,normal_number=0;
779    
780     /* Print the start message */
781    
782 amb 519 printf_first("Writing Segments: Segments=0");
783 amb 285
784 amb 558 /* Re-open the file */
785    
786 amb 643 segmentsx->fd=ReOpenFile(segmentsx->filename);
787 amb 558
788 amb 461 /* Write out the segments data */
789 amb 285
790 amb 502 fd=OpenFileNew(filename);
791 amb 461
792     SeekFile(fd,sizeof(SegmentsFile));
793    
794 amb 285 for(i=0;i<segmentsx->number;i++)
795     {
796 amb 643 SegmentX segmentx;
797     Segment segment;
798 amb 448
799 amb 643 ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
800 amb 558
801 amb 643 segment.node1 =segmentx.node1;
802     segment.node2 =segmentx.node2;
803     segment.next2 =segmentx.next2;
804     segment.way =segmentx.way;
805     segment.distance=segmentx.distance;
806    
807 amb 558 if(IsSuperSegment(&segment))
808 amb 285 super_number++;
809 amb 558 if(IsNormalSegment(&segment))
810 amb 285 normal_number++;
811    
812 amb 558 WriteFile(fd,&segment,sizeof(Segment));
813 amb 448
814 amb 285 if(!((i+1)%10000))
815 amb 519 printf_middle("Writing Segments: Segments=%d",i+1);
816 amb 285 }
817    
818 amb 461 /* Write out the header structure */
819    
820     segmentsfile.number=segmentsx->number;
821     segmentsfile.snumber=super_number;
822     segmentsfile.nnumber=normal_number;
823    
824     SeekFile(fd,0);
825     WriteFile(fd,&segmentsfile,sizeof(SegmentsFile));
826    
827 amb 285 CloseFile(fd);
828    
829 amb 558 /* Close the file */
830    
831 amb 643 segmentsx->fd=CloseFile(segmentsx->fd);
832 amb 558
833 amb 285 /* Print the final message */
834    
835 amb 519 printf_last("Wrote Segments: Segments=%d",segmentsx->number);
836 amb 285 }
837    
838    
839     /*++++++++++++++++++++++++++++++++++++++
840 amb 110 Calculate the distance between two nodes.
841    
842     distance_t DistanceX Returns the distance between the extended nodes.
843    
844     NodeX *nodex1 The starting node.
845    
846     NodeX *nodex2 The end node.
847     ++++++++++++++++++++++++++++++++++++++*/
848    
849 amb 228 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2)
850 amb 110 {
851 amb 223 double dlon = latlong_to_radians(nodex1->longitude) - latlong_to_radians(nodex2->longitude);
852     double dlat = latlong_to_radians(nodex1->latitude) - latlong_to_radians(nodex2->latitude);
853     double lat1 = latlong_to_radians(nodex1->latitude);
854     double lat2 = latlong_to_radians(nodex2->latitude);
855 amb 110
856 amb 219 double a1,a2,a,sa,c,d;
857 amb 110
858     if(dlon==0 && dlat==0)
859     return 0;
860    
861 amb 219 a1 = sin (dlat / 2);
862     a2 = sin (dlon / 2);
863     a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2;
864     sa = sqrt (a);
865 amb 110 if (sa <= 1.0)
866 amb 219 {c = 2 * asin (sa);}
867 amb 110 else
868 amb 219 {c = 2 * asin (1.0);}
869 amb 110 d = 6378.137 * c;
870    
871     return km_to_distance(d);
872     }

Properties

Name Value
cvs:description Extended segments functions.