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 1106 - (hide annotations) (download) (as text)
Sun Oct 21 15:55:48 2012 UTC (12 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 25433 byte(s)
Change the sorting functions to have a pre-sort and post-sort selection function
instead of just a post-selection one (this will allow deletion of some items
before sorting instead of after sorting in some cases).

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