Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/fakes.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 535 - (show annotations) (download) (as text)
Sun Nov 28 14:29:26 2010 UTC (14 years, 3 months ago) by amb
File MIME type: text/x-csrc
File size: 8343 byte(s)
Fix some problems with fake nodes, in particular a route between two fake nodes
on the same segment can now be calculated.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/fakes.c,v 1.4 2010-11-28 14:29:26 amb Exp $
3
4 Fake node and segment generation.
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 "types.h"
26 #include "nodes.h"
27 #include "segments.h"
28
29 #include "fakes.h"
30
31
32 /*+ The minimum distance along a segment from a node to insert a fake node. (in km). +*/
33 #define MINSEGMENT 0.005
34
35
36 /*+ A set of fake segments to allow start/finish in the middle of a segment. +*/
37 static Segment fake_segments[4*NWAYPOINTS+1];
38
39 /*+ A set of fake node latitudes and longitudes. +*/
40 static double fake_lon[NWAYPOINTS+1],fake_lat[NWAYPOINTS+1];
41
42 /*+ The previous waypoint. +*/
43 static int prevpoint=0;
44
45
46 /*++++++++++++++++++++++++++++++++++++++
47 Create a pair of fake segments corresponding to the given segment split in two.
48
49 index_t CreateFakes Returns the fake node index (or a real one in special cases).
50
51 Nodes *nodes The set of nodes to use.
52
53 int point Which of the waypoints is this.
54
55 Segment *segment The segment to split.
56
57 index_t node1 The first node at the end of this segment.
58
59 index_t node2 The second node at the end of this segment.
60
61 distance_t dist1 The distance to the first node.
62
63 distance_t dist2 The distance to the second node.
64 ++++++++++++++++++++++++++++++++++++++*/
65
66 index_t CreateFakes(Nodes *nodes,int point,Segment *segment,index_t node1,index_t node2,distance_t dist1,distance_t dist2)
67 {
68 index_t fakenode;
69 double lat1,lon1,lat2,lon2;
70
71 /* Initialise the segments to fake values */
72
73 fake_segments[4*point-4].node1=NO_NODE;
74 fake_segments[4*point-4].node2=NO_NODE;
75
76 fake_segments[4*point-3].node1=NO_NODE;
77 fake_segments[4*point-3].node2=NO_NODE;
78
79 fake_segments[4*point-2].node1=NO_NODE;
80 fake_segments[4*point-2].node2=NO_NODE;
81
82 fake_segments[4*point-1].node1=NO_NODE;
83 fake_segments[4*point-1].node2=NO_NODE;
84
85 /* Check if we are actually close enough to an existing node */
86
87 if(dist1<km_to_distance(MINSEGMENT) && dist2>km_to_distance(MINSEGMENT))
88 {
89 prevpoint=point;
90 return(node1);
91 }
92
93 if(dist2<km_to_distance(MINSEGMENT) && dist1>km_to_distance(MINSEGMENT))
94 {
95 prevpoint=point;
96 return(node2);
97 }
98
99 if(dist1<km_to_distance(MINSEGMENT) && dist2<km_to_distance(MINSEGMENT))
100 {
101 prevpoint=point;
102
103 if(dist1<dist2)
104 return(node1);
105 else
106 return(node2);
107 }
108
109 /* Create the fake node */
110
111 fakenode=NODE_FAKE+point;
112
113 GetLatLong(nodes,node1,&lat1,&lon1);
114 GetLatLong(nodes,node2,&lat2,&lon2);
115
116 if(lat1>3 && lat2<-3)
117 lat2+=2*M_PI;
118 else if(lat1<-3 && lat2>3)
119 lat1+=2*M_PI;
120
121 fake_lat[point]=lat1+(lat2-lat1)*(double)dist1/(double)(dist1+dist2);
122 fake_lon[point]=lon1+(lon2-lon1)*(double)dist1/(double)(dist1+dist2);
123
124 if(fake_lat[point]>M_PI) fake_lat[point]-=2*M_PI;
125
126 /* Create the first fake segment */
127
128 fake_segments[4*point-4]=*segment;
129
130 fake_segments[4*point-4].node2=fakenode;
131
132 fake_segments[4*point-4].distance=DISTANCE(dist1)|DISTFLAG(segment->distance);
133
134 /* Create the second fake segment */
135
136 fake_segments[4*point-3]=*segment;
137
138 fake_segments[4*point-3].node1=fakenode;
139
140 fake_segments[4*point-3].distance=DISTANCE(dist2)|DISTFLAG(segment->distance);
141
142 /* Create a third fake segment to join adjacent points if both are fake and on the same real segment */
143
144 if(prevpoint>0 && fake_segments[4*prevpoint-4].node1==node1 && fake_segments[4*prevpoint-3].node2==node2)
145 {
146 if(DISTANCE(dist1)>DISTANCE(fake_segments[4*prevpoint-4].distance)) /* closer to node2 */
147 {
148 fake_segments[4*point-2]=fake_segments[4*point-4];
149
150 fake_segments[4*point-2].node1=fakenode;
151
152 fake_segments[4*point-2].distance=(DISTANCE(dist1)-DISTANCE(fake_segments[4*prevpoint-4].distance))|DISTFLAG(segment->distance);
153 }
154 else
155 {
156 fake_segments[4*point-2]=fake_segments[4*point-2];
157
158 fake_segments[4*point-2].node2=fakenode;
159
160 fake_segments[4*point-2].distance=(DISTANCE(fake_segments[4*prevpoint-4].distance)-DISTANCE(dist1))|DISTFLAG(segment->distance);
161 }
162
163 fake_segments[4*prevpoint-1]=fake_segments[4*point-2];
164 }
165
166 /* Return the fake node */
167
168 prevpoint=point;
169
170 return(fakenode);
171 }
172
173
174 /*++++++++++++++++++++++++++++++++++++++
175 Lookup the latitude and longitude of a fake node.
176
177 index_t fakenode The node to lookup.
178
179 double *latitude Returns the latitude
180
181 double *longitude Returns the longitude.
182 ++++++++++++++++++++++++++++++++++++++*/
183
184 void GetFakeLatLong(index_t fakenode, double *latitude,double *longitude)
185 {
186 index_t realnode=fakenode-NODE_FAKE;
187
188 *latitude =fake_lat[realnode];
189 *longitude=fake_lon[realnode];
190 }
191
192
193 /*++++++++++++++++++++++++++++++++++++++
194 Finds the first fake segment associated to a fake node.
195
196 Segment *FirstFakeSegment Returns the first fake segment.
197
198 index_t fakenode The node to lookup.
199 ++++++++++++++++++++++++++++++++++++++*/
200
201 Segment *FirstFakeSegment(index_t fakenode)
202 {
203 index_t realnode=fakenode-NODE_FAKE;
204
205 return(&fake_segments[4*realnode-4]);
206 }
207
208
209 /*++++++++++++++++++++++++++++++++++++++
210 Finds the next (there can only be two) fake segment associated to a fake node.
211
212 Segment *NextFakeSegment Returns the second fake segment.
213
214 Segment *segment The first fake segment.
215
216 index_t fakenode The node to lookup.
217 ++++++++++++++++++++++++++++++++++++++*/
218
219 Segment *NextFakeSegment(Segment *segment,index_t fakenode)
220 {
221 index_t realnode=fakenode-NODE_FAKE;
222
223 if(segment==&fake_segments[4*realnode-4])
224 return(&fake_segments[4*realnode-3]);
225
226 if(segment==&fake_segments[4*realnode-3] && fake_segments[4*realnode-2].node1!=NO_NODE)
227 return(&fake_segments[4*realnode-2]);
228
229 if(segment==&fake_segments[4*realnode-3] && fake_segments[4*realnode-1].node1!=NO_NODE)
230 return(&fake_segments[4*realnode-1]);
231
232 if(segment==&fake_segments[4*realnode-2] && fake_segments[4*realnode-1].node1!=NO_NODE)
233 return(&fake_segments[4*realnode-1]);
234
235 return(NULL);
236 }
237
238
239 /*++++++++++++++++++++++++++++++++++++++
240 Finds the fake segment between a node and a fake node.
241
242 Segment *ExtraFakeSegment Returns a segment between the two specified nodes if it exists.
243
244 index_t node The real node.
245
246 index_t fakenode The fake node to lookup.
247 ++++++++++++++++++++++++++++++++++++++*/
248
249 Segment *ExtraFakeSegment(index_t node,index_t fakenode)
250 {
251 index_t realnode=fakenode-NODE_FAKE;
252
253 if(fake_segments[4*realnode-4].node1==node || fake_segments[4*realnode-4].node2==node)
254 return(&fake_segments[4*realnode-4]);
255
256 if(fake_segments[4*realnode-3].node1==node || fake_segments[4*realnode-3].node2==node)
257 return(&fake_segments[4*realnode-3]);
258
259 if(fake_segments[4*realnode-2].node1==node || fake_segments[4*realnode-2].node2==node)
260 return(&fake_segments[4*realnode-2]);
261
262 if(fake_segments[4*realnode-1].node1==node || fake_segments[4*realnode-1].node2==node)
263 return(&fake_segments[4*realnode-1]);
264
265 return(NULL);
266 }
267
268
269 /*++++++++++++++++++++++++++++++++++++++
270 Lookup a fake segment given its index.
271
272 Segment *LookupFakeSegment Returns a pointer to the segment.
273
274 index_t fakesegment The index of the fake segment.
275 ++++++++++++++++++++++++++++++++++++++*/
276
277 Segment *LookupFakeSegment(index_t fakesegment)
278 {
279 index_t realsegment=fakesegment-SEGMENT_FAKE;
280
281 return(&fake_segments[realsegment]);
282 }
283
284
285 /*++++++++++++++++++++++++++++++++++++++
286 Find the fake index of a fake segment.
287
288 index_t IndexFakeSegment Returns the fake segment.
289
290 Segment *segment The segment to look for.
291 ++++++++++++++++++++++++++++++++++++++*/
292
293 index_t IndexFakeSegment(Segment *segment)
294 {
295 index_t realsegment=segment-&fake_segments[0];
296
297 return(realsegment+SEGMENT_FAKE);
298 }

Properties

Name Value
cvs:description Move the fake nodes and segments to a new file.