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 641 - (hide annotations) (download) (as text)
Thu Feb 24 18:35:29 2011 UTC (14 years ago) by amb
File MIME type: text/x-csrc
File size: 24894 byte(s)
Create super-segments that go in loops and preserve all such loops.

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

Properties

Name Value
cvs:description Extended segments functions.