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/segments.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1164 - (hide annotations) (download) (as text)
Tue Nov 20 15:24:30 2012 UTC (12 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 8513 byte(s)
Replace the 32-bit combined distance and flags in the segment with 16 bits for
each.

1 amb 2 /***************************************
2     Segment data type functions.
3 amb 151
4     Part of the Routino routing software.
5 amb 2 ******************/ /******************
6 amb 955 This file Copyright 2008-2012 Andrew M. Bishop
7 amb 2
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 2 ***************************************/
21    
22    
23     #include <stdlib.h>
24 amb 669 #include <math.h>
25 amb 2
26 amb 109 #include "types.h"
27 amb 39 #include "nodes.h"
28 amb 26 #include "segments.h"
29 amb 109 #include "ways.h"
30 amb 955
31 amb 672 #include "fakes.h"
32 amb 449 #include "files.h"
33 amb 109 #include "profiles.h"
34 amb 2
35    
36 amb 23 /*++++++++++++++++++++++++++++++++++++++
37 amb 2 Load in a segment list from a file.
38    
39 amb 681 Segments *LoadSegmentList Returns the segment list that has just been loaded.
40 amb 23
41 amb 2 const char *filename The name of the file to load.
42     ++++++++++++++++++++++++++++++++++++++*/
43    
44 amb 23 Segments *LoadSegmentList(const char *filename)
45 amb 2 {
46 amb 88 Segments *segments;
47 amb 706 #if SLIM
48     int i;
49     #endif
50 amb 88
51     segments=(Segments*)malloc(sizeof(Segments));
52    
53 amb 459 #if !SLIM
54 amb 88
55 amb 459 segments->data=MapFile(filename);
56 amb 88
57 amb 459 /* Copy the SegmentsFile structure from the loaded data */
58 amb 88
59 amb 459 segments->file=*((SegmentsFile*)segments->data);
60 amb 88
61 amb 459 /* Set the pointers in the Segments structure. */
62 amb 88
63 amb 459 segments->segments=(Segment*)(segments->data+sizeof(SegmentsFile));
64    
65     #else
66    
67     segments->fd=ReOpenFile(filename);
68    
69     /* Copy the SegmentsFile header structure from the loaded data */
70    
71     ReadFile(segments->fd,&segments->file,sizeof(SegmentsFile));
72    
73 amb 706 for(i=0;i<sizeof(segments->cached)/sizeof(segments->cached[0]);i++)
74     segments->incache[i]=NO_SEGMENT;
75 amb 459
76     #endif
77    
78 amb 88 return(segments);
79 amb 2 }
80    
81    
82     /*++++++++++++++++++++++++++++++++++++++
83 amb 675 Find the closest segment from a specified node heading in a particular direction and optionally profile.
84    
85     index_t FindClosestSegmentHeading Returns the closest heading segment index.
86    
87 amb 681 Nodes *nodes The set of nodes to use.
88 amb 675
89     Segments *segments The set of segments to use.
90    
91     Ways *ways The set of ways to use.
92    
93     index_t node1 The node to start from.
94    
95     double heading The desired heading from the node.
96    
97     Profile *profile The profile of the mode of transport (or NULL).
98     ++++++++++++++++++++++++++++++++++++++*/
99    
100 amb 681 index_t FindClosestSegmentHeading(Nodes *nodes,Segments *segments,Ways *ways,index_t node1,double heading,Profile *profile)
101 amb 675 {
102 amb 1078 Segment *segmentp;
103 amb 675 index_t best_seg=NO_SEGMENT;
104     double best_difference=360;
105    
106     if(IsFakeNode(node1))
107 amb 1078 segmentp=FirstFakeSegment(node1);
108 amb 675 else
109 amb 885 {
110 amb 1078 Node *nodep=LookupNode(nodes,node1,3);
111 amb 675
112 amb 1078 segmentp=FirstSegment(segments,nodep,1);
113 amb 885 }
114    
115 amb 1078 while(segmentp)
116 amb 675 {
117 amb 1078 Way *wayp;
118 amb 675 index_t node2,seg2;
119     double bearing,difference;
120    
121 amb 1078 node2=OtherNode(segmentp,node1); /* need this here because we use node2 at the end of the loop */
122 amb 675
123 amb 1078 if(!IsNormalSegment(segmentp))
124 amb 675 goto endloop;
125    
126 amb 1078 if(profile->oneway && IsOnewayFrom(segmentp,node1))
127 amb 675 goto endloop;
128    
129     if(IsFakeNode(node1) || IsFakeNode(node2))
130 amb 1078 seg2=IndexFakeSegment(segmentp);
131 amb 675 else
132 amb 1078 seg2=IndexSegment(segments,segmentp);
133 amb 675
134 amb 1078 wayp=LookupWay(ways,segmentp->way,1);
135 amb 675
136 amb 1078 if(!(wayp->allow&profile->allow))
137 amb 675 goto endloop;
138    
139 amb 1078 bearing=BearingAngle(nodes,segmentp,node1);
140 amb 675
141     difference=(heading-bearing);
142    
143     if(difference<-180) difference+=360;
144     if(difference> 180) difference-=360;
145    
146     if(difference<0) difference=-difference;
147    
148     if(difference<best_difference)
149     {
150     best_difference=difference;
151     best_seg=seg2;
152     }
153    
154     endloop:
155    
156     if(IsFakeNode(node1))
157 amb 1078 segmentp=NextFakeSegment(segmentp,node1);
158 amb 675 else if(IsFakeNode(node2))
159 amb 1078 segmentp=NULL; /* cannot call NextSegment() with a fake segment */
160 amb 675 else
161 amb 1078 segmentp=NextSegment(segments,segmentp,node1);
162 amb 675 }
163    
164     return(best_seg);
165     }
166    
167    
168     /*++++++++++++++++++++++++++++++++++++++
169 amb 99 Calculate the distance between two locations.
170    
171 amb 114 distance_t Distance Returns the distance between the locations.
172 amb 99
173 amb 219 double lat1 The latitude of the first location.
174 amb 99
175 amb 219 double lon1 The longitude of the first location.
176 amb 99
177 amb 219 double lat2 The latitude of the second location.
178 amb 99
179 amb 219 double lon2 The longitude of the second location.
180 amb 99 ++++++++++++++++++++++++++++++++++++++*/
181    
182 amb 219 distance_t Distance(double lat1,double lon1,double lat2,double lon2)
183 amb 99 {
184 amb 219 double dlon = lon1 - lon2;
185     double dlat = lat1 - lat2;
186 amb 99
187 amb 219 double a1,a2,a,sa,c,d;
188 amb 99
189     if(dlon==0 && dlat==0)
190     return 0;
191    
192 amb 219 a1 = sin (dlat / 2);
193     a2 = sin (dlon / 2);
194     a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2;
195     sa = sqrt (a);
196 amb 99 if (sa <= 1.0)
197 amb 219 {c = 2 * asin (sa);}
198 amb 99 else
199 amb 219 {c = 2 * asin (1.0);}
200 amb 99 d = 6378.137 * c;
201    
202 amb 114 return km_to_distance(d);
203 amb 99 }
204    
205    
206     /*++++++++++++++++++++++++++++++++++++++
207 amb 680 Calculate the duration of travel on a segment.
208 amb 63
209 amb 680 duration_t Duration Returns the duration of travel.
210 amb 63
211 amb 1078 Segment *segmentp The segment to traverse.
212 amb 63
213 amb 1078 Way *wayp The way that the segment belongs to.
214 amb 63
215 amb 82 Profile *profile The profile of the transport being used.
216 amb 63 ++++++++++++++++++++++++++++++++++++++*/
217    
218 amb 1078 duration_t Duration(Segment *segmentp,Way *wayp,Profile *profile)
219 amb 63 {
220 amb 1164 speed_t speed1=wayp->speed;
221     speed_t speed2=profile->speed[HIGHWAY(wayp->type)];
222     segdist_t length=segmentp->length;
223 amb 63
224 amb 137 if(speed1==0)
225     {
226     if(speed2==0)
227     return(hours_to_duration(10));
228     else
229 amb 1164 return distance_speed_to_duration(length,speed2);
230 amb 137 }
231     else /* if(speed1!=0) */
232     {
233     if(speed2==0)
234 amb 1164 return distance_speed_to_duration(length,speed1);
235 amb 137 else if(speed1<=speed2)
236 amb 1164 return distance_speed_to_duration(length,speed1);
237 amb 137 else
238 amb 1164 return distance_speed_to_duration(length,speed2);
239 amb 137 }
240 amb 63 }
241 amb 672
242    
243     /*++++++++++++++++++++++++++++++++++++++
244     Calculate the angle to turn at a junction from segment1 to segment2 at node.
245    
246     double TurnAngle Returns a value in the range -180 to +180 indicating the angle to turn.
247    
248 amb 681 Nodes *nodes The set of nodes to use.
249 amb 672
250 amb 1078 Segment *segment1p The current segment.
251 amb 672
252 amb 1078 Segment *segment2p The next segment.
253 amb 672
254     index_t node The node at which they join.
255    
256     Straight ahead is zero, turning to the right is positive (e.g. +90 degrees) and turning to the left is negative (e.g. -90 degrees).
257     Angles are calculated using flat Cartesian lat/long grid approximation (after scaling longitude due to latitude).
258     ++++++++++++++++++++++++++++++++++++++*/
259    
260 amb 1078 double TurnAngle(Nodes *nodes,Segment *segment1p,Segment *segment2p,index_t node)
261 amb 672 {
262     double lat1,latm,lat2;
263     double lon1,lonm,lon2;
264     double angle1,angle2,angle;
265     index_t node1,node2;
266    
267 amb 1078 node1=OtherNode(segment1p,node);
268     node2=OtherNode(segment2p,node);
269 amb 672
270     if(IsFakeNode(node1))
271     GetFakeLatLong(node1,&lat1,&lon1);
272     else
273     GetLatLong(nodes,node1,&lat1,&lon1);
274    
275     if(IsFakeNode(node))
276     GetFakeLatLong(node,&latm,&lonm);
277     else
278     GetLatLong(nodes,node,&latm,&lonm);
279    
280     if(IsFakeNode(node2))
281     GetFakeLatLong(node2,&lat2,&lon2);
282     else
283     GetLatLong(nodes,node2,&lat2,&lon2);
284    
285     angle1=atan2((lonm-lon1)*cos(latm),(latm-lat1));
286     angle2=atan2((lon2-lonm)*cos(latm),(lat2-latm));
287    
288     angle=angle2-angle1;
289    
290     angle=radians_to_degrees(angle);
291    
292     if(angle<-180) angle+=360;
293     if(angle> 180) angle-=360;
294    
295     return(angle);
296     }
297    
298    
299     /*++++++++++++++++++++++++++++++++++++++
300 amb 675 Calculate the bearing of a segment when heading to the given node.
301 amb 672
302     double BearingAngle Returns a value in the range 0 to 359 indicating the bearing.
303    
304 amb 681 Nodes *nodes The set of nodes to use.
305 amb 672
306 amb 1078 Segment *segmentp The segment.
307 amb 672
308 amb 675 index_t node The node to finish.
309 amb 672
310     Angles are calculated using flat Cartesian lat/long grid approximation (after scaling longitude due to latitude).
311     ++++++++++++++++++++++++++++++++++++++*/
312    
313 amb 1078 double BearingAngle(Nodes *nodes,Segment *segmentp,index_t node)
314 amb 672 {
315     double lat1,lat2;
316     double lon1,lon2;
317     double angle;
318     index_t node1,node2;
319    
320     node1=node;
321 amb 1078 node2=OtherNode(segmentp,node);
322 amb 672
323     if(IsFakeNode(node1))
324     GetFakeLatLong(node1,&lat1,&lon1);
325     else
326     GetLatLong(nodes,node1,&lat1,&lon1);
327    
328     if(IsFakeNode(node2))
329     GetFakeLatLong(node2,&lat2,&lon2);
330     else
331     GetLatLong(nodes,node2,&lat2,&lon2);
332    
333     angle=atan2((lat2-lat1),(lon2-lon1)*cos(lat1));
334    
335     angle=radians_to_degrees(angle);
336    
337     angle=270-angle;
338    
339     if(angle< 0) angle+=360;
340     if(angle>360) angle-=360;
341    
342     return(angle);
343     }

Properties

Name Value
cvs:description Segment data type.