Routino SVN Repository Browser

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

ViewVC logotype

Contents of /trunk/src/segmentsx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 943 - (show annotations) (download) (as text)
Sun Dec 11 11:17:52 2011 UTC (13 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 22332 byte(s)
Remove the "position" parameter from the NextSegmentX() function.

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

Properties

Name Value
cvs:description Extended segments functions.