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 519 - (hide annotations) (download) (as text)
Sat Nov 13 14:22:28 2010 UTC (14 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 23100 byte(s)
Add an option to make the output more suitable for a log file.

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

Properties

Name Value
cvs:description Extended segments functions.