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 466 - (hide annotations) (download) (as text)
Sat Jul 31 14:56:17 2010 UTC (14 years, 7 months ago) by amb
File MIME type: text/x-csrc
File size: 23353 byte(s)
Assert if the number of nodes, segments or ways exceeds the legal range of the
index counters.

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

Properties

Name Value
cvs:description Extended segments functions.