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 554 - (hide annotations) (download) (as text)
Mon Dec 20 17:54:31 2010 UTC (14 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 24184 byte(s)
Make the last two changes work for slim mode.

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