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 1098 - (hide annotations) (download) (as text)
Sat Oct 20 12:52:01 2012 UTC (12 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 23556 byte(s)
Delete the pruned nodes before searching for super-nodes etc.

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

Properties

Name Value
cvs:description Extended segments functions.