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 812 - (hide annotations) (download) (as text)
Thu Jul 21 18:44:52 2011 UTC (13 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 21588 byte(s)
Add logging of parsing and processing errors.

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

Properties

Name Value
cvs:description Extended segments functions.