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 508 - (hide annotations) (download) (as text)
Sun Oct 3 15:02:11 2010 UTC (14 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 23541 byte(s)
Don't try mapping a file if it is zero length (e.g. no super-segments).

1 amb 110 /***************************************
2 amb 508 $Header: /home/amb/CVS/routino/src/segmentsx.c,v 1.67 2010-10-03 15:02:11 amb Exp $
3 amb 110
4     Extended Segment data type functions.
5 amb 151
6     Part of the Routino routing software.
7 amb 110 ******************/ /******************
8 amb 326 This file Copyright 2008-2010 Andrew M. Bishop
9 amb 110
10 amb 151 This program is free software: you can redistribute it and/or modify
11     it under the terms of the GNU Affero General Public License as published by
12     the Free Software Foundation, either version 3 of the License, or
13     (at your option) any later version.
14    
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18     GNU Affero General Public License for more details.
19    
20     You should have received a copy of the GNU Affero General Public License
21     along with this program. If not, see <http://www.gnu.org/licenses/>.
22 amb 110 ***************************************/
23    
24    
25     #include <assert.h>
26     #include <math.h>
27     #include <stdlib.h>
28     #include <stdio.h>
29 amb 256 #include <string.h>
30 amb 326 #include <sys/stat.h>
31 amb 110
32     #include "types.h"
33 amb 228 #include "nodes.h"
34     #include "segments.h"
35     #include "ways.h"
36 amb 110
37 amb 449 #include "nodesx.h"
38     #include "segmentsx.h"
39     #include "waysx.h"
40 amb 110
41 amb 466 #include "types.h"
42    
43 amb 449 #include "files.h"
44     #include "functions.h"
45    
46    
47 amb 256 /* Variables */
48 amb 110
49 amb 289 /*+ The command line '--tmpdir' option or its default value. +*/
50 amb 284 extern char *option_tmpdirname;
51 amb 110
52 amb 228 /* Local Functions */
53 amb 110
54 amb 275 static int sort_by_id(SegmentX *a,SegmentX *b);
55    
56 amb 228 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2);
57 amb 110
58    
59     /*++++++++++++++++++++++++++++++++++++++
60 amb 326 Allocate a new segment list (create a new file or open an existing one).
61 amb 110
62     SegmentsX *NewSegmentList Returns the segment list.
63 amb 326
64     int append Set to 1 if the file is to be opened for appending (now or later).
65 amb 110 ++++++++++++++++++++++++++++++++++++++*/
66    
67 amb 326 SegmentsX *NewSegmentList(int append)
68 amb 110 {
69     SegmentsX *segmentsx;
70    
71 amb 213 segmentsx=(SegmentsX*)calloc(1,sizeof(SegmentsX));
72 amb 110
73 amb 243 assert(segmentsx); /* Check calloc() worked */
74    
75 amb 284 segmentsx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
76 amb 216
77 amb 326 if(append)
78 amb 447 sprintf(segmentsx->filename,"%s/segmentsx.input.tmp",option_tmpdirname);
79 amb 326 else
80 amb 447 sprintf(segmentsx->filename,"%s/segmentsx.%p.tmp",option_tmpdirname,segmentsx);
81 amb 256
82 amb 452 #if SLIM
83 amb 448 segmentsx->sfilename=(char*)malloc(strlen(option_tmpdirname)+32);
84    
85     sprintf(segmentsx->sfilename,"%s/segments.%p.tmp",option_tmpdirname,segmentsx);
86 amb 452 #endif
87 amb 448
88 amb 326 if(append)
89     {
90 amb 331 off_t size;
91 amb 326
92 amb 502 segmentsx->fd=OpenFileAppend(segmentsx->filename);
93 amb 326
94 amb 331 size=SizeFile(segmentsx->filename);
95 amb 326
96 amb 331 segmentsx->xnumber=size/sizeof(SegmentX);
97 amb 326 }
98     else
99 amb 502 segmentsx->fd=OpenFileNew(segmentsx->filename);
100 amb 326
101 amb 110 return(segmentsx);
102     }
103    
104    
105     /*++++++++++++++++++++++++++++++++++++++
106 amb 226 Free a segment list.
107 amb 110
108     SegmentsX *segmentsx The list to be freed.
109 amb 326
110     int keep Set to 1 if the file is to be kept.
111 amb 110 ++++++++++++++++++++++++++++++++++++++*/
112    
113 amb 326 void FreeSegmentList(SegmentsX *segmentsx,int keep)
114 amb 110 {
115 amb 326 if(!keep)
116     DeleteFile(segmentsx->filename);
117    
118 amb 283 free(segmentsx->filename);
119 amb 256
120 amb 275 if(segmentsx->idata)
121     free(segmentsx->idata);
122 amb 226
123 amb 279 if(segmentsx->firstnode)
124     free(segmentsx->firstnode);
125    
126 amb 452 #if !SLIM
127 amb 226 if(segmentsx->sdata)
128     free(segmentsx->sdata);
129 amb 452 #endif
130 amb 226
131 amb 452 #if SLIM
132 amb 448 DeleteFile(segmentsx->sfilename);
133    
134     free(segmentsx->sfilename);
135 amb 452 #endif
136 amb 448
137 amb 110 free(segmentsx);
138     }
139    
140    
141     /*++++++++++++++++++++++++++++++++++++++
142 amb 493 Append a single segment to an unsorted segment list.
143 amb 110
144 amb 285 SegmentsX* segmentsx The set of segments to process.
145 amb 110
146 amb 285 way_t way The way that the segment belongs to.
147    
148     node_t node1 The first node in the segment.
149    
150     node_t node2 The second node in the segment.
151    
152     distance_t distance The distance between the nodes (or just the flags).
153 amb 110 ++++++++++++++++++++++++++++++++++++++*/
154    
155 amb 285 void AppendSegment(SegmentsX* segmentsx,way_t way,node_t node1,node_t node2,distance_t distance)
156 amb 110 {
157 amb 285 SegmentX segmentx;
158 amb 110
159 amb 285 segmentx.node1=node1;
160     segmentx.node2=node2;
161     segmentx.way=way;
162     segmentx.distance=distance;
163 amb 110
164 amb 285 WriteFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
165 amb 281
166 amb 285 segmentsx->xnumber++;
167 amb 466
168 amb 471 assert(segmentsx->xnumber<SEGMENT_FAKE); /* SEGMENT_FAKE marks the high-water mark for real segments. */
169 amb 285 }
170 amb 227
171 amb 281
172 amb 285 /*++++++++++++++++++++++++++++++++++++++
173     Sort the segment list.
174 amb 232
175 amb 285 SegmentsX* segmentsx The set of segments to process.
176     ++++++++++++++++++++++++++++++++++++++*/
177 amb 110
178 amb 285 void SortSegmentList(SegmentsX* segmentsx)
179     {
180     int fd;
181 amb 243
182 amb 504 if(segmentsx->xnumber==0)
183     return;
184    
185 amb 285 /* Print the start message */
186 amb 232
187 amb 285 printf("Sorting Segments");
188     fflush(stdout);
189 amb 110
190 amb 285 /* Close the files and re-open them (finished appending) */
191 amb 110
192 amb 285 CloseFile(segmentsx->fd);
193     segmentsx->fd=ReOpenFile(segmentsx->filename);
194 amb 110
195 amb 285 DeleteFile(segmentsx->filename);
196 amb 110
197 amb 502 fd=OpenFileNew(segmentsx->filename);
198 amb 110
199 amb 285 /* Sort by node indexes */
200 amb 132
201 amb 311 filesort_fixed(segmentsx->fd,fd,sizeof(SegmentX),(int (*)(const void*,const void*))sort_by_id,NULL);
202 amb 285
203     segmentsx->number=segmentsx->xnumber;
204    
205     /* Close the files and re-open them */
206    
207     CloseFile(segmentsx->fd);
208 amb 281 CloseFile(fd);
209    
210 amb 285 segmentsx->fd=ReOpenFile(segmentsx->filename);
211    
212 amb 281 /* Print the final message */
213    
214 amb 285 printf("\rSorted Segments: Segments=%d\n",segmentsx->xnumber);
215 amb 132 fflush(stdout);
216 amb 110 }
217    
218    
219     /*++++++++++++++++++++++++++++++++++++++
220 amb 285 Sort the segments into id order (node1 then node2).
221 amb 110
222 amb 285 int sort_by_id Returns the comparison of the node fields.
223 amb 110
224 amb 285 SegmentX *a The first segment.
225 amb 110
226 amb 285 SegmentX *b The second segment.
227 amb 256 ++++++++++++++++++++++++++++++++++++++*/
228    
229 amb 285 static int sort_by_id(SegmentX *a,SegmentX *b)
230 amb 256 {
231 amb 285 node_t a_id1=a->node1;
232     node_t b_id1=b->node1;
233 amb 256
234 amb 285 if(a_id1<b_id1)
235     return(-1);
236     else if(a_id1>b_id1)
237     return(1);
238     else /* if(a_id1==b_id1) */
239 amb 256 {
240 amb 285 node_t a_id2=a->node2;
241     node_t b_id2=b->node2;
242 amb 256
243 amb 285 if(a_id2<b_id2)
244     return(-1);
245     else if(a_id2>b_id2)
246     return(1);
247     else
248     {
249     distance_t a_distance=a->distance;
250     distance_t b_distance=b->distance;
251 amb 256
252 amb 285 if(a_distance<b_distance)
253     return(-1);
254     else if(a_distance>b_distance)
255     return(1);
256     else
257     return(0);
258     }
259 amb 256 }
260     }
261    
262    
263     /*++++++++++++++++++++++++++++++++++++++
264 amb 275 Find the first segment index with a particular starting node.
265 amb 257
266 amb 275 index_t IndexFirstSegmentX Returns a pointer to the index of the first extended segment with the specified id.
267 amb 256
268     SegmentsX* segmentsx The set of segments to process.
269    
270 amb 110 node_t node The node to look for.
271     ++++++++++++++++++++++++++++++++++++++*/
272    
273 amb 275 index_t IndexFirstSegmentX(SegmentsX* segmentsx,node_t node)
274 amb 110 {
275     int start=0;
276     int end=segmentsx->number-1;
277     int mid;
278     int found;
279    
280 amb 280 /* Check if the first node index exists */
281    
282 amb 279 if(segmentsx->firstnode)
283     {
284     index_t index=segmentsx->firstnode[node];
285    
286     if(segmentsx->firstnode[node+1]==index)
287     return(NO_SEGMENT);
288    
289     return(index);
290     }
291    
292 amb 110 /* Binary search - search key exact match only is required.
293     *
294     * # <- start | Check mid and move start or end if it doesn't match
295     * # |
296     * # | Since an exact match is wanted we can set end=mid-1
297     * # <- mid | or start=mid+1 because we know that mid doesn't match.
298     * # |
299     * # | Eventually either end=start or end=start+1 and one of
300     * # <- end | start or end is the wanted one.
301     */
302    
303 amb 275 if(end<start) /* There are no nodes */
304     return(NO_SEGMENT);
305     else if(node<segmentsx->idata[start]) /* Check key is not before start */
306     return(NO_SEGMENT);
307     else if(node>segmentsx->idata[end]) /* Check key is not after end */
308     return(NO_SEGMENT);
309 amb 257 else
310 amb 110 {
311 amb 257 do
312     {
313 amb 275 mid=(start+end)/2; /* Choose mid point */
314 amb 110
315 amb 275 if(segmentsx->idata[mid]<node) /* Mid point is too low */
316 amb 257 start=mid;
317 amb 275 else if(segmentsx->idata[mid]>node) /* Mid point is too high */
318 amb 257 end=mid;
319 amb 275 else /* Mid point is correct */
320 amb 257 {found=mid; goto found;}
321     }
322     while((end-start)>1);
323 amb 110
324 amb 275 if(segmentsx->idata[start]==node) /* Start is correct */
325 amb 257 {found=start; goto found;}
326    
327 amb 275 if(segmentsx->idata[end]==node) /* End is correct */
328 amb 257 {found=end; goto found;}
329 amb 110 }
330    
331 amb 275 return(NO_SEGMENT);
332 amb 110
333     found:
334    
335 amb 275 while(found>0 && segmentsx->idata[found-1]==node)
336 amb 110 found--;
337    
338 amb 275 return(found);
339 amb 110 }
340    
341    
342     /*++++++++++++++++++++++++++++++++++++++
343 amb 257 Find the next segment index with a particular starting node.
344 amb 110
345 amb 275 index_t IndexNextSegmentX Returns the index of the next segment with the same id.
346 amb 110
347     SegmentsX* segmentsx The set of segments to process.
348    
349 amb 279 index_t segindex The current segment index.
350    
351     index_t nodeindex The node index.
352 amb 110 ++++++++++++++++++++++++++++++++++++++*/
353    
354 amb 279 index_t IndexNextSegmentX(SegmentsX* segmentsx,index_t segindex,index_t nodeindex)
355 amb 110 {
356 amb 279 if(++segindex==segmentsx->firstnode[nodeindex+1])
357 amb 275 return(NO_SEGMENT);
358 amb 229 else
359 amb 279 return(segindex);
360 amb 110 }
361    
362    
363     /*++++++++++++++++++++++++++++++++++++++
364 amb 275 Remove bad segments (duplicated, zero length or missing nodes).
365 amb 110
366 amb 195 NodesX *nodesx The nodes to check.
367    
368 amb 110 SegmentsX *segmentsx The segments to modify.
369     ++++++++++++++++++++++++++++++++++++++*/
370    
371 amb 204 void RemoveBadSegments(NodesX *nodesx,SegmentsX *segmentsx)
372 amb 110 {
373 amb 275 int duplicate=0,loop=0,missing=0,good=0,total=0;
374     SegmentX segmentx;
375     int fd;
376     node_t prevnode1=NO_NODE,prevnode2=NO_NODE;
377 amb 110
378 amb 275 /* Print the start message */
379    
380 amb 227 printf("Checking: Segments=0 Duplicate=0 Loop=0 Missing-Node=0");
381     fflush(stdout);
382    
383 amb 279 /* Allocate the array of indexes */
384    
385     segmentsx->idata=(node_t*)malloc(segmentsx->xnumber*sizeof(node_t));
386    
387     assert(segmentsx->idata); /* Check malloc() worked */
388    
389 amb 275 /* Modify the on-disk image */
390    
391     DeleteFile(segmentsx->filename);
392    
393 amb 502 fd=OpenFileNew(segmentsx->filename);
394 amb 275 SeekFile(segmentsx->fd,0);
395    
396     while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
397 amb 110 {
398 amb 275 if(prevnode1==segmentx.node1 && prevnode2==segmentx.node2)
399     duplicate++;
400     else if(segmentx.node1==segmentx.node2)
401 amb 257 loop++;
402 amb 275 else if(IndexNodeX(nodesx,segmentx.node1)==NO_NODE ||
403     IndexNodeX(nodesx,segmentx.node2)==NO_NODE)
404     missing++;
405     else
406 amb 257 {
407 amb 275 WriteFile(fd,&segmentx,sizeof(SegmentX));
408    
409 amb 279 segmentsx->idata[good]=segmentx.node1;
410 amb 275 good++;
411    
412     prevnode1=segmentx.node1;
413     prevnode2=segmentx.node2;
414 amb 110 }
415    
416 amb 275 total++;
417 amb 256
418 amb 275 if(!(total%10000))
419 amb 110 {
420 amb 275 printf("\rChecking: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d",total,duplicate,loop,missing);
421 amb 110 fflush(stdout);
422     }
423     }
424    
425 amb 275 /* Close the files and re-open them */
426    
427     CloseFile(segmentsx->fd);
428     CloseFile(fd);
429    
430     segmentsx->fd=ReOpenFile(segmentsx->filename);
431    
432     segmentsx->number=good;
433    
434     /* Print the final message */
435    
436     printf("\rChecked: Segments=%d Duplicate=%d Loop=%d Missing-Node=%d \n",total,duplicate,loop,missing);
437 amb 110 fflush(stdout);
438     }
439    
440    
441     /*++++++++++++++++++++++++++++++++++++++
442 amb 285 Measure the segments and replace node/way ids with indexes.
443 amb 110
444     SegmentsX* segmentsx The set of segments to process.
445    
446     NodesX *nodesx The list of nodes to use.
447 amb 279
448     WaysX *waysx The list of ways to use.
449 amb 110 ++++++++++++++++++++++++++++++++++++++*/
450    
451 amb 279 void UpdateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
452 amb 110 {
453 amb 279 index_t index=0;
454     int i,fd;
455 amb 256 SegmentX segmentx;
456 amb 110
457 amb 275 /* Print the start message */
458    
459 amb 227 printf("Measuring Segments: Segments=0");
460     fflush(stdout);
461    
462 amb 275 /* Map into memory */
463 amb 257
464 amb 452 #if !SLIM
465     nodesx->xdata=MapFile(nodesx->filename);
466     #endif
467 amb 258
468 amb 280 /* Free the now-unneeded index */
469    
470     free(segmentsx->idata);
471     segmentsx->idata=NULL;
472    
473 amb 279 /* Allocate the array of indexes */
474    
475     segmentsx->firstnode=(index_t*)malloc((nodesx->number+1)*sizeof(index_t));
476    
477     assert(segmentsx->firstnode); /* Check malloc() worked */
478    
479     for(i=0;i<nodesx->number;i++)
480     segmentsx->firstnode[i]=NO_SEGMENT;
481    
482     segmentsx->firstnode[nodesx->number]=segmentsx->number;
483    
484 amb 275 /* Modify the on-disk image */
485    
486 amb 256 DeleteFile(segmentsx->filename);
487    
488 amb 502 fd=OpenFileNew(segmentsx->filename);
489 amb 256 SeekFile(segmentsx->fd,0);
490    
491     while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
492 amb 110 {
493 amb 279 index_t node1=IndexNodeX(nodesx,segmentx.node1);
494     index_t node2=IndexNodeX(nodesx,segmentx.node2);
495     index_t way =IndexWayX (waysx ,segmentx.way);
496 amb 110
497 amb 279 NodeX *nodex1=LookupNodeX(nodesx,node1,1);
498     NodeX *nodex2=LookupNodeX(nodesx,node2,2);
499    
500     /* Replace the node and way ids with their indexes */
501    
502     segmentx.node1=node1;
503     segmentx.node2=node2;
504     segmentx.way =way;
505    
506 amb 275 /* Set the distance but preserve the ONEWAY_* flags */
507    
508     segmentx.distance|=DISTANCE(DistanceX(nodex1,nodex2));
509    
510 amb 279 /* Set the first segment index in the nodes */
511    
512     if(index<segmentsx->firstnode[node1])
513     segmentsx->firstnode[node1]=index;
514    
515     /* Write the modified segment */
516    
517 amb 275 WriteFile(fd,&segmentx,sizeof(SegmentX));
518    
519 amb 279 index++;
520 amb 275
521 amb 279 if(!(index%10000))
522 amb 257 {
523 amb 279 printf("\rMeasuring Segments: Segments=%d",index);
524 amb 275 fflush(stdout);
525     }
526     }
527 amb 110
528 amb 275 /* Close the files and re-open them */
529 amb 257
530 amb 275 CloseFile(segmentsx->fd);
531     CloseFile(fd);
532    
533     segmentsx->fd=ReOpenFile(segmentsx->filename);
534    
535 amb 280 /* Free the other now-unneeded indexes */
536 amb 279
537     free(nodesx->idata);
538     nodesx->idata=NULL;
539    
540     free(waysx->idata);
541     waysx->idata=NULL;
542    
543 amb 275 /* Unmap from memory */
544    
545 amb 452 #if !SLIM
546     nodesx->xdata=UnmapFile(nodesx->filename);
547     #endif
548 amb 275
549     /* Print the final message */
550    
551     printf("\rMeasured Segments: Segments=%d \n",segmentsx->number);
552     fflush(stdout);
553     }
554    
555    
556     /*++++++++++++++++++++++++++++++++++++++
557     Make the segments all point the same way (node1<node2).
558    
559     SegmentsX* segmentsx The set of segments to process.
560     ++++++++++++++++++++++++++++++++++++++*/
561    
562     void RotateSegments(SegmentsX* segmentsx)
563     {
564     int index=0,rotated=0;
565     int fd;
566     SegmentX segmentx;
567    
568     /* Print the start message */
569    
570     printf("Rotating Segments: Segments=0 Rotated=0");
571     fflush(stdout);
572    
573     /* Close the files and re-open them (finished appending) */
574    
575     CloseFile(segmentsx->fd);
576     segmentsx->fd=ReOpenFile(segmentsx->filename);
577    
578     DeleteFile(segmentsx->filename);
579    
580 amb 502 fd=OpenFileNew(segmentsx->filename);
581 amb 275
582     /* Modify the file contents */
583    
584     while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
585     {
586     if(segmentx.node1>segmentx.node2)
587     {
588     node_t temp;
589    
590     temp=segmentx.node1;
591     segmentx.node1=segmentx.node2;
592     segmentx.node2=temp;
593    
594     if(segmentx.distance&(ONEWAY_2TO1|ONEWAY_1TO2))
595     segmentx.distance^=ONEWAY_2TO1|ONEWAY_1TO2;
596    
597     rotated++;
598 amb 257 }
599 amb 110
600 amb 256 WriteFile(fd,&segmentx,sizeof(SegmentX));
601    
602 amb 275 index++;
603 amb 256
604 amb 275 if(!(index%10000))
605 amb 110 {
606 amb 275 printf("\rRotating Segments: Segments=%d Rotated=%d",index,rotated);
607 amb 110 fflush(stdout);
608     }
609     }
610    
611 amb 275 /* Close the files and re-open them */
612    
613 amb 256 CloseFile(segmentsx->fd);
614     CloseFile(fd);
615    
616     segmentsx->fd=ReOpenFile(segmentsx->filename);
617    
618 amb 275 /* Print the final message */
619 amb 256
620 amb 275 printf("\rRotated Segments: Segments=%d Rotated=%d \n",index,rotated);
621 amb 110 fflush(stdout);
622     }
623    
624    
625     /*++++++++++++++++++++++++++++++++++++++
626 amb 275 Remove the duplicate segments.
627 amb 110
628     SegmentsX* segmentsx The set of segments to process.
629    
630 amb 279 NodesX *nodesx The list of nodes to use.
631    
632 amb 110 WaysX *waysx The list of ways to use.
633     ++++++++++++++++++++++++++++++++++++++*/
634    
635 amb 279 void DeduplicateSegments(SegmentsX* segmentsx,NodesX *nodesx,WaysX *waysx)
636 amb 110 {
637 amb 275 int duplicate=0,good=0;
638     index_t firstindex=0,index=0;
639 amb 279 int i,fd;
640 amb 275 SegmentX prevsegmentx[16],segmentx;
641 amb 110
642 amb 275 /* Print the start message */
643    
644 amb 227 printf("Deduplicating Segments: Segments=0 Duplicate=0");
645     fflush(stdout);
646    
647 amb 275 /* Map into memory */
648 amb 256
649 amb 452 #if !SLIM
650     waysx->xdata=MapFile(waysx->filename);
651     #endif
652 amb 275
653 amb 279 /* Allocate the array of indexes */
654    
655     segmentsx->firstnode=(index_t*)malloc((nodesx->number+1)*sizeof(index_t));
656    
657     assert(segmentsx->firstnode); /* Check malloc() worked */
658    
659     for(i=0;i<nodesx->number;i++)
660     segmentsx->firstnode[i]=NO_SEGMENT;
661    
662     segmentsx->firstnode[nodesx->number]=segmentsx->number;
663    
664 amb 275 /* Modify the on-disk image */
665    
666     DeleteFile(segmentsx->filename);
667    
668 amb 502 fd=OpenFileNew(segmentsx->filename);
669 amb 275 SeekFile(segmentsx->fd,0);
670    
671     while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
672 amb 110 {
673 amb 275 int isduplicate=0;
674 amb 256
675 amb 275 if(index && segmentx.node1==prevsegmentx[0].node1 &&
676     segmentx.node2==prevsegmentx[0].node2)
677 amb 110 {
678 amb 264 index_t previndex=firstindex;
679 amb 110
680 amb 275 while(previndex<index)
681 amb 110 {
682 amb 275 int offset=previndex-firstindex;
683    
684     if(DISTFLAG(segmentx.distance)==DISTFLAG(prevsegmentx[offset].distance))
685 amb 264 {
686 amb 279 WayX *wayx1=LookupWayX(waysx,prevsegmentx[offset].way,1);
687     WayX *wayx2=LookupWayX(waysx, segmentx .way,2);
688 amb 110
689 amb 275 if(!WaysCompare(&wayx1->way,&wayx2->way))
690 amb 264 {
691 amb 275 isduplicate=1;
692     duplicate++;
693     break;
694 amb 264 }
695     }
696    
697     previndex++;
698 amb 110 }
699 amb 275
700     assert((index-firstindex)<(sizeof(prevsegmentx)/sizeof(prevsegmentx[0])));
701    
702     prevsegmentx[index-firstindex]=segmentx;
703 amb 110 }
704 amb 264 else
705     {
706 amb 275 firstindex=index;
707     prevsegmentx[0]=segmentx;
708 amb 264 }
709 amb 110
710 amb 275 if(!isduplicate)
711 amb 110 {
712 amb 275 WriteFile(fd,&segmentx,sizeof(SegmentX));
713    
714 amb 279 if(good<segmentsx->firstnode[segmentx.node1])
715     segmentsx->firstnode[segmentx.node1]=good;
716    
717 amb 275 good++;
718     }
719    
720     index++;
721    
722     if(!(index%10000))
723     {
724     printf("\rDeduplicating Segments: Segments=%d Duplicate=%d",index,duplicate);
725 amb 110 fflush(stdout);
726     }
727     }
728    
729 amb 275 /* Close the files and re-open them */
730    
731     CloseFile(segmentsx->fd);
732     CloseFile(fd);
733    
734     segmentsx->fd=ReOpenFile(segmentsx->filename);
735    
736 amb 279 segmentsx->number=good;
737 amb 275
738 amb 279 /* Fix-up the firstnode index for the missing nodes */
739 amb 275
740 amb 279 for(i=nodesx->number-1;i>=0;i--)
741     if(segmentsx->firstnode[i]==NO_SEGMENT)
742     segmentsx->firstnode[i]=segmentsx->firstnode[i+1];
743 amb 275
744     /* Unmap from memory */
745    
746 amb 452 #if !SLIM
747     waysx->xdata=UnmapFile(waysx->filename);
748     #endif
749 amb 275
750     /* Print the final message */
751    
752     printf("\rDeduplicated Segments: Segments=%d Duplicate=%d Unique=%d\n",index,duplicate,index-duplicate);
753 amb 110 fflush(stdout);
754     }
755    
756    
757     /*++++++++++++++++++++++++++++++++++++++
758 amb 209 Create the real segments data.
759    
760     SegmentsX* segmentsx The set of segments to use.
761    
762     WaysX* waysx The set of ways to use.
763     ++++++++++++++++++++++++++++++++++++++*/
764    
765     void CreateRealSegments(SegmentsX *segmentsx,WaysX *waysx)
766     {
767 amb 214 index_t i;
768 amb 209
769 amb 508 if(segmentsx->xnumber==0 || waysx->xnumber)
770     return;
771    
772 amb 275 /* Print the start message */
773    
774 amb 227 printf("Creating Real Segments: Segments=0");
775     fflush(stdout);
776    
777 amb 275 /* Map into memory */
778 amb 209
779 amb 452 #if !SLIM
780     segmentsx->xdata=MapFile(segmentsx->filename);
781     waysx->xdata=MapFile(waysx->filename);
782     #endif
783 amb 275
784 amb 280 /* Free the unneeded memory */
785    
786     free(segmentsx->firstnode);
787     segmentsx->firstnode=NULL;
788    
789 amb 448 /* Allocate the memory (or open the file) */
790 amb 275
791 amb 452 #if !SLIM
792     segmentsx->sdata=(Segment*)malloc(segmentsx->number*sizeof(Segment));
793 amb 209
794 amb 452 assert(segmentsx->sdata); /* Check malloc() worked */
795     #else
796 amb 502 segmentsx->sfd=OpenFileNew(segmentsx->sfilename);
797 amb 452 #endif
798 amb 243
799 amb 275 /* Loop through and fill */
800 amb 209
801     for(i=0;i<segmentsx->number;i++)
802     {
803 amb 275 SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
804 amb 448 Segment *segment =LookupSegmentXSegment(segmentsx,i,1);
805     WayX *wayx=LookupWayX(waysx,segmentx->way,1);
806 amb 209
807 amb 448 segment->node1=0;
808     segment->node2=0;
809     segment->next2=NO_NODE;
810     segment->way=wayx->prop;
811     segment->distance=segmentx->distance;
812 amb 209
813 amb 452 #if SLIM
814     PutBackSegmentXSegment(segmentsx,i,1);
815     #endif
816 amb 448
817 amb 209 if(!((i+1)%10000))
818     {
819     printf("\rCreating Real Segments: Segments=%d",i+1);
820     fflush(stdout);
821     }
822     }
823    
824 amb 275 /* Unmap from memory */
825    
826 amb 452 #if !SLIM
827     segmentsx->xdata=UnmapFile(segmentsx->filename);
828     waysx->xdata=UnmapFile(waysx->filename);
829     #endif
830 amb 275
831     /* Print the final message */
832    
833 amb 209 printf("\rCreating Real Segments: Segments=%d \n",segmentsx->number);
834     fflush(stdout);
835     }
836    
837    
838     /*++++++++++++++++++++++++++++++++++++++
839 amb 110 Assign the nodes indexes to the segments.
840    
841     SegmentsX* segmentsx The set of segments to process.
842    
843     NodesX *nodesx The list of nodes to use.
844     ++++++++++++++++++++++++++++++++++++++*/
845    
846     void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx)
847     {
848 amb 214 index_t i;
849 amb 110
850 amb 508 if(nodesx->number==0 || segmentsx->xnumber==0)
851     return;
852    
853 amb 275 /* Print the start message */
854    
855 amb 227 printf("Indexing Nodes: Nodes=0");
856     fflush(stdout);
857    
858 amb 275 /* Map into memory */
859    
860 amb 452 #if !SLIM
861     nodesx->xdata=MapFile(nodesx->filename);
862     segmentsx->xdata=MapFile(segmentsx->filename);
863     #endif
864 amb 275
865 amb 110 /* Index the segments */
866    
867     for(i=0;i<nodesx->number;i++)
868     {
869 amb 281 NodeX *nodex=LookupNodeX(nodesx,i,1);
870 amb 448 Node *node =LookupNodeXNode(nodesx,nodex->id,1);
871 amb 467 index_t index=node->firstseg;
872 amb 110
873     do
874     {
875 amb 275 SegmentX *segmentx=LookupSegmentX(segmentsx,index,1);
876 amb 448 Segment *segment =LookupSegmentXSegment(segmentsx,index,1);
877 amb 256
878 amb 281 if(segmentx->node1==nodex->id)
879 amb 110 {
880 amb 448 segment->node1=i;
881 amb 110
882 amb 452 #if SLIM
883 amb 448 PutBackSegmentXSegment(segmentsx,index,1);
884 amb 452 #endif
885 amb 448
886 amb 209 index++;
887 amb 128
888 amb 256 if(index>=segmentsx->number)
889 amb 209 break;
890 amb 256
891 amb 275 segmentx=LookupSegmentX(segmentsx,index,1);
892 amb 256
893 amb 281 if(segmentx->node1!=nodex->id)
894 amb 256 break;
895 amb 110 }
896     else
897     {
898 amb 448 segment->node2=i;
899 amb 110
900 amb 452 #if SLIM
901 amb 448 PutBackSegmentXSegment(segmentsx,index,1);
902 amb 452 #endif
903 amb 448
904     if(segment->next2==NO_NODE)
905 amb 209 break;
906 amb 110 else
907 amb 448 index=segment->next2;
908 amb 110 }
909     }
910 amb 209 while(1);
911 amb 110
912     if(!((i+1)%10000))
913     {
914     printf("\rIndexing Nodes: Nodes=%d",i+1);
915     fflush(stdout);
916     }
917     }
918    
919 amb 275 /* Unmap from memory */
920    
921 amb 452 #if !SLIM
922     nodesx->xdata=UnmapFile(nodesx->filename);
923     segmentsx->xdata=UnmapFile(segmentsx->filename);
924     #endif
925 amb 275
926     /* Print the final message */
927    
928 amb 110 printf("\rIndexed Nodes: Nodes=%d \n",nodesx->number);
929     fflush(stdout);
930     }
931    
932    
933     /*++++++++++++++++++++++++++++++++++++++
934 amb 285 Save the segment list to a file.
935    
936     SegmentsX* segmentsx The set of segments to save.
937    
938     const char *filename The name of the file to save.
939     ++++++++++++++++++++++++++++++++++++++*/
940    
941     void SaveSegmentList(SegmentsX* segmentsx,const char *filename)
942     {
943     index_t i;
944     int fd;
945 amb 500 SegmentsFile segmentsfile={0};
946 amb 285 int super_number=0,normal_number=0;
947    
948     /* Print the start message */
949    
950     printf("Writing Segments: Segments=0");
951     fflush(stdout);
952    
953 amb 461 /* Write out the segments data */
954 amb 285
955 amb 502 fd=OpenFileNew(filename);
956 amb 461
957     SeekFile(fd,sizeof(SegmentsFile));
958    
959 amb 285 for(i=0;i<segmentsx->number;i++)
960     {
961 amb 448 Segment *segment=LookupSegmentXSegment(segmentsx,i,1);
962    
963     if(IsSuperSegment(segment))
964 amb 285 super_number++;
965 amb 448 if(IsNormalSegment(segment))
966 amb 285 normal_number++;
967    
968 amb 448 WriteFile(fd,segment,sizeof(Segment));
969    
970 amb 285 if(!((i+1)%10000))
971     {
972     printf("\rWriting Segments: Segments=%d",i+1);
973     fflush(stdout);
974     }
975     }
976    
977 amb 461 /* Write out the header structure */
978    
979     segmentsfile.number=segmentsx->number;
980     segmentsfile.snumber=super_number;
981     segmentsfile.nnumber=normal_number;
982    
983     SeekFile(fd,0);
984     WriteFile(fd,&segmentsfile,sizeof(SegmentsFile));
985    
986 amb 285 CloseFile(fd);
987    
988     /* Print the final message */
989    
990 amb 461 printf("\rWrote Segments: Segments=%d \n",segmentsx->number);
991 amb 285 fflush(stdout);
992     }
993    
994    
995     /*++++++++++++++++++++++++++++++++++++++
996 amb 110 Calculate the distance between two nodes.
997    
998     distance_t DistanceX Returns the distance between the extended nodes.
999    
1000     NodeX *nodex1 The starting node.
1001    
1002     NodeX *nodex2 The end node.
1003     ++++++++++++++++++++++++++++++++++++++*/
1004    
1005 amb 228 static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2)
1006 amb 110 {
1007 amb 223 double dlon = latlong_to_radians(nodex1->longitude) - latlong_to_radians(nodex2->longitude);
1008     double dlat = latlong_to_radians(nodex1->latitude) - latlong_to_radians(nodex2->latitude);
1009     double lat1 = latlong_to_radians(nodex1->latitude);
1010     double lat2 = latlong_to_radians(nodex2->latitude);
1011 amb 110
1012 amb 219 double a1,a2,a,sa,c,d;
1013 amb 110
1014     if(dlon==0 && dlat==0)
1015     return 0;
1016    
1017 amb 219 a1 = sin (dlat / 2);
1018     a2 = sin (dlon / 2);
1019     a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2;
1020     sa = sqrt (a);
1021 amb 110 if (sa <= 1.0)
1022 amb 219 {c = 2 * asin (sa);}
1023 amb 110 else
1024 amb 219 {c = 2 * asin (1.0);}
1025 amb 110 d = 6378.137 * c;
1026    
1027     return km_to_distance(d);
1028     }

Properties

Name Value
cvs:description Extended segments functions.