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 1137 - (hide annotations) (download) (as text)
Sun Nov 11 16:05:10 2012 UTC (12 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 27430 byte(s)
Mark those segments that come from ways which are areas with an explicit flag
rather than an implicit one (also fixes a bug).

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

Properties

Name Value
cvs:description Extended segments functions.