Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /branches/libroutino/src/routino.c
Parent Directory
|
Revision Log
Revision 1738 -
(show annotations)
(download)
(as text)
Thu Jul 9 19:01:12 2015 UTC (9 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 10264 byte(s)
Thu Jul 9 19:01:12 2015 UTC (9 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 10264 byte(s)
Update the library and include a version of the router program that uses the libroutino shared library for calculating routes. Currently generates output files of all types and accepts but ignores all options to change this.
1 | /*************************************** |
2 | Routino library functions file. |
3 | |
4 | Part of the Routino routing software. |
5 | ******************/ /****************** |
6 | This file Copyright 2015 Andrew M. Bishop |
7 | |
8 | 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 | ***************************************/ |
21 | |
22 | #include <stdlib.h> |
23 | |
24 | #include "routino.h" |
25 | |
26 | #include "types.h" |
27 | #include "nodes.h" |
28 | #include "segments.h" |
29 | #include "ways.h" |
30 | #include "relations.h" |
31 | |
32 | #include "fakes.h" |
33 | #include "results.h" |
34 | #include "functions.h" |
35 | #include "profiles.h" |
36 | #include "translations.h" |
37 | |
38 | |
39 | /* Global variables */ |
40 | |
41 | /*+ The options to select the format of the output. +*/ |
42 | int option_html=1,option_gpx_track=1,option_gpx_route=1,option_text=1,option_text_all=1,option_stdout=0; |
43 | |
44 | /*+ The option to calculate the quickest route insted of the shortest. +*/ |
45 | int option_quickest=0; |
46 | |
47 | |
48 | /* Static variables */ |
49 | |
50 | static distance_t distmax=km_to_distance(1); |
51 | |
52 | |
53 | /* Local types */ |
54 | |
55 | struct _Routino_Database |
56 | { |
57 | Nodes *nodes; |
58 | Segments *segments; |
59 | Ways *ways; |
60 | Relations *relations; |
61 | }; |
62 | |
63 | struct _Routino_Waypoint |
64 | { |
65 | index_t segment; |
66 | index_t node1,node2; |
67 | distance_t dist1,dist2; |
68 | }; |
69 | |
70 | |
71 | /*++++++++++++++++++++++++++++++++++++++ |
72 | Select quickest routes. |
73 | ++++++++++++++++++++++++++++++++++++++*/ |
74 | |
75 | DLL_PUBLIC void Routino_Quickest(void) |
76 | { |
77 | option_quickest=1; |
78 | } |
79 | |
80 | |
81 | /*++++++++++++++++++++++++++++++++++++++ |
82 | Select shortest routes. |
83 | ++++++++++++++++++++++++++++++++++++++*/ |
84 | |
85 | DLL_PUBLIC void Routino_Shortest(void) |
86 | { |
87 | option_quickest=0; |
88 | } |
89 | |
90 | |
91 | /*++++++++++++++++++++++++++++++++++++++ |
92 | Load a database of files for Routino to use for routing. |
93 | |
94 | Routino_Database *Routino_LoadDatabase Returns a pointer to the database. |
95 | |
96 | const char *dirname The pathname of the directory containing the database files. |
97 | |
98 | const char *prefix The prefix of the database files. |
99 | ++++++++++++++++++++++++++++++++++++++*/ |
100 | |
101 | DLL_PUBLIC Routino_Database *Routino_LoadDatabase(const char *dirname,const char *prefix) |
102 | { |
103 | char *nodes_filename; |
104 | char *segments_filename; |
105 | char *ways_filename; |
106 | char *relations_filename; |
107 | Routino_Database *database=calloc(sizeof(Routino_Database),1); |
108 | |
109 | nodes_filename =FileName(dirname,prefix,"nodes.mem"); |
110 | segments_filename =FileName(dirname,prefix,"segments.mem"); |
111 | ways_filename =FileName(dirname,prefix,"ways.mem"); |
112 | relations_filename=FileName(dirname,prefix,"relations.mem"); |
113 | |
114 | database->nodes =LoadNodeList (nodes_filename); |
115 | database->segments =LoadSegmentList (segments_filename); |
116 | database->ways =LoadWayList (ways_filename); |
117 | database->relations=LoadRelationList(relations_filename); |
118 | |
119 | free(nodes_filename); |
120 | free(segments_filename); |
121 | free(ways_filename); |
122 | free(relations_filename); |
123 | |
124 | if(!database->nodes || !database->segments || !database->ways || !database->relations) |
125 | { |
126 | Routino_UnloadDatabase(database); |
127 | return(NULL); |
128 | } |
129 | |
130 | return(database); |
131 | } |
132 | |
133 | |
134 | /*++++++++++++++++++++++++++++++++++++++ |
135 | Close the database files that were opened by a call to Routino_LoadDatabase(). |
136 | |
137 | Routino_Database *database The database to close. |
138 | ++++++++++++++++++++++++++++++++++++++*/ |
139 | |
140 | DLL_PUBLIC void Routino_UnloadDatabase(Routino_Database *database) |
141 | { |
142 | if(database->nodes) DestroyNodeList (database->nodes); |
143 | if(database->segments) DestroySegmentList (database->segments); |
144 | if(database->ways) DestroyWayList (database->ways); |
145 | if(database->relations) DestroyRelationList(database->relations); |
146 | |
147 | free(database); |
148 | } |
149 | |
150 | |
151 | /*++++++++++++++++++++++++++++++++++++++ |
152 | Parse a Routino XML file containing profiles, must be called before selecting a profile. |
153 | |
154 | int Routino_ParseXMLProfiles Returns non-zero in case of an error or zero if there was no error. |
155 | |
156 | const char *filename The full pathname of the file to read. |
157 | ++++++++++++++++++++++++++++++++++++++*/ |
158 | |
159 | DLL_PUBLIC int Routino_ParseXMLProfiles(const char *filename) |
160 | { |
161 | return ParseXMLProfiles(filename,NULL,1); |
162 | } |
163 | |
164 | |
165 | /*++++++++++++++++++++++++++++++++++++++ |
166 | Select a specific routing profile from the set of Routino profiles that have been loaded from the XML file or NULL in case of an error. |
167 | |
168 | Routino_Profile *Routino_GetProfile Returns a pointer to an internal data structure - do not free. |
169 | |
170 | const char *name The name of the profile to select. |
171 | ++++++++++++++++++++++++++++++++++++++*/ |
172 | |
173 | DLL_PUBLIC Routino_Profile *Routino_GetProfile(const char *name) |
174 | { |
175 | return GetProfile(name); |
176 | } |
177 | |
178 | |
179 | /*++++++++++++++++++++++++++++++++++++++ |
180 | Free the internal memory that was allocated for the Routino profiles loaded from the XML file. |
181 | ++++++++++++++++++++++++++++++++++++++*/ |
182 | |
183 | DLL_PUBLIC void Routino_FreeXMLProfiles(void) |
184 | { |
185 | FreeXMLProfiles(); |
186 | } |
187 | |
188 | |
189 | /*++++++++++++++++++++++++++++++++++++++ |
190 | Parse a Routino XML file containing translations, must be called before selecting a translation. |
191 | |
192 | int Routino_ParseXMLTranslations Returns non-zero in case of an error or zero if there was no error. |
193 | |
194 | const char *filename The full pathname of the file to read. |
195 | ++++++++++++++++++++++++++++++++++++++*/ |
196 | |
197 | DLL_PUBLIC int Routino_ParseXMLTranslations(const char *filename) |
198 | { |
199 | return ParseXMLTranslations(filename,NULL,1); |
200 | } |
201 | |
202 | |
203 | /*++++++++++++++++++++++++++++++++++++++ |
204 | Select a specific translation from the set of Routino translations that have been loaded from the XML file or NULL in case of an error. |
205 | |
206 | Routino_Translation *Routino_GetTranslation Returns a pointer to an internal data structure - do not free. |
207 | |
208 | const char *language The language to select (as a country code, e.g. 'en', 'de') or NULL for the built-in English version. |
209 | ++++++++++++++++++++++++++++++++++++++*/ |
210 | |
211 | DLL_PUBLIC Routino_Translation *Routino_GetTranslation(const char *language) |
212 | { |
213 | return GetTranslation(language); |
214 | } |
215 | |
216 | |
217 | /*++++++++++++++++++++++++++++++++++++++ |
218 | Free the internal memory that was allocated for the Routino translations loaded from the XML file. |
219 | ++++++++++++++++++++++++++++++++++++++*/ |
220 | |
221 | DLL_PUBLIC void Routino_FreeXMLTranslations(void) |
222 | { |
223 | FreeXMLTranslations(); |
224 | } |
225 | |
226 | |
227 | /*++++++++++++++++++++++++++++++++++++++ |
228 | Finds the nearest point in the database to the specified latitude and longitude. |
229 | |
230 | Routino_Waypoint *Routino_FindWaypoint Returns a pointer to a newly allocated Routino waypoint or NULL if none could be found. |
231 | |
232 | Routino_Database *database The Routino database to use. |
233 | |
234 | Routino_Profile *profile The Routino profile to use. |
235 | |
236 | double latitude The latitude in degrees of the point. |
237 | |
238 | double longitude The longitude in degrees of the point. |
239 | ++++++++++++++++++++++++++++++++++++++*/ |
240 | |
241 | DLL_PUBLIC Routino_Waypoint *Routino_FindWaypoint(Routino_Database *database,Routino_Profile *profile,double latitude,double longitude) |
242 | { |
243 | distance_t dist; |
244 | Routino_Waypoint *waypoint; |
245 | Profile updated_profile; |
246 | |
247 | if(!database) return(NULL); |
248 | if(!profile) return(NULL); |
249 | |
250 | waypoint=calloc(sizeof(Routino_Waypoint),1); |
251 | |
252 | updated_profile=*profile; |
253 | |
254 | if(UpdateProfile(&updated_profile,database->ways)) return(NULL); |
255 | |
256 | waypoint->segment=FindClosestSegment(database->nodes,database->segments,database->ways, |
257 | degrees_to_radians(latitude),degrees_to_radians(longitude),distmax,&updated_profile, |
258 | &dist,&waypoint->node1,&waypoint->node2,&waypoint->dist1,&waypoint->dist2); |
259 | |
260 | if(waypoint->segment==NO_SEGMENT) |
261 | { |
262 | free(waypoint); |
263 | return(NULL); |
264 | } |
265 | |
266 | return(waypoint); |
267 | } |
268 | |
269 | |
270 | /*++++++++++++++++++++++++++++++++++++++ |
271 | Calculate a route using a loaded database, chosen profile, chosen translation and set of waypoints. |
272 | |
273 | int Routino_CalculateRoute Return zero on success or some other value in case of an error. |
274 | |
275 | Routino_Database *database The loaded database to use. |
276 | |
277 | Routino_Profile *profile The chosen routing profile to use. |
278 | |
279 | Routino_Translation *translation The chosen translation information to use. |
280 | |
281 | Routino_Waypoint **waypoints The set of waypoints. |
282 | |
283 | int nwaypoints The number of waypoints. |
284 | ++++++++++++++++++++++++++++++++++++++*/ |
285 | |
286 | DLL_PUBLIC int Routino_CalculateRoute(Routino_Database *database,Routino_Profile *profile,Routino_Translation *translation, |
287 | Routino_Waypoint **waypoints,int nwaypoints) |
288 | { |
289 | int waypoint,retval=0; |
290 | index_t start_node,finish_node=NO_NODE; |
291 | index_t join_segment=NO_SEGMENT; |
292 | Profile updated_profile; |
293 | Results **results=calloc(sizeof(Results*),nwaypoints); |
294 | |
295 | /* Check the input data */ |
296 | |
297 | if(!database) return(1); |
298 | if(!profile) return(2); |
299 | if(!translation) return(3); |
300 | |
301 | updated_profile=*profile; |
302 | |
303 | if(UpdateProfile(&updated_profile,database->ways)) return(4); |
304 | |
305 | /* Loop through all pairs of waypoints */ |
306 | |
307 | for(waypoint=0;waypoint<nwaypoints;waypoint++) |
308 | { |
309 | start_node=finish_node; |
310 | |
311 | finish_node=CreateFakes(database->nodes,database->segments,waypoint+1, |
312 | LookupSegment(database->segments,waypoints[waypoint]->segment,1), |
313 | waypoints[waypoint]->node1,waypoints[waypoint]->node2,waypoints[waypoint]->dist1,waypoints[waypoint]->dist2); |
314 | |
315 | if(waypoint==0) |
316 | continue; |
317 | |
318 | results[waypoint-1]=CalculateRoute(database->nodes,database->segments,database->ways,database->relations, |
319 | &updated_profile,start_node,join_segment,finish_node,waypoint,waypoint+1); |
320 | |
321 | if(!results[waypoint-1]) |
322 | { |
323 | retval=5; |
324 | goto tidy_and_exit; |
325 | } |
326 | |
327 | join_segment=results[waypoint-1]->last_segment; |
328 | } |
329 | |
330 | /* Print the route */ |
331 | |
332 | PrintRoute(results,nwaypoints-1,database->nodes,database->segments,database->ways,&updated_profile,translation); |
333 | |
334 | /* Tidy up and exit */ |
335 | |
336 | tidy_and_exit: |
337 | |
338 | DeleteFakeNodes(); |
339 | |
340 | for(waypoint=0;waypoint<nwaypoints;waypoint++) |
341 | if(results[waypoint]) |
342 | FreeResultsList(results[waypoint]); |
343 | |
344 | free(results); |
345 | |
346 | return(retval); |
347 | } |