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 280 - (hide annotations) (download) (as text)
Fri Oct 9 18:47:40 2009 UTC (15 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 23950 byte(s)
Free the nodesx->super array and the segmentsx->firstnode array when finished
with them.  Remove wayx->cid and overwrite wayx->id instead.  Overwrite
nodex[i]->id=i for later geographically sorted use.

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

Properties

Name Value
cvs:description Extended segments functions.