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 1989 - (hide annotations) (download) (as text)
Wed Apr 17 17:54:45 2019 UTC (5 years, 11 months ago) by amb
File MIME type: text/x-csrc
File size: 10311 byte(s)
Rename some structure members and function names to reflect more
clearly their meaning (mostly change "allow" to "transport").  No
changes to file formats or API.

1 amb 2 /***************************************
2     Segment data type functions.
3 amb 151
4     Part of the Routino routing software.
5 amb 2 ******************/ /******************
6 amb 1989 This file Copyright 2008-2015, 2019 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    
48     segments=(Segments*)malloc(sizeof(Segments));
49    
50 amb 459 #if !SLIM
51 amb 88
52 amb 459 segments->data=MapFile(filename);
53 amb 88
54 amb 459 /* Copy the SegmentsFile structure from the loaded data */
55 amb 88
56 amb 459 segments->file=*((SegmentsFile*)segments->data);
57 amb 88
58 amb 459 /* Set the pointers in the Segments structure. */
59 amb 88
60 amb 459 segments->segments=(Segment*)(segments->data+sizeof(SegmentsFile));
61    
62     #else
63    
64 amb 1415 segments->fd=SlimMapFile(filename);
65 amb 459
66     /* Copy the SegmentsFile header structure from the loaded data */
67    
68 amb 1415 SlimFetch(segments->fd,&segments->file,sizeof(SegmentsFile),0);
69 amb 459
70 amb 1292 segments->cache=NewSegmentCache();
71 amb 1784 #ifndef LIBROUTINO
72 amb 1602 log_malloc(segments->cache,sizeof(*segments->cache));
73 amb 1784 #endif
74 amb 459
75     #endif
76    
77 amb 88 return(segments);
78 amb 2 }
79    
80    
81     /*++++++++++++++++++++++++++++++++++++++
82 amb 1312 Destroy the segment list.
83    
84     Segments *segments The segment list to destroy.
85     ++++++++++++++++++++++++++++++++++++++*/
86    
87     void DestroySegmentList(Segments *segments)
88     {
89     #if !SLIM
90    
91     segments->data=UnmapFile(segments->data);
92    
93     #else
94    
95 amb 1415 segments->fd=SlimUnmapFile(segments->fd);
96 amb 1312
97 amb 1784 #ifndef LIBROUTINO
98 amb 1602 log_free(segments->cache);
99 amb 1784 #endif
100 amb 1312 DeleteSegmentCache(segments->cache);
101    
102     #endif
103    
104     free(segments);
105     }
106    
107    
108     /*++++++++++++++++++++++++++++++++++++++
109 amb 675 Find the closest segment from a specified node heading in a particular direction and optionally profile.
110    
111     index_t FindClosestSegmentHeading Returns the closest heading segment index.
112    
113 amb 681 Nodes *nodes The set of nodes to use.
114 amb 675
115     Segments *segments The set of segments to use.
116    
117     Ways *ways The set of ways to use.
118    
119     index_t node1 The node to start from.
120    
121     double heading The desired heading from the node.
122    
123     Profile *profile The profile of the mode of transport (or NULL).
124     ++++++++++++++++++++++++++++++++++++++*/
125    
126 amb 681 index_t FindClosestSegmentHeading(Nodes *nodes,Segments *segments,Ways *ways,index_t node1,double heading,Profile *profile)
127 amb 675 {
128 amb 1078 Segment *segmentp;
129 amb 675 index_t best_seg=NO_SEGMENT;
130     double best_difference=360;
131    
132     if(IsFakeNode(node1))
133 amb 1078 segmentp=FirstFakeSegment(node1);
134 amb 675 else
135 amb 885 {
136 amb 1078 Node *nodep=LookupNode(nodes,node1,3);
137 amb 675
138 amb 1078 segmentp=FirstSegment(segments,nodep,1);
139 amb 885 }
140    
141 amb 1078 while(segmentp)
142 amb 675 {
143 amb 1078 Way *wayp;
144 amb 675 index_t node2,seg2;
145     double bearing,difference;
146    
147 amb 1078 node2=OtherNode(segmentp,node1); /* need this here because we use node2 at the end of the loop */
148 amb 675
149 amb 1078 if(!IsNormalSegment(segmentp))
150 amb 675 goto endloop;
151    
152     if(IsFakeNode(node1) || IsFakeNode(node2))
153 amb 1078 seg2=IndexFakeSegment(segmentp);
154 amb 675 else
155 amb 1078 seg2=IndexSegment(segments,segmentp);
156 amb 675
157 amb 1078 wayp=LookupWay(ways,segmentp->way,1);
158 amb 675
159 amb 1989 if(!(wayp->allow&profile->transports))
160 amb 675 goto endloop;
161    
162 amb 1497 if(profile->oneway && IsOnewayFrom(segmentp,node1))
163     {
164 amb 1989 if(profile->transports!=Transports_Bicycle)
165 amb 1497 goto endloop;
166    
167 amb 1559 if(!(wayp->type&Highway_CycleBothWays))
168 amb 1497 goto endloop;
169     }
170    
171 amb 1078 bearing=BearingAngle(nodes,segmentp,node1);
172 amb 675
173     difference=(heading-bearing);
174    
175     if(difference<-180) difference+=360;
176     if(difference> 180) difference-=360;
177    
178     if(difference<0) difference=-difference;
179    
180     if(difference<best_difference)
181     {
182     best_difference=difference;
183     best_seg=seg2;
184     }
185    
186     endloop:
187    
188     if(IsFakeNode(node1))
189 amb 1078 segmentp=NextFakeSegment(segmentp,node1);
190 amb 675 else if(IsFakeNode(node2))
191 amb 1078 segmentp=NULL; /* cannot call NextSegment() with a fake segment */
192 amb 675 else
193 amb 1078 segmentp=NextSegment(segments,segmentp,node1);
194 amb 675 }
195    
196     return(best_seg);
197     }
198    
199    
200     /*++++++++++++++++++++++++++++++++++++++
201 amb 99 Calculate the distance between two locations.
202    
203 amb 114 distance_t Distance Returns the distance between the locations.
204 amb 99
205 amb 219 double lat1 The latitude of the first location.
206 amb 99
207 amb 219 double lon1 The longitude of the first location.
208 amb 99
209 amb 219 double lat2 The latitude of the second location.
210 amb 99
211 amb 219 double lon2 The longitude of the second location.
212 amb 99 ++++++++++++++++++++++++++++++++++++++*/
213    
214 amb 219 distance_t Distance(double lat1,double lon1,double lat2,double lon2)
215 amb 99 {
216 amb 219 double dlon = lon1 - lon2;
217     double dlat = lat1 - lat2;
218 amb 99
219 amb 219 double a1,a2,a,sa,c,d;
220 amb 99
221     if(dlon==0 && dlat==0)
222     return 0;
223    
224 amb 219 a1 = sin (dlat / 2);
225     a2 = sin (dlon / 2);
226 amb 1603 a = a1 * a1 + cos (lat1) * cos (lat2) * a2 * a2;
227 amb 219 sa = sqrt (a);
228 amb 99 if (sa <= 1.0)
229 amb 219 {c = 2 * asin (sa);}
230 amb 99 else
231 amb 219 {c = 2 * asin (1.0);}
232 amb 99 d = 6378.137 * c;
233    
234 amb 114 return km_to_distance(d);
235 amb 99 }
236    
237    
238     /*++++++++++++++++++++++++++++++++++++++
239 amb 1603 Calculate the change in latitude (same longitude) between two locations a known distance apart.
240    
241     double DeltaLat Returns the difference in latitude between the locations.
242    
243     double lon The longitude of the locations.
244    
245     distance_t distance The distance between the locations.
246     ++++++++++++++++++++++++++++++++++++++*/
247    
248     double DeltaLat(double lon,distance_t distance)
249     {
250     double dlat;
251    
252     double c,d;
253    
254     if(distance==0)
255     return 0;
256    
257     d = distance_to_km(distance);
258    
259     c = d / 6378.137;
260    
261     dlat = c;
262    
263     return dlat;
264     }
265    
266    
267     /*++++++++++++++++++++++++++++++++++++++
268     Calculate the change in longitude (same latitude) between two locations a known distance apart.
269    
270     double DeltaLon Returns the difference in longitude between the locations.
271    
272     double lat The latitude of the locations.
273    
274     distance_t distance The distance between the locations.
275     ++++++++++++++++++++++++++++++++++++++*/
276    
277     double DeltaLon(double lat,distance_t distance)
278     {
279     double dlon;
280    
281     double a2,sa,c,d;
282    
283     if(distance==0)
284     return 0;
285    
286     d = distance_to_km(distance);
287    
288     c = d / 6378.137;
289    
290     sa = sin(c/2);
291    
292     a2 = sa / cos(lat);
293    
294     dlon = 2*asin(a2);
295    
296     return dlon;
297     }
298    
299    
300     /*++++++++++++++++++++++++++++++++++++++
301 amb 680 Calculate the duration of travel on a segment.
302 amb 63
303 amb 680 duration_t Duration Returns the duration of travel.
304 amb 63
305 amb 1078 Segment *segmentp The segment to traverse.
306 amb 63
307 amb 1078 Way *wayp The way that the segment belongs to.
308 amb 63
309 amb 82 Profile *profile The profile of the transport being used.
310 amb 63 ++++++++++++++++++++++++++++++++++++++*/
311    
312 amb 1078 duration_t Duration(Segment *segmentp,Way *wayp,Profile *profile)
313 amb 63 {
314 amb 1168 speed_t speed1=wayp->speed;
315     speed_t speed2=profile->speed[HIGHWAY(wayp->type)];
316     distance_t distance=DISTANCE(segmentp->distance);
317 amb 63
318 amb 137 if(speed1==0)
319     {
320     if(speed2==0)
321     return(hours_to_duration(10));
322     else
323 amb 1168 return distance_speed_to_duration(distance,speed2);
324 amb 137 }
325     else /* if(speed1!=0) */
326     {
327     if(speed2==0)
328 amb 1168 return distance_speed_to_duration(distance,speed1);
329 amb 137 else if(speed1<=speed2)
330 amb 1168 return distance_speed_to_duration(distance,speed1);
331 amb 137 else
332 amb 1168 return distance_speed_to_duration(distance,speed2);
333 amb 137 }
334 amb 63 }
335 amb 672
336    
337     /*++++++++++++++++++++++++++++++++++++++
338     Calculate the angle to turn at a junction from segment1 to segment2 at node.
339    
340     double TurnAngle Returns a value in the range -180 to +180 indicating the angle to turn.
341    
342 amb 681 Nodes *nodes The set of nodes to use.
343 amb 672
344 amb 1078 Segment *segment1p The current segment.
345 amb 672
346 amb 1078 Segment *segment2p The next segment.
347 amb 672
348     index_t node The node at which they join.
349    
350     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).
351     Angles are calculated using flat Cartesian lat/long grid approximation (after scaling longitude due to latitude).
352     ++++++++++++++++++++++++++++++++++++++*/
353    
354 amb 1078 double TurnAngle(Nodes *nodes,Segment *segment1p,Segment *segment2p,index_t node)
355 amb 672 {
356     double lat1,latm,lat2;
357     double lon1,lonm,lon2;
358     double angle1,angle2,angle;
359     index_t node1,node2;
360    
361 amb 1078 node1=OtherNode(segment1p,node);
362     node2=OtherNode(segment2p,node);
363 amb 672
364     if(IsFakeNode(node1))
365     GetFakeLatLong(node1,&lat1,&lon1);
366     else
367 amb 1291 GetLatLong(nodes,node1,NULL,&lat1,&lon1);
368 amb 672
369     if(IsFakeNode(node))
370     GetFakeLatLong(node,&latm,&lonm);
371     else
372 amb 1291 GetLatLong(nodes,node,NULL,&latm,&lonm);
373 amb 672
374     if(IsFakeNode(node2))
375     GetFakeLatLong(node2,&lat2,&lon2);
376     else
377 amb 1291 GetLatLong(nodes,node2,NULL,&lat2,&lon2);
378 amb 672
379     angle1=atan2((lonm-lon1)*cos(latm),(latm-lat1));
380     angle2=atan2((lon2-lonm)*cos(latm),(lat2-latm));
381    
382     angle=angle2-angle1;
383    
384     angle=radians_to_degrees(angle);
385    
386     if(angle<-180) angle+=360;
387     if(angle> 180) angle-=360;
388    
389     return(angle);
390     }
391    
392    
393     /*++++++++++++++++++++++++++++++++++++++
394 amb 675 Calculate the bearing of a segment when heading to the given node.
395 amb 672
396     double BearingAngle Returns a value in the range 0 to 359 indicating the bearing.
397    
398 amb 681 Nodes *nodes The set of nodes to use.
399 amb 672
400 amb 1078 Segment *segmentp The segment.
401 amb 672
402 amb 675 index_t node The node to finish.
403 amb 672
404     Angles are calculated using flat Cartesian lat/long grid approximation (after scaling longitude due to latitude).
405     ++++++++++++++++++++++++++++++++++++++*/
406    
407 amb 1078 double BearingAngle(Nodes *nodes,Segment *segmentp,index_t node)
408 amb 672 {
409     double lat1,lat2;
410     double lon1,lon2;
411     double angle;
412     index_t node1,node2;
413    
414     node1=node;
415 amb 1078 node2=OtherNode(segmentp,node);
416 amb 672
417     if(IsFakeNode(node1))
418     GetFakeLatLong(node1,&lat1,&lon1);
419     else
420 amb 1291 GetLatLong(nodes,node1,NULL,&lat1,&lon1);
421 amb 672
422     if(IsFakeNode(node2))
423     GetFakeLatLong(node2,&lat2,&lon2);
424     else
425 amb 1291 GetLatLong(nodes,node2,NULL,&lat2,&lon2);
426 amb 672
427     angle=atan2((lat2-lat1),(lon2-lon1)*cos(lat1));
428    
429     angle=radians_to_degrees(angle);
430    
431     angle=270-angle;
432    
433     if(angle< 0) angle+=360;
434     if(angle>360) angle-=360;
435    
436     return(angle);
437     }

Properties

Name Value
cvs:description Segment data type.