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 557 - (hide annotations) (download) (as text)
Mon Dec 20 19:11:02 2010 UTC (14 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 24728 byte(s)
Make the PutBack*() functions be no-ops in slim mode and remove the
pre-processor guards from around the function calls.

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

Properties

Name Value
cvs:description Extended segments functions.