initial packaging
[routino] / src / segments.c
1 /***************************************
2  $Header: /home/amb/routino/src/RCS/segments.c,v 1.45 2010/04/28 17:27:02 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 "functions.h"
30 #include "nodes.h"
31 #include "segments.h"
32 #include "ways.h"
33 #include "profiles.h"
34
35
36 /*++++++++++++++++++++++++++++++++++++++
37   Load in a segment list from a file.
38
39   Segments* LoadSegmentList Returns the segment list that has just been loaded.
40
41   const char *filename The name of the file to load.
42   ++++++++++++++++++++++++++++++++++++++*/
43
44 Segments *LoadSegmentList(const char *filename)
45 {
46  void *data;
47  Segments *segments;
48
49  segments=(Segments*)malloc(sizeof(Segments));
50
51  data=MapFile(filename);
52
53  /* Copy the Segments structure from the loaded data */
54
55  *segments=*((Segments*)data);
56
57  /* Adjust the pointers in the Segments structure. */
58
59  segments->data=data;
60  segments->segments=(Segment*)(data+sizeof(Segments));
61
62  return(segments);
63 }
64
65
66 /*++++++++++++++++++++++++++++++++++++++
67   Find the next segment with a particular starting node.
68
69   Segment *NextSegment Returns a pointer to the next segment with the same id.
70
71   Segments* segments The set of segments to process.
72
73   Segment *segment The current segment.
74
75   index_t node The current node.
76   ++++++++++++++++++++++++++++++++++++++*/
77
78 Segment *NextSegment(Segments* segments,Segment *segment,index_t node)
79 {
80  if(segment->node1==node)
81    {
82     segment++;
83     if((segment-segments->segments)>=segments->number || segment->node1!=node)
84        return(NULL);
85     else
86        return(segment);
87    }
88  else
89    {
90     if(segment->next2==NO_NODE)
91        return(NULL);
92     else
93        return(LookupSegment(segments,segment->next2));
94    }
95 }
96  
97  
98 /*++++++++++++++++++++++++++++++++++++++
99   Calculate the distance between two locations.
100
101   distance_t Distance Returns the distance between the locations.
102
103   double lat1 The latitude of the first location.
104
105   double lon1 The longitude of the first location.
106
107   double lat2 The latitude of the second location.
108
109   double lon2 The longitude of the second location.
110   ++++++++++++++++++++++++++++++++++++++*/
111
112 distance_t Distance(double lat1,double lon1,double lat2,double lon2)
113 {
114  double dlon = lon1 - lon2;
115  double dlat = lat1 - lat2;
116
117  double a1,a2,a,sa,c,d;
118
119  if(dlon==0 && dlat==0)
120    return 0;
121
122  a1 = sin (dlat / 2);
123  a2 = sin (dlon / 2);
124  a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2;
125  sa = sqrt (a);
126  if (sa <= 1.0)
127    {c = 2 * asin (sa);}
128  else
129    {c = 2 * asin (1.0);}
130  d = 6378.137 * c;
131
132  return km_to_distance(d);
133 }
134
135
136 /*++++++++++++++++++++++++++++++++++++++
137   Calculate the duration of segment.
138
139   duration_t Duration Returns the duration of travel between the nodes.
140
141   Segment *segment The segment to traverse.
142
143   Way *way The way that the segment belongs to.
144
145   Profile *profile The profile of the transport being used.
146   ++++++++++++++++++++++++++++++++++++++*/
147
148 duration_t Duration(Segment *segment,Way *way,Profile *profile)
149 {
150  speed_t    speed1=way->speed;
151  speed_t    speed2=profile->speed[HIGHWAY(way->type)];
152  distance_t distance=DISTANCE(segment->distance);
153
154  if(speed1==0)
155    {
156     if(speed2==0)
157        return(hours_to_duration(10));
158     else
159        return distance_speed_to_duration(distance,speed2);
160    }
161  else /* if(speed1!=0) */
162    {
163     if(speed2==0)
164        return distance_speed_to_duration(distance,speed1);
165     else if(speed1<=speed2)
166        return distance_speed_to_duration(distance,speed1);
167     else
168        return distance_speed_to_duration(distance,speed2);
169    }
170 }