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 1350 - (hide annotations) (download) (as text)
Thu May 30 16:53:27 2013 UTC (11 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 27535 byte(s)
Delete the non-highway nodes by searching for them in the ways rather than
marking them when processing the segments.

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

Properties

Name Value
cvs:description Extended segments functions.