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 1115 - (hide annotations) (download) (as text)
Wed Oct 24 08:12:55 2012 UTC (12 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 25518 byte(s)
Remove a debugging print statement.

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

Properties

Name Value
cvs:description Extended segments functions.