1 /***************************************
2 $Header: /home/amb/routino/src/RCS/fakes.c,v 1.2 2010/08/04 16:44:51 amb Exp $
4 Fake node and segment generation.
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008-2010 Andrew M. Bishop
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.
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.
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 ***************************************/
29 #include "functions.h"
32 /*+ The minimum distance along a segment from a node to insert a fake node. (in km). +*/
33 #define MINSEGMENT 0.005
36 /*+ A set of fake segments to allow start/finish in the middle of a segment. +*/
37 static Segment fake_segments[2*NWAYPOINTS];
39 /*+ A set of fake node latitudes and longitudes. +*/
40 static double fake_lon[NWAYPOINTS+1],fake_lat[NWAYPOINTS+1];
43 /*++++++++++++++++++++++++++++++++++++++
44 Create a pair of fake segments corresponding to the given segment split in two.
46 index_t CreateFakes Returns the fake node index (or a real one in special cases).
48 Nodes *nodes The set of nodes to use.
50 int point Which of the waypoints is this.
52 Segment *segment The segment to split.
54 index_t node1 The first node at the end of this segment.
56 index_t node2 The second node at the end of this segment.
58 distance_t dist1 The distance to the first node.
60 distance_t dist2 The distance to the second node.
61 ++++++++++++++++++++++++++++++++++++++*/
63 index_t CreateFakes(Nodes *nodes,int point,Segment *segment,index_t node1,index_t node2,distance_t dist1,distance_t dist2)
66 double lat1,lon1,lat2,lon2;
68 /* Check if we are actually close enough to an existing node */
70 if(dist1<km_to_distance(MINSEGMENT) && dist2>km_to_distance(MINSEGMENT))
73 if(dist2<km_to_distance(MINSEGMENT) && dist1>km_to_distance(MINSEGMENT))
76 if(dist1<km_to_distance(MINSEGMENT) && dist2<km_to_distance(MINSEGMENT))
84 /* Create the fake node */
86 fakenode=NODE_FAKE+point;
88 GetLatLong(nodes,node1,&lat1,&lon1);
89 GetLatLong(nodes,node2,&lat2,&lon2);
93 else if(lat1<-3 && lat2>3)
96 fake_lat[point]=lat1+(lat2-lat1)*(double)dist1/(double)(dist1+dist2);
97 fake_lon[point]=lon1+(lon2-lon1)*(double)dist1/(double)(dist1+dist2);
99 if(fake_lat[point]>M_PI) fake_lat[point]-=2*M_PI;
101 /* Create the first fake segment */
103 fake_segments[2*point-2]=*segment;
105 if(segment->node1==node1)
106 fake_segments[2*point-2].node1=fakenode;
108 fake_segments[2*point-2].node2=fakenode;
110 fake_segments[2*point-2].distance=DISTANCE(dist1)|DISTFLAG(segment->distance);
112 /* Create the second fake segment */
114 fake_segments[2*point-1]=*segment;
116 if(segment->node1==node2)
117 fake_segments[2*point-1].node1=fakenode;
119 fake_segments[2*point-1].node2=fakenode;
121 fake_segments[2*point-1].distance=DISTANCE(dist2)|DISTFLAG(segment->distance);
127 /*++++++++++++++++++++++++++++++++++++++
128 Lookup the latitude and longitude of a fake node.
130 index_t fakenode The node to lookup.
132 double *latitude Returns the latitude
134 double *longitude Returns the longitude.
135 ++++++++++++++++++++++++++++++++++++++*/
137 void GetFakeLatLong(index_t fakenode, double *latitude,double *longitude)
139 index_t realnode=fakenode-NODE_FAKE;
141 *latitude =fake_lat[realnode];
142 *longitude=fake_lon[realnode];
146 /*++++++++++++++++++++++++++++++++++++++
147 Finds the first fake segment associated to a fake node.
149 Segment *FirstFakeSegment Returns the first fake segment.
151 index_t fakenode The node to lookup.
152 ++++++++++++++++++++++++++++++++++++++*/
154 Segment *FirstFakeSegment(index_t fakenode)
156 index_t realnode=fakenode-NODE_FAKE;
158 return(&fake_segments[2*realnode-2]);
162 /*++++++++++++++++++++++++++++++++++++++
163 Finds the next (there can only be two) fake segment associated to a fake node.
165 Segment *NextFakeSegment Returns the second fake segment.
167 Segment *segment The first fake segment.
169 index_t fakenode The node to lookup.
170 ++++++++++++++++++++++++++++++++++++++*/
172 Segment *NextFakeSegment(Segment *segment,index_t fakenode)
174 index_t realnode=fakenode-NODE_FAKE;
176 if(segment==&fake_segments[2*realnode-2])
177 return(&fake_segments[2*realnode-1]);
183 /*++++++++++++++++++++++++++++++++++++++
184 Finds the fake segment between a node and a fake node.
186 Segment *ExtraFakeSegment Returns a segment between the two specified nodes if it exists.
188 index_t node The real node.
190 index_t fakenode The fake node to lookup.
191 ++++++++++++++++++++++++++++++++++++++*/
193 Segment *ExtraFakeSegment(index_t node,index_t fakenode)
195 index_t realnode=fakenode-NODE_FAKE;
197 if(fake_segments[2*realnode-2].node1==node || fake_segments[2*realnode-2].node2==node)
198 return(&fake_segments[2*realnode-2]);
200 if(fake_segments[2*realnode-1].node1==node || fake_segments[2*realnode-1].node2==node)
201 return(&fake_segments[2*realnode-1]);
207 /*++++++++++++++++++++++++++++++++++++++
208 Lookup a fake segment given its index.
210 Segment *LookupFakeSegment Returns a pointer to the segment.
212 index_t fakesegment The index of the fake segment.
213 ++++++++++++++++++++++++++++++++++++++*/
215 Segment *LookupFakeSegment(index_t fakesegment)
217 index_t realsegment=fakesegment-SEGMENT_FAKE;
219 return(&fake_segments[realsegment]);
223 /*++++++++++++++++++++++++++++++++++++++
224 Find the fake index of a fake segment.
226 index_t IndexFakeSegment Returns the fake segment.
228 Segment *segment The segment to look for.
229 ++++++++++++++++++++++++++++++++++++++*/
231 index_t IndexFakeSegment(Segment *segment)
233 index_t realsegment=segment-&fake_segments[0];
235 return(realsegment+SEGMENT_FAKE);