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 311 - (hide annotations) (download) (as text)
Sat Dec 12 11:08:50 2009 UTC (15 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 24286 byte(s)
Add some FILESORT_* #defines and use them.

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

Properties

Name Value
cvs:description Extended segments functions.