Imported Upstream version 1.5
[routino] / src / segments.c
1 /***************************************
2  $Header: /home/amb/routino/src/RCS/segments.c,v 1.47 2010/07/23 14:35:27 amb Exp $
3
4  Segment data type functions.
5
6  Part of the Routino routing software.
7  ******************/ /******************
8  This file Copyright 2008-2010 Andrew M. Bishop
9
10  This program is free software: you can redistribute it and/or modify
11  it under the terms of the GNU Affero General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU Affero General Public License for more details.
19
20  You should have received a copy of the GNU Affero General Public License
21  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  ***************************************/
23
24
25 #include <sys/types.h>
26 #include <stdlib.h>
27
28 #include "types.h"
29 #include "nodes.h"
30 #include "segments.h"
31 #include "ways.h"
32
33 #include "files.h"
34 #include "profiles.h"
35
36
37 /*++++++++++++++++++++++++++++++++++++++
38   Load in a segment list from a file.
39
40   Segments* LoadSegmentList Returns the segment list that has just been loaded.
41
42   const char *filename The name of the file to load.
43   ++++++++++++++++++++++++++++++++++++++*/
44
45 Segments *LoadSegmentList(const char *filename)
46 {
47  Segments *segments;
48
49  segments=(Segments*)malloc(sizeof(Segments));
50
51 #if !SLIM
52
53  segments->data=MapFile(filename);
54
55  /* Copy the SegmentsFile structure from the loaded data */
56
57  segments->file=*((SegmentsFile*)segments->data);
58
59  /* Set the pointers in the Segments structure. */
60
61  segments->segments=(Segment*)(segments->data+sizeof(SegmentsFile));
62
63 #else
64
65  segments->fd=ReOpenFile(filename);
66
67  /* Copy the SegmentsFile header structure from the loaded data */
68
69  ReadFile(segments->fd,&segments->file,sizeof(SegmentsFile));
70
71  segments->incache[0]=NO_SEGMENT;
72  segments->incache[1]=NO_SEGMENT;
73  segments->incache[2]=NO_SEGMENT;
74
75 #endif
76
77  return(segments);
78 }
79
80
81 /*++++++++++++++++++++++++++++++++++++++
82   Find the next segment with a particular starting node.
83
84   Segment *NextSegment Returns a pointer to the next segment with the same id.
85
86   Segments* segments The set of segments to process.
87
88   Segment *segment The current segment.
89
90   index_t node The current node.
91   ++++++++++++++++++++++++++++++++++++++*/
92
93 Segment *NextSegment(Segments* segments,Segment *segment,index_t node)
94 {
95  if(segment->node1==node)
96    {
97 #if SLIM
98     index_t index=IndexSegment(segments,segment);
99     index++;
100
101     if(index>=segments->file.number)
102        return(NULL);
103     segment=LookupSegment(segments,index,1);
104     if(segment->node1!=node)
105        return(NULL);
106     else
107        return(segment);
108 #else
109     segment++;
110     if(IndexSegment(segments,segment)>=segments->file.number || segment->node1!=node)
111        return(NULL);
112     else
113        return(segment);
114 #endif
115    }
116  else
117    {
118     if(segment->next2==NO_NODE)
119        return(NULL);
120     else
121        return(LookupSegment(segments,segment->next2,1));
122    }
123 }
124  
125  
126 /*++++++++++++++++++++++++++++++++++++++
127   Calculate the distance between two locations.
128
129   distance_t Distance Returns the distance between the locations.
130
131   double lat1 The latitude of the first location.
132
133   double lon1 The longitude of the first location.
134
135   double lat2 The latitude of the second location.
136
137   double lon2 The longitude of the second location.
138   ++++++++++++++++++++++++++++++++++++++*/
139
140 distance_t Distance(double lat1,double lon1,double lat2,double lon2)
141 {
142  double dlon = lon1 - lon2;
143  double dlat = lat1 - lat2;
144
145  double a1,a2,a,sa,c,d;
146
147  if(dlon==0 && dlat==0)
148    return 0;
149
150  a1 = sin (dlat / 2);
151  a2 = sin (dlon / 2);
152  a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2;
153  sa = sqrt (a);
154  if (sa <= 1.0)
155    {c = 2 * asin (sa);}
156  else
157    {c = 2 * asin (1.0);}
158  d = 6378.137 * c;
159
160  return km_to_distance(d);
161 }
162
163
164 /*++++++++++++++++++++++++++++++++++++++
165   Calculate the duration of segment.
166
167   duration_t Duration Returns the duration of travel between the nodes.
168
169   Segment *segment The segment to traverse.
170
171   Way *way The way that the segment belongs to.
172
173   Profile *profile The profile of the transport being used.
174   ++++++++++++++++++++++++++++++++++++++*/
175
176 duration_t Duration(Segment *segment,Way *way,Profile *profile)
177 {
178  speed_t    speed1=way->speed;
179  speed_t    speed2=profile->speed[HIGHWAY(way->type)];
180  distance_t distance=DISTANCE(segment->distance);
181
182  if(speed1==0)
183    {
184     if(speed2==0)
185        return(hours_to_duration(10));
186     else
187        return distance_speed_to_duration(distance,speed2);
188    }
189  else /* if(speed1!=0) */
190    {
191     if(speed2==0)
192        return distance_speed_to_duration(distance,speed1);
193     else if(speed1<=speed2)
194        return distance_speed_to_duration(distance,speed1);
195     else
196        return distance_speed_to_duration(distance,speed2);
197    }
198 }