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 284 - (hide annotations) (download) (as text)
Mon Oct 12 17:35:26 2009 UTC (15 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 24237 byte(s)
Rename the tmpdirname variable.

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

Properties

Name Value
cvs:description Extended segments functions.