/[zanavi_public1]/navit/navit/route.c
ZANavi

Diff of /navit/navit/route.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 26 Revision 27
70#include "roadprofile.h" 70#include "roadprofile.h"
71#include "debug.h" 71#include "debug.h"
72 72
73#include "navit.h" 73#include "navit.h"
74 74
75struct map_priv { 75struct map_priv
76{
76 struct route *route; 77 struct route *route;
77}; 78};
78 79
79int debug_route=0; 80int debug_route = 0;
80 81
81/** 82/**
82 * @brief A point in the route graph 83 * @brief A point in the route graph
83 * 84 *
84 * This represents a point in the route graph. A point usually connects two or more segments, 85 * This represents a point in the route graph. A point usually connects two or more segments,
85 * but there are also points which don't do that (e.g. at the end of a dead-end). 86 * but there are also points which don't do that (e.g. at the end of a dead-end).
86 */ 87 */
87struct route_graph_point { 88struct route_graph_point
89{
88 struct route_graph_point *hash_next; /**< Pointer to a chained hashlist of all route_graph_points with this hash */ 90 struct route_graph_point *hash_next; /**< Pointer to a chained hashlist of all route_graph_points with this hash */
89 struct route_graph_segment *start; /**< Pointer to a list of segments of which this point is the start. The links 91 struct route_graph_segment *start; /**< Pointer to a list of segments of which this point is the start. The links
90 * of this linked-list are in route_graph_segment->start_next.*/ 92 * of this linked-list are in route_graph_segment->start_next.*/
91 struct route_graph_segment *end; /**< Pointer to a list of segments of which this pointer is the end. The links 93 struct route_graph_segment *end; /**< Pointer to a list of segments of which this pointer is the end. The links
92 * of this linked-list are in route_graph_segment->end_next. */ 94 * of this linked-list are in route_graph_segment->end_next. */
93 struct route_graph_segment *seg; /**< Pointer to the segment one should use to reach the destination at 95 struct route_graph_segment *seg; /**< Pointer to the segment one should use to reach the destination at
94 * least costs */ 96 * least costs */
95 struct fibheap_el *el; /**< When this point is put on a Fibonacci heap, this is a pointer 97 struct fibheap_el *el; /**< When this point is put on a Fibonacci heap, this is a pointer
96 * to this point's heap-element */ 98 * to this point's heap-element */
97 int value; /**< The cost at which one can reach the destination from this point on */ 99 int value; /**< The cost at which one can reach the destination from this point on */
98 struct coord c; /**< Coordinates of this point */ 100 struct coord c; /**< Coordinates of this point */
99 int flags; /**< Flags for this point (eg traffic distortion) */ 101 int flags; /**< Flags for this point (eg traffic distortion) */
100}; 102};
101 103
102#define RP_TRAFFIC_DISTORTION 1 104#define RP_TRAFFIC_DISTORTION 1
103#define RP_TURN_RESTRICTION 2 105#define RP_TURN_RESTRICTION 2
104#define RP_TURN_RESTRICTION_RESOLVED 4 106#define RP_TURN_RESTRICTION_RESOLVED 4
107 * @brief A segment in the route graph or path 109 * @brief A segment in the route graph or path
108 * 110 *
109 * This is a segment in the route graph or path. A segment represents a driveable way. 111 * This is a segment in the route graph or path. A segment represents a driveable way.
110 */ 112 */
111 113
112struct route_segment_data { 114struct route_segment_data
115{
113 struct item item; /**< The item (e.g. street) that this segment represents. */ 116 struct item item; /**< The item (e.g. street) that this segment represents. */
114 int flags; 117 int flags;
115 int len; /**< Length of this segment */ 118 int len; /**< Length of this segment */
116 /*NOTE: After a segment, various fields may follow, depending on what flags are set. Order of fields: 119/*NOTE: After a segment, various fields may follow, depending on what flags are set. Order of fields:
117 1.) maxspeed Maximum allowed speed on this segment. Present if AF_SPEED_LIMIT is set. 120 1.) maxspeed Maximum allowed speed on this segment. Present if AF_SPEED_LIMIT is set.
118 2.) offset If the item is segmented (i.e. represented by more than one segment), this 121 2.) offset If the item is segmented (i.e. represented by more than one segment), this
119 indicates the position of this segment in the item. Present if AF_SEGMENTED is set. 122 indicates the position of this segment in the item. Present if AF_SEGMENTED is set.
120 */ 123 */
121}; 124};
122 125
123
124struct size_weight_limit { 126struct size_weight_limit
127{
125 int width; 128 int width;
126 int length; 129 int length;
127 int height; 130 int height;
128 int weight; 131 int weight;
129 int axle_weight; 132 int axle_weight;
132#define RSD_OFFSET(x) *((int *)route_segment_data_field_pos((x), attr_offset)) 135#define RSD_OFFSET(x) *((int *)route_segment_data_field_pos((x), attr_offset))
133#define RSD_MAXSPEED(x) *((int *)route_segment_data_field_pos((x), attr_maxspeed)) 136#define RSD_MAXSPEED(x) *((int *)route_segment_data_field_pos((x), attr_maxspeed))
134#define RSD_SIZE_WEIGHT(x) *((struct size_weight_limit *)route_segment_data_field_pos((x), attr_vehicle_width)) 137#define RSD_SIZE_WEIGHT(x) *((struct size_weight_limit *)route_segment_data_field_pos((x), attr_vehicle_width))
135#define RSD_DANGEROUS_GOODS(x) *((int *)route_segment_data_field_pos((x), attr_vehicle_dangerous_goods)) 138#define RSD_DANGEROUS_GOODS(x) *((int *)route_segment_data_field_pos((x), attr_vehicle_dangerous_goods))
136 139
137
138struct route_graph_segment_data { 140struct route_graph_segment_data
141{
139 struct item *item; 142 struct item *item;
140 int offset; 143 int offset;
141 int flags; 144 int flags;
142 int len; 145 int len;
143 int maxspeed; 146 int maxspeed;
148/** 151/**
149 * @brief A segment in the route graph 152 * @brief A segment in the route graph
150 * 153 *
151 * This is a segment in the route graph. A segment represents a driveable way. 154 * This is a segment in the route graph. A segment represents a driveable way.
152 */ 155 */
153struct route_graph_segment { 156struct route_graph_segment
157{
154 struct route_graph_segment *next; /**< Linked-list pointer to a list of all route_graph_segments */ 158 struct route_graph_segment *next; /**< Linked-list pointer to a list of all route_graph_segments */
155 struct route_graph_segment *start_next; /**< Pointer to the next element in the list of segments that start at the 159 struct route_graph_segment *start_next; /**< Pointer to the next element in the list of segments that start at the
156 * same point. Start of this list is in route_graph_point->start. */ 160 * same point. Start of this list is in route_graph_point->start. */
157 struct route_graph_segment *end_next; /**< Pointer to the next element in the list of segments that end at the 161 struct route_graph_segment *end_next; /**< Pointer to the next element in the list of segments that end at the
158 * same point. Start of this list is in route_graph_point->end. */ 162 * same point. Start of this list is in route_graph_point->end. */
159 struct route_graph_point *start; /**< Pointer to the point this segment starts at. */ 163 struct route_graph_point *start; /**< Pointer to the point this segment starts at. */
160 struct route_graph_point *end; /**< Pointer to the point this segment ends at. */ 164 struct route_graph_point *end; /**< Pointer to the point this segment ends at. */
161 struct route_segment_data data; /**< The segment data */ 165 struct route_segment_data data; /**< The segment data */
162}; 166};
163 167
164/** 168/**
165 * @brief A traffic distortion 169 * @brief A traffic distortion
166 * 170 *
167 * This is distortion in the traffic where you can't drive as fast as usual or have to wait for some time 171 * This is distortion in the traffic where you can't drive as fast as usual or have to wait for some time
168 */ 172 */
169struct route_traffic_distortion { 173struct route_traffic_distortion
174{
170 int maxspeed; /**< Maximum speed possible in km/h */ 175 int maxspeed; /**< Maximum speed possible in km/h */
171 int delay; /**< Delay in tenths of seconds */ 176 int delay; /**< Delay in tenths of seconds */
172}; 177};
173 178
174/** 179/**
175 * @brief A segment in the route path 180 * @brief A segment in the route path
176 * 181 *
177 * This is a segment in the route path. 182 * This is a segment in the route path.
178 */ 183 */
179struct route_path_segment { 184struct route_path_segment
185{
180 struct route_path_segment *next; /**< Pointer to the next segment in the path */ 186 struct route_path_segment *next; /**< Pointer to the next segment in the path */
181 struct route_segment_data *data; /**< The segment data */ 187 struct route_segment_data *data; /**< The segment data */
182 int direction; /**< Order in which the coordinates are ordered. >0 means "First 188 int direction; /**< Order in which the coordinates are ordered. >0 means "First
183 * coordinate of the segment is the first coordinate of the item", <=0 189 * coordinate of the segment is the first coordinate of the item", <=0
184 * means reverse. */ 190 * means reverse. */
185 unsigned ncoords; /**< How many coordinates does this segment have? */ 191 unsigned ncoords; /**< How many coordinates does this segment have? */
186 struct coord c[0]; /**< Pointer to the ncoords coordinates of this segment */ 192 struct coord c[0]; /**< Pointer to the ncoords coordinates of this segment */
187 /* WARNING: There will be coordinates following here, so do not create new fields after c! */ 193/* WARNING: There will be coordinates following here, so do not create new fields after c! */
188}; 194};
189 195
190/**
191 * @brief Usually represents a destination or position
192 *
193 * This struct usually represents a destination or position
194 */
195struct route_info {
196 struct coord c; /**< The actual destination / position */
197 struct coord lp; /**< The nearest point on a street to c */
198 int pos; /**< The position of lp within the coords of the street */
199 int lenpos; /**< Distance between lp and the end of the street */
200 int lenneg; /**< Distance between lp and the start of the street */
201 int lenextra; /**< Distance between lp and c */
202 int percent; /**< ratio of lenneg to lenght of whole street in percent */
203 struct street_data *street; /**< The street lp is on */
204 int street_direction; /**< Direction of vehicle on street -1 = Negative direction, 1 = Positive direction, 0 = Unknown */
205 int dir; /**< Direction to take when following the route -1 = Negative direction, 1 = Positive direction */
206};
207 196
208/** 197/**
209 * @brief A complete route path 198 * @brief A complete route path
210 * 199 *
211 * This structure describes a whole routing path 200 * This structure describes a whole routing path
212 */ 201 */
213struct route_path { 202struct route_path
203{
214 int in_use; /**< The path is in use and can not be updated */ 204 int in_use; /**< The path is in use and can not be updated */
215 int update_required; /**< The path needs to be updated after it is no longer in use */ 205 int update_required; /**< The path needs to be updated after it is no longer in use */
216 int updated; /**< The path has only been updated */ 206 int updated; /**< The path has only been updated */
217 int path_time; /**< Time to pass the path */ 207 int path_time; /**< Time to pass the path */
218 int path_len; /**< Length of the path */ 208 int path_len; /**< Length of the path */
219 struct route_path_segment *path; /**< The first segment in the path, i.e. the segment one should 209 struct route_path_segment *path; /**< The first segment in the path, i.e. the segment one should
220 * drive in next */ 210 * drive in next */
221 struct route_path_segment *path_last; /**< The last segment in the path */ 211 struct route_path_segment *path_last; /**< The last segment in the path */
222 /* XXX: path_hash is not necessery now */ 212 /* XXX: path_hash is not necessery now */
223 struct item_hash *path_hash; /**< A hashtable of all the items represented by this route's segements */ 213 struct item_hash *path_hash; /**< A hashtable of all the items represented by this route's segements */
224 struct route_path *next; /**< Next route path in case of intermediate destinations */ 214 struct route_path *next; /**< Next route path in case of intermediate destinations */
225}; 215};
226 216
227/** 217/**
228 * @brief A complete route 218 * @brief A complete route
229 * 219 *
233/** 223/**
234 * @brief A complete route graph 224 * @brief A complete route graph
235 * 225 *
236 * This structure describes a whole routing graph 226 * This structure describes a whole routing graph
237 */ 227 */
238struct route_graph { 228struct route_graph
229{
239 int busy; /**< The graph is being built */ 230 int busy; /**< The graph is being built */
240 struct map_selection *sel; /**< The rectangle selection for the graph */ 231 struct map_selection *sel; /**< The rectangle selection for the graph */
241 struct mapset_handle *h; /**< Handle to the mapset */ 232 struct mapset_handle *h; /**< Handle to the mapset */
242 struct map *m; /**< Pointer to the currently active map */ 233 struct map *m; /**< Pointer to the currently active map */
243 struct map_rect *mr; /**< Pointer to the currently active map rectangle */ 234 struct map_rect *mr; /**< Pointer to the currently active map rectangle */
244 struct vehicleprofile *vehicleprofile; /**< The vehicle profile */ 235 struct vehicleprofile *vehicleprofile; /**< The vehicle profile */
245 struct callback *idle_cb; /**< Idle callback to process the graph */ 236 struct callback *idle_cb; /**< Idle callback to process the graph */
246 struct callback *done_cb; /**< Callback when graph is done */ 237 struct callback *done_cb; /**< Callback when graph is done */
247 struct event_idle *idle_ev; /**< The pointer to the idle event */ 238 struct event_idle *idle_ev; /**< The pointer to the idle event */
248 struct route_graph_segment *route_segments; /**< Pointer to the first route_graph_segment in the linked list of all segments */ 239 struct route_graph_segment *route_segments; /**< Pointer to the first route_graph_segment in the linked list of all segments */
249#define HASH_SIZE 8192 240#define HASH_SIZE 8192
250 struct route_graph_point *hash[HASH_SIZE]; /**< A hashtable containing all route_graph_points in this graph */ 241 struct route_graph_point *hash[HASH_SIZE]; /**< A hashtable containing all route_graph_points in this graph */
251}; 242};
252 243
253#define HASHCOORD(c) ((((c)->x +(c)->y) * 2654435761UL) & (HASH_SIZE-1)) 244#define HASHCOORD(c) ((((c)->x +(c)->y) * 2654435761UL) & (HASH_SIZE-1))
254 245
255/** 246/**
256 * @brief Iterator to iterate through all route graph segments in a route graph point 247 * @brief Iterator to iterate through all route graph segments in a route graph point
257 * 248 *
258 * This structure can be used to iterate through all route graph segments connected to a 249 * This structure can be used to iterate through all route graph segments connected to a
259 * route graph point. Use this with the rp_iterator_* functions. 250 * route graph point. Use this with the rp_iterator_* functions.
260 */ 251 */
261struct route_graph_point_iterator { 252struct route_graph_point_iterator
253{
262 struct route_graph_point *p; /**< The route graph point whose segments should be iterated */ 254 struct route_graph_point *p; /**< The route graph point whose segments should be iterated */
263 int end; /**< Indicates if we have finished iterating through the "start" segments */ 255 int end; /**< Indicates if we have finished iterating through the "start" segments */
264 struct route_graph_segment *next; /**< The next segment to be returned */ 256 struct route_graph_segment *next; /**< The next segment to be returned */
265}; 257};
266 258
267struct attr_iter { 259struct attr_iter
260{
268 union { 261 union
262 {
269 GList *list; 263 GList *list;
270 } u; 264 } u;
271}; 265};
272 266
273static struct route_info * route_find_nearest_street(struct vehicleprofile *vehicleprofile, struct mapset *ms, struct pcoord *c); 267static struct route_info * route_find_nearest_street(
274static struct route_graph_point *route_graph_get_point(struct route_graph *this, struct coord *c); 268 struct vehicleprofile *vehicleprofile, struct mapset *ms,
269 struct pcoord *c);
270static struct route_graph_point *route_graph_get_point(
271 struct route_graph *this, struct coord *c);
275static void route_graph_update(struct route *this, struct callback *cb, int async); 272static void route_graph_update(struct route *this, struct callback *cb,
273 int async);
276static void route_graph_build_done(struct route_graph *rg, int cancel); 274static void route_graph_build_done(struct route_graph *rg, int cancel);
277static struct route_path *route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile); 275static struct route_path *route_path_new(struct route_graph *this,
278static void route_process_street_graph(struct route_graph *this, struct item *item, struct vehicleprofile *profile); 276 struct route_path *oldpath, struct route_info *pos,
277 struct route_info *dst, struct vehicleprofile *profile);
278static void route_process_street_graph(struct route_graph *this,
279 struct item *item, struct vehicleprofile *profile);
279static void route_graph_destroy(struct route_graph *this); 280//static void route_graph_destroy(struct route_graph *this);
280static void route_path_update(struct route *this, int cancel, int async); 281static void route_path_update(struct route *this, int cancel, int async);
281static int route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over, struct route_traffic_distortion *dist); 282static int route_time_seg(struct vehicleprofile *profile,
282static void route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehicleprofile *profile, struct callback *cb); 283 struct route_segment_data *over, struct route_traffic_distortion *dist);
284static void route_graph_flood(struct route_graph *this, struct route_info *dst,
285 struct vehicleprofile *profile, struct callback *cb);
283static void route_graph_reset(struct route_graph *this); 286static void route_graph_reset(struct route_graph *this);
284
285 287
286/** 288/**
287 * @brief Returns the projection used for this route 289 * @brief Returns the projection used for this route
288 * 290 *
289 * @param route The route to return the projection for 291 * @param route The route to return the projection for
290 * @return The projection used for this route 292 * @return The projection used for this route
291 */ 293 */
292static enum projection route_projection(struct route *route) 294static enum projection route_projection(struct route *route)
293{ 295{
294 struct street_data *street; 296 struct street_data *street;
295 struct route_info *dst=route_get_dst(route); 297 struct route_info *dst = route_get_dst(route);
296 if (!route->pos && !dst) 298 if (!route->pos && !dst)
297 return projection_none; 299 return projection_none;
298 street = route->pos ? route->pos->street : dst->street; 300 street = route->pos ? route->pos->street : dst->street;
299 if (!street || !street->item.map) 301 if (!street || !street->item.map)
300 return projection_none; 302 return projection_none;
308 * iterate through all segments connected to the point. 310 * iterate through all segments connected to the point.
309 * 311 *
310 * @param p The route graph point to create the iterator from 312 * @param p The route graph point to create the iterator from
311 * @return A new iterator. 313 * @return A new iterator.
312 */ 314 */
313static struct route_graph_point_iterator 315static struct route_graph_point_iterator rp_iterator_new(
314rp_iterator_new(struct route_graph_point *p) 316 struct route_graph_point *p)
315{ 317{
316 struct route_graph_point_iterator it; 318 struct route_graph_point_iterator it;
317 319
318 it.p = p; 320 it.p = p;
319 if (p->start) { 321 if (p->start)
322 {
320 it.next = p->start; 323 it.next = p->start;
321 it.end = 0; 324 it.end = 0;
322 } else { 325 }
326 else
327 {
323 it.next = p->end; 328 it.next = p->end;
324 it.end = 1; 329 it.end = 1;
325 } 330 }
326 331
327 return it; 332 return it;
331 * @brief Gets the next segment connected to a route graph point from an iterator 336 * @brief Gets the next segment connected to a route graph point from an iterator
332 * 337 *
333 * @param it The route graph point iterator to get the segment from 338 * @param it The route graph point iterator to get the segment from
334 * @return The next segment or NULL if there are no more segments 339 * @return The next segment or NULL if there are no more segments
335 */ 340 */
336static struct route_graph_segment 341static struct route_graph_segment *rp_iterator_next(
337*rp_iterator_next(struct route_graph_point_iterator *it) 342 struct route_graph_point_iterator *it)
338{ 343{
339 struct route_graph_segment *ret; 344 struct route_graph_segment *ret;
340 345
341 ret = it->next; 346 ret = it->next;
342 if (!ret) { 347 if (!ret)
348 {
343 return NULL; 349 return NULL;
344 } 350 }
345 351
346 if (!it->end) { 352 if (!it->end)
353 {
347 if (ret->start_next) { 354 if (ret->start_next)
355 {
348 it->next = ret->start_next; 356 it->next = ret->start_next;
357 }
349 } else { 358 else
359 {
350 it->next = it->p->end; 360 it->next = it->p->end;
351 it->end = 1; 361 it->end = 1;
352 } 362 }
353 } else { 363 }
364 else
365 {
354 it->next = ret->end_next; 366 it->next = ret->end_next;
355 } 367 }
356 368
357 return ret; 369 return ret;
358} 370}
361 * @brief Checks if the last segment returned from a route_graph_point_iterator comes from the end 373 * @brief Checks if the last segment returned from a route_graph_point_iterator comes from the end
362 * 374 *
363 * @param it The route graph point iterator to be checked 375 * @param it The route graph point iterator to be checked
364 * @return 1 if the last segment returned comes from the end of the route graph point, 0 otherwise 376 * @return 1 if the last segment returned comes from the end of the route graph point, 0 otherwise
365 */ 377 */
366static int
367rp_iterator_end(struct route_graph_point_iterator *it) { 378static int rp_iterator_end(struct route_graph_point_iterator *it)
379{
368 if (it->end && (it->next != it->p->end)) { 380 if (it->end && (it->next != it->p->end))
381 {
369 return 1; 382 return 1;
370 } else { 383 }
384 else
385 {
371 return 0; 386 return 0;
372 } 387 }
373} 388}
374 389
375/** 390/**
376 * @brief Destroys a route_path 391 * @brief Destroys a route_path
377 * 392 *
378 * @param this The route_path to be destroyed 393 * @param this The route_path to be destroyed
379 */ 394 */
380static void
381route_path_destroy(struct route_path *this, int recurse) 395void route_path_destroy(struct route_path *this, int recurse)
382{ 396{
383 struct route_path_segment *c,*n; 397 struct route_path_segment *c, *n;
384 struct route_path *next; 398 struct route_path *next;
385 while (this) { 399 while (this)
400 {
386 next=this->next; 401 next = this->next;
387 if (this->path_hash) { 402 if (this->path_hash)
403 {
388 item_hash_destroy(this->path_hash); 404 item_hash_destroy(this->path_hash);
389 this->path_hash=NULL; 405 this->path_hash = NULL;
390 } 406 }
391 c=this->path; 407 c = this->path;
392 while (c) { 408 while (c)
409 {
393 n=c->next; 410 n = c->next;
394 g_free(c); 411 g_free(c);
395 c=n; 412 c = n;
396 } 413 }
397 this->in_use--; 414 this->in_use--;
398 if (!this->in_use) 415 if (!this->in_use)
399 g_free(this); 416 g_free(this);
400 if (!recurse) 417 if (!recurse)
401 break; 418 break;
402 this=next; 419 this = next;
403 } 420 }
404} 421}
405 422
406/** 423/**
407 * @brief Creates a completely new route structure 424 * @brief Creates a completely new route structure
413route_new(struct attr *parent, struct attr **attrs) 430route_new(struct attr *parent, struct attr **attrs)
414{ 431{
415 struct route *this=g_new0(struct route, 1); 432 struct route *this=g_new0(struct route, 1);
416 struct attr dest_attr; 433 struct attr dest_attr;
417 434
418 if (attr_generic_get_attr(attrs, NULL, attr_destination_distance, &dest_attr, NULL)) { 435 if (attr_generic_get_attr(attrs, NULL, attr_destination_distance,
436 &dest_attr, NULL))
437 {
419 this->destination_distance = dest_attr.u.num; 438 this->destination_distance = dest_attr.u.num;
420 } else { 439 }
440 else
441 {
421 this->destination_distance = 50; // Default value 442 this->destination_distance = 50; // Default value
422 } 443 }
423 this->cbl2=callback_list_new(); 444 this->cbl2 = callback_list_new();
424 445
425 return this; 446 return this;
426} 447}
427 448
428/** 449/**
434 * @param level How deep to scan the route graph 455 * @param level How deep to scan the route graph
435 * @param direction Set this to 1 if we're entering the segment through its end, to 0 otherwise 456 * @param direction Set this to 1 if we're entering the segment through its end, to 0 otherwise
436 * @param origin Used internally, set to NULL 457 * @param origin Used internally, set to NULL
437 * @return 1 If a roundabout was detected, 0 otherwise 458 * @return 1 If a roundabout was detected, 0 otherwise
438 */ 459 */
439static int 460static int route_check_roundabout(struct route_graph_segment *seg, int level,
440route_check_roundabout(struct route_graph_segment *seg, int level, int direction, struct route_graph_segment *origin) 461 int direction, struct route_graph_segment *origin)
441{ 462{
442 struct route_graph_point_iterator it,it2; 463 struct route_graph_point_iterator it, it2;
443 struct route_graph_segment *cur; 464 struct route_graph_segment *cur;
444 int count=0; 465 int count = 0;
445 466
446 if (!level) { 467 if (!level)
468 {
447 return 0; 469 return 0;
448 } 470 }
449 if (!direction && !(seg->data.flags & AF_ONEWAY)) { 471 if (!direction && !(seg->data.flags & AF_ONEWAY))
472 {
450 return 0; 473 return 0;
451 } 474 }
452 if (direction && !(seg->data.flags & AF_ONEWAYREV)) { 475 if (direction && !(seg->data.flags & AF_ONEWAYREV))
476 {
453 return 0; 477 return 0;
454 } 478 }
455 if (seg->data.flags & AF_ROUNDABOUT_VALID) 479 if (seg->data.flags & AF_ROUNDABOUT_VALID)
456 return 0; 480 return 0;
457 481
458 if (!origin) { 482 if (!origin)
483 {
459 origin = seg; 484 origin = seg;
460 } 485 }
461 486
462 if (!direction) { 487 if (!direction)
488 {
463 it = rp_iterator_new(seg->end); 489 it = rp_iterator_new(seg->end);
464 } else { 490 }
491 else
492 {
465 it = rp_iterator_new(seg->start); 493 it = rp_iterator_new(seg->start);
466 } 494 }
467 it2=it; 495 it2 = it;
468 496
469 while ((cur = rp_iterator_next(&it2))) 497 while ((cur = rp_iterator_next(&it2)))
470 count++; 498 count++;
471 499
472 if (count > 3) 500 if (count > 3)
473 return 0; 501 return 0;
474 cur = rp_iterator_next(&it); 502 cur = rp_iterator_next(&it);
475 while (cur) { 503 while (cur)
504 {
476 if (cur == seg) { 505 if (cur == seg)
506 {
477 cur = rp_iterator_next(&it); 507 cur = rp_iterator_next(&it);
478 continue; 508 continue;
479 } 509 }
480 510
481 if (cur->data.item.type != origin->data.item.type) { 511 if (cur->data.item.type != origin->data.item.type)
512 {
482 // This street is of another type, can't be part of the roundabout 513 // This street is of another type, can't be part of the roundabout
483 cur = rp_iterator_next(&it); 514 cur = rp_iterator_next(&it);
484 continue; 515 continue;
485 } 516 }
486 517
487 if (cur == origin) { 518 if (cur == origin)
519 {
488 seg->data.flags |= AF_ROUNDABOUT; 520 seg->data.flags |= AF_ROUNDABOUT;
489 return 1; 521 return 1;
490 } 522 }
491 523
492 if (route_check_roundabout(cur, (level-1), rp_iterator_end(&it), origin)) { 524 if (route_check_roundabout(cur, (level - 1), rp_iterator_end(&it),
525 origin))
526 {
493 seg->data.flags |= AF_ROUNDABOUT; 527 seg->data.flags |= AF_ROUNDABOUT;
494 return 1; 528 return 1;
495 } 529 }
496 530
497 cur = rp_iterator_next(&it); 531 cur = rp_iterator_next(&it);
504 * @brief Sets the mapset of the route passwd 538 * @brief Sets the mapset of the route passwd
505 * 539 *
506 * @param this The route to set the mapset for 540 * @param this The route to set the mapset for
507 * @param ms The mapset to set for this route 541 * @param ms The mapset to set for this route
508 */ 542 */
509void
510route_set_mapset(struct route *this, struct mapset *ms) 543void route_set_mapset(struct route *this, struct mapset *ms)
511{ 544{
512 this->ms=ms; 545 this->ms = ms;
513} 546}
514 547
515/** 548/**
516 * @brief Sets the vehicle profile of a route 549 * @brief Sets the vehicle profile of a route
517 * 550 *
518 * @param this The route to set the profile for 551 * @param this The route to set the profile for
519 * @param prof The vehicle profile 552 * @param prof The vehicle profile
520 */ 553 */
521 554
522void
523route_set_profile(struct route *this, struct vehicleprofile *prof) 555void route_set_profile(struct route *this, struct vehicleprofile *prof)
524{ 556{
525 if (this->vehicleprofile != prof) { 557 if (this->vehicleprofile != prof)
558 {
526 this->vehicleprofile=prof; 559 this->vehicleprofile = prof;
527 route_path_update(this, 1, 1); 560 route_path_update(this, 1, 1);
528 } 561 }
529} 562}
530 563
531/** 564/**
559 * @return The destination of the route passed 592 * @return The destination of the route passed
560 */ 593 */
561struct route_info * 594struct route_info *
562route_get_dst(struct route *this) 595route_get_dst(struct route *this)
563{ 596{
564 struct route_info *dst=NULL; 597 struct route_info *dst = NULL;
565 598
566 if (this->destinations) 599 if (this->destinations)
567 dst=g_list_last(this->destinations)->data; 600 dst = g_list_last(this->destinations)->data;
568 return dst; 601 return dst;
569} 602}
570 603
571/** 604/**
572 * @brief Checks if the path is calculated for the route passed 605 * @brief Checks if the path is calculated for the route passed
573 * 606 *
574 * @param this The route to check 607 * @param this The route to check
575 * @return True if the path is calculated, false if not 608 * @return True if the path is calculated, false if not
576 */ 609 */
577int
578route_get_path_set(struct route *this) 610int route_get_path_set(struct route *this)
579{ 611{
580 return this->path2 != NULL; 612 return this->path2 != NULL;
581} 613}
582 614
583/** 615/**
589 * 621 *
590 * @param this The route to check for this item 622 * @param this The route to check for this item
591 * @param item The item to search for 623 * @param item The item to search for
592 * @return True if the item was found, false if the item was not found or the route was not calculated 624 * @return True if the item was found, false if the item was not found or the route was not calculated
593 */ 625 */
594int
595route_contains(struct route *this, struct item *item) 626int route_contains(struct route *this, struct item *item)
596{ 627{
597 if (! this->path2 || !this->path2->path_hash) 628 if (!this->path2 || !this->path2->path_hash)
598 return 0; 629 return 0;
599 if (item_hash_lookup(this->path2->path_hash, item)) 630 if (item_hash_lookup(this->path2->path_hash, item))
600 return 1; 631 return 1;
601 if (! this->pos || !this->pos->street) 632 if (!this->pos || !this->pos->street)
602 return 0; 633 return 0;
603 return item_is_equal(this->pos->street->item, *item); 634 return item_is_equal(this->pos->street->item, *item);
604 635
605} 636}
606 637
616 * @brief Checks if a route has reached its destination 647 * @brief Checks if a route has reached its destination
617 * 648 *
618 * @param this The route to be checked 649 * @param this The route to be checked
619 * @return True if the destination is "reached", false otherwise. 650 * @return True if the destination is "reached", false otherwise.
620 */ 651 */
621int
622route_destination_reached(struct route *this) 652int route_destination_reached(struct route *this)
623{ 653{
624 struct street_data *sd = NULL; 654 struct street_data *sd = NULL;
625 enum projection pro; 655 enum projection pro;
626 struct route_info *dst=route_next_destination(this); 656 struct route_info *dst = route_next_destination(this);
627 657
628 if (!this->pos) 658 if (!this->pos)
629 return 0; 659 return 0;
630 if (!dst) 660 if (!dst)
631 return 0; 661 return 0;
632 662
633 sd = this->pos->street; 663 sd = this->pos->street;
634 664
635 if (!this->path2) { 665 if (!this->path2)
666 {
636 return 0; 667 return 0;
637 } 668 }
638 669
639 if (!item_is_equal(this->pos->street->item, dst->street->item)) { 670 if (!item_is_equal(this->pos->street->item, dst->street->item))
671 {
640 return 0; 672 return 0;
641 } 673 }
642 674
643 if ((sd->flags & AF_ONEWAY) && (this->pos->lenneg >= dst->lenneg)) { // We would have to drive against the one-way road 675 if ((sd->flags & AF_ONEWAY) && (this->pos->lenneg >= dst->lenneg))
676 { // We would have to drive against the one-way road
644 return 0; 677 return 0;
645 } 678 }
646 if ((sd->flags & AF_ONEWAYREV) && (this->pos->lenpos >= dst->lenpos)) { 679 if ((sd->flags & AF_ONEWAYREV) && (this->pos->lenpos >= dst->lenpos))
680 {
647 return 0; 681 return 0;
648 } 682 }
649 pro=route_projection(this); 683 pro = route_projection(this);
650 if (pro == projection_none) 684 if (pro == projection_none)
651 return 0; 685 return 0;
652 686
653 if (transform_distance(pro, &this->pos->c, &dst->lp) > this->destination_distance) { 687 if (transform_distance(pro, &this->pos->c, &dst->lp)
688 > this->destination_distance)
689 {
654 return 0; 690 return 0;
655 } 691 }
656 692
657 if (g_list_next(this->destinations)) 693 if (g_list_next(this->destinations))
658 return 1; 694 return 1;
659 else 695 else
660 return 2; 696 return 2;
661} 697}
662 698
663static struct route_info * 699static struct route_info *
664route_previous_destination(struct route *this) 700route_previous_destination(struct route *this)
665{ 701{
666 GList *l=g_list_find(this->destinations, this->current_dst); 702 GList *l = g_list_find(this->destinations, this->current_dst);
667 if (!l) 703 if (!l)
668 return this->pos; 704 return this->pos;
669 l=g_list_previous(l); 705 l = g_list_previous(l);
670 if (!l) 706 if (!l)
671 return this->pos; 707 return this->pos;
672 return l->data; 708 return l->data;
673} 709}
674 710
675static void
676route_path_update_done(struct route *this, int new_graph) 711static void route_path_update_done(struct route *this, int new_graph)
677{ 712{
678 struct route_path *oldpath=this->path2; 713 struct route_path *oldpath = this->path2;
679 struct attr route_status; 714 struct attr route_status;
680 struct route_info *prev_dst; 715 struct route_info *prev_dst;
681 route_status.type=attr_route_status; 716 route_status.type = attr_route_status;
682 if (this->path2 && (this->path2->in_use>1)) { 717 if (this->path2 && (this->path2->in_use > 1))
718 {
683 this->path2->update_required=1+new_graph; 719 this->path2->update_required = 1 + new_graph;
684 return; 720 return;
685 } 721 }
686 route_status.u.num=route_status_building_path; 722 route_status.u.num = route_status_building_path;
687 route_set_attr(this, &route_status); 723 route_set_attr(this, &route_status);
688 prev_dst=route_previous_destination(this); 724 prev_dst = route_previous_destination(this);
689 if (this->link_path) { 725 if (this->link_path)
690 this->path2=route_path_new(this->graph, NULL, prev_dst, this->current_dst, this->vehicleprofile); 726 {
727 this->path2 = route_path_new(this->graph, NULL, prev_dst,
728 this->current_dst, this->vehicleprofile);
691 if (this->path2) 729 if (this->path2)
692 this->path2->next=oldpath; 730 this->path2->next = oldpath;
693 } else { 731 }
694 this->path2=route_path_new(this->graph, oldpath, prev_dst, this->current_dst, this->vehicleprofile); 732 else
733 {
734 this->path2 = route_path_new(this->graph, oldpath, prev_dst,
735 this->current_dst, this->vehicleprofile);
695 if (oldpath && this->path2) { 736 if (oldpath && this->path2)
737 {
696 this->path2->next=oldpath->next; 738 this->path2->next = oldpath->next;
697 route_path_destroy(oldpath,0); 739 route_path_destroy(oldpath, 0);
698 }
699 } 740 }
741 }
700 if (this->path2) { 742 if (this->path2)
743 {
701 struct route_path_segment *seg=this->path2->path; 744 struct route_path_segment *seg = this->path2->path;
702 int path_time=0,path_len=0; 745 int path_time = 0, path_len = 0;
703 while (seg) { 746 while (seg)
747 {
704 /* FIXME */ 748 /* FIXME */
749 int seg_time =
705 int seg_time=route_time_seg(this->vehicleprofile, seg->data, NULL); 750 route_time_seg(this->vehicleprofile, seg->data, NULL);
706 if (seg_time == INT_MAX) { 751 if (seg_time == INT_MAX)
752 {
707 dbg(1,"error\n"); 753 dbg(1, "error\n");
754 }
708 } else 755 else
709 path_time+=seg_time; 756 path_time += seg_time;
710 path_len+=seg->data->len; 757 path_len += seg->data->len;
711 seg=seg->next; 758 seg = seg->next;
712 } 759 }
713 this->path2->path_time=path_time; 760 this->path2->path_time = path_time;
714 this->path2->path_len=path_len; 761 this->path2->path_len = path_len;
715 if (prev_dst != this->pos) { 762 if (prev_dst != this->pos)
763 {
716 this->link_path=1; 764 this->link_path = 1;
717 this->current_dst=prev_dst; 765 this->current_dst = prev_dst;
718 route_graph_reset(this->graph); 766 route_graph_reset(this->graph);
719 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, this->route_graph_flood_done_cb); 767 route_graph_flood(this->graph, this->current_dst,
768 this->vehicleprofile, this->route_graph_flood_done_cb);
720 return; 769 return;
721 } 770 }
722 if (!new_graph && this->path2->updated) 771 if (!new_graph && this->path2->updated)
723 { 772 {
724 route_status.u.num=route_status_path_done_incremental; 773 route_status.u.num = route_status_path_done_incremental;
725 } 774 }
726 else 775 else
727 { 776 {
728 route_status.u.num=route_status_path_done_new; 777 route_status.u.num = route_status_path_done_new;
778 }
729 } 779 }
730 }
731 else 780 else
732 { 781 {
733 route_status.u.num=route_status_not_found; 782 route_status.u.num = route_status_not_found;
734 dbg(0,"try harder\n"); 783 dbg(0, "try harder\n");
735 // Try to rebuild the graph with smaller roads 784 // Try to rebuild the graph with smaller roads
736 if (this->try_harder == 0) 785 if (this->try_harder == 0)
737 { 786 {
738 this->try_harder = 1; 787 this->try_harder = 1;
739 route_graph_destroy(this->graph); 788 route_graph_destroy(this->graph);
740 this->graph=NULL; 789 this->graph = NULL;
741 route_path_update(this, 1, 1); 790 route_path_update(this, 1, 1);
742 }
743 } 791 }
792 }
744 this->link_path=0; 793 this->link_path = 0;
745 route_set_attr(this, &route_status); 794 route_set_attr(this, &route_status);
746} 795}
747 796
748/** 797/**
749 * @brief Updates the route graph and the route path if something changed with the route 798 * @brief Updates the route graph and the route path if something changed with the route
754 * @attention For this to work the route graph has to be destroyed if the route's 803 * @attention For this to work the route graph has to be destroyed if the route's
755 * @attention destination is changed somewhere! 804 * @attention destination is changed somewhere!
756 * 805 *
757 * @param this The route to update 806 * @param this The route to update
758 */ 807 */
759static void
760route_path_update(struct route *this, int cancel, int async) 808static void route_path_update(struct route *this, int cancel, int async)
761{ 809{
762 dbg(1,"enter %d\n", cancel); 810 //dbg(1, "enter %d\n", cancel);
763 if (! this->pos || ! this->destinations) { 811 if (!this->pos || !this->destinations)
812 {
764 dbg(1,"destroy\n"); 813 //dbg(1, "destroy\n");
765 route_path_destroy(this->path2,1); 814 route_path_destroy(this->path2, 1);
766 this->path2 = NULL; 815 this->path2 = NULL;
767 return; 816 return;
768 } 817 }
769 if (cancel) { 818 if (cancel)
819 {
770 route_graph_destroy(this->graph); 820 route_graph_destroy(this->graph);
771 this->graph=NULL; 821 this->graph = NULL;
772 } 822 }
773 /* the graph is destroyed when setting the destination */ 823 /* the graph is destroyed when setting the destination */
774 if (this->graph) { 824 if (this->graph)
825 {
775 if (this->graph->busy) { 826 if (this->graph->busy)
827 {
776 dbg(1,"busy building graph\n"); 828 //dbg(1, "busy building graph\n");
777 return; 829 return;
778 } 830 }
779 // we can try to update 831 // we can try to update
780 dbg(1,"try update\n"); 832 //dbg(1, "try update\n");
781 route_path_update_done(this, 0); 833 route_path_update_done(this, 0);
782 } else { 834 }
835 else
836 {
783 route_path_destroy(this->path2,1); 837 route_path_destroy(this->path2, 1);
784 this->path2 = NULL; 838 this->path2 = NULL;
785 } 839 }
786 if (!this->graph || !this->path2) { 840 if (!this->graph || !this->path2)
841 {
787 dbg(1,"rebuild graph\n"); 842 //dbg(1, "rebuild graph\n");
788 if (! this->route_graph_flood_done_cb) 843 if (!this->route_graph_flood_done_cb)
789 this->route_graph_flood_done_cb=callback_new_2(callback_cast(route_path_update_done), this, (long)1); 844 {
845 this->route_graph_flood_done_cb = callback_new_2(
846 callback_cast(route_path_update_done), this, (long) 1);
847 }
790 dbg(1,"route_graph_update\n"); 848 //dbg(1, "route_graph_update\n");
791 route_graph_update(this, this->route_graph_flood_done_cb, async); 849 route_graph_update(this, this->route_graph_flood_done_cb, async);
792 } 850 }
793} 851}
794 852
795/** 853/**
796 * @brief This will calculate all the distances stored in a route_info 854 * @brief This will calculate all the distances stored in a route_info
797 * 855 *
798 * @param ri The route_info to calculate the distances for 856 * @param ri The route_info to calculate the distances for
799 * @param pro The projection used for this route 857 * @param pro The projection used for this route
800 */ 858 */
801static void
802route_info_distances(struct route_info *ri, enum projection pro) 859static void route_info_distances(struct route_info *ri, enum projection pro)
803{ 860{
804 int npos=ri->pos+1; 861 int npos = ri->pos + 1;
805 struct street_data *sd=ri->street; 862 struct street_data *sd = ri->street;
806 /* 0 1 2 X 3 4 5 6 pos=2 npos=3 count=7 0,1,2 3,4,5,6*/ 863 /* 0 1 2 X 3 4 5 6 pos=2 npos=3 count=7 0,1,2 3,4,5,6*/
807 ri->lenextra=transform_distance(pro, &ri->lp, &ri->c); 864 ri->lenextra = transform_distance(pro, &ri->lp, &ri->c);
808 ri->lenneg=transform_polyline_length(pro, sd->c, npos)+transform_distance(pro, &sd->c[ri->pos], &ri->lp); 865 ri->lenneg = transform_polyline_length(pro, sd->c, npos)
809 ri->lenpos=transform_polyline_length(pro, sd->c+npos, sd->count-npos)+transform_distance(pro, &sd->c[npos], &ri->lp); 866 + transform_distance(pro, &sd->c[ri->pos], &ri->lp);
867 ri->lenpos = transform_polyline_length(pro, sd->c + npos, sd->count - npos)
868 + transform_distance(pro, &sd->c[npos], &ri->lp);
810 if (ri->lenneg || ri->lenpos) 869 if (ri->lenneg || ri->lenpos)
811 ri->percent=(ri->lenneg*100)/(ri->lenneg+ri->lenpos); 870 ri->percent = (ri->lenneg * 100) / (ri->lenneg + ri->lenpos);
812 else 871 else
813 ri->percent=50; 872 ri->percent = 50;
814} 873}
815 874
816/** 875/**
817 * @brief This sets the current position of the route passed 876 * @brief This sets the current position of the route passed
818 * 877 *
820 * passed coordinates. It also automatically updates the route. 879 * passed coordinates. It also automatically updates the route.
821 * 880 *
822 * @param this The route to set the position of 881 * @param this The route to set the position of
823 * @param pos Coordinates to set as position 882 * @param pos Coordinates to set as position
824 */ 883 */
825void
826route_set_position(struct route *this, struct pcoord *pos) 884void route_set_position(struct route *this, struct pcoord *pos)
827{ 885{
828 if (this->pos) 886 if (this->pos)
829 route_info_free(this->pos); 887 route_info_free(this->pos);
830 this->pos=NULL; 888 this->pos = NULL;
831 this->pos=route_find_nearest_street(this->vehicleprofile, this->ms, pos); 889 this->pos = route_find_nearest_street(this->vehicleprofile, this->ms, pos);
832 890
833 // If there is no nearest street, bail out. 891 // If there is no nearest street, bail out.
834 if (!this->pos) return; 892 if (!this->pos)
893 return;
835 894
836 this->pos->street_direction=0; 895 this->pos->street_direction = 0;
837 dbg(1,"this->pos=%p\n", this->pos); 896 //dbg(1, "this->pos=%p\n", this->pos);
838 route_info_distances(this->pos, pos->pro); 897 route_info_distances(this->pos, pos->pro);
839 route_path_update(this, 0, 1); 898 route_path_update(this, 0, 1);
840} 899}
841 900
842/** 901/**
843 * @brief Sets a route's current position based on coordinates from tracking 902 * @brief Sets a route's current position based on coordinates from tracking
844 * 903 *
845 * @param this The route to set the current position of 904 * @param this The route to set the current position of
846 * @param tracking The tracking to get the coordinates from 905 * @param tracking The tracking to get the coordinates from
847 */ 906 */
848void 907void route_set_position_from_tracking(struct route *this,
849route_set_position_from_tracking(struct route *this, struct tracking *tracking, enum projection pro) 908 struct tracking *tracking, enum projection pro)
850{ 909{
851 struct coord *c; 910 struct coord *c;
852 struct route_info *ret; 911 struct route_info *ret;
853 struct street_data *sd; 912 struct street_data *sd;
854 913
855 dbg(2,"enter\n"); 914 //dbg(2, "enter\n");
856 c=tracking_get_pos(tracking); 915 c = tracking_get_pos(tracking);
857 ret=g_new0(struct route_info, 1); 916 ret=g_new0(struct route_info, 1);
858 if (!ret) { 917 if (!ret)
918 {
859 printf("%s:Out of memory\n", __FUNCTION__); 919 printf("%s:Out of memory\n", __FUNCTION__);
860 return; 920 return;
861 } 921 }
862 if (this->pos) 922 if (this->pos)
863 route_info_free(this->pos); 923 route_info_free(this->pos);
864 this->pos=NULL; 924 this->pos = NULL;
865 ret->c=*c; 925 ret->c = *c;
866 ret->lp=*c; 926 ret->lp = *c;
867 ret->pos=tracking_get_segment_pos(tracking); 927 ret->pos = tracking_get_segment_pos(tracking);
868 ret->street_direction=tracking_get_street_direction(tracking); 928 ret->street_direction = tracking_get_street_direction(tracking);
869 sd=tracking_get_street_data(tracking); 929 sd = tracking_get_street_data(tracking);
870 if (sd) { 930 if (sd)
931 {
871 ret->street=street_data_dup(sd); 932 ret->street = street_data_dup(sd);
872 route_info_distances(ret, pro); 933 route_info_distances(ret, pro);
873 } 934 }
874 dbg(3,"position 0x%x,0x%x item 0x%x,0x%x direction %d pos %d lenpos %d lenneg %d\n",c->x,c->y,sd?sd->item.id_hi:0,sd?sd->item.id_lo:0,ret->street_direction,ret->pos,ret->lenpos,ret->lenneg); 935 //dbg(
875 dbg(3,"c->x=0x%x, c->y=0x%x pos=%d item=(0x%x,0x%x)\n", c->x, c->y, ret->pos, ret->street?ret->street->item.id_hi:0, ret->street?ret->street->item.id_lo:0); 936 // 3,
876 dbg(3,"street 0=(0x%x,0x%x) %d=(0x%x,0x%x)\n", ret->street?ret->street->c[0].x:0, ret->street?ret->street->c[0].y:0, ret->street?ret->street->count-1:0, ret->street?ret->street->c[ret->street->count-1].x:0, ret->street?ret->street->c[ret->street->count-1].y:0); 937 // "position 0x%x,0x%x item 0x%x,0x%x direction %d pos %d lenpos %d lenneg %d\n",
938 // c->x, c->y, sd ? sd->item.id_hi : 0, sd ? sd->item.id_lo : 0,
939 // ret->street_direction, ret->pos, ret->lenpos, ret->lenneg);
940 //dbg(3, "c->x=0x%x, c->y=0x%x pos=%d item=(0x%x,0x%x)\n", c->x, c->y,
941 // ret->pos, ret->street ? ret->street->item.id_hi : 0,
942 // ret->street ? ret->street->item.id_lo : 0);
943 //dbg(3, "street 0=(0x%x,0x%x) %d=(0x%x,0x%x)\n",
944 // ret->street ? ret->street->c[0].x : 0,
945 // ret->street ? ret->street->c[0].y : 0,
946 // ret->street ? ret->street->count - 1 : 0,
947 // ret->street ? ret->street->c[ret->street->count - 1].x : 0,
948 // ret->street ? ret->street->c[ret->street->count - 1].y : 0);
877 this->pos=ret; 949 this->pos = ret;
878 if (this->destinations) 950 if (this->destinations)
879 route_path_update(this, 0, 1); 951 route_path_update(this, 0, 1);
880 dbg(2,"ret\n"); 952 //dbg(2, "ret\n");
881} 953}
882 954
883/* Used for debuging of route_rect, what routing sees */ 955/* Used for debuging of route_rect, what routing sees */
884struct map_selection *route_selection; 956struct map_selection *route_selection;
885 957
887 * @brief Returns a single map selection 959 * @brief Returns a single map selection
888 */ 960 */
889struct map_selection * 961struct map_selection *
890route_rect(int order, struct coord *c1, struct coord *c2, int rel, int abs) 962route_rect(int order, struct coord *c1, struct coord *c2, int rel, int abs)
891{ 963{
892 int dx,dy,sx=1,sy=1,d,m; 964 int dx, dy, sx = 1, sy = 1, d, m;
893 struct map_selection *sel=g_new(struct map_selection, 1); 965 struct map_selection *sel=g_new(struct map_selection, 1);
894 if (!sel) { 966 if (!sel)
967 {
895 printf("%s:Out of memory\n", __FUNCTION__); 968 printf("%s:Out of memory\n", __FUNCTION__);
896 return sel; 969 return sel;
897 } 970 }
898 sel->order=order; 971 sel->order = order;
899 sel->range.min=route_item_first; 972 sel->range.min = route_item_first;
900 sel->range.max=route_item_last; 973 sel->range.max = route_item_last;
901 dbg(1,"%p %p\n", c1, c2); 974 dbg(1, "%p %p\n", c1, c2);
902 dx=c1->x-c2->x; 975 dx = c1->x - c2->x;
903 dy=c1->y-c2->y; 976 dy = c1->y - c2->y;
904 if (dx < 0) { 977 if (dx < 0)
978 {
905 sx=-1; 979 sx = -1;
906 sel->u.c_rect.lu.x=c1->x; 980 sel->u.c_rect.lu.x = c1->x;
907 sel->u.c_rect.rl.x=c2->x; 981 sel->u.c_rect.rl.x = c2->x;
908 } else {
909 sel->u.c_rect.lu.x=c2->x;
910 sel->u.c_rect.rl.x=c1->x;
911 } 982 }
912 if (dy < 0) {
913 sy=-1;
914 sel->u.c_rect.lu.y=c2->y;
915 sel->u.c_rect.rl.y=c1->y;
916 } else {
917 sel->u.c_rect.lu.y=c1->y;
918 sel->u.c_rect.rl.y=c2->y;
919 }
920 if (dx*sx > dy*sy)
921 d=dx*sx;
922 else 983 else
984 {
985 sel->u.c_rect.lu.x = c2->x;
986 sel->u.c_rect.rl.x = c1->x;
987 }
988 if (dy < 0)
989 {
990 sy = -1;
991 sel->u.c_rect.lu.y = c2->y;
992 sel->u.c_rect.rl.y = c1->y;
993 }
994 else
995 {
996 sel->u.c_rect.lu.y = c1->y;
997 sel->u.c_rect.rl.y = c2->y;
998 }
999 if (dx * sx > dy * sy)
1000 d = dx * sx;
1001 else
923 d=dy*sy; 1002 d = dy * sy;
924 m=d*rel/100+abs; 1003 m = d * rel / 100 + abs;
925 sel->u.c_rect.lu.x-=m; 1004 sel->u.c_rect.lu.x -= m;
926 sel->u.c_rect.rl.x+=m; 1005 sel->u.c_rect.rl.x += m;
927 sel->u.c_rect.lu.y+=m; 1006 sel->u.c_rect.lu.y += m;
928 sel->u.c_rect.rl.y-=m; 1007 sel->u.c_rect.rl.y -= m;
929 sel->next=NULL; 1008 sel->next = NULL;
930 return sel; 1009 return sel;
931} 1010}
932 1011
933/** 1012/**
934 * @brief Returns a list of map selections useable to create a route graph 1013 * @brief Returns a list of map selections useable to create a route graph
939 * 1018 *
940 * @param c1 Corner 1 of the rectangle 1019 * @param c1 Corner 1 of the rectangle
941 * @param c2 Corder 2 of the rectangle 1020 * @param c2 Corder 2 of the rectangle
942 */ 1021 */
943static struct map_selection * 1022static struct map_selection *
944route_calc_selection(struct coord *c, int count, int try_harder) 1023route_calc_selection(struct coord *c, int count, int try_harder)
945{ 1024{
946 struct map_selection *ret,*sel; 1025 struct map_selection *ret, *sel;
947 int i; 1026 int i;
948 struct coord_rect r; 1027 struct coord_rect r;
949 1028
950 if (!count) 1029 if (!count)
951 return NULL; 1030 return NULL;
952 r.lu=c[0]; 1031 r.lu = c[0];
953 r.rl=c[0]; 1032 r.rl = c[0];
954 for (i = 1 ; i < count ; i++) 1033 for (i = 1; i < count; i++)
955 { 1034 {
956 coord_rect_extend(&r, &c[i]); 1035 coord_rect_extend(&r, &c[i]);
957 } 1036 }
958 1037
959 if (routing_mode == 0) 1038 if (routing_mode == 0)
960 { 1039 {
961 // normal highway routing 1040 // normal highway routing
962 // sel=route_rect(4, &r.lu, &r.rl, 25, 0); 1041 // sel=route_rect(4, &r.lu, &r.rl, 25, 0);
963 sel=route_rect(try_harder?6:4, &r.lu, &r.rl, 25, 0); 1042 sel = route_rect(try_harder ? 6 : 4, &r.lu, &r.rl, 25, 0);
964 } 1043 }
965 else if (routing_mode == 1) 1044 else if (routing_mode == 1)
966 { 1045 {
967 // normal roads routing (should take longer and use more roads) 1046 // normal roads routing (should take longer and use more roads)
968 // sel=route_rect(6, &r.lu, &r.rl, 25, 0); 1047 // sel=route_rect(6, &r.lu, &r.rl, 25, 0);
969 sel=route_rect(try_harder?7:6, &r.lu, &r.rl, 25, 0); 1048 sel = route_rect(try_harder ? 7 : 6, &r.lu, &r.rl, 25, 0);
970 } 1049 }
971 else 1050 else
972 { 1051 {
973 // DEFAULT setting 1052 // DEFAULT setting
974 // normal highway routing 1053 // normal highway routing
975 // sel=route_rect(4, &r.lu, &r.rl, 25, 0); 1054 // sel=route_rect(4, &r.lu, &r.rl, 25, 0);
976 sel=route_rect(try_harder?6:4, &r.lu, &r.rl, 25, 0); 1055 sel = route_rect(try_harder ? 6 : 4, &r.lu, &r.rl, 25, 0);
977 } 1056 }
978 1057
979 ret=sel; 1058 ret = sel;
980 for (i = 0 ; i < count ; i++) { 1059 for (i = 0; i < count; i++)
1060 {
981 sel->next=route_rect(8, &c[i], &c[i], 0, 40000); 1061 sel->next = route_rect(8, &c[i], &c[i], 0, 40000);
982 sel=sel->next; 1062 sel = sel->next;
983 sel->next=route_rect(18, &c[i], &c[i], 0, 10000); 1063 sel->next = route_rect(18, &c[i], &c[i], 0, 10000);
984 sel=sel->next; 1064 sel = sel->next;
985 } 1065 }
986 /* route_selection=ret; */ 1066 /* route_selection=ret; */
987 return ret; 1067 return ret;
988} 1068}
989 1069
990/** 1070/**
991 * @brief Destroys a list of map selections 1071 * @brief Destroys a list of map selections
992 * 1072 *
993 * @param sel Start of the list to be destroyed 1073 * @param sel Start of the list to be destroyed
994 */ 1074 */
995static void
996route_free_selection(struct map_selection *sel) 1075static void route_free_selection(struct map_selection *sel)
997{ 1076{
998 struct map_selection *next; 1077 struct map_selection *next;
999 while (sel) { 1078 while (sel)
1079 {
1000 next=sel->next; 1080 next = sel->next;
1001 g_free(sel); 1081 g_free(sel);
1002 sel=next; 1082 sel = next;
1003 } 1083 }
1004} 1084}
1005 1085
1006
1007static void
1008route_clear_destinations(struct route *this_) 1086static void route_clear_destinations(struct route *this_)
1009{ 1087{
1010 g_list_foreach(this_->destinations, (GFunc)route_info_free, NULL); 1088 g_list_foreach(this_->destinations, (GFunc) route_info_free, NULL);
1011 g_list_free(this_->destinations); 1089 g_list_free(this_->destinations);
1012 this_->destinations=NULL; 1090 this_->destinations = NULL;
1013} 1091}
1014 1092
1015/** 1093/**
1016 * @brief Sets the destination of a route 1094 * @brief Sets the destination of a route
1017 * 1095 *
1022 * @param dst Coordinates to set as destination 1100 * @param dst Coordinates to set as destination
1023 * @param count: Number of destinations (last one is final) 1101 * @param count: Number of destinations (last one is final)
1024 * @param async: If set, do routing asynchronously 1102 * @param async: If set, do routing asynchronously
1025 */ 1103 */
1026 1104
1027void
1028route_set_destinations(struct route *this, struct pcoord *dst, int count, int async) 1105void route_set_destinations(struct route *this, struct pcoord *dst, int count, int async)
1029{ 1106{
1030 struct attr route_status; 1107 struct attr route_status;
1031 struct route_info *dsti; 1108 struct route_info *dsti;
1032 int i; 1109 int i;
1033 route_status.type=attr_route_status; 1110 route_status.type = attr_route_status;
1034 1111
1035 profile(0,NULL); 1112 //profile(0,NULL);
1036 route_clear_destinations(this); 1113 route_clear_destinations(this);
1114
1037 if (dst && count) { 1115 if (dst && count)
1116 {
1038 for (i = 0 ; i < count ; i++) { 1117 for (i = 0; i < count; i++)
1118 {
1039 dsti=route_find_nearest_street(this->vehicleprofile, this->ms, &dst[i]); 1119 dsti = route_find_nearest_street(this->vehicleprofile, this->ms, &dst[i]);
1040 if(dsti) { 1120 if (dsti)
1121 {
1122 //dbg(0, "1: x y: %i %i\n", dst[i].x, dst[i].y);
1123 //dbg(0, "2: x y: %i %i\n", dsti->c.x, dsti->c.y);
1041 route_info_distances(dsti, dst->pro); 1124 route_info_distances(dsti, dst->pro);
1042 this->destinations=g_list_append(this->destinations, dsti); 1125 this->destinations = g_list_append(this->destinations, dsti);
1043 }
1044 } 1126 }
1127 }
1045 route_status.u.num=route_status_destination_set; 1128 route_status.u.num = route_status_destination_set;
1046 } else 1129 }
1130 else
1131 {
1047 route_status.u.num=route_status_no_destination; 1132 route_status.u.num = route_status_no_destination;
1133 }
1048 callback_list_call_attr_1(this->cbl2, attr_destination, this); 1134 callback_list_call_attr_1(this->cbl2, attr_destination, this);
1049 route_set_attr(this, &route_status); 1135 route_set_attr(this, &route_status);
1050 profile(1,"find_nearest_street"); 1136 //profile(1,"find_nearest_street");
1051 1137
1052 /* The graph has to be destroyed and set to NULL, otherwise route_path_update() doesn't work */ 1138 /* The graph has to be destroyed and set to NULL, otherwise route_path_update() doesn't work */
1053 route_graph_destroy(this->graph); 1139 route_graph_destroy(this->graph);
1054 this->graph=NULL; 1140 this->graph = NULL;
1055 this->current_dst=route_get_dst(this); 1141 this->current_dst = route_get_dst(this);
1056 this->try_harder=0; 1142 this->try_harder = 0;
1057 route_path_update(this, 1, async); 1143 route_path_update(this, 1, async);
1058 profile(0,"end"); 1144 //profile(0,"end");
1059} 1145}
1060 1146
1061int 1147void route_add_destination(struct route *this, struct pcoord *dst, int async)
1148{
1149 struct attr route_status;
1150 struct route_info *dsti;
1151 route_status.type = attr_route_status;
1152
1153 dsti = route_find_nearest_street(this->vehicleprofile, this->ms, &dst[0]);
1154 if (dsti)
1155 {
1156 //dbg(0, "1: x y: %i %i\n", dst[0].x, dst[0].y);
1157 //dbg(0, "2: x y: %i %i\n", dsti->c.x, dsti->c.y);
1158
1159 route_info_distances(dsti, dst->pro);
1160 this->destinations = g_list_append(this->destinations, dsti);
1161
1162 route_status.u.num = route_status_destination_set;
1163 }
1164
1165 callback_list_call_attr_1(this->cbl2, attr_destination, this);
1166 route_set_attr(this, &route_status);
1167
1168 /* The graph has to be destroyed and set to NULL, otherwise route_path_update() doesn't work */
1169 route_graph_destroy(this->graph);
1170 this->graph = NULL;
1171 this->current_dst = route_get_dst(this);
1172 this->try_harder = 0;
1173 route_path_update(this, 1, async);
1174}
1175
1062route_get_destinations(struct route *this, struct pcoord *pc, int count) 1176int route_get_destinations(struct route *this, struct pcoord *pc, int count)
1063{ 1177{
1064 int ret=0; 1178 int ret = 0;
1065 GList *l=this->destinations; 1179 GList *l = this->destinations;
1066 while (l && ret < count) { 1180 while (l && ret < count)
1181 {
1067 struct route_info *dst=l->data; 1182 struct route_info *dst = l->data;
1068 pc->x=dst->c.x; 1183 pc->x = dst->c.x;
1069 pc->y=dst->c.y; 1184 pc->y = dst->c.y;
1070 pc->pro=projection_mg; /* FIXME */ 1185 pc->pro = projection_mg; /* FIXME */
1071 pc++; 1186 pc++;
1072 ret++; 1187 ret++;
1073 l=g_list_next(l); 1188 l = g_list_next(l);
1074 } 1189 }
1075 return ret; 1190 return ret;
1076} 1191}
1077 1192
1078void
1079route_set_destination(struct route *this, struct pcoord *dst, int async) 1193void route_set_destination(struct route *this, struct pcoord *dst, int async)
1080{ 1194{
1081 route_set_destinations(this, dst, dst?1:0, async); 1195 route_set_destinations(this, dst, dst ? 1 : 0, async);
1082} 1196}
1083 1197
1084void
1085route_remove_waypoint(struct route *this) 1198void route_remove_waypoint(struct route *this)
1086{ 1199{
1087 struct route_path *path=this->path2; 1200 struct route_path *path = this->path2;
1088 this->destinations=g_list_remove(this->destinations,this->destinations->data); 1201 this->destinations = g_list_remove(this->destinations,
1202 this->destinations->data);
1089 this->path2=this->path2->next; 1203 this->path2 = this->path2->next;
1090 route_path_destroy(path,0); 1204 route_path_destroy(path, 0);
1091 if (!this->destinations) 1205 if (!this->destinations)
1092 return; 1206 return;
1093 route_graph_reset(this->graph); 1207 route_graph_reset(this->graph);
1094 this->current_dst=this->destinations->data; 1208 this->current_dst = this->destinations->data;
1095 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, this->route_graph_flood_done_cb); 1209 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile,
1096 1210 this->route_graph_flood_done_cb);
1211
1097} 1212}
1098 1213
1099/** 1214/**
1100 * @brief Gets the route_graph_point with the specified coordinates 1215 * @brief Gets the route_graph_point with the specified coordinates
1101 * 1216 *
1103 * @param c Coordinates to search for 1218 * @param c Coordinates to search for
1104 * @param last The last route graph point returned to iterate over multiple points with the same coordinates 1219 * @param last The last route graph point returned to iterate over multiple points with the same coordinates
1105 * @return The point at the specified coordinates or NULL if not found 1220 * @return The point at the specified coordinates or NULL if not found
1106 */ 1221 */
1107static struct route_graph_point * 1222static struct route_graph_point *
1108route_graph_get_point_next(struct route_graph *this, struct coord *c, struct route_graph_point *last) 1223route_graph_get_point_next(struct route_graph *this, struct coord *c,
1224 struct route_graph_point *last)
1109{ 1225{
1110 struct route_graph_point *p; 1226 struct route_graph_point *p;
1111 int seen=0,hashval=HASHCOORD(c); 1227 int seen = 0, hashval = HASHCOORD(c);
1112 p=this->hash[hashval]; 1228 p = this->hash[hashval];
1113 while (p) { 1229 while (p)
1230 {
1114 if (p->c.x == c->x && p->c.y == c->y) { 1231 if (p->c.x == c->x && p->c.y == c->y)
1232 {
1115 if (!last || seen) 1233 if (!last || seen)
1116 return p; 1234 return p;
1117 if (p == last) 1235 if (p == last)
1118 seen=1; 1236 seen = 1;
1119 } 1237 }
1120 p=p->hash_next; 1238 p = p->hash_next;
1121 } 1239 }
1122 return NULL; 1240 return NULL;
1123} 1241}
1124 1242
1125static struct route_graph_point * 1243static struct route_graph_point *
1136 * @return The point at the specified coordinates or NULL if not found 1254 * @return The point at the specified coordinates or NULL if not found
1137 */ 1255 */
1138static struct route_graph_point * 1256static struct route_graph_point *
1139route_graph_get_point_last(struct route_graph *this, struct coord *c) 1257route_graph_get_point_last(struct route_graph *this, struct coord *c)
1140{ 1258{
1141 struct route_graph_point *p,*ret=NULL; 1259 struct route_graph_point *p, *ret = NULL;
1142 int hashval=HASHCOORD(c); 1260 int hashval = HASHCOORD(c);
1143 p=this->hash[hashval]; 1261 p = this->hash[hashval];
1144 while (p) { 1262 while (p)
1263 {
1145 if (p->c.x == c->x && p->c.y == c->y) 1264 if (p->c.x == c->x && p->c.y == c->y)
1146 ret=p; 1265 ret = p;
1147 p=p->hash_next; 1266 p = p->hash_next;
1148 } 1267 }
1149 return ret; 1268 return ret;
1150} 1269}
1151
1152
1153 1270
1154/** 1271/**
1155 * @brief Create a new point for the route graph with the specified coordinates 1272 * @brief Create a new point for the route graph with the specified coordinates
1156 * 1273 *
1157 * @param this The route to insert the point into 1274 * @param this The route to insert the point into
1163route_graph_point_new(struct route_graph *this, struct coord *f) 1280route_graph_point_new(struct route_graph *this, struct coord *f)
1164{ 1281{
1165 int hashval; 1282 int hashval;
1166 struct route_graph_point *p; 1283 struct route_graph_point *p;
1167 1284
1168 hashval=HASHCOORD(f); 1285 hashval = HASHCOORD(f);
1169 if (debug_route) 1286 if (debug_route)
1170 printf("p (0x%x,0x%x)\n", f->x, f->y); 1287 printf("p (0x%x,0x%x)\n", f->x, f->y);
1171 p=g_slice_new0(struct route_graph_point); 1288 p=g_slice_new0(struct route_graph_point);
1172 p->hash_next=this->hash[hashval]; 1289 p->hash_next = this->hash[hashval];
1173 this->hash[hashval]=p; 1290 this->hash[hashval] = p;
1174 p->value=INT_MAX; 1291 p->value = INT_MAX;
1175 p->c=*f; 1292 p->c = *f;
1176 return p; 1293 return p;
1177} 1294}
1178 1295
1179/** 1296/**
1180 * @brief Inserts a point into the route graph at the specified coordinates 1297 * @brief Inserts a point into the route graph at the specified coordinates
1189static struct route_graph_point * 1306static struct route_graph_point *
1190route_graph_add_point(struct route_graph *this, struct coord *f) 1307route_graph_add_point(struct route_graph *this, struct coord *f)
1191{ 1308{
1192 struct route_graph_point *p; 1309 struct route_graph_point *p;
1193 1310
1194 p=route_graph_get_point(this,f); 1311 p = route_graph_get_point(this, f);
1195 if (!p) 1312 if (!p)
1196 p=route_graph_point_new(this,f); 1313 p = route_graph_point_new(this, f);
1197 return p; 1314 return p;
1198} 1315}
1199 1316
1200/** 1317/**
1201 * @brief Frees all the memory used for points in the route graph passed 1318 * @brief Frees all the memory used for points in the route graph passed
1202 * 1319 *
1203 * @param this The route graph to delete all points from 1320 * @param this The route graph to delete all points from
1204 */ 1321 */
1205static void
1206route_graph_free_points(struct route_graph *this) 1322static void route_graph_free_points(struct route_graph *this)
1207{ 1323{
1208 struct route_graph_point *curr,*next; 1324 struct route_graph_point *curr, *next;
1209 int i; 1325 int i;
1210 for (i = 0 ; i < HASH_SIZE ; i++) { 1326 for (i = 0; i < HASH_SIZE; i++)
1327 {
1211 curr=this->hash[i]; 1328 curr = this->hash[i];
1212 while (curr) { 1329 while (curr)
1330 {
1213 next=curr->hash_next; 1331 next = curr->hash_next;
1214 g_slice_free(struct route_graph_point, curr); 1332 g_slice_free(struct route_graph_point, curr);
1215 curr=next; 1333 curr = next;
1216 } 1334 }
1217 this->hash[i]=NULL; 1335 this->hash[i] = NULL;
1218 } 1336 }
1219} 1337}
1220 1338
1221/** 1339/**
1222 * @brief Resets all nodes 1340 * @brief Resets all nodes
1223 * 1341 *
1224 * @param this The route graph to reset 1342 * @param this The route graph to reset
1225 */ 1343 */
1226static void
1227route_graph_reset(struct route_graph *this) 1344static void route_graph_reset(struct route_graph *this)
1228{ 1345{
1229 struct route_graph_point *curr; 1346 struct route_graph_point *curr;
1230 int i; 1347 int i;
1231 for (i = 0 ; i < HASH_SIZE ; i++) { 1348 for (i = 0; i < HASH_SIZE; i++)
1349 {
1232 curr=this->hash[i]; 1350 curr = this->hash[i];
1233 while (curr) { 1351 while (curr)
1352 {
1234 curr->value=INT_MAX; 1353 curr->value = INT_MAX;
1235 curr->seg=NULL; 1354 curr->seg = NULL;
1236 curr->el=NULL; 1355 curr->el = NULL;
1237 curr=curr->hash_next; 1356 curr = curr->hash_next;
1238 } 1357 }
1239 } 1358 }
1240} 1359}
1241 1360
1242/** 1361/**
1248 * @param seg The route graph segment the field is appended to 1367 * @param seg The route graph segment the field is appended to
1249 * @param type Type of the field that should be returned 1368 * @param type Type of the field that should be returned
1250 * @return A pointer to a field of a certain type, or NULL if no such field is present 1369 * @return A pointer to a field of a certain type, or NULL if no such field is present
1251 */ 1370 */
1252static void * 1371static void *
1253route_segment_data_field_pos(struct route_segment_data *seg, enum attr_type type) 1372route_segment_data_field_pos(struct route_segment_data *seg,
1373 enum attr_type type)
1254{ 1374{
1255 unsigned char *ptr; 1375 unsigned char *ptr;
1256 1376
1257 ptr = ((unsigned char*)seg) + sizeof(struct route_segment_data); 1377 ptr = ((unsigned char*) seg) + sizeof(struct route_segment_data);
1258 1378
1259 if (seg->flags & AF_SPEED_LIMIT) { 1379 if (seg->flags & AF_SPEED_LIMIT)
1380 {
1260 if (type == attr_maxspeed) 1381 if (type == attr_maxspeed)
1261 return (void*)ptr; 1382 return (void*) ptr;
1262 ptr += sizeof(int); 1383 ptr += sizeof(int);
1263 } 1384 }
1264 if (seg->flags & AF_SEGMENTED) { 1385 if (seg->flags & AF_SEGMENTED)
1386 {
1265 if (type == attr_offset) 1387 if (type == attr_offset)
1266 return (void*)ptr; 1388 return (void*) ptr;
1267 ptr += sizeof(int); 1389 ptr += sizeof(int);
1268 } 1390 }
1269 if (seg->flags & AF_SIZE_OR_WEIGHT_LIMIT) { 1391 if (seg->flags & AF_SIZE_OR_WEIGHT_LIMIT)
1392 {
1270 if (type == attr_vehicle_width) 1393 if (type == attr_vehicle_width)
1271 return (void*)ptr; 1394 return (void*) ptr;
1272 ptr += sizeof(struct size_weight_limit); 1395 ptr += sizeof(struct size_weight_limit);
1273 } 1396 }
1274 if (seg->flags & AF_DANGEROUS_GOODS) { 1397 if (seg->flags & AF_DANGEROUS_GOODS)
1398 {
1275 if (type == attr_vehicle_dangerous_goods) 1399 if (type == attr_vehicle_dangerous_goods)
1276 return (void*)ptr; 1400 return (void*) ptr;
1277 ptr += sizeof(int); 1401 ptr += sizeof(int);
1278 } 1402 }
1279 return NULL; 1403 return NULL;
1280} 1404}
1281 1405
1283 * @brief Calculates the size of a route_segment_data struct with given flags 1407 * @brief Calculates the size of a route_segment_data struct with given flags
1284 * 1408 *
1285 * @param flags The flags of the route_segment_data 1409 * @param flags The flags of the route_segment_data
1286 */ 1410 */
1287 1411
1288static int
1289route_segment_data_size(int flags) 1412static int route_segment_data_size(int flags)
1290{ 1413{
1291 int ret=sizeof(struct route_segment_data); 1414 int ret = sizeof(struct route_segment_data);
1292 if (flags & AF_SPEED_LIMIT) 1415 if (flags & AF_SPEED_LIMIT)
1293 ret+=sizeof(int); 1416 ret += sizeof(int);
1294 if (flags & AF_SEGMENTED) 1417 if (flags & AF_SEGMENTED)
1295 ret+=sizeof(int); 1418 ret += sizeof(int);
1296 if (flags & AF_SIZE_OR_WEIGHT_LIMIT) 1419 if (flags & AF_SIZE_OR_WEIGHT_LIMIT)
1297 ret+=sizeof(struct size_weight_limit); 1420 ret += sizeof(struct size_weight_limit);
1298 if (flags & AF_DANGEROUS_GOODS) 1421 if (flags & AF_DANGEROUS_GOODS)
1299 ret+=sizeof(int); 1422 ret += sizeof(int);
1300 return ret; 1423 return ret;
1301} 1424}
1302 1425
1303 1426static int route_graph_segment_is_duplicate(struct route_graph_point *start,
1304static int 1427 struct route_graph_segment_data *data)
1305route_graph_segment_is_duplicate(struct route_graph_point *start, struct route_graph_segment_data *data)
1306{ 1428{
1307 struct route_graph_segment *s; 1429 struct route_graph_segment *s;
1308 s=start->start; 1430 s = start->start;
1309 while (s) { 1431 while (s)
1432 {
1310 if (item_is_equal(*data->item, s->data.item)) { 1433 if (item_is_equal(*data->item, s->data.item))
1434 {
1311 if (data->flags & AF_SEGMENTED) { 1435 if (data->flags & AF_SEGMENTED)
1436 {
1312 if (RSD_OFFSET(&s->data) == data->offset) { 1437 if (RSD_OFFSET(&s->data) == data->offset)
1438 {
1313 return 1; 1439 return 1;
1314 } 1440 }
1441 }
1315 } else 1442 else
1316 return 1; 1443 return 1;
1317 } 1444 }
1318 s=s->start_next; 1445 s = s->start_next;
1319 } 1446 }
1320 return 0; 1447 return 0;
1321} 1448}
1322 1449
1323/** 1450/**
1324 * @brief Inserts a new segment into the route graph 1451 * @brief Inserts a new segment into the route graph
1333 * @param item The item that is represented by this segment 1460 * @param item The item that is represented by this segment
1334 * @param flags Flags for this segment 1461 * @param flags Flags for this segment
1335 * @param offset If the item passed in "item" is segmented (i.e. divided into several segments), this indicates the position of this segment within the item 1462 * @param offset If the item passed in "item" is segmented (i.e. divided into several segments), this indicates the position of this segment within the item
1336 * @param maxspeed The maximum speed allowed on this segment in km/h. -1 if not known. 1463 * @param maxspeed The maximum speed allowed on this segment in km/h. -1 if not known.
1337 */ 1464 */
1338static void 1465static void route_graph_add_segment(struct route_graph *this,
1339route_graph_add_segment(struct route_graph *this, struct route_graph_point *start,
1340 struct route_graph_point *end, struct route_graph_segment_data *data) 1466 struct route_graph_point *start, struct route_graph_point *end,
1467 struct route_graph_segment_data *data)
1341{ 1468{
1342 struct route_graph_segment *s; 1469 struct route_graph_segment *s;
1343 int size; 1470 int size;
1344 1471
1345 size = sizeof(struct route_graph_segment)-sizeof(struct route_segment_data)+route_segment_data_size(data->flags); 1472 size = sizeof(struct route_graph_segment)
1473 - sizeof(struct route_segment_data) + route_segment_data_size(
1474 data->flags);
1346 s = g_slice_alloc0(size); 1475 s = g_slice_alloc0(size);
1347 if (!s) { 1476 if (!s)
1477 {
1348 printf("%s:Out of memory\n", __FUNCTION__); 1478 printf("%s:Out of memory\n", __FUNCTION__);
1349 return; 1479 return;
1350 } 1480 }
1351 s->start=start; 1481 s->start = start;
1352 s->start_next=start->start; 1482 s->start_next = start->start;
1353 start->start=s; 1483 start->start = s;
1354 s->end=end; 1484 s->end = end;
1355 s->end_next=end->end; 1485 s->end_next = end->end;
1356 end->end=s; 1486 end->end = s;
1357 dbg_assert(data->len >= 0); 1487 dbg_assert(data->len >= 0);
1358 s->data.len=data->len; 1488 s->data.len = data->len;
1359 s->data.item=*data->item; 1489 s->data.item = *data->item;
1360 s->data.flags=data->flags; 1490 s->data.flags = data->flags;
1361 1491
1362 if (data->flags & AF_SPEED_LIMIT) 1492 if (data->flags & AF_SPEED_LIMIT)
1363 RSD_MAXSPEED(&s->data)=data->maxspeed; 1493 RSD_MAXSPEED(&s->data) = data->maxspeed;
1364 if (data->flags & AF_SEGMENTED) 1494 if (data->flags & AF_SEGMENTED)
1365 RSD_OFFSET(&s->data)=data->offset; 1495 RSD_OFFSET(&s->data) = data->offset;
1366 if (data->flags & AF_SIZE_OR_WEIGHT_LIMIT) 1496 if (data->flags & AF_SIZE_OR_WEIGHT_LIMIT)
1367 RSD_SIZE_WEIGHT(&s->data)=data->size_weight; 1497 RSD_SIZE_WEIGHT(&s->data) = data->size_weight;
1368 if (data->flags & AF_DANGEROUS_GOODS) 1498 if (data->flags & AF_DANGEROUS_GOODS)
1369 RSD_DANGEROUS_GOODS(&s->data)=data->dangerous_goods; 1499 RSD_DANGEROUS_GOODS(&s->data) = data->dangerous_goods;
1370 1500
1371 s->next=this->route_segments; 1501 s->next = this->route_segments;
1372 this->route_segments=s; 1502 this->route_segments = s;
1373 if (debug_route) 1503 if (debug_route)
1374 printf("l (0x%x,0x%x)-(0x%x,0x%x)\n", start->c.x, start->c.y, end->c.x, end->c.y); 1504 printf("l (0x%x,0x%x)-(0x%x,0x%x)\n", start->c.x, start->c.y, end->c.x,
1505 end->c.y);
1375} 1506}
1376 1507
1377/** 1508/**
1378 * @brief Gets all the coordinates of an item 1509 * @brief Gets all the coordinates of an item
1379 * 1510 *
1397{ 1528{
1398 struct map_rect *mr; 1529 struct map_rect *mr;
1399 struct item *item; 1530 struct item *item;
1400 int rc = 0, p = 0; 1531 int rc = 0, p = 0;
1401 struct coord c1; 1532 struct coord c1;
1402 mr=map_rect_new(i->map, NULL); 1533 mr = map_rect_new(i->map, NULL);
1403 if (!mr) 1534 if (!mr)
1404 return 0; 1535 return 0;
1405 item = map_rect_get_item_byid(mr, i->id_hi, i->id_lo); 1536 item = map_rect_get_item_byid(mr, i->id_hi, i->id_lo);
1406 if (item) { 1537 if (item)
1538 {
1407 rc = item_coord_get(item, &c1, 1); 1539 rc = item_coord_get(item, &c1, 1);
1408 while (rc && (c1.x != start->x || c1.y != start->y)) { 1540 while (rc && (c1.x != start->x || c1.y != start->y))
1541 {
1409 rc = item_coord_get(item, &c1, 1); 1542 rc = item_coord_get(item, &c1, 1);
1410 } 1543 }
1411 while (rc && p < max) { 1544 while (rc && p < max)
1545 {
1412 c[p++] = c1; 1546 c[p++] = c1;
1413 if (c1.x == end->x && c1.y == end->y) 1547 if (c1.x == end->x && c1.y == end->y)
1414 break; 1548 break;
1415 rc = item_coord_get(item, &c1, 1); 1549 rc = item_coord_get(item, &c1, 1);
1416 } 1550 }
1427 * @param offset Offset of the segment within the item to remove. If the item is not segmented this should be 1. 1561 * @param offset Offset of the segment within the item to remove. If the item is not segmented this should be 1.
1428 * @return The segment removed 1562 * @return The segment removed
1429 */ 1563 */
1430static struct route_path_segment * 1564static struct route_path_segment *
1431route_extract_segment_from_path(struct route_path *path, struct item *item, 1565route_extract_segment_from_path(struct route_path *path, struct item *item,
1432 int offset) 1566 int offset)
1433{ 1567{
1434 int soffset; 1568 int soffset;
1435 struct route_path_segment *sp = NULL, *s; 1569 struct route_path_segment *sp = NULL, *s;
1436 s = path->path; 1570 s = path->path;
1437 while (s) { 1571 while (s)
1572 {
1438 if (item_is_equal(s->data->item,*item)) { 1573 if (item_is_equal(s->data->item, *item))
1574 {
1439 if (s->data->flags & AF_SEGMENTED) 1575 if (s->data->flags & AF_SEGMENTED)
1440 soffset=RSD_OFFSET(s->data); 1576 soffset = RSD_OFFSET(s->data);
1441 else 1577 else
1442 soffset=1; 1578 soffset = 1;
1443 if (soffset == offset) { 1579 if (soffset == offset)
1580 {
1444 if (sp) { 1581 if (sp)
1582 {
1445 sp->next = s->next; 1583 sp->next = s->next;
1446 break; 1584 break;
1585 }
1447 } else { 1586 else
1587 {
1448 path->path = s->next; 1588 path->path = s->next;
1449 break; 1589 break;
1450 } 1590 }
1451 } 1591 }
1452 } 1592 }
1462 * @brief Adds a segment and the end of a path 1602 * @brief Adds a segment and the end of a path
1463 * 1603 *
1464 * @param this The path to add the segment to 1604 * @param this The path to add the segment to
1465 * @param segment The segment to add 1605 * @param segment The segment to add
1466 */ 1606 */
1467static void 1607static void route_path_add_segment(struct route_path *this,
1468route_path_add_segment(struct route_path *this, struct route_path_segment *segment) 1608 struct route_path_segment *segment)
1469{ 1609{
1470 if (!this->path) 1610 if (!this->path)
1471 this->path=segment; 1611 this->path = segment;
1472 if (this->path_last) 1612 if (this->path_last)
1473 this->path_last->next=segment; 1613 this->path_last->next = segment;
1474 this->path_last=segment; 1614 this->path_last = segment;
1475} 1615}
1476 1616
1477/** 1617/**
1478 * @brief Adds a two coordinate line to a path 1618 * @brief Adds a two coordinate line to a path
1479 * 1619 *
1482 * @param this The path to add the item to 1622 * @param this The path to add the item to
1483 * @param start coordinate to add to the start of the item. If none should be added, make this NULL. 1623 * @param start coordinate to add to the start of the item. If none should be added, make this NULL.
1484 * @param end coordinate to add to the end of the item. If none should be added, make this NULL. 1624 * @param end coordinate to add to the end of the item. If none should be added, make this NULL.
1485 * @param len The length of the item 1625 * @param len The length of the item
1486 */ 1626 */
1487static void
1488route_path_add_line(struct route_path *this, struct coord *start, struct coord *end, int len) 1627static void route_path_add_line(struct route_path *this, struct coord *start,
1628 struct coord *end, int len)
1489{ 1629{
1490 int ccnt=2; 1630 int ccnt = 2;
1491 struct route_path_segment *segment; 1631 struct route_path_segment *segment;
1492 int seg_size,seg_dat_size; 1632 int seg_size, seg_dat_size;
1493 1633
1494 dbg(1,"line from 0x%x,0x%x-0x%x,0x%x\n", start->x, start->y, end->x, end->y); 1634 //dbg(1, "line from 0x%x,0x%x-0x%x,0x%x\n", start->x, start->y, end->x,
1635 // end->y);
1495 seg_size=sizeof(*segment) + sizeof(struct coord) * ccnt; 1636 seg_size = sizeof(*segment) + sizeof(struct coord) * ccnt;
1496 seg_dat_size=sizeof(struct route_segment_data); 1637 seg_dat_size = sizeof(struct route_segment_data);
1497 segment=g_malloc0(seg_size + seg_dat_size); 1638 segment = g_malloc0(seg_size + seg_dat_size);
1498 segment->data=(struct route_segment_data *)((char *)segment+seg_size); 1639 segment->data = (struct route_segment_data *) ((char *) segment + seg_size);
1499 segment->ncoords=ccnt; 1640 segment->ncoords = ccnt;
1500 segment->direction=0; 1641 segment->direction = 0;
1501 segment->c[0]=*start; 1642 segment->c[0] = *start;
1502 segment->c[1]=*end; 1643 segment->c[1] = *end;
1503 segment->data->len=len; 1644 segment->data->len = len;
1504 route_path_add_segment(this, segment); 1645 route_path_add_segment(this, segment);
1505} 1646}
1506 1647
1507/** 1648/**
1508 * @brief Inserts a new item into the path 1649 * @brief Inserts a new item into the path
1522 * @param dir Order in which to add the coordinates. See route_path_add_item() 1663 * @param dir Order in which to add the coordinates. See route_path_add_item()
1523 * @param pos Information about start point if this is the first segment 1664 * @param pos Information about start point if this is the first segment
1524 * @param dst Information about end point if this is the last segment 1665 * @param dst Information about end point if this is the last segment
1525 */ 1666 */
1526 1667
1527static int 1668static int route_path_add_item_from_graph(struct route_path *this,
1528route_path_add_item_from_graph(struct route_path *this, struct route_path *oldpath, struct route_graph_segment *rgs, int dir, struct route_info *pos, struct route_info *dst) 1669 struct route_path *oldpath, struct route_graph_segment *rgs, int dir,
1670 struct route_info *pos, struct route_info *dst)
1529{ 1671{
1530 struct route_path_segment *segment; 1672 struct route_path_segment *segment;
1531 int i, ccnt, extra=0, ret=0; 1673 int i, ccnt, extra = 0, ret = 0;
1532 struct coord *c,*cd,ca[2048]; 1674 struct coord *c, *cd, ca[2048];
1533 int offset=1; 1675 int offset = 1;
1534 int seg_size,seg_dat_size; 1676 int seg_size, seg_dat_size;
1535 int len=rgs->data.len; 1677 int len = rgs->data.len;
1536 if (rgs->data.flags & AF_SEGMENTED) 1678 if (rgs->data.flags & AF_SEGMENTED)
1679 {
1537 offset=RSD_OFFSET(&rgs->data); 1680 offset = RSD_OFFSET(&rgs->data);
1681 }
1538 1682
1539 dbg(1,"enter (0x%x,0x%x) dir=%d pos=%p dst=%p\n", rgs->data.item.id_hi, rgs->data.item.id_lo, dir, pos, dst); 1683 //dbg(1, "enter (0x%x,0x%x) dir=%d pos=%p dst=%p\n", rgs->data.item.id_hi,
1684 // rgs->data.item.id_lo, dir, pos, dst);
1540 if (oldpath) { 1685 if (oldpath)
1686 {
1541 segment=item_hash_lookup(oldpath->path_hash, &rgs->data.item); 1687 segment = item_hash_lookup(oldpath->path_hash, &rgs->data.item);
1542 if (segment && segment->direction == dir) { 1688 if (segment && segment->direction == dir)
1689 {
1543 segment = route_extract_segment_from_path(oldpath, &rgs->data.item, offset); 1690 segment = route_extract_segment_from_path(oldpath, &rgs->data.item,
1691 offset);
1544 if (segment) { 1692 if (segment)
1693 {
1545 ret=1; 1694 ret = 1;
1546 if (!pos) 1695 if (!pos)
1547 goto linkold; 1696 goto linkold;
1548 } 1697 }
1549 } 1698 }
1550 } 1699 }
1551 1700
1552 if (pos) { 1701 if (pos)
1702 {
1553 if (dst) { 1703 if (dst)
1704 {
1554 extra=2; 1705 extra = 2;
1555 if (dst->lenneg >= pos->lenneg) { 1706 if (dst->lenneg >= pos->lenneg)
1707 {
1556 dir=1; 1708 dir = 1;
1557 ccnt=dst->pos-pos->pos; 1709 ccnt = dst->pos - pos->pos;
1558 c=pos->street->c+pos->pos+1; 1710 c = pos->street->c + pos->pos + 1;
1559 len=dst->lenneg-pos->lenneg; 1711 len = dst->lenneg - pos->lenneg;
1712 }
1560 } else { 1713 else
1714 {
1561 dir=-1; 1715 dir = -1;
1562 ccnt=pos->pos-dst->pos; 1716 ccnt = pos->pos - dst->pos;
1563 c=pos->street->c+dst->pos+1; 1717 c = pos->street->c + dst->pos + 1;
1564 len=pos->lenneg-dst->lenneg; 1718 len = pos->lenneg - dst->lenneg;
1719 }
1565 } 1720 }
1566 } else { 1721 else
1722 {
1567 extra=1; 1723 extra = 1;
1568 dbg(1,"pos dir=%d\n", dir); 1724 //dbg(1, "pos dir=%d\n", dir);
1569 dbg(1,"pos pos=%d\n", pos->pos); 1725 //dbg(1, "pos pos=%d\n", pos->pos);
1570 dbg(1,"pos count=%d\n", pos->street->count); 1726 //dbg(1, "pos count=%d\n", pos->street->count);
1571 if (dir > 0) { 1727 if (dir > 0)
1728 {
1572 c=pos->street->c+pos->pos+1; 1729 c = pos->street->c + pos->pos + 1;
1573 ccnt=pos->street->count-pos->pos-1; 1730 ccnt = pos->street->count - pos->pos - 1;
1574 len=pos->lenpos; 1731 len = pos->lenpos;
1732 }
1575 } else { 1733 else
1734 {
1576 c=pos->street->c; 1735 c = pos->street->c;
1577 ccnt=pos->pos+1; 1736 ccnt = pos->pos + 1;
1578 len=pos->lenneg; 1737 len = pos->lenneg;
1579 }
1580 } 1738 }
1739 }
1581 pos->dir=dir; 1740 pos->dir = dir;
1741 }
1582 } else if (dst) { 1742 else if (dst)
1743 {
1583 extra=1; 1744 extra = 1;
1584 dbg(1,"dst dir=%d\n", dir); 1745 //dbg(1, "dst dir=%d\n", dir);
1585 dbg(1,"dst pos=%d\n", dst->pos); 1746 //dbg(1, "dst pos=%d\n", dst->pos);
1586 if (dir > 0) { 1747 if (dir > 0)
1748 {
1587 c=dst->street->c; 1749 c = dst->street->c;
1588 ccnt=dst->pos+1; 1750 ccnt = dst->pos + 1;
1589 len=dst->lenpos; 1751 len = dst->lenpos;
1752 }
1590 } else { 1753 else
1754 {
1591 c=dst->street->c+dst->pos+1; 1755 c = dst->street->c + dst->pos + 1;
1592 ccnt=dst->street->count-dst->pos-1; 1756 ccnt = dst->street->count - dst->pos - 1;
1593 len=dst->lenneg; 1757 len = dst->lenneg;
1758 }
1594 } 1759 }
1595 } else { 1760 else
1761 {
1596 ccnt=get_item_seg_coords(&rgs->data.item, ca, 2047, &rgs->start->c, &rgs->end->c); 1762 ccnt = get_item_seg_coords(&rgs->data.item, ca, 2047, &rgs->start->c,
1763 &rgs->end->c);
1597 c=ca; 1764 c = ca;
1598 } 1765 }
1599 seg_size=sizeof(*segment) + sizeof(struct coord) * (ccnt + extra); 1766 seg_size = sizeof(*segment) + sizeof(struct coord) * (ccnt + extra);
1600 seg_dat_size=route_segment_data_size(rgs->data.flags); 1767 seg_dat_size = route_segment_data_size(rgs->data.flags);
1601 segment=g_malloc0(seg_size + seg_dat_size); 1768 segment = g_malloc0(seg_size + seg_dat_size);
1602 segment->data=(struct route_segment_data *)((char *)segment+seg_size); 1769 segment->data = (struct route_segment_data *) ((char *) segment + seg_size);
1603 segment->direction=dir; 1770 segment->direction = dir;
1604 cd=segment->c; 1771 cd = segment->c;
1605 if (pos && (c[0].x != pos->lp.x || c[0].y != pos->lp.y)) 1772 if (pos && (c[0].x != pos->lp.x || c[0].y != pos->lp.y))
1606 *cd++=pos->lp; 1773 *cd++ = pos->lp;
1607 if (dir < 0) 1774 if (dir < 0)
1608 c+=ccnt-1; 1775 c += ccnt - 1;
1609 for (i = 0 ; i < ccnt ; i++) { 1776 for (i = 0; i < ccnt; i++)
1777 {
1610 *cd++=*c; 1778 *cd++ = *c;
1611 c+=dir; 1779 c += dir;
1612 } 1780 }
1613 segment->ncoords+=ccnt; 1781 segment->ncoords += ccnt;
1614 if (dst && (cd[-1].x != dst->lp.x || cd[-1].y != dst->lp.y)) 1782 if (dst && (cd[-1].x != dst->lp.x || cd[-1].y != dst->lp.y))
1615 *cd++=dst->lp; 1783 *cd++ = dst->lp;
1616 segment->ncoords=cd-segment->c; 1784 segment->ncoords = cd - segment->c;
1617 if (segment->ncoords <= 1) { 1785 if (segment->ncoords <= 1)
1786 {
1618 g_free(segment); 1787 g_free(segment);
1619 return 1; 1788 return 1;
1620 } 1789 }
1621 1790
1622 /* We check if the route graph segment is part of a roundabout here, because this 1791 /* We check if the route graph segment is part of a roundabout here, because this
1623 * only matters for route graph segments which form parts of the route path */ 1792 * only matters for route graph segments which form parts of the route path */
1624 if (!(rgs->data.flags & AF_ROUNDABOUT)) { // We identified this roundabout earlier 1793 if (!(rgs->data.flags & AF_ROUNDABOUT))
1794 { // We identified this roundabout earlier
1625 route_check_roundabout(rgs, 13, (dir < 1), NULL); 1795 route_check_roundabout(rgs, 13, (dir < 1), NULL);
1626 } 1796 }
1627 1797
1628 memcpy(segment->data, &rgs->data, seg_dat_size); 1798 memcpy(segment->data, &rgs->data, seg_dat_size);
1629linkold:
1630 segment->data->len=len; 1799 linkold: segment->data->len = len;
1631 segment->next=NULL; 1800 segment->next = NULL;
1632 item_hash_insert(this->path_hash, &rgs->data.item, segment); 1801 item_hash_insert(this->path_hash, &rgs->data.item, segment);
1633 1802
1634 route_path_add_segment(this, segment); 1803 route_path_add_segment(this, segment);
1635 1804
1636 return ret; 1805 return ret;
1637} 1806}
1639/** 1808/**
1640 * @brief Destroys all segments of a route graph 1809 * @brief Destroys all segments of a route graph
1641 * 1810 *
1642 * @param this The graph to destroy all segments from 1811 * @param this The graph to destroy all segments from
1643 */ 1812 */
1644static void
1645route_graph_free_segments(struct route_graph *this) 1813static void route_graph_free_segments(struct route_graph *this)
1646{ 1814{
1647 struct route_graph_segment *curr,*next; 1815 struct route_graph_segment *curr, *next;
1648 int size; 1816 int size;
1649 curr=this->route_segments; 1817 curr = this->route_segments;
1650 while (curr) { 1818 while (curr)
1819 {
1651 next=curr->next; 1820 next = curr->next;
1652 size = sizeof(struct route_graph_segment)-sizeof(struct route_segment_data)+route_segment_data_size(curr->data.flags); 1821 size = sizeof(struct route_graph_segment)
1822 - sizeof(struct route_segment_data) + route_segment_data_size(
1823 curr->data.flags);
1653 g_slice_free1(size, curr); 1824 g_slice_free1(size, curr);
1654 curr=next; 1825 curr = next;
1655 } 1826 }
1656 this->route_segments=NULL; 1827 this->route_segments = NULL;
1657} 1828}
1658 1829
1659/** 1830/**
1660 * @brief Destroys a route graph 1831 * @brief Destroys a route graph
1661 * 1832 *
1662 * @param this The route graph to be destroyed 1833 * @param this The route graph to be destroyed
1663 */ 1834 */
1664static void
1665route_graph_destroy(struct route_graph *this) 1835void route_graph_destroy(struct route_graph *this)
1666{ 1836{
1667 if (this) { 1837 if (this)
1838 {
1668 route_graph_build_done(this, 1); 1839 route_graph_build_done(this, 1);
1669 route_graph_free_points(this); 1840 route_graph_free_points(this);
1670 route_graph_free_segments(this); 1841 route_graph_free_segments(this);
1671 g_free(this); 1842 g_free(this);
1672 } 1843 }
1680 * @param profile The routing preferences 1851 * @param profile The routing preferences
1681 * @param over The segment which is passed 1852 * @param over The segment which is passed
1682 * @param dist A traffic distortion if applicable 1853 * @param dist A traffic distortion if applicable
1683 * @return The estimated speed 1854 * @return The estimated speed
1684 */ 1855 */
1685static int 1856static int route_seg_speed(struct vehicleprofile *profile,
1686route_seg_speed(struct vehicleprofile *profile, struct route_segment_data *over, struct route_traffic_distortion *dist) 1857 struct route_segment_data *over, struct route_traffic_distortion *dist)
1687{ 1858{
1688 struct roadprofile *roadprofile=vehicleprofile_get_roadprofile(profile, over->item.type); 1859 struct roadprofile *roadprofile = vehicleprofile_get_roadprofile(profile,
1860 over->item.type);
1689 int speed,maxspeed; 1861 int speed, maxspeed;
1690 if (!roadprofile || !roadprofile->route_weight) 1862 if (!roadprofile || !roadprofile->route_weight)
1691 return 0; 1863 return 0;
1692 /* maxspeed_handling: 0=always, 1 only if maxspeed restricts the speed, 2 never */ 1864 /* maxspeed_handling: 0=always, 1 only if maxspeed restricts the speed, 2 never */
1693 speed=roadprofile->route_weight; 1865 speed = roadprofile->route_weight;
1694 if (profile->maxspeed_handling != 2) { 1866 if (profile->maxspeed_handling != 2)
1867 {
1695 if (over->flags & AF_SPEED_LIMIT) { 1868 if (over->flags & AF_SPEED_LIMIT)
1869 {
1696 maxspeed=RSD_MAXSPEED(over); 1870 maxspeed = RSD_MAXSPEED(over);
1697 if (!profile->maxspeed_handling) 1871 if (!profile->maxspeed_handling)
1698 speed=maxspeed; 1872 speed = maxspeed;
1873 }
1699 } else 1874 else
1700 maxspeed=INT_MAX; 1875 maxspeed = INT_MAX;
1701 if (dist && maxspeed > dist->maxspeed) 1876 if (dist && maxspeed > dist->maxspeed)
1702 maxspeed=dist->maxspeed; 1877 maxspeed = dist->maxspeed;
1703 if (maxspeed != INT_MAX && (profile->maxspeed_handling != 1 || maxspeed < speed)) 1878 if (maxspeed != INT_MAX && (profile->maxspeed_handling != 1 || maxspeed
1879 < speed))
1704 speed=maxspeed; 1880 speed = maxspeed;
1705 } 1881 }
1706 if (over->flags & AF_DANGEROUS_GOODS) { 1882 if (over->flags & AF_DANGEROUS_GOODS)
1883 {
1707 if (profile->dangerous_goods & RSD_DANGEROUS_GOODS(over)) 1884 if (profile->dangerous_goods & RSD_DANGEROUS_GOODS(over))
1708 return 0; 1885 return 0;
1709 } 1886 }
1710 if (over->flags & AF_SIZE_OR_WEIGHT_LIMIT) { 1887 if (over->flags & AF_SIZE_OR_WEIGHT_LIMIT)
1888 {
1711 struct size_weight_limit *size_weight=&RSD_SIZE_WEIGHT(over); 1889 struct size_weight_limit *size_weight = &RSD_SIZE_WEIGHT(over);
1712 if (size_weight->width != -1 && profile->width != -1 && profile->width > size_weight->width) 1890 if (size_weight->width != -1 && profile->width != -1 && profile->width
1891 > size_weight->width)
1713 return 0; 1892 return 0;
1714 if (size_weight->height != -1 && profile->height != -1 && profile->height > size_weight->height) 1893 if (size_weight->height != -1 && profile->height != -1
1894 && profile->height > size_weight->height)
1715 return 0; 1895 return 0;
1716 if (size_weight->length != -1 && profile->length != -1 && profile->length > size_weight->length) 1896 if (size_weight->length != -1 && profile->length != -1
1897 && profile->length > size_weight->length)
1717 return 0; 1898 return 0;
1718 if (size_weight->weight != -1 && profile->weight != -1 && profile->weight > size_weight->weight) 1899 if (size_weight->weight != -1 && profile->weight != -1
1900 && profile->weight > size_weight->weight)
1719 return 0; 1901 return 0;
1720 if (size_weight->axle_weight != -1 && profile->axle_weight != -1 && profile->axle_weight > size_weight->axle_weight) 1902 if (size_weight->axle_weight != -1 && profile->axle_weight != -1
1903 && profile->axle_weight > size_weight->axle_weight)
1721 return 0; 1904 return 0;
1722 } 1905 }
1723 return speed; 1906 return speed;
1724} 1907}
1725 1908
1733 * @param over The segment which is passed 1916 * @param over The segment which is passed
1734 * @param dist A traffic distortion if applicable 1917 * @param dist A traffic distortion if applicable
1735 * @return The time needed to drive len on item in thenth of senconds 1918 * @return The time needed to drive len on item in thenth of senconds
1736 */ 1919 */
1737 1920
1738static int 1921static int route_time_seg(struct vehicleprofile *profile,
1739route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over, struct route_traffic_distortion *dist) 1922 struct route_segment_data *over, struct route_traffic_distortion *dist)
1740{ 1923{
1741 int speed=route_seg_speed(profile, over, dist); 1924 int speed = route_seg_speed(profile, over, dist);
1742 if (!speed) 1925 if (!speed)
1743 return INT_MAX; 1926 return INT_MAX;
1744 return over->len*36/speed+(dist ? dist->delay : 0); 1927 return over->len * 36 / speed + (dist ? dist->delay : 0);
1745} 1928}
1746 1929
1747static int 1930static int route_get_traffic_distortion(struct route_graph_segment *seg,
1748route_get_traffic_distortion(struct route_graph_segment *seg, struct route_traffic_distortion *ret) 1931 struct route_traffic_distortion *ret)
1749{ 1932{
1750 struct route_graph_point *start=seg->start; 1933 struct route_graph_point *start = seg->start;
1751 struct route_graph_point *end=seg->end; 1934 struct route_graph_point *end = seg->end;
1752 struct route_graph_segment *tmp,*found=NULL; 1935 struct route_graph_segment *tmp, *found = NULL;
1753 tmp=start->start; 1936 tmp = start->start;
1754 while (tmp && !found) { 1937 while (tmp && !found)
1938 {
1755 if (tmp->data.item.type == type_traffic_distortion && tmp->start == start && tmp->end == end) 1939 if (tmp->data.item.type == type_traffic_distortion && tmp->start
1940 == start && tmp->end == end)
1756 found=tmp; 1941 found = tmp;
1757 tmp=tmp->start_next; 1942 tmp = tmp->start_next;
1758 } 1943 }
1759 tmp=start->end; 1944 tmp = start->end;
1760 while (tmp && !found) { 1945 while (tmp && !found)
1946 {
1761 if (tmp->data.item.type == type_traffic_distortion && tmp->end == start && tmp->start == end) 1947 if (tmp->data.item.type == type_traffic_distortion && tmp->end == start
1948 && tmp->start == end)
1762 found=tmp; 1949 found = tmp;
1763 tmp=tmp->end_next; 1950 tmp = tmp->end_next;
1764 } 1951 }
1765 if (found) { 1952 if (found)
1953 {
1766 ret->delay=found->data.len; 1954 ret->delay = found->data.len;
1767 if (found->data.flags & AF_SPEED_LIMIT) 1955 if (found->data.flags & AF_SPEED_LIMIT)
1768 ret->maxspeed=RSD_MAXSPEED(&found->data); 1956 ret->maxspeed = RSD_MAXSPEED(&found->data);
1769 else 1957 else
1770 ret->maxspeed=INT_MAX; 1958 ret->maxspeed = INT_MAX;
1771 return 1; 1959 return 1;
1772 } 1960 }
1773 return 0; 1961 return 0;
1774} 1962}
1775 1963
1776static int 1964static int route_through_traffic_allowed(struct vehicleprofile *profile,
1777route_through_traffic_allowed(struct vehicleprofile *profile, struct route_graph_segment *seg) 1965 struct route_graph_segment *seg)
1778{ 1966{
1779 return (seg->data.flags & AF_THROUGH_TRAFFIC_LIMIT) == 0; 1967 return (seg->data.flags & AF_THROUGH_TRAFFIC_LIMIT) == 0;
1780} 1968}
1781 1969
1782/** 1970/**
1785 * @param profile The routing preferences 1973 * @param profile The routing preferences
1786 * @param from The point where we are starting 1974 * @param from The point where we are starting
1787 * @param over The segment we are using 1975 * @param over The segment we are using
1788 * @param dir The direction of segment which we are driving 1976 * @param dir The direction of segment which we are driving
1789 * @return The "costs" needed to drive len on item 1977 * @return The "costs" needed to drive len on item
1790 */ 1978 */
1791 1979
1792static int 1980static int route_value_seg(struct vehicleprofile *profile,
1793route_value_seg(struct vehicleprofile *profile, struct route_graph_point *from, struct route_graph_segment *over, int dir) 1981 struct route_graph_point *from, struct route_graph_segment *over,
1982 int dir)
1794{ 1983{
1795 int ret; 1984 int ret;
1796 struct route_traffic_distortion dist,*distp=NULL; 1985 struct route_traffic_distortion dist, *distp = NULL;
1797#if 0 1986#if 0
1798 dbg(0,"flags 0x%x mask 0x%x flags 0x%x\n", over->flags, dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask, profile->flags); 1987 dbg(0,"flags 0x%x mask 0x%x flags 0x%x\n", over->flags, dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask, profile->flags);
1799#endif 1988#endif
1800 if ((over->data.flags & (dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask)) != profile->flags) 1989 if ((over->data.flags & (dir >= 0 ? profile->flags_forward_mask
1990 : profile->flags_reverse_mask)) != profile->flags)
1801 return INT_MAX; 1991 return INT_MAX;
1802 if (dir > 0 && (over->start->flags & RP_TURN_RESTRICTION)) 1992 if (dir > 0 && (over->start->flags & RP_TURN_RESTRICTION))
1803 return INT_MAX; 1993 return INT_MAX;
1804 if (dir < 0 && (over->end->flags & RP_TURN_RESTRICTION)) 1994 if (dir < 0 && (over->end->flags & RP_TURN_RESTRICTION))
1805 return INT_MAX; 1995 return INT_MAX;
1806 if (from && from->seg == over) 1996 if (from && from->seg == over)
1807 return INT_MAX; 1997 return INT_MAX;
1808 if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags & RP_TRAFFIC_DISTORTION) && 1998 if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags
1809 route_get_traffic_distortion(over, &dist)) { 1999 & RP_TRAFFIC_DISTORTION) && route_get_traffic_distortion(over,
2000 &dist))
2001 {
1810 distp=&dist; 2002 distp = &dist;
1811 } 2003 }
1812 ret=route_time_seg(profile, &over->data, distp); 2004 ret = route_time_seg(profile, &over->data, distp);
1813 if (ret == INT_MAX) 2005 if (ret == INT_MAX)
1814 return ret; 2006 return ret;
1815 if (!route_through_traffic_allowed(profile, over) && from && route_through_traffic_allowed(profile, from->seg)) 2007 if (!route_through_traffic_allowed(profile, over) && from
2008 && route_through_traffic_allowed(profile, from->seg))
1816 ret+=profile->through_traffic_penalty; 2009 ret += profile->through_traffic_penalty;
1817 return ret; 2010 return ret;
1818} 2011}
1819 2012
1820/** 2013/**
1821 * @brief Adds a route distortion item to the route graph 2014 * @brief Adds a route distortion item to the route graph
1822 * 2015 *
1823 * @param this The route graph to add to 2016 * @param this The route graph to add to
1824 * @param item The item to add 2017 * @param item The item to add
1825 */ 2018 */
1826static void
1827route_process_traffic_distortion(struct route_graph *this, struct item *item) 2019static void route_process_traffic_distortion(struct route_graph *this,
2020 struct item *item)
1828{ 2021{
1829 struct route_graph_point *s_pnt,*e_pnt; 2022 struct route_graph_point *s_pnt, *e_pnt;
1830 struct coord c,l; 2023 struct coord c, l;
1831 struct attr delay_attr, maxspeed_attr; 2024 struct attr delay_attr, maxspeed_attr;
1832 struct route_graph_segment_data data; 2025 struct route_graph_segment_data data;
1833 2026
1834 data.item=item; 2027 data.item = item;
1835 data.len=0; 2028 data.len = 0;
1836 data.flags=0; 2029 data.flags = 0;
1837 data.offset=1; 2030 data.offset = 1;
1838 data.maxspeed = INT_MAX; 2031 data.maxspeed = INT_MAX;
1839 2032
1840 if (item_coord_get(item, &l, 1)) { 2033 if (item_coord_get(item, &l, 1))
2034 {
1841 s_pnt=route_graph_add_point(this,&l); 2035 s_pnt = route_graph_add_point(this, &l);
1842 while (item_coord_get(item, &c, 1)) { 2036 while (item_coord_get(item, &c, 1))
2037 {
1843 l=c; 2038 l = c;
1844 } 2039 }
1845 e_pnt=route_graph_add_point(this,&l); 2040 e_pnt = route_graph_add_point(this, &l);
1846 s_pnt->flags |= RP_TRAFFIC_DISTORTION; 2041 s_pnt->flags |= RP_TRAFFIC_DISTORTION;
1847 e_pnt->flags |= RP_TRAFFIC_DISTORTION; 2042 e_pnt->flags |= RP_TRAFFIC_DISTORTION;
1848 if (item_attr_get(item, attr_maxspeed, &maxspeed_attr)) { 2043 if (item_attr_get(item, attr_maxspeed, &maxspeed_attr))
2044 {
1849 data.flags |= AF_SPEED_LIMIT; 2045 data.flags |= AF_SPEED_LIMIT;
1850 data.maxspeed=maxspeed_attr.u.num; 2046 data.maxspeed = maxspeed_attr.u.num;
1851 } 2047 }
1852 if (item_attr_get(item, attr_delay, &delay_attr)) 2048 if (item_attr_get(item, attr_delay, &delay_attr))
1853 data.len=delay_attr.u.num; 2049 data.len = delay_attr.u.num;
1854 route_graph_add_segment(this, s_pnt, e_pnt, &data); 2050 route_graph_add_segment(this, s_pnt, e_pnt, &data);
1855 } 2051 }
1856} 2052}
1857 2053
1858/** 2054/**
1859 * @brief Adds a route distortion item to the route graph 2055 * @brief Adds a route distortion item to the route graph
1860 * 2056 *
1861 * @param this The route graph to add to 2057 * @param this The route graph to add to
1862 * @param item The item to add 2058 * @param item The item to add
1863 */ 2059 */
1864static void
1865route_process_turn_restriction(struct route_graph *this, struct item *item) 2060static void route_process_turn_restriction(struct route_graph *this,
2061 struct item *item)
1866{ 2062{
1867 struct route_graph_point *pnt[4]; 2063 struct route_graph_point *pnt[4];
1868 struct coord c[5]; 2064 struct coord c[5];
1869 int i,count; 2065 int i, count;
1870 struct route_graph_segment_data data; 2066 struct route_graph_segment_data data;
1871 2067
1872 count=item_coord_get(item, c, 5); 2068 count = item_coord_get(item, c, 5);
1873 if (count != 3 && count != 4) { 2069 if (count != 3 && count != 4)
2070 {
1874 dbg(0,"wrong count %d\n",count); 2071 dbg(0, "wrong count %d\n", count);
1875 return; 2072 return;
1876 } 2073 }
1877 if (count == 4) 2074 if (count == 4)
2075 {
1878 return; 2076 return;
2077 }
1879 for (i = 0 ; i < count ; i++) 2078 for (i = 0; i < count; i++)
2079 {
1880 pnt[i]=route_graph_add_point(this,&c[i]); 2080 pnt[i] = route_graph_add_point(this, &c[i]);
1881 dbg(1,"%s: (0x%x,0x%x)-(0x%x,0x%x)-(0x%x,0x%x) %p-%p-%p\n",item_to_name(item->type),c[0].x,c[0].y,c[1].x,c[1].y,c[2].x,c[2].y,pnt[0],pnt[1],pnt[2]); 2081 }
2082 //dbg(1, "%s: (0x%x,0x%x)-(0x%x,0x%x)-(0x%x,0x%x) %p-%p-%p\n",
2083 // item_to_name(item->type), c[0].x, c[0].y, c[1].x, c[1].y, c[2].x,
2084 // c[2].y, pnt[0], pnt[1], pnt[2]);
1882 data.item=item; 2085 data.item = item;
1883 data.flags=0; 2086 data.flags = 0;
1884 data.len=0; 2087 data.len = 0;
1885 route_graph_add_segment(this, pnt[0], pnt[1], &data); 2088 route_graph_add_segment(this, pnt[0], pnt[1], &data);
1886 route_graph_add_segment(this, pnt[1], pnt[2], &data); 2089 route_graph_add_segment(this, pnt[1], pnt[2], &data);
1887#if 1 2090#if 1
1888 if (count == 4) { 2091 if (count == 4)
2092 {
1889 pnt[1]->flags |= RP_TURN_RESTRICTION; 2093 pnt[1]->flags |= RP_TURN_RESTRICTION;
1890 pnt[2]->flags |= RP_TURN_RESTRICTION; 2094 pnt[2]->flags |= RP_TURN_RESTRICTION;
1891 route_graph_add_segment(this, pnt[2], pnt[3], &data); 2095 route_graph_add_segment(this, pnt[2], pnt[3], &data);
2096 }
1892 } else 2097 else
2098 {
1893 pnt[1]->flags |= RP_TURN_RESTRICTION; 2099 pnt[1]->flags |= RP_TURN_RESTRICTION;
2100 }
1894#endif 2101#endif
1895} 2102}
1896 2103
1897/** 2104/**
1898 * @brief Adds an item to the route graph 2105 * @brief Adds an item to the route graph
1902 * 2109 *
1903 * @param this The route graph to add to 2110 * @param this The route graph to add to
1904 * @param item The item to add 2111 * @param item The item to add
1905 * @param profile The vehicle profile currently in use 2112 * @param profile The vehicle profile currently in use
1906 */ 2113 */
1907static void 2114static void route_process_street_graph(struct route_graph *this,
1908route_process_street_graph(struct route_graph *this, struct item *item, struct vehicleprofile *profile) 2115 struct item *item, struct vehicleprofile *profile)
1909{ 2116{
1910#ifdef AVOID_FLOAT 2117#ifdef AVOID_FLOAT
1911 int len=0; 2118 int len=0;
1912#else 2119#else
1913 double len=0; 2120 double len = 0;
1914#endif 2121#endif
1915 int segmented = 0; 2122 int segmented = 0;
1916 struct roadprofile *roadp; 2123 struct roadprofile *roadp;
1917 struct route_graph_point *s_pnt,*e_pnt; 2124 struct route_graph_point *s_pnt, *e_pnt;
1918 struct coord c,l; 2125 struct coord c, l;
1919 struct attr attr; 2126 struct attr attr;
1920 struct route_graph_segment_data data; 2127 struct route_graph_segment_data data;
1921 data.flags=0; 2128 data.flags = 0;
1922 data.offset=1; 2129 data.offset = 1;
1923 data.maxspeed=-1; 2130 data.maxspeed = -1;
1924 data.item=item; 2131 data.item = item;
1925 2132
1926 roadp = vehicleprofile_get_roadprofile(profile, item->type); 2133 roadp = vehicleprofile_get_roadprofile(profile, item->type);
1927 if (!roadp) { 2134 if (!roadp)
2135 {
1928 // Don't include any roads that don't have a road profile in our vehicle profile 2136 // Don't include any roads that don't have a road profile in our vehicle profile
1929 return; 2137 return;
1930 } 2138 }
1931 2139
1932 if (item_coord_get(item, &l, 1)) { 2140 if (item_coord_get(item, &l, 1))
2141 {
1933 int *default_flags=item_get_default_flags(item->type); 2142 int *default_flags = item_get_default_flags(item->type);
1934 if (! default_flags) 2143 if (!default_flags)
1935 return; 2144 return;
1936 if (item_attr_get(item, attr_flags, &attr)) { 2145 if (item_attr_get(item, attr_flags, &attr))
2146 {
1937 data.flags = attr.u.num; 2147 data.flags = attr.u.num;
1938 if (data.flags & AF_SEGMENTED) 2148 if (data.flags & AF_SEGMENTED)
1939 segmented = 1; 2149 segmented = 1;
2150 }
1940 } else 2151 else
1941 data.flags = *default_flags; 2152 data.flags = *default_flags;
1942
1943 2153
1944 if (data.flags & AF_SPEED_LIMIT) { 2154 if (data.flags & AF_SPEED_LIMIT)
2155 {
1945 if (item_attr_get(item, attr_maxspeed, &attr)) 2156 if (item_attr_get(item, attr_maxspeed, &attr))
1946 data.maxspeed = attr.u.num; 2157 data.maxspeed = attr.u.num;
1947 } 2158 }
1948 if (data.flags & AF_DANGEROUS_GOODS) { 2159 if (data.flags & AF_DANGEROUS_GOODS)
2160 {
1949 if (item_attr_get(item, attr_vehicle_dangerous_goods, &attr)) 2161 if (item_attr_get(item, attr_vehicle_dangerous_goods, &attr))
1950 data.dangerous_goods = attr.u.num; 2162 data.dangerous_goods = attr.u.num;
1951 else 2163 else
1952 data.flags &= ~AF_DANGEROUS_GOODS; 2164 data.flags &= ~AF_DANGEROUS_GOODS;
1953 } 2165 }
1954 if (data.flags & AF_SIZE_OR_WEIGHT_LIMIT) { 2166 if (data.flags & AF_SIZE_OR_WEIGHT_LIMIT)
2167 {
1955 if (item_attr_get(item, attr_vehicle_width, &attr)) 2168 if (item_attr_get(item, attr_vehicle_width, &attr))
1956 data.size_weight.width=attr.u.num; 2169 data.size_weight.width = attr.u.num;
1957 else 2170 else
1958 data.size_weight.width=-1; 2171 data.size_weight.width = -1;
1959 if (item_attr_get(item, attr_vehicle_height, &attr)) 2172 if (item_attr_get(item, attr_vehicle_height, &attr))
1960 data.size_weight.height=attr.u.num; 2173 data.size_weight.height = attr.u.num;
1961 else 2174 else
1962 data.size_weight.height=-1; 2175 data.size_weight.height = -1;
1963 if (item_attr_get(item, attr_vehicle_length, &attr)) 2176 if (item_attr_get(item, attr_vehicle_length, &attr))
1964 data.size_weight.length=attr.u.num; 2177 data.size_weight.length = attr.u.num;
1965 else 2178 else
1966 data.size_weight.length=-1; 2179 data.size_weight.length = -1;
1967 if (item_attr_get(item, attr_vehicle_weight, &attr)) 2180 if (item_attr_get(item, attr_vehicle_weight, &attr))
1968 data.size_weight.weight=attr.u.num; 2181 data.size_weight.weight = attr.u.num;
1969 else 2182 else
1970 data.size_weight.weight=-1; 2183 data.size_weight.weight = -1;
1971 if (item_attr_get(item, attr_vehicle_axle_weight, &attr)) 2184 if (item_attr_get(item, attr_vehicle_axle_weight, &attr))
1972 data.size_weight.axle_weight=attr.u.num; 2185 data.size_weight.axle_weight = attr.u.num;
1973 else 2186 else
1974 data.size_weight.axle_weight=-1; 2187 data.size_weight.axle_weight = -1;
1975 } 2188 }
1976 2189
1977 s_pnt=route_graph_add_point(this,&l); 2190 s_pnt = route_graph_add_point(this, &l);
1978 if (!segmented) { 2191 if (!segmented)
2192 {
1979 while (item_coord_get(item, &c, 1)) { 2193 while (item_coord_get(item, &c, 1))
2194 {
1980 len+=transform_distance(map_projection(item->map), &l, &c); 2195 len += transform_distance(map_projection(item->map), &l, &c);
1981 l=c; 2196 l = c;
1982 } 2197 }
1983 e_pnt=route_graph_add_point(this,&l); 2198 e_pnt = route_graph_add_point(this, &l);
1984 dbg_assert(len >= 0); 2199 dbg_assert(len >= 0);
1985 data.len=len; 2200 data.len = len;
1986 if (!route_graph_segment_is_duplicate(s_pnt, &data)) 2201 if (!route_graph_segment_is_duplicate(s_pnt, &data))
1987 route_graph_add_segment(this, s_pnt, e_pnt, &data); 2202 route_graph_add_segment(this, s_pnt, e_pnt, &data);
2203 }
1988 } else { 2204 else
2205 {
1989 int isseg,rc; 2206 int isseg, rc;
1990 int sc = 0; 2207 int sc = 0;
1991 do { 2208 do
2209 {
1992 isseg = item_coord_is_node(item); 2210 isseg = item_coord_is_node(item);
1993 rc = item_coord_get(item, &c, 1); 2211 rc = item_coord_get(item, &c, 1);
1994 if (rc) { 2212 if (rc)
2213 {
2214 len
1995 len+=transform_distance(map_projection(item->map), &l, &c); 2215 += transform_distance(map_projection(item->map),
2216 &l, &c);
1996 l=c; 2217 l = c;
1997 if (isseg) { 2218 if (isseg)
2219 {
1998 e_pnt=route_graph_add_point(this,&l); 2220 e_pnt = route_graph_add_point(this, &l);
1999 data.len=len; 2221 data.len = len;
2000 if (!route_graph_segment_is_duplicate(s_pnt, &data)) 2222 if (!route_graph_segment_is_duplicate(s_pnt, &data))
2001 route_graph_add_segment(this, s_pnt, e_pnt, &data); 2223 route_graph_add_segment(this, s_pnt, e_pnt, &data);
2002 data.offset++; 2224 data.offset++;
2003 s_pnt=route_graph_add_point(this,&l); 2225 s_pnt = route_graph_add_point(this, &l);
2004 len = 0; 2226 len = 0;
2005 } 2227 }
2006 } 2228 }
2229 }
2007 } while(rc); 2230 while (rc);
2008 e_pnt=route_graph_add_point(this,&l); 2231 e_pnt = route_graph_add_point(this, &l);
2009 dbg_assert(len >= 0); 2232 dbg_assert(len >= 0);
2010 sc++; 2233 sc++;
2011 data.len=len; 2234 data.len = len;
2012 if (!route_graph_segment_is_duplicate(s_pnt, &data)) 2235 if (!route_graph_segment_is_duplicate(s_pnt, &data))
2013 route_graph_add_segment(this, s_pnt, e_pnt, &data); 2236 route_graph_add_segment(this, s_pnt, e_pnt, &data);
2014 } 2237 }
2015 } 2238 }
2016} 2239}
2017 2240
2018static struct route_graph_segment * 2241static struct route_graph_segment *
2019route_graph_get_segment(struct route_graph *graph, struct street_data *sd, struct route_graph_segment *last) 2242route_graph_get_segment(struct route_graph *graph, struct street_data *sd,
2243 struct route_graph_segment *last)
2020{ 2244{
2021 struct route_graph_point *start=NULL; 2245 struct route_graph_point *start = NULL;
2022 struct route_graph_segment *s; 2246 struct route_graph_segment *s;
2023 int seen=0; 2247 int seen = 0;
2024 2248
2025 while ((start=route_graph_get_point_next(graph, &sd->c[0], start))) { 2249 while ((start = route_graph_get_point_next(graph, &sd->c[0], start)))
2250 {
2026 s=start->start; 2251 s = start->start;
2027 while (s) { 2252 while (s)
2253 {
2028 if (item_is_equal(sd->item, s->data.item)) { 2254 if (item_is_equal(sd->item, s->data.item))
2255 {
2029 if (!last || seen) 2256 if (!last || seen)
2030 return s; 2257 return s;
2031 if (last == s) 2258 if (last == s)
2032 seen=1; 2259 seen = 1;
2033 } 2260 }
2034 s=s->start_next; 2261 s = s->start_next;
2035 } 2262 }
2036 } 2263 }
2037 return NULL; 2264 return NULL;
2038} 2265}
2039 2266
2046 * stated costs. 2273 * stated costs.
2047 * 2274 *
2048 * This function uses Dijkstra's algorithm to do the routing. To understand it you should have a look 2275 * This function uses Dijkstra's algorithm to do the routing. To understand it you should have a look
2049 * at this algorithm. 2276 * at this algorithm.
2050 */ 2277 */
2051static void 2278static void route_graph_flood(struct route_graph *this, struct route_info *dst,
2052route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehicleprofile *profile, struct callback *cb) 2279 struct vehicleprofile *profile, struct callback *cb)
2053{ 2280{
2054 struct route_graph_point *p_min; 2281 struct route_graph_point *p_min;
2055 struct route_graph_segment *s=NULL; 2282 struct route_graph_segment *s = NULL;
2056 int min,new,old,val; 2283 int min, new, old, val;
2057 struct fibheap *heap; /* This heap will hold all points with "temporarily" calculated costs */ 2284 struct fibheap *heap; /* This heap will hold all points with "temporarily" calculated costs */
2058 2285
2059 heap = fh_makekeyheap(); 2286 heap = fh_makekeyheap();
2060 2287
2061 while ((s=route_graph_get_segment(this, dst->street, s))) { 2288 while ((s = route_graph_get_segment(this, dst->street, s)))
2289 {
2062 val=route_value_seg(profile, NULL, s, -1); 2290 val = route_value_seg(profile, NULL, s, -1);
2063 if (val != INT_MAX) { 2291 if (val != INT_MAX)
2292 {
2064 val=val*(100-dst->percent)/100; 2293 val = val * (100 - dst->percent) / 100;
2065 s->end->seg=s; 2294 s->end->seg = s;
2066 s->end->value=val; 2295 s->end->value = val;
2067 s->end->el=fh_insertkey(heap, s->end->value, s->end); 2296 s->end->el = fh_insertkey(heap, s->end->value, s->end);
2068 } 2297 }
2069 val=route_value_seg(profile, NULL, s, 1); 2298 val = route_value_seg(profile, NULL, s, 1);
2070 if (val != INT_MAX) { 2299 if (val != INT_MAX)
2300 {
2071 val=val*dst->percent/100; 2301 val = val * dst->percent / 100;
2072 s->start->seg=s; 2302 s->start->seg = s;
2073 s->start->value=val; 2303 s->start->value = val;
2074 s->start->el=fh_insertkey(heap, s->start->value, s->start); 2304 s->start->el = fh_insertkey(heap, s->start->value, s->start);
2075 }
2076 } 2305 }
2306 }
2077 for (;;) { 2307 for (;;)
2308 {
2078 p_min=fh_extractmin(heap); /* Starting Dijkstra by selecting the point with the minimum costs on the heap */ 2309 p_min = fh_extractmin(heap); /* Starting Dijkstra by selecting the point with the minimum costs on the heap */
2079 if (! p_min) /* There are no more points with temporarily calculated costs, Dijkstra has finished */ 2310 if (!p_min) /* There are no more points with temporarily calculated costs, Dijkstra has finished */
2080 break; 2311 break;
2081 min=p_min->value; 2312 min = p_min->value;
2082 if (debug_route) 2313 if (debug_route)
2083 printf("extract p=%p free el=%p min=%d, 0x%x, 0x%x\n", p_min, p_min->el, min, p_min->c.x, p_min->c.y); 2314 printf("extract p=%p free el=%p min=%d, 0x%x, 0x%x\n", p_min,
2315 p_min->el, min, p_min->c.x, p_min->c.y);
2084 p_min->el=NULL; /* This point is permanently calculated now, we've taken it out of the heap */ 2316 p_min->el = NULL; /* This point is permanently calculated now, we've taken it out of the heap */
2085 s=p_min->start; 2317 s = p_min->start;
2318 while (s)
2086 while (s) { /* Iterating all the segments leading away from our point to update the points at their ends */ 2319 { /* Iterating all the segments leading away from our point to update the points at their ends */
2087 val=route_value_seg(profile, p_min, s, -1); 2320 val = route_value_seg(profile, p_min, s, -1);
2088 if (val != INT_MAX && !item_is_equal(s->data.item,p_min->seg->data.item)) { 2321 if (val != INT_MAX && !item_is_equal(s->data.item,
2322 p_min->seg->data.item))
2323 {
2089 new=min+val; 2324 new = min + val;
2090 if (debug_route) 2325 if (debug_route)
2091 printf("begin %d len %d vs %d (0x%x,0x%x)\n",new,val,s->end->value, s->end->c.x, s->end->c.y); 2326 printf("begin %d len %d vs %d (0x%x,0x%x)\n", new, val,
2327 s->end->value, s->end->c.x, s->end->c.y);
2328 if (new < s->end->value)
2092 if (new < s->end->value) { /* We've found a less costly way to reach the end of s, update it */ 2329 { /* We've found a less costly way to reach the end of s, update it */
2093 s->end->value=new; 2330 s->end->value = new;
2094 s->end->seg=s; 2331 s->end->seg = s;
2095 if (! s->end->el) { 2332 if (!s->end->el)
2333 {
2096 if (debug_route) 2334 if (debug_route)
2097 printf("insert_end p=%p el=%p val=%d ", s->end, s->end->el, s->end->value); 2335 printf("insert_end p=%p el=%p val=%d ", s->end,
2336 s->end->el, s->end->value);
2098 s->end->el=fh_insertkey(heap, new, s->end); 2337 s->end->el = fh_insertkey(heap, new, s->end);
2099 if (debug_route) 2338 if (debug_route)
2100 printf("el new=%p\n", s->end->el); 2339 printf("el new=%p\n", s->end->el);
2101 } 2340 }
2102 else { 2341 else
2342 {
2103 if (debug_route) 2343 if (debug_route)
2104 printf("replace_end p=%p el=%p val=%d\n", s->end, s->end->el, s->end->value); 2344 printf("replace_end p=%p el=%p val=%d\n", s->end,
2345 s->end->el, s->end->value);
2105 fh_replacekey(heap, s->end->el, new); 2346 fh_replacekey(heap, s->end->el, new);
2106 } 2347 }
2107 } 2348 }
2108 if (debug_route) 2349 if (debug_route)
2109 printf("\n"); 2350 printf("\n");
2110 } 2351 }
2111 s=s->start_next; 2352 s = s->start_next;
2112 } 2353 }
2113 s=p_min->end; 2354 s = p_min->end;
2355 while (s)
2114 while (s) { /* Doing the same as above with the segments leading towards our point */ 2356 { /* Doing the same as above with the segments leading towards our point */
2115 val=route_value_seg(profile, p_min, s, 1); 2357 val = route_value_seg(profile, p_min, s, 1);
2116 if (val != INT_MAX && !item_is_equal(s->data.item,p_min->seg->data.item)) { 2358 if (val != INT_MAX && !item_is_equal(s->data.item,
2359 p_min->seg->data.item))
2360 {
2117 new=min+val; 2361 new = min + val;
2118 if (debug_route) 2362 if (debug_route)
2119 printf("end %d len %d vs %d (0x%x,0x%x)\n",new,val,s->start->value,s->start->c.x, s->start->c.y); 2363 printf("end %d len %d vs %d (0x%x,0x%x)\n", new, val,
2364 s->start->value, s->start->c.x, s->start->c.y);
2120 if (new < s->start->value) { 2365 if (new < s->start->value)
2366 {
2121 old=s->start->value; 2367 old = s->start->value;
2122 s->start->value=new; 2368 s->start->value = new;
2123 s->start->seg=s; 2369 s->start->seg = s;
2124 if (! s->start->el) { 2370 if (!s->start->el)
2371 {
2125 if (debug_route) 2372 if (debug_route)
2126 printf("insert_start p=%p el=%p val=%d ", s->start, s->start->el, s->start->value); 2373 printf("insert_start p=%p el=%p val=%d ", s->start,
2374 s->start->el, s->start->value);
2127 s->start->el=fh_insertkey(heap, new, s->start); 2375 s->start->el = fh_insertkey(heap, new, s->start);
2128 if (debug_route) 2376 if (debug_route)
2129 printf("el new=%p\n", s->start->el); 2377 printf("el new=%p\n", s->start->el);
2130 } 2378 }
2131 else { 2379 else
2380 {
2132 if (debug_route) 2381 if (debug_route)
2133 printf("replace_start p=%p el=%p val=%d\n", s->start, s->start->el, s->start->value); 2382 printf("replace_start p=%p el=%p val=%d\n",
2383 s->start, s->start->el, s->start->value);
2134 fh_replacekey(heap, s->start->el, new); 2384 fh_replacekey(heap, s->start->el, new);
2135 } 2385 }
2136 } 2386 }
2137 if (debug_route) 2387 if (debug_route)
2138 printf("\n"); 2388 printf("\n");
2139 } 2389 }
2140 s=s->end_next; 2390 s = s->end_next;
2141 } 2391 }
2142 } 2392 }
2143 fh_deleteheap(heap); 2393 fh_deleteheap(heap);
2144 callback_call_0(cb); 2394 callback_call_0(cb);
2145 dbg(1,"return\n"); 2395 //dbg(1, "return\n");
2146} 2396}
2147 2397
2148/** 2398/**
2149 * @brief Starts an "offroad" path 2399 * @brief Starts an "offroad" path
2150 * 2400 *
2156 * @param dst The destination of the new path 2406 * @param dst The destination of the new path
2157 * @param dir Not used 2407 * @param dir Not used
2158 * @return The new path 2408 * @return The new path
2159 */ 2409 */
2160static struct route_path * 2410static struct route_path *
2161route_path_new_offroad(struct route_graph *this, struct route_info *pos, struct route_info *dst) 2411route_path_new_offroad(struct route_graph *this, struct route_info *pos,
2412 struct route_info *dst)
2162{ 2413{
2163 struct route_path *ret; 2414 struct route_path *ret;
2164 2415
2165 ret=g_new0(struct route_path, 1); 2416 ret=g_new0(struct route_path, 1);
2166 ret->in_use=1; 2417 ret->in_use = 1;
2167 ret->path_hash=item_hash_new(); 2418 ret->path_hash = item_hash_new();
2168 route_path_add_line(ret, &pos->c, &dst->c, pos->lenextra+dst->lenextra); 2419 route_path_add_line(ret, &pos->c, &dst->c, pos->lenextra + dst->lenextra);
2169 ret->updated=1; 2420 ret->updated = 1;
2170 2421
2171 return ret; 2422 return ret;
2172} 2423}
2173 2424
2174/** 2425/**
2179 * 2430 *
2180 * @param this_ The route we're driving upon 2431 * @param this_ The route we're driving upon
2181 * @param dist The distance in meters 2432 * @param dist The distance in meters
2182 * @return The coordinate where the user will be in that distance 2433 * @return The coordinate where the user will be in that distance
2183 */ 2434 */
2184struct coord
2185route_get_coord_dist(struct route *this_, int dist) 2435struct coord route_get_coord_dist(struct route *this_, int dist)
2186{ 2436{
2187 int d,l,i,len; 2437 int d, l, i, len;
2188 int dx,dy; 2438 int dx, dy;
2189 double frac; 2439 double frac;
2190 struct route_path_segment *cur; 2440 struct route_path_segment *cur;
2191 struct coord ret; 2441 struct coord ret;
2192 enum projection pro=route_projection(this_); 2442 enum projection pro = route_projection(this_);
2193 struct route_info *dst=route_get_dst(this_); 2443 struct route_info *dst = route_get_dst(this_);
2194 2444
2195 d = dist; 2445 d = dist;
2196 2446
2197 if (!this_->path2 || pro == projection_none) { 2447 if (!this_->path2 || pro == projection_none)
2448 {
2198 return this_->pos->c; 2449 return this_->pos->c;
2199 } 2450 }
2200 2451
2201 ret = this_->pos->c; 2452 ret = this_->pos->c;
2202 cur = this_->path2->path; 2453 cur = this_->path2->path;
2203 while (cur) { 2454 while (cur)
2455 {
2204 if (cur->data->len < d) { 2456 if (cur->data->len < d)
2457 {
2205 d -= cur->data->len; 2458 d -= cur->data->len;
2459 }
2206 } else { 2460 else
2461 {
2207 for (i=0; i < (cur->ncoords-1); i++) { 2462 for (i = 0; i < (cur->ncoords - 1); i++)
2463 {
2208 l = d; 2464 l = d;
2209 len = (int)transform_polyline_length(pro, (cur->c + i), 2); 2465 len = (int) transform_polyline_length(pro, (cur->c + i), 2);
2210 d -= len; 2466 d -= len;
2211 if (d <= 0) { 2467 if (d <= 0)
2468 {
2212 // We interpolate a bit here... 2469 // We interpolate a bit here...
2213 frac = (double)l / len; 2470 frac = (double) l / len;
2214 2471
2215 dx = (cur->c + i + 1)->x - (cur->c + i)->x; 2472 dx = (cur->c + i + 1)->x - (cur->c + i)->x;
2216 dy = (cur->c + i + 1)->y - (cur->c + i)->y; 2473 dy = (cur->c + i + 1)->y - (cur->c + i)->y;
2217 2474
2218 ret.x = (cur->c + i)->x + (frac * dx); 2475 ret.x = (cur->c + i)->x + (frac * dx);
2219 ret.y = (cur->c + i)->y + (frac * dy); 2476 ret.y = (cur->c + i)->y + (frac * dy);
2220 return ret; 2477 return ret;
2221 } 2478 }
2222 } 2479 }
2223 return cur->c[(cur->ncoords-1)]; 2480 return cur->c[(cur->ncoords - 1)];
2224 } 2481 }
2225 cur = cur->next; 2482 cur = cur->next;
2226 } 2483 }
2227 2484
2228 return dst->c; 2485 return dst->c;
2240 * @param dst The destination of the route 2497 * @param dst The destination of the route
2241 * @param preferences The routing preferences 2498 * @param preferences The routing preferences
2242 * @return The new route path 2499 * @return The new route path
2243 */ 2500 */
2244static struct route_path * 2501static struct route_path *
2245route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile) 2502route_path_new(struct route_graph *this, struct route_path *oldpath,
2503 struct route_info *pos, struct route_info *dst,
2504 struct vehicleprofile *profile)
2246{ 2505{
2247 struct route_graph_segment *first,*s=NULL,*s1=NULL,*s2=NULL; 2506 struct route_graph_segment *first, *s = NULL, *s1 = NULL, *s2 = NULL;
2248 struct route_graph_point *start; 2507 struct route_graph_point *start;
2249 struct route_info *posinfo, *dstinfo; 2508 struct route_info *posinfo, *dstinfo;
2250 int segs=0; 2509 int segs = 0;
2251 int val1=INT_MAX,val2=INT_MAX; 2510 int val1 = INT_MAX, val2 = INT_MAX;
2252 int val,val1_new,val2_new; 2511 int val, val1_new, val2_new;
2253 struct route_path *ret; 2512 struct route_path *ret;
2254 2513
2255 if (! pos->street || ! dst->street) { 2514 if (!pos->street || !dst->street)
2515 {
2256 dbg(0,"pos or dest not set\n"); 2516 dbg(0, "pos or dest not set\n");
2257 return NULL; 2517 return NULL;
2258 } 2518 }
2259 2519
2260 if (profile->mode == 2 || (profile->mode == 0 && pos->lenextra + dst->lenextra > transform_distance(map_projection(pos->street->item.map), &pos->c, &dst->c))) 2520 if (profile->mode == 2 || (profile->mode == 0 && pos->lenextra
2521 + dst->lenextra > transform_distance(
2522 map_projection(pos->street->item.map), &pos->c, &dst->c)))
2261 return route_path_new_offroad(this, pos, dst); 2523 return route_path_new_offroad(this, pos, dst);
2262 while ((s=route_graph_get_segment(this, pos->street, s))) { 2524 while ((s = route_graph_get_segment(this, pos->street, s)))
2525 {
2263 val=route_value_seg(profile, NULL, s, 1); 2526 val = route_value_seg(profile, NULL, s, 1);
2264 if (val != INT_MAX && s->end->value != INT_MAX) { 2527 if (val != INT_MAX && s->end->value != INT_MAX)
2528 {
2265 val=val*(100-pos->percent)/100; 2529 val = val * (100 - pos->percent) / 100;
2266 val1_new=s->end->value+val; 2530 val1_new = s->end->value + val;
2267 if (val1_new < val1) { 2531 if (val1_new < val1)
2532 {
2268 val1=val1_new; 2533 val1 = val1_new;
2269 s1=s; 2534 s1 = s;
2270 }
2271 } 2535 }
2536 }
2272 val=route_value_seg(profile, NULL, s, -1); 2537 val = route_value_seg(profile, NULL, s, -1);
2273 if (val != INT_MAX && s->start->value != INT_MAX) { 2538 if (val != INT_MAX && s->start->value != INT_MAX)
2539 {
2274 val=val*pos->percent/100; 2540 val = val * pos->percent / 100;
2275 val2_new=s->start->value+val; 2541 val2_new = s->start->value + val;
2276 if (val2_new < val2) { 2542 if (val2_new < val2)
2543 {
2277 val2=val2_new; 2544 val2 = val2_new;
2278 s2=s; 2545 s2 = s;
2279 }
2280 } 2546 }
2281 } 2547 }
2548 }
2282 if (val1 == INT_MAX && val2 == INT_MAX) { 2549 if (val1 == INT_MAX && val2 == INT_MAX)
2550 {
2283 dbg(0,"no route found, pos blocked\n"); 2551 dbg(0, "no route found, pos blocked\n");
2284 return NULL; 2552 return NULL;
2285 } 2553 }
2286 if (val1 == val2) { 2554 if (val1 == val2)
2555 {
2287 val1=s1->end->value; 2556 val1 = s1->end->value;
2288 val2=s2->start->value; 2557 val2 = s2->start->value;
2289 } 2558 }
2290 if (val1 < val2) { 2559 if (val1 < val2)
2560 {
2291 start=s1->start; 2561 start = s1->start;
2292 s=s1; 2562 s = s1;
2293 } else { 2563 }
2564 else
2565 {
2294 start=s2->end; 2566 start = s2->end;
2295 s=s2; 2567 s = s2;
2296 }
2297 ret=g_new0(struct route_path, 1); 2568 }ret=g_new0(struct route_path, 1);
2298 ret->in_use=1; 2569 ret->in_use = 1;
2299 ret->updated=1; 2570 ret->updated = 1;
2300 if (pos->lenextra) 2571 if (pos->lenextra)
2301 route_path_add_line(ret, &pos->c, &pos->lp, pos->lenextra); 2572 route_path_add_line(ret, &pos->c, &pos->lp, pos->lenextra);
2302 ret->path_hash=item_hash_new(); 2573 ret->path_hash = item_hash_new();
2303 dstinfo=NULL; 2574 dstinfo = NULL;
2304 posinfo=pos; 2575 posinfo = pos;
2305 first=s; 2576 first = s;
2577 while (s && !dstinfo)
2306 while (s && !dstinfo) { /* following start->seg, which indicates the least costly way to reach our destination */ 2578 { /* following start->seg, which indicates the least costly way to reach our destination */
2307 segs++; 2579 segs++;
2308#if 0 2580#if 0
2309 printf("start->value=%d 0x%x,0x%x\n", start->value, start->c.x, start->c.y); 2581 printf("start->value=%d 0x%x,0x%x\n", start->value, start->c.x, start->c.y);
2310#endif 2582#endif
2311 if (s->start == start) { 2583 if (s->start == start)
2584 {
2312 if (item_is_equal(s->data.item, dst->street->item) && (s->end->seg == s || !posinfo)) 2585 if (item_is_equal(s->data.item, dst->street->item) && (s->end->seg
2586 == s || !posinfo))
2313 dstinfo=dst; 2587 dstinfo = dst;
2314 if (!route_path_add_item_from_graph(ret, oldpath, s, 1, posinfo, dstinfo)) 2588 if (!route_path_add_item_from_graph(ret, oldpath, s, 1, posinfo,
2589 dstinfo))
2315 ret->updated=0; 2590 ret->updated = 0;
2316 start=s->end; 2591 start = s->end;
2592 }
2317 } else { 2593 else
2318 if (item_is_equal(s->data.item, dst->street->item) && (s->start->seg == s || !posinfo)) 2594 {
2595 if (item_is_equal(s->data.item, dst->street->item)
2596 && (s->start->seg == s || !posinfo))
2319 dstinfo=dst; 2597 dstinfo = dst;
2320 if (!route_path_add_item_from_graph(ret, oldpath, s, -1, posinfo, dstinfo)) 2598 if (!route_path_add_item_from_graph(ret, oldpath, s, -1, posinfo,
2599 dstinfo))
2321 ret->updated=0; 2600 ret->updated = 0;
2322 start=s->start; 2601 start = s->start;
2323 } 2602 }
2324 posinfo=NULL; 2603 posinfo = NULL;
2325 s=start->seg; 2604 s = start->seg;
2326 } 2605 }
2327 if (dst->lenextra) 2606 if (dst->lenextra)
2328 route_path_add_line(ret, &dst->lp, &dst->c, dst->lenextra); 2607 route_path_add_line(ret, &dst->lp, &dst->c, dst->lenextra);
2329 dbg(1, "%d segments\n", segs); 2608 //dbg(1, "%d segments\n", segs);
2330 return ret; 2609 return ret;
2331} 2610}
2332 2611
2333static int
2334route_graph_build_next_map(struct route_graph *rg) 2612static int route_graph_build_next_map(struct route_graph *rg)
2335{ 2613{
2336 do { 2614 do
2615 {
2337 rg->m=mapset_next(rg->h, 2); 2616 rg->m = mapset_next(rg->h, 2);
2338 if (! rg->m) 2617 if (!rg->m)
2339 return 0; 2618 return 0;
2340 map_rect_destroy(rg->mr); 2619 map_rect_destroy(rg->mr);
2341 rg->mr=map_rect_new(rg->m, rg->sel); 2620 rg->mr = map_rect_new(rg->m, rg->sel);
2621 }
2342 } while (!rg->mr); 2622 while (!rg->mr);
2343 2623
2344 return 1; 2624 return 1;
2345} 2625}
2346 2626
2347 2627static int is_turn_allowed(struct route_graph_point *p,
2348static int 2628 struct route_graph_segment *from, struct route_graph_segment *to)
2349is_turn_allowed(struct route_graph_point *p, struct route_graph_segment *from, struct route_graph_segment *to)
2350{ 2629{
2351 struct route_graph_point *prev,*next; 2630 struct route_graph_point *prev, *next;
2352 struct route_graph_segment *tmp1,*tmp2; 2631 struct route_graph_segment *tmp1, *tmp2;
2353 if (item_is_equal(from->data.item, to->data.item)) 2632 if (item_is_equal(from->data.item, to->data.item))
2354 return 0; 2633 return 0;
2355 if (from->start == p) 2634 if (from->start == p)
2356 prev=from->end; 2635 prev = from->end;
2357 else 2636 else
2358 prev=from->start; 2637 prev = from->start;
2359 if (to->start == p) 2638 if (to->start == p)
2360 next=to->end; 2639 next = to->end;
2361 else 2640 else
2362 next=to->start; 2641 next = to->start;
2363 tmp1=p->end; 2642 tmp1 = p->end;
2364 while (tmp1) { 2643 while (tmp1)
2644 {
2365 if (tmp1->start->c.x == prev->c.x && tmp1->start->c.y == prev->c.y && 2645 if (tmp1->start->c.x == prev->c.x && tmp1->start->c.y == prev->c.y
2366 (tmp1->data.item.type == type_street_turn_restriction_no || 2646 && (tmp1->data.item.type == type_street_turn_restriction_no
2367 tmp1->data.item.type == type_street_turn_restriction_only)) { 2647 || tmp1->data.item.type
2648 == type_street_turn_restriction_only))
2649 {
2368 tmp2=p->start; 2650 tmp2 = p->start;
2369 dbg(1,"found %s (0x%x,0x%x) (0x%x,0x%x)-(0x%x,0x%x) %p-%p\n",item_to_name(tmp1->data.item.type),tmp1->data.item.id_hi,tmp1->data.item.id_lo,tmp1->start->c.x,tmp1->start->c.y,tmp1->end->c.x,tmp1->end->c.y,tmp1->start,tmp1->end); 2651 //dbg(1, "found %s (0x%x,0x%x) (0x%x,0x%x)-(0x%x,0x%x) %p-%p\n",
2652 // item_to_name(tmp1->data.item.type), tmp1->data.item.id_hi,
2653 // tmp1->data.item.id_lo, tmp1->start->c.x, tmp1->start->c.y,
2654 // tmp1->end->c.x, tmp1->end->c.y, tmp1->start, tmp1->end);
2370 while (tmp2) { 2655 while (tmp2)
2371 dbg(1,"compare %s (0x%x,0x%x) (0x%x,0x%x)-(0x%x,0x%x) %p-%p\n",item_to_name(tmp2->data.item.type),tmp2->data.item.id_hi,tmp2->data.item.id_lo,tmp2->start->c.x,tmp2->start->c.y,tmp2->end->c.x,tmp2->end->c.y,tmp2->start,tmp2->end); 2656 {
2657 //dbg(
2658 // 1,
2659 // "compare %s (0x%x,0x%x) (0x%x,0x%x)-(0x%x,0x%x) %p-%p\n",
2660 // item_to_name(tmp2->data.item.type),
2661 // tmp2->data.item.id_hi, tmp2->data.item.id_lo,
2662 // tmp2->start->c.x, tmp2->start->c.y, tmp2->end->c.x,
2663 // tmp2->end->c.y, tmp2->start, tmp2->end);
2372 if (item_is_equal(tmp1->data.item, tmp2->data.item)) 2664 if (item_is_equal(tmp1->data.item, tmp2->data.item))
2373 break; 2665 break;
2374 tmp2=tmp2->start_next; 2666 tmp2 = tmp2->start_next;
2375 } 2667 }
2376 dbg(1,"tmp2=%p\n",tmp2); 2668 //dbg(1, "tmp2=%p\n", tmp2);
2377 if (tmp2) { 2669 if (tmp2)
2378 dbg(1,"%s tmp2->end=%p next=%p\n",item_to_name(tmp1->data.item.type),tmp2->end,next);
2379 } 2670 {
2380 if (tmp1->data.item.type == type_street_turn_restriction_no && tmp2 && tmp2->end->c.x == next->c.x && tmp2->end->c.y == next->c.y) { 2671 //dbg(1, "%s tmp2->end=%p next=%p\n",
2381 dbg(1,"from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x not allowed (no)\n",prev->c.x,prev->c.y,p->c.x,p->c.y,next->c.x,next->c.y); 2672 // item_to_name(tmp1->data.item.type), tmp2->end, next);
2673 }
2674 if (tmp1->data.item.type == type_street_turn_restriction_no && tmp2
2675 && tmp2->end->c.x == next->c.x && tmp2->end->c.y
2676 == next->c.y)
2677 {
2678 //dbg(
2679 // 1,
2680 // "from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x not allowed (no)\n",
2681 // prev->c.x, prev->c.y, p->c.x, p->c.y, next->c.x,
2682 // next->c.y);
2382 return 0; 2683 return 0;
2383 } 2684 }
2384 if (tmp1->data.item.type == type_street_turn_restriction_only && tmp2 && (tmp2->end->c.x != next->c.x || tmp2->end->c.y != next->c.y)) { 2685 if (tmp1->data.item.type == type_street_turn_restriction_only
2385 dbg(1,"from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x not allowed (only)\n",prev->c.x,prev->c.y,p->c.x,p->c.y,next->c.x,next->c.y); 2686 && tmp2 && (tmp2->end->c.x != next->c.x || tmp2->end->c.y
2687 != next->c.y))
2688 {
2689 //dbg(
2690 // 1,
2691 // "from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x not allowed (only)\n",
2692 // prev->c.x, prev->c.y, p->c.x, p->c.y, next->c.x,
2693 // next->c.y);
2386 return 0; 2694 return 0;
2387 } 2695 }
2388 } 2696 }
2389 tmp1=tmp1->end_next; 2697 tmp1 = tmp1->end_next;
2390 } 2698 }
2391 dbg(1,"from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x allowed\n",prev->c.x,prev->c.y,p->c.x,p->c.y,next->c.x,next->c.y); 2699 //dbg(1, "from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x allowed\n", prev->c.x,
2700 // prev->c.y, p->c.x, p->c.y, next->c.x, next->c.y);
2392 return 1; 2701 return 1;
2393} 2702}
2394 2703
2395static void 2704static void route_graph_clone_segment(struct route_graph *this,
2396route_graph_clone_segment(struct route_graph *this, struct route_graph_segment *s, struct route_graph_point *start, struct route_graph_point *end, int flags) 2705 struct route_graph_segment *s, struct route_graph_point *start,
2706 struct route_graph_point *end, int flags)
2397{ 2707{
2398 struct route_graph_segment_data data; 2708 struct route_graph_segment_data data;
2399 data.flags=s->data.flags|flags; 2709 data.flags = s->data.flags | flags;
2400 data.offset=1; 2710 data.offset = 1;
2401 data.maxspeed=-1; 2711 data.maxspeed = -1;
2402 data.item=&s->data.item; 2712 data.item = &s->data.item;
2403 data.len=s->data.len+1; 2713 data.len = s->data.len + 1;
2404 if (s->data.flags & AF_SPEED_LIMIT) 2714 if (s->data.flags & AF_SPEED_LIMIT)
2405 data.maxspeed=RSD_MAXSPEED(&s->data); 2715 data.maxspeed = RSD_MAXSPEED(&s->data);
2406 if (s->data.flags & AF_SEGMENTED) 2716 if (s->data.flags & AF_SEGMENTED)
2407 data.offset=RSD_OFFSET(&s->data); 2717 data.offset = RSD_OFFSET(&s->data);
2408 dbg(1,"cloning segment from %p (0x%x,0x%x) to %p (0x%x,0x%x)\n",start,start->c.x,start->c.y, end, end->c.x, end->c.y); 2718 //dbg(1, "cloning segment from %p (0x%x,0x%x) to %p (0x%x,0x%x)\n", start,
2719 // start->c.x, start->c.y, end, end->c.x, end->c.y);
2409 route_graph_add_segment(this, start, end, &data); 2720 route_graph_add_segment(this, start, end, &data);
2410} 2721}
2411 2722
2412static void 2723static void route_graph_process_restriction_segment(struct route_graph *this,
2413route_graph_process_restriction_segment(struct route_graph *this, struct route_graph_point *p, struct route_graph_segment *s, int dir) 2724 struct route_graph_point *p, struct route_graph_segment *s, int dir)
2414{ 2725{
2415 struct route_graph_segment *tmp; 2726 struct route_graph_segment *tmp;
2416 struct route_graph_point *pn; 2727 struct route_graph_point *pn;
2417 struct coord c=p->c; 2728 struct coord c = p->c;
2418 int dx=0; 2729 int dx = 0;
2419 int dy=0; 2730 int dy = 0;
2420 c.x+=dx; 2731 c.x += dx;
2421 c.y+=dy; 2732 c.y += dy;
2422 dbg(1,"From %s %d,%d\n",item_to_name(s->data.item.type),dx,dy); 2733 //dbg(1, "From %s %d,%d\n", item_to_name(s->data.item.type), dx, dy);
2423 pn=route_graph_point_new(this, &c); 2734 pn = route_graph_point_new(this, &c);
2424 if (dir > 0) { /* going away */ 2735 if (dir > 0)
2736 { /* going away */
2425 dbg(1,"other 0x%x,0x%x\n",s->end->c.x,s->end->c.y); 2737 //dbg(1, "other 0x%x,0x%x\n", s->end->c.x, s->end->c.y);
2426 if (s->data.flags & AF_ONEWAY) { 2738 if (s->data.flags & AF_ONEWAY)
2739 {
2427 dbg(1,"Not possible\n"); 2740 //dbg(1, "Not possible\n");
2428 return; 2741 return;
2429 } 2742 }
2430 route_graph_clone_segment(this, s, pn, s->end, AF_ONEWAYREV); 2743 route_graph_clone_segment(this, s, pn, s->end, AF_ONEWAYREV);
2744 }
2745 else
2431 } else { /* coming in */ 2746 { /* coming in */
2432 dbg(1,"other 0x%x,0x%x\n",s->start->c.x,s->start->c.y); 2747 //dbg(1, "other 0x%x,0x%x\n", s->start->c.x, s->start->c.y);
2433 if (s->data.flags & AF_ONEWAYREV) { 2748 if (s->data.flags & AF_ONEWAYREV)
2749 {
2434 dbg(1,"Not possible\n"); 2750 //dbg(1, "Not possible\n");
2435 return; 2751 return;
2436 } 2752 }
2437 route_graph_clone_segment(this, s, s->start, pn, AF_ONEWAY); 2753 route_graph_clone_segment(this, s, s->start, pn, AF_ONEWAY);
2438 } 2754 }
2439 tmp=p->start; 2755 tmp = p->start;
2440 while (tmp) { 2756 while (tmp)
2757 {
2441 if (tmp != s && tmp->data.item.type != type_street_turn_restriction_no && 2758 if (tmp != s && tmp->data.item.type != type_street_turn_restriction_no
2442 tmp->data.item.type != type_street_turn_restriction_only && 2759 && tmp->data.item.type != type_street_turn_restriction_only
2443 !(tmp->data.flags & AF_ONEWAYREV) && is_turn_allowed(p, s, tmp)) { 2760 && !(tmp->data.flags & AF_ONEWAYREV) && is_turn_allowed(p, s,
2761 tmp))
2762 {
2444 route_graph_clone_segment(this, tmp, pn, tmp->end, AF_ONEWAY); 2763 route_graph_clone_segment(this, tmp, pn, tmp->end, AF_ONEWAY);
2445 dbg(1,"To start %s\n",item_to_name(tmp->data.item.type)); 2764 //dbg(1, "To start %s\n", item_to_name(tmp->data.item.type));
2446 } 2765 }
2447 tmp=tmp->start_next; 2766 tmp = tmp->start_next;
2448 } 2767 }
2449 tmp=p->end; 2768 tmp = p->end;
2450 while (tmp) { 2769 while (tmp)
2770 {
2451 if (tmp != s && tmp->data.item.type != type_street_turn_restriction_no && 2771 if (tmp != s && tmp->data.item.type != type_street_turn_restriction_no
2452 tmp->data.item.type != type_street_turn_restriction_only && 2772 && tmp->data.item.type != type_street_turn_restriction_only
2453 !(tmp->data.flags & AF_ONEWAY) && is_turn_allowed(p, s, tmp)) { 2773 && !(tmp->data.flags & AF_ONEWAY) && is_turn_allowed(p, s, tmp))
2774 {
2454 route_graph_clone_segment(this, tmp, tmp->start, pn, AF_ONEWAYREV); 2775 route_graph_clone_segment(this, tmp, tmp->start, pn, AF_ONEWAYREV);
2455 dbg(1,"To end %s\n",item_to_name(tmp->data.item.type)); 2776 //dbg(1, "To end %s\n", item_to_name(tmp->data.item.type));
2456 } 2777 }
2457 tmp=tmp->end_next; 2778 tmp = tmp->end_next;
2458 } 2779 }
2459} 2780}
2460 2781
2461static void
2462route_graph_process_restriction_point(struct route_graph *this, struct route_graph_point *p) 2782static void route_graph_process_restriction_point(struct route_graph *this,
2783 struct route_graph_point *p)
2463{ 2784{
2464 struct route_graph_segment *tmp; 2785 struct route_graph_segment *tmp;
2465 tmp=p->start; 2786 tmp = p->start;
2466 dbg(1,"node 0x%x,0x%x\n",p->c.x,p->c.y); 2787 //dbg(1, "node 0x%x,0x%x\n", p->c.x, p->c.y);
2467 while (tmp) { 2788 while (tmp)
2789 {
2468 if (tmp->data.item.type != type_street_turn_restriction_no && 2790 if (tmp->data.item.type != type_street_turn_restriction_no
2469 tmp->data.item.type != type_street_turn_restriction_only) 2791 && tmp->data.item.type != type_street_turn_restriction_only)
2470 route_graph_process_restriction_segment(this, p, tmp, 1); 2792 route_graph_process_restriction_segment(this, p, tmp, 1);
2471 tmp=tmp->start_next; 2793 tmp = tmp->start_next;
2472 } 2794 }
2473 tmp=p->end; 2795 tmp = p->end;
2474 while (tmp) { 2796 while (tmp)
2797 {
2475 if (tmp->data.item.type != type_street_turn_restriction_no && 2798 if (tmp->data.item.type != type_street_turn_restriction_no
2476 tmp->data.item.type != type_street_turn_restriction_only) 2799 && tmp->data.item.type != type_street_turn_restriction_only)
2477 route_graph_process_restriction_segment(this, p, tmp, -1); 2800 route_graph_process_restriction_segment(this, p, tmp, -1);
2478 tmp=tmp->end_next; 2801 tmp = tmp->end_next;
2479 } 2802 }
2480 p->flags |= RP_TURN_RESTRICTION_RESOLVED; 2803 p->flags |= RP_TURN_RESTRICTION_RESOLVED;
2481} 2804}
2482 2805
2483static void
2484route_graph_process_restrictions(struct route_graph *this) 2806static void route_graph_process_restrictions(struct route_graph *this)
2485{ 2807{
2486 struct route_graph_point *curr; 2808 struct route_graph_point *curr;
2487 int i; 2809 int i;
2488 dbg(1,"enter\n"); 2810 //dbg(1, "enter\n");
2489 for (i = 0 ; i < HASH_SIZE ; i++) { 2811 for (i = 0; i < HASH_SIZE; i++)
2812 {
2490 curr=this->hash[i]; 2813 curr = this->hash[i];
2491 while (curr) { 2814 while (curr)
2815 {
2492 if (curr->flags & RP_TURN_RESTRICTION) 2816 if (curr->flags & RP_TURN_RESTRICTION)
2493 route_graph_process_restriction_point(this, curr); 2817 route_graph_process_restriction_point(this, curr);
2494 curr=curr->hash_next; 2818 curr = curr->hash_next;
2495 }
2496 } 2819 }
2820 }
2497} 2821}
2498 2822
2499static void
2500route_graph_build_done(struct route_graph *rg, int cancel) 2823static void route_graph_build_done(struct route_graph *rg, int cancel)
2501{ 2824{
2502 dbg(1,"cancel=%d\n",cancel); 2825 //dbg(1, "cancel=%d\n", cancel);
2503 if (rg->idle_ev) 2826 if (rg->idle_ev)
2504 event_remove_idle(rg->idle_ev); 2827 event_remove_idle(rg->idle_ev);
2505 if (rg->idle_cb) 2828 if (rg->idle_cb)
2506 callback_destroy(rg->idle_cb); 2829 callback_destroy(rg->idle_cb);
2507 map_rect_destroy(rg->mr); 2830 map_rect_destroy(rg->mr);
2508 mapset_close(rg->h); 2831 mapset_close(rg->h);
2509 route_free_selection(rg->sel); 2832 route_free_selection(rg->sel);
2510 rg->idle_ev=NULL; 2833 rg->idle_ev = NULL;
2511 rg->idle_cb=NULL; 2834 rg->idle_cb = NULL;
2512 rg->mr=NULL; 2835 rg->mr = NULL;
2513 rg->h=NULL; 2836 rg->h = NULL;
2514 rg->sel=NULL; 2837 rg->sel = NULL;
2515 if (! cancel) { 2838 if (!cancel)
2839 {
2516 route_graph_process_restrictions(rg); 2840 route_graph_process_restrictions(rg);
2517 callback_call_0(rg->done_cb); 2841 callback_call_0(rg->done_cb);
2518 } 2842 }
2519 rg->busy=0; 2843 rg->busy = 0;
2520} 2844}
2521 2845
2522static void 2846static void route_graph_build_idle(struct route_graph *rg,
2523route_graph_build_idle(struct route_graph *rg, struct vehicleprofile *profile) 2847 struct vehicleprofile *profile)
2524{ 2848{
2525 int count=1000; 2849 int count = 1000;
2526 struct item *item; 2850 struct item *item;
2527 2851
2528 while (count > 0) { 2852 while (count > 0)
2853 {
2529 for (;;) { 2854 for (;;)
2855 {
2530 item=map_rect_get_item(rg->mr); 2856 item = map_rect_get_item(rg->mr);
2531 if (item) 2857 if (item)
2532 break; 2858 break;
2533 if (!route_graph_build_next_map(rg)) { 2859 if (!route_graph_build_next_map(rg))
2860 {
2534 route_graph_build_done(rg, 0); 2861 route_graph_build_done(rg, 0);
2535 return; 2862 return;
2536 } 2863 }
2537 } 2864 }
2538 if (item->type == type_traffic_distortion) 2865 if (item->type == type_traffic_distortion)
2539 route_process_traffic_distortion(rg, item); 2866 route_process_traffic_distortion(rg, item);
2540 else if (item->type == type_street_turn_restriction_no || item->type == type_street_turn_restriction_only) 2867 else if (item->type == type_street_turn_restriction_no || item->type
2868 == type_street_turn_restriction_only)
2541 route_process_turn_restriction(rg, item); 2869 route_process_turn_restriction(rg, item);
2542 else 2870 else
2543 route_process_street_graph(rg, item, profile); 2871 route_process_street_graph(rg, item, profile);
2544 count--; 2872 count--;
2545 } 2873 }
2560 * @param c2 Corner 2 of the rectangle to use from the map 2888 * @param c2 Corner 2 of the rectangle to use from the map
2561 * @param done_cb The callback which will be called when graph is complete 2889 * @param done_cb The callback which will be called when graph is complete
2562 * @return The new route graph. 2890 * @return The new route graph.
2563 */ 2891 */
2564static struct route_graph * 2892static struct route_graph *
2565route_graph_build(struct mapset *ms, struct coord *c, int count, struct callback *done_cb, int async, struct vehicleprofile *profile, int try_harder) 2893route_graph_build(struct mapset *ms, struct coord *c, int count,
2894 struct callback *done_cb, int async, struct vehicleprofile *profile,
2895 int try_harder)
2566{ 2896{
2567 struct route_graph *ret=g_new0(struct route_graph, 1); 2897 struct route_graph *ret=g_new0(struct route_graph, 1);
2568 2898
2569 dbg(1,"enter\n"); 2899 //dbg(1, "enter\n");
2570 2900
2571 ret->sel=route_calc_selection(c, count, try_harder); 2901 ret->sel = route_calc_selection(c, count, try_harder);
2572 ret->h=mapset_open(ms); 2902 ret->h = mapset_open(ms);
2573 ret->done_cb=done_cb; 2903 ret->done_cb = done_cb;
2574 ret->busy=1; 2904 ret->busy = 1;
2575 if (route_graph_build_next_map(ret)) { 2905 if (route_graph_build_next_map(ret))
2906 {
2576 if (async) { 2907 if (async)
2908 {
2909 ret->idle_cb = callback_new_2(
2577 ret->idle_cb=callback_new_2(callback_cast(route_graph_build_idle), ret, profile); 2910 callback_cast(route_graph_build_idle), ret, profile);
2578 ret->idle_ev=event_add_idle(50, ret->idle_cb); 2911 ret->idle_ev = event_add_idle(50, ret->idle_cb);
2912 }
2579 } 2913 }
2580 } else 2914 else
2581 route_graph_build_done(ret, 0); 2915 route_graph_build_done(ret, 0);
2582 2916
2583 return ret; 2917 return ret;
2584} 2918}
2585 2919
2586static void
2587route_graph_update_done(struct route *this, struct callback *cb) 2920static void route_graph_update_done(struct route *this, struct callback *cb)
2588{ 2921{
2589 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, cb); 2922 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, cb);
2590} 2923}
2591 2924
2592/** 2925/**
2595 * This updates the route graph after settings in the route have changed. It also 2928 * This updates the route graph after settings in the route have changed. It also
2596 * adds routing information afterwards by calling route_graph_flood(). 2929 * adds routing information afterwards by calling route_graph_flood().
2597 * 2930 *
2598 * @param this The route to update the graph for 2931 * @param this The route to update the graph for
2599 */ 2932 */
2600static void
2601route_graph_update(struct route *this, struct callback *cb, int async) 2933static void route_graph_update(struct route *this, struct callback *cb,
2934 int async)
2602{ 2935{
2603 struct attr route_status; 2936 struct attr route_status;
2937 struct coord *c = g_alloca(
2604 struct coord *c=g_alloca(sizeof(struct coord)*(1+g_list_length(this->destinations))); 2938 sizeof(struct coord) * (1 + g_list_length(this->destinations)));
2605 int i=0; 2939 int i = 0;
2606 GList *tmp; 2940 GList *tmp;
2607 2941
2608 route_status.type=attr_route_status; 2942 route_status.type = attr_route_status;
2609 route_graph_destroy(this->graph); 2943 route_graph_destroy(this->graph);
2610 this->graph=NULL; 2944 this->graph = NULL;
2611 callback_destroy(this->route_graph_done_cb); 2945 callback_destroy(this->route_graph_done_cb);
2612 this->route_graph_done_cb=callback_new_2(callback_cast(route_graph_update_done), this, cb); 2946 this->route_graph_done_cb = callback_new_2(
2947 callback_cast(route_graph_update_done), this, cb);
2613 route_status.u.num=route_status_building_graph; 2948 route_status.u.num = route_status_building_graph;
2614 route_set_attr(this, &route_status); 2949 route_set_attr(this, &route_status);
2615 c[i++]=this->pos->c; 2950 c[i++] = this->pos->c;
2616 tmp=this->destinations; 2951 tmp = this->destinations;
2617 while (tmp) { 2952 while (tmp)
2953 {
2618 struct route_info *dst=tmp->data; 2954 struct route_info *dst = tmp->data;
2619 c[i++]=dst->c; 2955 c[i++] = dst->c;
2620 tmp=g_list_next(tmp); 2956 tmp = g_list_next(tmp);
2621 } 2957 }
2622 this->graph=route_graph_build(this->ms, c, i, this->route_graph_done_cb, async, this->vehicleprofile, this->try_harder); 2958 this->graph = route_graph_build(this->ms, c, i, this->route_graph_done_cb,
2959 async, this->vehicleprofile, this->try_harder);
2623 if (! async) { 2960 if (!async)
2961 {
2624 while (this->graph->busy) 2962 while (this->graph->busy)
2625 route_graph_build_idle(this->graph, this->vehicleprofile); 2963 route_graph_build_idle(this->graph, this->vehicleprofile);
2626 } 2964 }
2627} 2965}
2628 2966
2629/** 2967/**
2631 * 2969 *
2632 * @param item The item to get the data for 2970 * @param item The item to get the data for
2633 * @return Street data for the item 2971 * @return Street data for the item
2634 */ 2972 */
2635struct street_data * 2973struct street_data *
2636street_get_data (struct item *item) 2974street_get_data(struct item *item)
2637{ 2975{
2638 int count=0,*flags; 2976 int count = 0, *flags;
2639 struct street_data *ret = NULL, *ret1; 2977 struct street_data *ret = NULL, *ret1;
2640 struct attr flags_attr, maxspeed_attr; 2978 struct attr flags_attr, maxspeed_attr;
2641 const int step = 128; 2979 const int step = 128;
2642 int c; 2980 int c;
2643 2981
2644 do { 2982 do
2645 ret1=g_realloc(ret, sizeof(struct street_data)+(count+step)*sizeof(struct coord)); 2983 {
2984 ret1 = g_realloc(
2985 ret,
2986 sizeof(struct street_data) + (count + step)
2987 * sizeof(struct coord));
2646 if (!ret1) { 2988 if (!ret1)
2989 {
2647 if (ret) 2990 if (ret)
2648 g_free(ret); 2991 g_free(ret);
2649 return NULL; 2992 return NULL;
2650 } 2993 }
2651 ret = ret1; 2994 ret = ret1;
2652 c = item_coord_get(item, &ret->c[count], step); 2995 c = item_coord_get(item, &ret->c[count], step);
2653 count += c; 2996 count += c;
2997 }
2654 } while (c && c == step); 2998 while (c && c == step);
2655 2999
3000 ret1 = g_realloc(ret,
2656 ret1=g_realloc(ret, sizeof(struct street_data)+count*sizeof(struct coord)); 3001 sizeof(struct street_data) + count * sizeof(struct coord));
2657 if (ret1) 3002 if (ret1)
2658 ret = ret1; 3003 ret = ret1;
2659 ret->item=*item; 3004 ret->item = *item;
2660 ret->count=count; 3005 ret->count = count;
2661 if (item_attr_get(item, attr_flags, &flags_attr)) 3006 if (item_attr_get(item, attr_flags, &flags_attr))
2662 ret->flags=flags_attr.u.num; 3007 ret->flags = flags_attr.u.num;
2663 else { 3008 else
3009 {
2664 flags=item_get_default_flags(item->type); 3010 flags = item_get_default_flags(item->type);
2665 if (flags) 3011 if (flags)
2666 ret->flags=*flags; 3012 ret->flags = *flags;
2667 else 3013 else
2668 ret->flags=0; 3014 ret->flags = 0;
2669 } 3015 }
2670 3016
2671 ret->maxspeed = -1; 3017 ret->maxspeed = -1;
2672 if (ret->flags & AF_SPEED_LIMIT) { 3018 if (ret->flags & AF_SPEED_LIMIT)
3019 {
2673 if (item_attr_get(item, attr_maxspeed, &maxspeed_attr)) { 3020 if (item_attr_get(item, attr_maxspeed, &maxspeed_attr))
3021 {
2674 ret->maxspeed = maxspeed_attr.u.num; 3022 ret->maxspeed = maxspeed_attr.u.num;
2675 } 3023 }
2676 } 3024 }
2677 3025
2678 return ret; 3026 return ret;
2681/** 3029/**
2682 * @brief Copies street data 3030 * @brief Copies street data
2683 * 3031 *
2684 * @param orig The street data to copy 3032 * @param orig The street data to copy
2685 * @return The copied street data 3033 * @return The copied street data
2686 */ 3034 */
2687struct street_data * 3035struct street_data *
2688street_data_dup(struct street_data *orig) 3036street_data_dup(struct street_data *orig)
2689{ 3037{
2690 struct street_data *ret; 3038 struct street_data *ret;
2691 int size=sizeof(struct street_data)+orig->count*sizeof(struct coord); 3039 int size = sizeof(struct street_data) + orig->count * sizeof(struct coord);
2692 3040
2693 ret=g_malloc(size); 3041 ret = g_malloc(size);
2694 memcpy(ret, orig, size); 3042 memcpy(ret, orig, size);
2695 3043
2696 return ret; 3044 return ret;
2697} 3045}
2698 3046
2699/** 3047/**
2700 * @brief Frees street data 3048 * @brief Frees street data
2701 * 3049 *
2702 * @param sd Street data to be freed 3050 * @param sd Street data to be freed
2703 */ 3051 */
2704void
2705street_data_free(struct street_data *sd) 3052void street_data_free(struct street_data *sd)
2706{ 3053{
2707 g_free(sd); 3054 g_free(sd);
2708} 3055}
2709 3056
2710/** 3057/**
2713 * @param ms The mapset to search in for the street 3060 * @param ms The mapset to search in for the street
2714 * @param pc The coordinate to find a street nearby 3061 * @param pc The coordinate to find a street nearby
2715 * @return The nearest street 3062 * @return The nearest street
2716 */ 3063 */
2717static struct route_info * 3064static struct route_info *
2718route_find_nearest_street(struct vehicleprofile *vehicleprofile, struct mapset *ms, struct pcoord *pc) 3065route_find_nearest_street(struct vehicleprofile *vehicleprofile,
3066 struct mapset *ms, struct pcoord *pc)
2719{ 3067{
2720 struct route_info *ret=NULL; 3068 struct route_info *ret = NULL;
2721 int max_dist=1000; 3069 int max_dist = 1000;
2722 struct map_selection *sel; 3070 struct map_selection *sel;
2723 int dist,mindist=0,pos; 3071 int dist, mindist = 0, pos;
2724 struct mapset_handle *h; 3072 struct mapset_handle *h;
2725 struct map *m; 3073 struct map *m;
2726 struct map_rect *mr; 3074 struct map_rect *mr;
2727 struct item *item; 3075 struct item *item;
2728 struct coord lp; 3076 struct coord lp;
2731 struct coord_geo g; 3079 struct coord_geo g;
2732 3080
2733 ret=g_new0(struct route_info, 1); 3081 ret=g_new0(struct route_info, 1);
2734 mindist = INT_MAX; 3082 mindist = INT_MAX;
2735 3083
2736 h=mapset_open(ms); 3084 h = mapset_open(ms);
2737 while ((m=mapset_next(h,2))) { 3085 while ((m = mapset_next(h, 2)))
3086 {
2738 c.x = pc->x; 3087 c.x = pc->x;
2739 c.y = pc->y; 3088 c.y = pc->y;
2740 if (map_projection(m) != pc->pro) { 3089 if (map_projection(m) != pc->pro)
3090 {
2741 transform_to_geo(pc->pro, &c, &g); 3091 transform_to_geo(pc->pro, &c, &g);
2742 transform_from_geo(map_projection(m), &g, &c); 3092 transform_from_geo(map_projection(m), &g, &c);
2743 } 3093 }
2744 sel = route_rect(18, &c, &c, 0, max_dist); 3094 sel = route_rect(18, &c, &c, 0, max_dist);
2745 if (!sel) 3095 if (!sel)
2746 continue; 3096 continue;
2747 mr=map_rect_new(m, sel); 3097 mr = map_rect_new(m, sel);
2748 if (!mr) { 3098 if (!mr)
3099 {
2749 map_selection_destroy(sel); 3100 map_selection_destroy(sel);
2750 continue; 3101 continue;
2751 } 3102 }
2752 while ((item=map_rect_get_item(mr))) { 3103 while ((item = map_rect_get_item(mr)))
3104 {
2753 if (item_get_default_flags(item->type)) { 3105 if (item_get_default_flags(item->type))
3106 {
2754 sd=street_get_data(item); 3107 sd = street_get_data(item);
2755 if (!sd) 3108 if (!sd)
2756 continue; 3109 continue;
2757 dist=transform_distance_polyline_sq(sd->c, sd->count, &c, &lp, &pos); 3110 dist = transform_distance_polyline_sq(sd->c, sd->count, &c,
3111 &lp, &pos);
2758 if (dist < mindist && ( 3112 if (dist < mindist && ((sd->flags
2759 (sd->flags & vehicleprofile->flags_forward_mask) == vehicleprofile->flags || 3113 & vehicleprofile->flags_forward_mask)
2760 (sd->flags & vehicleprofile->flags_reverse_mask) == vehicleprofile->flags)) { 3114 == vehicleprofile->flags || (sd->flags
3115 & vehicleprofile->flags_reverse_mask)
3116 == vehicleprofile->flags))
3117 {
2761 mindist = dist; 3118 mindist = dist;
2762 if (ret->street) { 3119 if (ret->street)
3120 {
2763 street_data_free(ret->street); 3121 street_data_free(ret->street);
2764 } 3122 }
2765 ret->c=c; 3123 ret->c = c;
2766 ret->lp=lp; 3124 ret->lp = lp;
2767 ret->pos=pos; 3125 ret->pos = pos;
2768 ret->street=sd; 3126 ret->street = sd;
2769 dbg(1,"dist=%d id 0x%x 0x%x pos=%d\n", dist, item->id_hi, item->id_lo, pos); 3127 //dbg(1, "dist=%d id 0x%x 0x%x pos=%d\n", dist, item->id_hi,
3128 // item->id_lo, pos);
3129 }
2770 } else { 3130 else
3131 {
2771 street_data_free(sd); 3132 street_data_free(sd);
2772 } 3133 }
2773 } 3134 }
2774 } 3135 }
2775 map_selection_destroy(sel); 3136 map_selection_destroy(sel);
2776 map_rect_destroy(mr); 3137 map_rect_destroy(mr);
2777 } 3138 }
2778 mapset_close(h); 3139 mapset_close(h);
2779 3140
2780 if (!ret->street || mindist > max_dist*max_dist) { 3141 if (!ret->street || mindist > max_dist * max_dist)
3142 {
2781 if (ret->street) { 3143 if (ret->street)
3144 {
2782 street_data_free(ret->street); 3145 street_data_free(ret->street);
2783 dbg(1,"Much too far %d > %d\n", mindist, max_dist); 3146 //dbg(1, "Much too far %d > %d\n", mindist, max_dist);
2784 } 3147 }
2785 g_free(ret); 3148 g_free(ret);
2786 ret = NULL; 3149 ret = NULL;
2787 } 3150 }
2788 3151
2792/** 3155/**
2793 * @brief Destroys a route_info 3156 * @brief Destroys a route_info
2794 * 3157 *
2795 * @param info The route info to be destroyed 3158 * @param info The route info to be destroyed
2796 */ 3159 */
2797void
2798route_info_free(struct route_info *inf) 3160void route_info_free(struct route_info *inf)
2799{ 3161{
2800 if (!inf) 3162 if (!inf)
2801 return; 3163 return;
2802 if (inf->street) 3164 if (inf->street)
2803 street_data_free(inf->street); 3165 street_data_free(inf->street);
2804 g_free(inf); 3166 g_free(inf);
2805} 3167}
2806 3168
2807
2808#include "point.h" 3169#include "point.h"
2809 3170
2810/** 3171/**
2811 * @brief Returns street data for a route info 3172 * @brief Returns street data for a route info
2812 * 3173 *
2821 3182
2822#if 0 3183#if 0
2823struct route_crossings * 3184struct route_crossings *
2824route_crossings_get(struct route *this, struct coord *c) 3185route_crossings_get(struct route *this, struct coord *c)
2825{ 3186{
2826 struct route_point *pnt; 3187 struct route_point *pnt;
2827 struct route_segment *seg; 3188 struct route_segment *seg;
2828 int crossings=0; 3189 int crossings=0;
2829 struct route_crossings *ret; 3190 struct route_crossings *ret;
2830 3191
2831 pnt=route_graph_get_point(this, c); 3192 pnt=route_graph_get_point(this, c);
2832 seg=pnt->start; 3193 seg=pnt->start;
2833 while (seg) { 3194 while (seg)
3195 {
2834 printf("start: 0x%x 0x%x\n", seg->item.id_hi, seg->item.id_lo); 3196 printf("start: 0x%x 0x%x\n", seg->item.id_hi, seg->item.id_lo);
2835 crossings++; 3197 crossings++;
2836 seg=seg->start_next; 3198 seg=seg->start_next;
2837 } 3199 }
2838 seg=pnt->end; 3200 seg=pnt->end;
2839 while (seg) { 3201 while (seg)
3202 {
2840 printf("end: 0x%x 0x%x\n", seg->item.id_hi, seg->item.id_lo); 3203 printf("end: 0x%x 0x%x\n", seg->item.id_hi, seg->item.id_lo);
2841 crossings++; 3204 crossings++;
2842 seg=seg->end_next; 3205 seg=seg->end_next;
2843 } 3206 }
2844 ret=g_malloc(sizeof(struct route_crossings)+crossings*sizeof(struct route_crossing)); 3207 ret=g_malloc(sizeof(struct route_crossings)+crossings*sizeof(struct route_crossing));
2845 ret->count=crossings; 3208 ret->count=crossings;
2846 return ret; 3209 return ret;
2847} 3210}
2848#endif 3211#endif
2849 3212
2850
2851struct map_rect_priv { 3213struct map_rect_priv
3214{
2852 struct route_info_handle *ri; 3215 struct route_info_handle *ri;
2853 enum attr_type attr_next; 3216 enum attr_type attr_next;
2854 int pos; 3217 int pos;
2855 struct map_priv *mpriv; 3218 struct map_priv *mpriv;
2856 struct item item; 3219 struct item item;
2857 unsigned int last_coord; 3220 unsigned int last_coord;
2858 struct route_path *path; 3221 struct route_path *path;
2859 struct route_path_segment *seg,*seg_next; 3222 struct route_path_segment *seg, *seg_next;
2860 struct route_graph_point *point; 3223 struct route_graph_point *point;
2861 struct route_graph_segment *rseg; 3224 struct route_graph_segment *rseg;
2862 char *str; 3225 char *str;
2863 int hash_bucket; 3226 int hash_bucket;
2864 struct coord *coord_sel; /**< Set this to a coordinate if you want to filter for just a single route graph point */ 3227 struct coord *coord_sel; /**< Set this to a coordinate if you want to filter for just a single route graph point */
2865 struct route_graph_point_iterator it; 3228 struct route_graph_point_iterator it;
2866}; 3229};
2867 3230
2868static void
2869rm_coord_rewind(void *priv_data) 3231static void rm_coord_rewind(void *priv_data)
2870{ 3232{
2871 struct map_rect_priv *mr = priv_data; 3233 struct map_rect_priv *mr = priv_data;
2872 mr->last_coord = 0; 3234 mr->last_coord = 0;
2873} 3235}
2874 3236
2875static void
2876rm_attr_rewind(void *priv_data) 3237static void rm_attr_rewind(void *priv_data)
2877{ 3238{
2878 struct map_rect_priv *mr = priv_data; 3239 struct map_rect_priv *mr = priv_data;
2879 mr->attr_next = attr_street_item; 3240 mr->attr_next = attr_street_item;
2880} 3241}
2881 3242
2882static int
2883rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) 3243static int rm_attr_get(void *priv_data, enum attr_type attr_type,
3244 struct attr *attr)
2884{ 3245{
2885 struct map_rect_priv *mr = priv_data; 3246 struct map_rect_priv *mr = priv_data;
2886 struct route_path_segment *seg=mr->seg; 3247 struct route_path_segment *seg = mr->seg;
2887 struct route *route=mr->mpriv->route; 3248 struct route *route = mr->mpriv->route;
2888 if (mr->item.type != type_street_route) 3249 if (mr->item.type != type_street_route)
2889 return 0; 3250 return 0;
2890 attr->type=attr_type; 3251 attr->type = attr_type;
2891 switch (attr_type) { 3252 switch (attr_type)
3253 {
2892 case attr_any: 3254 case attr_any:
2893 while (mr->attr_next != attr_none) { 3255 while (mr->attr_next != attr_none)
3256 {
2894 if (rm_attr_get(priv_data, mr->attr_next, attr)) 3257 if (rm_attr_get(priv_data, mr->attr_next, attr))
2895 return 1; 3258 return 1;
2896 } 3259 }
2897 return 0; 3260 return 0;
2898 case attr_maxspeed: 3261 case attr_maxspeed:
2899 mr->attr_next = attr_street_item; 3262 mr->attr_next = attr_street_item;
2900 if (seg && seg->data->flags & AF_SPEED_LIMIT) { 3263 if (seg && seg->data->flags & AF_SPEED_LIMIT)
3264 {
2901 attr->u.num=RSD_MAXSPEED(seg->data); 3265 attr->u.num = RSD_MAXSPEED(seg->data);
2902 3266
3267 }
2903 } else { 3268 else
3269 {
2904 return 0; 3270 return 0;
2905 } 3271 }
2906 return 1; 3272 return 1;
2907 case attr_street_item: 3273 case attr_street_item:
2908 mr->attr_next=attr_direction; 3274 mr->attr_next = attr_direction;
2909 if (seg && seg->data->item.map) 3275 if (seg && seg->data->item.map)
2910 attr->u.item=&seg->data->item; 3276 attr->u.item = &seg->data->item;
2911 else 3277 else
2912 return 0; 3278 return 0;
2913 return 1; 3279 return 1;
2914 case attr_direction: 3280 case attr_direction:
2915 mr->attr_next=attr_route; 3281 mr->attr_next = attr_route;
2916 if (seg) 3282 if (seg)
2917 attr->u.num=seg->direction; 3283 attr->u.num = seg->direction;
2918 else 3284 else
2919 return 0; 3285 return 0;
2920 return 1; 3286 return 1;
2921 case attr_route: 3287 case attr_route:
2922 mr->attr_next=attr_length; 3288 mr->attr_next = attr_length;
2923 attr->u.route = mr->mpriv->route; 3289 attr->u.route = mr->mpriv->route;
2924 return 1; 3290 return 1;
2925 case attr_length: 3291 case attr_length:
2926 mr->attr_next=attr_time; 3292 mr->attr_next = attr_time;
2927 if (seg) 3293 if (seg)
2928 attr->u.num=seg->data->len; 3294 attr->u.num = seg->data->len;
2929 else 3295 else
2930 return 0; 3296 return 0;
2931 return 1; 3297 return 1;
2932 case attr_time: 3298 case attr_time:
2933 mr->attr_next=attr_speed; 3299 mr->attr_next = attr_speed;
2934 if (seg) 3300 if (seg)
2935 attr->u.num=route_time_seg(route->vehicleprofile, seg->data, NULL); 3301 attr->u.num = route_time_seg(route->vehicleprofile, seg->data,
3302 NULL);
2936 else 3303 else
2937 return 0; 3304 return 0;
2938 return 1; 3305 return 1;
2939 case attr_speed: 3306 case attr_speed:
2940 mr->attr_next=attr_none; 3307 mr->attr_next = attr_none;
2941 if (seg) 3308 if (seg)
2942 attr->u.num=route_seg_speed(route->vehicleprofile, seg->data, NULL); 3309 attr->u.num = route_seg_speed(route->vehicleprofile, seg->data,
3310 NULL);
2943 else 3311 else
2944 return 0; 3312 return 0;
2945 return 1; 3313 return 1;
2946 case attr_label: 3314 case attr_label:
2947 mr->attr_next=attr_none; 3315 mr->attr_next = attr_none;
2948 return 0; 3316 return 0;
2949 default: 3317 default:
2950 mr->attr_next=attr_none; 3318 mr->attr_next = attr_none;
2951 attr->type=attr_none; 3319 attr->type = attr_none;
2952 return 0; 3320 return 0;
2953 } 3321 }
2954 return 0; 3322 return 0;
2955} 3323}
2956 3324
2957static int
2958rm_coord_get(void *priv_data, struct coord *c, int count) 3325static int rm_coord_get(void *priv_data, struct coord *c, int count)
2959{ 3326{
2960 struct map_rect_priv *mr = priv_data; 3327 struct map_rect_priv *mr = priv_data;
2961 struct route_path_segment *seg = mr->seg; 3328 struct route_path_segment *seg = mr->seg;
2962 int i,rc=0; 3329 int i, rc = 0;
2963 struct route *r = mr->mpriv->route; 3330 struct route *r = mr->mpriv->route;
2964 enum projection pro = route_projection(r); 3331 enum projection pro = route_projection(r);
2965 3332
2966 if (pro == projection_none) 3333 if (pro == projection_none)
2967 return 0; 3334 return 0;
2968 if (mr->item.type == type_route_start || mr->item.type == type_route_start_reverse || mr->item.type == type_route_end) { 3335 if (mr->item.type == type_route_start || mr->item.type
3336 == type_route_start_reverse || mr->item.type == type_route_end)
3337 {
2969 if (! count || mr->last_coord) 3338 if (!count || mr->last_coord)
2970 return 0; 3339 return 0;
2971 mr->last_coord=1; 3340 mr->last_coord = 1;
2972 if (mr->item.type == type_route_start || mr->item.type == type_route_start_reverse) 3341 if (mr->item.type == type_route_start || mr->item.type
3342 == type_route_start_reverse)
2973 c[0]=r->pos->c; 3343 c[0] = r->pos->c;
2974 else { 3344 else
3345 {
2975 c[0]=route_get_dst(r)->c; 3346 c[0] = route_get_dst(r)->c;
2976 } 3347 }
2977 return 1; 3348 return 1;
2978 } 3349 }
2979 if (! seg) 3350 if (!seg)
2980 return 0; 3351 return 0;
2981 for (i=0; i < count; i++) { 3352 for (i = 0; i < count; i++)
3353 {
2982 if (mr->last_coord >= seg->ncoords) 3354 if (mr->last_coord >= seg->ncoords)
2983 break; 3355 break;
2984 if (i >= seg->ncoords) 3356 if (i >= seg->ncoords)
2985 break; 3357 break;
2986 if (pro != projection_mg) 3358 if (pro != projection_mg)
2987 transform_from_to(&seg->c[mr->last_coord++], pro, 3359 transform_from_to(&seg->c[mr->last_coord++], pro, &c[i],
2988 &c[i],projection_mg); 3360 projection_mg);
2989 else 3361 else
2990 c[i] = seg->c[mr->last_coord++]; 3362 c[i] = seg->c[mr->last_coord++];
2991 rc++; 3363 rc++;
2992 } 3364 }
2993 dbg(1,"return %d\n",rc); 3365 //dbg(1, "return %d\n", rc);
2994 return rc; 3366 return rc;
2995} 3367}
2996 3368
2997static struct item_methods methods_route_item = { 3369static struct item_methods methods_route_item =
2998 rm_coord_rewind, 3370{ rm_coord_rewind, rm_coord_get, rm_attr_rewind, rm_attr_get, };
2999 rm_coord_get,
3000 rm_attr_rewind,
3001 rm_attr_get,
3002};
3003 3371
3004static void
3005rp_attr_rewind(void *priv_data) 3372static void rp_attr_rewind(void *priv_data)
3006{ 3373{
3007 struct map_rect_priv *mr = priv_data; 3374 struct map_rect_priv *mr = priv_data;
3008 mr->attr_next = attr_label; 3375 mr->attr_next = attr_label;
3009} 3376}
3010 3377
3011static int
3012rp_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) 3378static int rp_attr_get(void *priv_data, enum attr_type attr_type,
3379 struct attr *attr)
3013{ 3380{
3014 struct map_rect_priv *mr = priv_data; 3381 struct map_rect_priv *mr = priv_data;
3015 struct route_graph_point *p = mr->point; 3382 struct route_graph_point *p = mr->point;
3016 struct route_graph_segment *seg = mr->rseg; 3383 struct route_graph_segment *seg = mr->rseg;
3017 struct route *route=mr->mpriv->route; 3384 struct route *route = mr->mpriv->route;
3018 3385
3019 attr->type=attr_type; 3386 attr->type = attr_type;
3020 switch (attr_type) { 3387 switch (attr_type)
3388 {
3021 case attr_any: // works only with rg_points for now 3389 case attr_any: // works only with rg_points for now
3022 while (mr->attr_next != attr_none) { 3390 while (mr->attr_next != attr_none)
3391 {
3023 dbg(0,"querying %s\n", attr_to_name(mr->attr_next)); 3392 //dbg(0, "querying %s\n", attr_to_name(mr->attr_next));
3024 if (rp_attr_get(priv_data, mr->attr_next, attr)) 3393 if (rp_attr_get(priv_data, mr->attr_next, attr))
3394 return 1;
3395 }
3396 return 0;
3397 case attr_maxspeed:
3398 mr->attr_next = attr_label;
3399 if (mr->item.type != type_rg_segment)
3400 return 0;
3401 if (seg && (seg->data.flags & AF_SPEED_LIMIT))
3402 {
3403 attr->type = attr_maxspeed;
3404 attr->u.num = RSD_MAXSPEED(&seg->data);
3025 return 1; 3405 return 1;
3026 } 3406 }
3027 return 0;
3028 case attr_maxspeed:
3029 mr->attr_next = attr_label;
3030 if (mr->item.type != type_rg_segment)
3031 return 0;
3032 if (seg && (seg->data.flags & AF_SPEED_LIMIT)) {
3033 attr->type = attr_maxspeed;
3034 attr->u.num=RSD_MAXSPEED(&seg->data);
3035 return 1;
3036 } else {
3037 return 0;
3038 }
3039 case attr_label:
3040 mr->attr_next=attr_street_item;
3041 if (mr->item.type != type_rg_point)
3042 return 0;
3043 attr->type = attr_label;
3044 if (mr->str)
3045 g_free(mr->str);
3046 if (p->value != INT_MAX)
3047 mr->str=g_strdup_printf("%d", p->value);
3048 else 3407 else
3049 mr->str=g_strdup("-");
3050 attr->u.str = mr->str;
3051 return 1;
3052 case attr_street_item:
3053 mr->attr_next=attr_flags;
3054 if (mr->item.type != type_rg_segment)
3055 return 0;
3056 if (seg && seg->data.item.map)
3057 attr->u.item=&seg->data.item;
3058 else
3059 return 0;
3060 return 1;
3061 case attr_flags:
3062 mr->attr_next = attr_direction;
3063 if (mr->item.type != type_rg_segment)
3064 return 0;
3065 if (seg) {
3066 attr->u.num = seg->data.flags;
3067 } else {
3068 return 0;
3069 }
3070 return 1;
3071 case attr_direction:
3072 mr->attr_next = attr_debug;
3073 // This only works if the map has been opened at a single point, and in that case indicates if the
3074 // segment returned last is connected to this point via its start (1) or its end (-1)
3075 if (!mr->coord_sel || (mr->item.type != type_rg_segment))
3076 return 0;
3077 if (seg->start == mr->point) {
3078 attr->u.num=1;
3079 } else if (seg->end == mr->point) {
3080 attr->u.num=-1;
3081 } else {
3082 return 0;
3083 }
3084 return 1;
3085 case attr_debug:
3086 mr->attr_next=attr_none;
3087 if (mr->str)
3088 g_free(mr->str);
3089 switch (mr->item.type) {
3090 case type_rg_point:
3091 { 3408 {
3092 struct route_graph_segment *tmp;
3093 int start=0;
3094 int end=0;
3095 tmp=p->start;
3096 while (tmp) {
3097 start++;
3098 tmp=tmp->start_next;
3099 }
3100 tmp=p->end;
3101 while (tmp) {
3102 end++;
3103 tmp=tmp->end_next;
3104 }
3105 mr->str=g_strdup_printf("%d %d %p (0x%x,0x%x)", start, end, p, p->c.x, p->c.y);
3106 attr->u.str = mr->str;
3107 }
3108 return 1;
3109 case type_rg_segment:
3110 if (! seg)
3111 return 0; 3409 return 0;
3112 mr->str=g_strdup_printf("len %d time %d start %p end %p",seg->data.len, route_time_seg(route->vehicleprofile, &seg->data, NULL), seg->start, seg->end); 3410 }
3411 case attr_label:
3412 mr->attr_next = attr_street_item;
3413 if (mr->item.type != type_rg_point)
3414 return 0;
3415 attr->type = attr_label;
3416 if (mr->str)
3417 g_free(mr->str);
3418 if (p->value != INT_MAX)
3419 mr->str = g_strdup_printf("%d", p->value);
3420 else
3421 mr->str = g_strdup("-");
3113 attr->u.str = mr->str; 3422 attr->u.str = mr->str;
3114 return 1; 3423 return 1;
3424 case attr_street_item:
3425 mr->attr_next = attr_flags;
3426 if (mr->item.type != type_rg_segment)
3427 return 0;
3428 if (seg && seg->data.item.map)
3429 attr->u.item = &seg->data.item;
3430 else
3431 return 0;
3432 return 1;
3433 case attr_flags:
3434 mr->attr_next = attr_direction;
3435 if (mr->item.type != type_rg_segment)
3436 return 0;
3437 if (seg)
3438 {
3439 attr->u.num = seg->data.flags;
3440 }
3441 else
3442 {
3443 return 0;
3444 }
3445 return 1;
3446 case attr_direction:
3447 mr->attr_next = attr_debug;
3448 // This only works if the map has been opened at a single point, and in that case indicates if the
3449 // segment returned last is connected to this point via its start (1) or its end (-1)
3450 if (!mr->coord_sel || (mr->item.type != type_rg_segment))
3451 return 0;
3452 if (seg->start == mr->point)
3453 {
3454 attr->u.num = 1;
3455 }
3456 else if (seg->end == mr->point)
3457 {
3458 attr->u.num = -1;
3459 }
3460 else
3461 {
3462 return 0;
3463 }
3464 return 1;
3465 case attr_debug:
3466 mr->attr_next = attr_none;
3467 if (mr->str)
3468 g_free(mr->str);
3469 switch (mr->item.type)
3470 {
3471 case type_rg_point:
3472 {
3473 struct route_graph_segment *tmp;
3474 int start = 0;
3475 int end = 0;
3476 tmp = p->start;
3477 while (tmp)
3478 {
3479 start++;
3480 tmp = tmp->start_next;
3481 }
3482 tmp = p->end;
3483 while (tmp)
3484 {
3485 end++;
3486 tmp = tmp->end_next;
3487 }
3488 mr->str = g_strdup_printf("%d %d %p (0x%x,0x%x)", start,
3489 end, p, p->c.x, p->c.y);
3490 attr->u.str = mr->str;
3491 }
3492 return 1;
3493 case type_rg_segment:
3494 if (!seg)
3495 return 0;
3496 mr->str = g_strdup_printf(
3497 "len %d time %d start %p end %p",
3498 seg->data.len,
3499 route_time_seg(route->vehicleprofile, &seg->data,
3500 NULL), seg->start, seg->end);
3501 attr->u.str = mr->str;
3502 return 1;
3503 default:
3504 return 0;
3505 }
3115 default: 3506 default:
3507 mr->attr_next = attr_none;
3508 attr->type = attr_none;
3116 return 0; 3509 return 0;
3117 }
3118 default:
3119 mr->attr_next=attr_none;
3120 attr->type=attr_none;
3121 return 0;
3122 } 3510 }
3123} 3511}
3124 3512
3125/** 3513/**
3126 * @brief Returns the coordinates of a route graph item 3514 * @brief Returns the coordinates of a route graph item
3128 * @param priv_data The route graph item's private data 3516 * @param priv_data The route graph item's private data
3129 * @param c Pointer where to store the coordinates 3517 * @param c Pointer where to store the coordinates
3130 * @param count How many coordinates to get at a max? 3518 * @param count How many coordinates to get at a max?
3131 * @return The number of coordinates retrieved 3519 * @return The number of coordinates retrieved
3132 */ 3520 */
3133static int
3134rp_coord_get(void *priv_data, struct coord *c, int count) 3521static int rp_coord_get(void *priv_data, struct coord *c, int count)
3135{ 3522{
3136 struct map_rect_priv *mr = priv_data; 3523 struct map_rect_priv *mr = priv_data;
3137 struct route_graph_point *p = mr->point; 3524 struct route_graph_point *p = mr->point;
3138 struct route_graph_segment *seg = mr->rseg; 3525 struct route_graph_segment *seg = mr->rseg;
3139 int rc = 0,i,dir; 3526 int rc = 0, i, dir;
3140 struct route *r = mr->mpriv->route; 3527 struct route *r = mr->mpriv->route;
3141 enum projection pro = route_projection(r); 3528 enum projection pro = route_projection(r);
3142 3529
3143 if (pro == projection_none) 3530 if (pro == projection_none)
3144 return 0; 3531 return 0;
3145 for (i=0; i < count; i++) { 3532 for (i = 0; i < count; i++)
3533 {
3146 if (mr->item.type == type_rg_point) { 3534 if (mr->item.type == type_rg_point)
3535 {
3147 if (mr->last_coord >= 1) 3536 if (mr->last_coord >= 1)
3148 break; 3537 break;
3149 if (pro != projection_mg) 3538 if (pro != projection_mg)
3150 transform_from_to(&p->c, pro, 3539 transform_from_to(&p->c, pro, &c[i], projection_mg);
3151 &c[i],projection_mg);
3152 else 3540 else
3153 c[i] = p->c; 3541 c[i] = p->c;
3542 }
3154 } else { 3543 else
3544 {
3155 if (mr->last_coord >= 2) 3545 if (mr->last_coord >= 2)
3156 break; 3546 break;
3157 dir=0; 3547 dir = 0;
3158 if (seg->end->seg == seg) 3548 if (seg->end->seg == seg)
3159 dir=1; 3549 dir = 1;
3160 if (mr->last_coord) 3550 if (mr->last_coord)
3161 dir=1-dir; 3551 dir = 1 - dir;
3162 if (dir) { 3552 if (dir)
3553 {
3163 if (pro != projection_mg) 3554 if (pro != projection_mg)
3164 transform_from_to(&seg->end->c, pro, 3555 transform_from_to(&seg->end->c, pro, &c[i], projection_mg);
3165 &c[i],projection_mg);
3166 else 3556 else
3167 c[i] = seg->end->c; 3557 c[i] = seg->end->c;
3558 }
3168 } else { 3559 else
3560 {
3169 if (pro != projection_mg) 3561 if (pro != projection_mg)
3170 transform_from_to(&seg->start->c, pro, 3562 transform_from_to(&seg->start->c, pro, &c[i], projection_mg);
3171 &c[i],projection_mg);
3172 else 3563 else
3173 c[i] = seg->start->c; 3564 c[i] = seg->start->c;
3174 } 3565 }
3175 } 3566 }
3176 mr->last_coord++; 3567 mr->last_coord++;
3177 rc++; 3568 rc++;
3178 } 3569 }
3179 return rc; 3570 return rc;
3180} 3571}
3181 3572
3182static struct item_methods methods_point_item = { 3573static struct item_methods methods_point_item =
3183 rm_coord_rewind, 3574{ rm_coord_rewind, rp_coord_get, rp_attr_rewind, rp_attr_get, };
3184 rp_coord_get,
3185 rp_attr_rewind,
3186 rp_attr_get,
3187};
3188 3575
3189static void
3190rp_destroy(struct map_priv *priv) 3576static void rp_destroy(struct map_priv *priv)
3191{ 3577{
3192 g_free(priv); 3578 g_free(priv);
3193} 3579}
3194 3580
3195static void
3196rm_destroy(struct map_priv *priv) 3581static void rm_destroy(struct map_priv *priv)
3197{ 3582{
3198 g_free(priv); 3583 g_free(priv);
3199} 3584}
3200 3585
3201static struct map_rect_priv * 3586static struct map_rect_priv *
3202rm_rect_new(struct map_priv *priv, struct map_selection *sel) 3587rm_rect_new(struct map_priv *priv, struct map_selection *sel)
3203{ 3588{
3204 struct map_rect_priv * mr; 3589 struct map_rect_priv * mr;
3205 dbg(1,"enter\n"); 3590 //dbg(1, "enter\n");
3591
3206#if 0 3592#if 0
3207 if (! route_get_pos(priv->route)) 3593 if (! route_get_pos(priv->route))
3208 return NULL; 3594 return NULL;
3209 if (! route_get_dst(priv->route)) 3595 if (! route_get_dst(priv->route))
3210 return NULL; 3596 return NULL;
3211#endif 3597#endif
3598
3212#if 0 3599#if 0
3213 if (! priv->route->path2) 3600 if (! priv->route->path2)
3214 return NULL; 3601 return NULL;
3215#endif 3602#endif
3603
3216 mr=g_new0(struct map_rect_priv, 1); 3604 mr=g_new0(struct map_rect_priv, 1);
3217 mr->mpriv = priv; 3605 mr->mpriv = priv;
3218 mr->item.priv_data = mr; 3606 mr->item.priv_data = mr;
3219 mr->item.type = type_none; 3607 mr->item.type = type_none;
3220 mr->item.meth = &methods_route_item; 3608 mr->item.meth = &methods_route_item;
3221 if (priv->route->path2) { 3609 if (priv->route->path2)
3610 {
3222 mr->path=priv->route->path2; 3611 mr->path = priv->route->path2;
3223 mr->seg_next=mr->path->path; 3612 mr->seg_next = mr->path->path;
3224 mr->path->in_use++; 3613 mr->path->in_use++;
3614 }
3225 } else 3615 else
3226 mr->seg_next=NULL; 3616 mr->seg_next = NULL;
3227 return mr; 3617 return mr;
3228} 3618}
3229 3619
3230/** 3620/**
3231 * @brief Opens a new map rectangle on the route graph's map 3621 * @brief Opens a new map rectangle on the route graph's map
3239 * 3629 *
3240 * @param priv The route graph map's private data 3630 * @param priv The route graph map's private data
3241 * @param sel Here it's possible to specify a point for which to search. Please read the function's description. 3631 * @param sel Here it's possible to specify a point for which to search. Please read the function's description.
3242 * @return A new map rect's private data 3632 * @return A new map rect's private data
3243 */ 3633 */
3244static struct map_rect_priv * 3634static struct map_rect_priv *
3245rp_rect_new(struct map_priv *priv, struct map_selection *sel) 3635rp_rect_new(struct map_priv *priv, struct map_selection *sel)
3246{ 3636{
3247 struct map_rect_priv * mr; 3637 struct map_rect_priv * mr;
3248 3638
3249 dbg(1,"enter\n"); 3639 //dbg(1, "enter\n");
3250 if (! priv->route->graph) 3640 if (!priv->route->graph)
3251 return NULL;
3252 mr=g_new0(struct map_rect_priv, 1); 3641 return NULL;mr=g_new0(struct map_rect_priv, 1);
3253 mr->mpriv = priv; 3642 mr->mpriv = priv;
3254 mr->item.priv_data = mr; 3643 mr->item.priv_data = mr;
3255 mr->item.type = type_rg_point; 3644 mr->item.type = type_rg_point;
3256 mr->item.meth = &methods_point_item; 3645 mr->item.meth = &methods_point_item;
3257 if (sel) { 3646 if (sel)
3647 {
3258 if ((sel->u.c_rect.lu.x == sel->u.c_rect.rl.x) && (sel->u.c_rect.lu.y == sel->u.c_rect.rl.y)) { 3648 if ((sel->u.c_rect.lu.x == sel->u.c_rect.rl.x) && (sel->u.c_rect.lu.y
3649 == sel->u.c_rect.rl.y))
3650 {
3259 mr->coord_sel = g_malloc(sizeof(struct coord)); 3651 mr->coord_sel = g_malloc(sizeof(struct coord));
3260 *(mr->coord_sel) = sel->u.c_rect.lu; 3652 *(mr->coord_sel) = sel->u.c_rect.lu;
3261 } 3653 }
3262 } 3654 }
3263 return mr; 3655 return mr;
3264} 3656}
3265 3657
3266static void
3267rm_rect_destroy(struct map_rect_priv *mr) 3658static void rm_rect_destroy(struct map_rect_priv *mr)
3268{ 3659{
3269 if (mr->str) 3660 if (mr->str)
3270 g_free(mr->str); 3661 g_free(mr->str);
3271 if (mr->coord_sel) { 3662 if (mr->coord_sel)
3663 {
3272 g_free(mr->coord_sel); 3664 g_free(mr->coord_sel);
3273 } 3665 }
3274 if (mr->path) { 3666 if (mr->path)
3667 {
3275 mr->path->in_use--; 3668 mr->path->in_use--;
3276 if (mr->path->update_required && (mr->path->in_use==1)) 3669 if (mr->path->update_required && (mr->path->in_use == 1))
3277 route_path_update_done(mr->mpriv->route, mr->path->update_required-1); 3670 route_path_update_done(mr->mpriv->route,
3671 mr->path->update_required - 1);
3278 else if (!mr->path->in_use) 3672 else if (!mr->path->in_use)
3279 g_free(mr->path); 3673 g_free(mr->path);
3280 } 3674 }
3281 3675
3282 g_free(mr); 3676 g_free(mr);
3287{ 3681{
3288 struct route *r = mr->mpriv->route; 3682 struct route *r = mr->mpriv->route;
3289 struct route_graph_point *p = mr->point; 3683 struct route_graph_point *p = mr->point;
3290 struct route_graph_segment *seg = mr->rseg; 3684 struct route_graph_segment *seg = mr->rseg;
3291 3685
3292 if (mr->item.type == type_rg_point) { 3686 if (mr->item.type == type_rg_point)
3687 {
3293 if (mr->coord_sel) { 3688 if (mr->coord_sel)
3689 {
3294 // We are supposed to return only the point at one specified coordinate... 3690 // We are supposed to return only the point at one specified coordinate...
3295 if (!p) { 3691 if (!p)
3692 {
3296 p = route_graph_get_point_last(r->graph, mr->coord_sel); 3693 p = route_graph_get_point_last(r->graph, mr->coord_sel);
3297 if (!p) { 3694 if (!p)
3695 {
3298 mr->point = NULL; // This indicates that no point has been found 3696 mr->point = NULL; // This indicates that no point has been found
3697 }
3299 } else { 3698 else
3699 {
3300 mr->it = rp_iterator_new(p); 3700 mr->it = rp_iterator_new(p);
3301 } 3701 }
3702 }
3302 } else { 3703 else
3704 {
3303 p = NULL; 3705 p = NULL;
3304 } 3706 }
3707 }
3305 } else { 3708 else
3709 {
3306 if (!p) { 3710 if (!p)
3711 {
3307 mr->hash_bucket=0; 3712 mr->hash_bucket = 0;
3308 p = r->graph->hash[0]; 3713 p = r->graph->hash[0];
3714 }
3309 } else 3715 else
3310 p=p->hash_next; 3716 p = p->hash_next;
3311 while (!p) { 3717 while (!p)
3718 {
3312 mr->hash_bucket++; 3719 mr->hash_bucket++;
3313 if (mr->hash_bucket >= HASH_SIZE) 3720 if (mr->hash_bucket >= HASH_SIZE)
3314 break; 3721 break;
3315 p = r->graph->hash[mr->hash_bucket]; 3722 p = r->graph->hash[mr->hash_bucket];
3316 } 3723 }
3317 } 3724 }
3318 if (p) { 3725 if (p)
3726 {
3319 mr->point = p; 3727 mr->point = p;
3320 mr->item.id_lo++; 3728 mr->item.id_lo++;
3321 rm_coord_rewind(mr); 3729 rm_coord_rewind(mr);
3322 rp_attr_rewind(mr); 3730 rp_attr_rewind(mr);
3323 return &mr->item; 3731 return &mr->item;
3732 }
3324 } else 3733 else
3325 mr->item.type = type_rg_segment; 3734 mr->item.type = type_rg_segment;
3326 } 3735 }
3327 3736
3328 if (mr->coord_sel) { 3737 if (mr->coord_sel)
3329 if (!mr->point) { // This means that no point has been found 3738 {
3739 if (!mr->point)
3740 { // This means that no point has been found
3330 return NULL; 3741 return NULL;
3331 } 3742 }
3332 seg = rp_iterator_next(&(mr->it)); 3743 seg = rp_iterator_next(&(mr->it));
3333 } else { 3744 }
3745 else
3746 {
3334 if (!seg) 3747 if (!seg)
3335 seg=r->graph->route_segments; 3748 seg = r->graph->route_segments;
3336 else 3749 else
3337 seg=seg->next; 3750 seg = seg->next;
3338 } 3751 }
3339 3752
3340 if (seg) { 3753 if (seg)
3754 {
3341 mr->rseg = seg; 3755 mr->rseg = seg;
3342 mr->item.id_lo++; 3756 mr->item.id_lo++;
3343 rm_coord_rewind(mr); 3757 rm_coord_rewind(mr);
3344 rp_attr_rewind(mr); 3758 rp_attr_rewind(mr);
3345 return &mr->item; 3759 return &mr->item;
3346 } 3760 }
3347 return NULL; 3761 return NULL;
3348 3762
3349} 3763}
3350 3764
3351static struct item * 3765static struct item *
3352rp_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) 3766rp_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
3353{ 3767{
3354 struct item *ret=NULL; 3768 struct item *ret = NULL;
3355 while (id_lo-- > 0) 3769 while (id_lo-- > 0)
3356 ret=rp_get_item(mr); 3770 ret = rp_get_item(mr);
3357 return ret; 3771 return ret;
3358} 3772}
3359
3360 3773
3361static struct item * 3774static struct item *
3362rm_get_item(struct map_rect_priv *mr) 3775rm_get_item(struct map_rect_priv *mr)
3363{ 3776{
3364 struct route *route=mr->mpriv->route; 3777 struct route *route = mr->mpriv->route;
3365 dbg(1,"enter\n", mr->pos); 3778 //dbg(1, "enter\n", mr->pos);
3366 3779
3367 switch (mr->item.type) { 3780 switch (mr->item.type)
3781 {
3368 case type_none: 3782 case type_none:
3369 if (route->pos && route->pos->street_direction && route->pos->street_direction != route->pos->dir) 3783 if (route->pos && route->pos->street_direction
3784 && route->pos->street_direction != route->pos->dir)
3370 mr->item.type=type_route_start_reverse; 3785 mr->item.type = type_route_start_reverse;
3371 else 3786 else
3372 mr->item.type=type_route_start; 3787 mr->item.type = type_route_start;
3373 if (route->pos) 3788 if (route->pos)
3374 break; 3789 break;
3375 default: 3790 default:
3376 mr->item.type=type_street_route; 3791 mr->item.type = type_street_route;
3377 mr->seg=mr->seg_next; 3792 mr->seg = mr->seg_next;
3378 if (!mr->seg && mr->path && mr->path->next) { 3793 if (!mr->seg && mr->path && mr->path->next)
3794 {
3379 struct route_path *p=NULL; 3795 struct route_path *p = NULL;
3380 mr->path->in_use--; 3796 mr->path->in_use--;
3381 if (!mr->path->in_use) 3797 if (!mr->path->in_use)
3382 p=mr->path; 3798 p = mr->path;
3383 mr->path=mr->path->next; 3799 mr->path = mr->path->next;
3384 mr->path->in_use++; 3800 mr->path->in_use++;
3385 mr->seg=mr->path->path; 3801 mr->seg = mr->path->path;
3386 if (p) 3802 if (p)
3387 g_free(p); 3803 g_free(p);
3388 } 3804 }
3389 if (mr->seg) { 3805 if (mr->seg)
3806 {
3390 mr->seg_next=mr->seg->next; 3807 mr->seg_next = mr->seg->next;
3391 break; 3808 break;
3392 } 3809 }
3393 mr->item.type=type_route_end; 3810 mr->item.type = type_route_end;
3811 // dbg(0,"* set route_end *\n");
3394 if (mr->mpriv->route->destinations) 3812 if (mr->mpriv->route->destinations)
3395 break; 3813 break;
3396 case type_route_end: 3814 case type_route_end:
3397 return NULL; 3815 return NULL;
3398 } 3816 }
3399 mr->last_coord = 0; 3817 mr->last_coord = 0;
3400 mr->item.id_lo++; 3818 mr->item.id_lo++;
3401 rm_attr_rewind(mr); 3819 rm_attr_rewind(mr);
3402 return &mr->item; 3820 return &mr->item;
3403} 3821}
3404 3822
3405static struct item * 3823static struct item *
3406rm_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) 3824rm_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
3407{ 3825{
3408 struct item *ret=NULL; 3826 struct item *ret = NULL;
3409 while (id_lo-- > 0) 3827 while (id_lo-- > 0)
3410 ret=rm_get_item(mr); 3828 ret = rm_get_item(mr);
3411 return ret; 3829 return ret;
3412} 3830}
3413 3831
3414static struct map_methods route_meth = { 3832static struct map_methods route_meth =
3415 projection_mg, 3833{ projection_mg, "utf-8", rm_destroy, rm_rect_new, rm_rect_destroy,
3416 "utf-8", 3834 rm_get_item, rm_get_item_byid, NULL, NULL, NULL, };
3417 rm_destroy,
3418 rm_rect_new,
3419 rm_rect_destroy,
3420 rm_get_item,
3421 rm_get_item_byid,
3422 NULL,
3423 NULL,
3424 NULL,
3425};
3426 3835
3427static struct map_methods route_graph_meth = { 3836static struct map_methods route_graph_meth =
3428 projection_mg, 3837{ projection_mg, "utf-8", rp_destroy, rp_rect_new, rm_rect_destroy,
3429 "utf-8", 3838 rp_get_item, rp_get_item_byid, NULL, NULL, NULL, };
3430 rp_destroy,
3431 rp_rect_new,
3432 rm_rect_destroy,
3433 rp_get_item,
3434 rp_get_item_byid,
3435 NULL,
3436 NULL,
3437 NULL,
3438};
3439 3839
3440static struct map_priv * 3840static struct map_priv *
3441route_map_new_helper(struct map_methods *meth, struct attr **attrs, int graph) 3841route_map_new_helper(struct map_methods *meth, struct attr **attrs, int graph)
3442{ 3842{
3443 struct map_priv *ret; 3843 struct map_priv *ret;
3444 struct attr *route_attr; 3844 struct attr *route_attr;
3445 3845
3446 route_attr=attr_search(attrs, NULL, attr_route); 3846 route_attr = attr_search(attrs, NULL, attr_route);
3447 if (! route_attr) 3847 if (!route_attr)
3448 return NULL;
3449 ret=g_new0(struct map_priv, 1); 3848 return NULL;ret=g_new0(struct map_priv, 1);
3450 if (graph) 3849 if (graph)
3451 *meth=route_graph_meth; 3850 *meth = route_graph_meth;
3452 else 3851 else
3453 *meth=route_meth; 3852 *meth = route_meth;
3454 ret->route=route_attr->u.route; 3853 ret->route = route_attr->u.route;
3455 3854
3456 return ret; 3855 return ret;
3457} 3856}
3458 3857
3459static struct map_priv * 3858static struct map_priv *
3460route_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) 3859route_map_new(struct map_methods *meth, struct attr **attrs,
3860 struct callback_list *cbl)
3461{ 3861{
3462 return route_map_new_helper(meth, attrs, 0); 3862 return route_map_new_helper(meth, attrs, 0);
3463} 3863}
3464 3864
3465static struct map_priv * 3865static struct map_priv *
3466route_graph_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) 3866route_graph_map_new(struct map_methods *meth, struct attr **attrs,
3867 struct callback_list *cbl)
3467{ 3868{
3468 return route_map_new_helper(meth, attrs, 1); 3869 return route_map_new_helper(meth, attrs, 1);
3469} 3870}
3470 3871
3471static struct map * 3872static struct map *
3472route_get_map_helper(struct route *this_, struct map **map, char *type, char *description) 3873route_get_map_helper(struct route *this_, struct map **map, char *type,
3874 char *description)
3473{ 3875{
3474 struct attr *attrs[5]; 3876 struct attr *attrs[5];
3475 struct attr a_type,navigation,data,a_description; 3877 struct attr a_type, navigation, data, a_description;
3476 a_type.type=attr_type; 3878 a_type.type = attr_type;
3477 a_type.u.str=type; 3879 a_type.u.str = type;
3478 navigation.type=attr_route; 3880 navigation.type = attr_route;
3479 navigation.u.route=this_; 3881 navigation.u.route = this_;
3480 data.type=attr_data; 3882 data.type = attr_data;
3481 data.u.str=""; 3883 data.u.str = "";
3482 a_description.type=attr_description; 3884 a_description.type = attr_description;
3483 a_description.u.str=description; 3885 a_description.u.str = description;
3484 3886
3485 attrs[0]=&a_type; 3887 attrs[0] = &a_type;
3486 attrs[1]=&navigation; 3888 attrs[1] = &navigation;
3487 attrs[2]=&data; 3889 attrs[2] = &data;
3488 attrs[3]=&a_description; 3890 attrs[3] = &a_description;
3489 attrs[4]=NULL; 3891 attrs[4] = NULL;
3490 3892
3491 if (! *map) { 3893 if (!*map)
3894 {
3492 *map=map_new(NULL, attrs); 3895 *map = map_new(NULL, attrs);
3493 map_ref(*map); 3896 map_ref(*map);
3494 } 3897 }
3495 3898
3496 return *map; 3899 return *map;
3497} 3900}
3498 3901
3499/** 3902/**
3500 * @brief Returns a new map containing the route path 3903 * @brief Returns a new map containing the route path
3507 * @return A new map containing the route path 3910 * @return A new map containing the route path
3508 */ 3911 */
3509struct map * 3912struct map *
3510route_get_map(struct route *this_) 3913route_get_map(struct route *this_)
3511{ 3914{
3512 return route_get_map_helper(this_, &this_->map, "route","Route"); 3915 return route_get_map_helper(this_, &this_->map, "route", "Route");
3513} 3916}
3514
3515 3917
3516/** 3918/**
3517 * @brief Returns a new map containing the route graph 3919 * @brief Returns a new map containing the route graph
3518 * 3920 *
3519 * This function returns a new map containing the route graph. 3921 * This function returns a new map containing the route graph.
3524 * @return A new map containing the route graph 3926 * @return A new map containing the route graph
3525 */ 3927 */
3526struct map * 3928struct map *
3527route_get_graph_map(struct route *this_) 3929route_get_graph_map(struct route *this_)
3528{ 3930{
3529 return route_get_map_helper(this_, &this_->graph_map, "route_graph","Route Graph"); 3931 return route_get_map_helper(this_, &this_->graph_map, "route_graph",
3932 "Route Graph");
3530} 3933}
3531 3934
3532void
3533route_set_projection(struct route *this_, enum projection pro) 3935void route_set_projection(struct route *this_, enum projection pro)
3534{ 3936{
3535} 3937}
3536 3938
3537int
3538route_set_attr(struct route *this_, struct attr *attr) 3939int route_set_attr(struct route *this_, struct attr *attr)
3539{ 3940{
3540 int attr_updated=0; 3941 int attr_updated = 0;
3541 switch (attr->type) { 3942 switch (attr->type)
3943 {
3542 case attr_route_status: 3944 case attr_route_status:
3543 attr_updated = (this_->route_status != attr->u.num); 3945 attr_updated = (this_->route_status != attr->u.num);
3544 this_->route_status = attr->u.num; 3946 this_->route_status = attr->u.num;
3545 // update global route_status notifier 3947 // update global route_status notifier
3546 this_->route_status_was_updated = 1; 3948 this_->route_status_was_updated = 1;
3547 break; 3949 break;
3548 case attr_destination: 3950 case attr_destination:
3549 route_set_destination(this_, attr->u.pcoord, 1); 3951 route_set_destination(this_, attr->u.pcoord, 1);
3550 return 1; 3952 return 1;
3551 case attr_vehicle: 3953 case attr_vehicle:
3552 attr_updated = (this_->v != attr->u.vehicle); 3954 attr_updated = (this_->v != attr->u.vehicle);
3553 this_->v=attr->u.vehicle; 3955 this_->v = attr->u.vehicle;
3554 if (attr_updated) { 3956 if (attr_updated)
3957 {
3555 struct attr g; 3958 struct attr g;
3556 struct pcoord pc; 3959 struct pcoord pc;
3557 struct coord c; 3960 struct coord c;
3558 if (vehicle_get_attr(this_->v, attr_position_coord_geo, &g, NULL)) { 3961 if (vehicle_get_attr(this_->v, attr_position_coord_geo, &g,
3962 NULL))
3963 {
3559 pc.pro=projection_mg; 3964 pc.pro = projection_mg;
3560 transform_from_geo(projection_mg, g.u.coord_geo, &c); 3965 transform_from_geo(projection_mg, g.u.coord_geo, &c);
3561 pc.x=c.x; 3966 pc.x = c.x;
3562 pc.y=c.y; 3967 pc.y = c.y;
3563 route_set_position(this_, &pc); 3968 route_set_position(this_, &pc);
3564 } 3969 }
3565 } 3970 }
3566 break; 3971 break;
3567 default: 3972 default:
3568 dbg(0,"unsupported attribute: %s\n",attr_to_name(attr->type)); 3973 dbg(0, "unsupported attribute: %s\n", attr_to_name(attr->type));
3569 return 0; 3974 return 0;
3570 } 3975 }
3571 if (attr_updated) 3976 if (attr_updated)
3572 callback_list_call_attr_2(this_->cbl2, attr->type, this_, attr); 3977 callback_list_call_attr_2(this_->cbl2, attr->type, this_, attr);
3573 return 1; 3978 return 1;
3574} 3979}
3575 3980
3576int
3577route_add_attr(struct route *this_, struct attr *attr) 3981int route_add_attr(struct route *this_, struct attr *attr)
3578{ 3982{
3579 switch (attr->type) { 3983 switch (attr->type)
3984 {
3580 case attr_callback: 3985 case attr_callback:
3581 callback_list_add(this_->cbl2, attr->u.callback); 3986 callback_list_add(this_->cbl2, attr->u.callback);
3582 return 1; 3987 return 1;
3583 default: 3988 default:
3584 return 0; 3989 return 0;
3585 } 3990 }
3586} 3991}
3587 3992
3588int
3589route_remove_attr(struct route *this_, struct attr *attr) 3993int route_remove_attr(struct route *this_, struct attr *attr)
3590{ 3994{
3591 //dbg(0,"enter\n"); 3995 //dbg(0,"enter\n");
3592 switch (attr->type) { 3996 switch (attr->type)
3997 {
3593 case attr_callback: 3998 case attr_callback:
3594 callback_list_remove(this_->cbl2, attr->u.callback); 3999 callback_list_remove(this_->cbl2, attr->u.callback);
3595 return 1; 4000 return 1;
3596 case attr_vehicle: 4001 case attr_vehicle:
3597 this_->v=NULL; 4002 this_->v = NULL;
3598 return 1; 4003 return 1;
3599 default: 4004 default:
3600 return 0; 4005 return 0;
3601 } 4006 }
3602} 4007}
3603 4008
3604int
3605route_get_attr(struct route *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) 4009int route_get_attr(struct route *this_, enum attr_type type, struct attr *attr,
4010 struct attr_iter *iter)
3606{ 4011{
3607 int ret=1; 4012 int ret = 1;
3608 switch (type) { 4013 switch (type)
4014 {
3609 case attr_map: 4015 case attr_map:
3610 attr->u.map=route_get_map(this_); 4016 attr->u.map = route_get_map(this_);
3611 ret=(attr->u.map != NULL); 4017 ret = (attr->u.map != NULL);
3612 break; 4018 break;
3613 case attr_destination: 4019 case attr_destination:
3614 if (this_->destinations) { 4020 if (this_->destinations)
4021 {
3615 struct route_info *dst; 4022 struct route_info *dst;
3616 if (iter) { 4023 if (iter)
4024 {
3617 if (iter->u.list) { 4025 if (iter->u.list)
4026 {
3618 iter->u.list=g_list_next(iter->u.list); 4027 iter->u.list = g_list_next(iter->u.list);
4028 }
3619 } else { 4029 else
4030 {
3620 iter->u.list=this_->destinations; 4031 iter->u.list = this_->destinations;
4032 }
4033 if (!iter->u.list)
4034 {
4035 return 0;
4036 }
4037 dst = (struct route_info*) iter->u.list->data;
3621 } 4038 }
3622 if (!iter->u.list) { 4039 else
3623 return 0; 4040 { //No iter handling
4041 dst = route_get_dst(this_);
3624 } 4042 }
3625 dst = (struct route_info*)iter->u.list->data;
3626 } else { //No iter handling
3627 dst=route_get_dst(this_);
3628 }
3629 attr->u.pcoord=&this_->pc; 4043 attr->u.pcoord = &this_->pc;
3630 this_->pc.pro=projection_mg; /* fixme */ 4044 this_->pc.pro = projection_mg; /* fixme */
3631 this_->pc.x=dst->c.x; 4045 this_->pc.x = dst->c.x;
3632 this_->pc.y=dst->c.y; 4046 this_->pc.y = dst->c.y;
4047 }
3633 } else 4048 else
3634 ret=0; 4049 ret = 0;
3635 break; 4050 break;
3636 case attr_vehicle: 4051 case attr_vehicle:
3637 attr->u.vehicle=this_->v; 4052 attr->u.vehicle = this_->v;
3638 ret=(this_->v != NULL); 4053 ret = (this_->v != NULL);
3639 //dbg(0,"get vehicle %p\n",this_->v); 4054 //dbg(0,"get vehicle %p\n",this_->v);
3640 break; 4055 break;
3641 case attr_vehicleprofile: 4056 case attr_vehicleprofile:
3642 attr->u.vehicleprofile=this_->vehicleprofile; 4057 attr->u.vehicleprofile = this_->vehicleprofile;
3643 ret=(this_->vehicleprofile != NULL); 4058 ret = (this_->vehicleprofile != NULL);
3644 break; 4059 break;
3645 case attr_route_status: 4060 case attr_route_status:
3646 attr->u.num=this_->route_status; 4061 attr->u.num = this_->route_status;
3647 break; 4062 break;
3648 case attr_destination_time: 4063 case attr_destination_time:
3649 if (this_->path2 && (this_->route_status == route_status_path_done_new || this_->route_status == route_status_path_done_incremental)) { 4064 if (this_->path2 && (this_->route_status
4065 == route_status_path_done_new || this_->route_status
4066 == route_status_path_done_incremental))
4067 {
3650 4068
3651 attr->u.num=this_->path2->path_time; 4069 attr->u.num = this_->path2->path_time;
3652 dbg(1,"path_time %d\n",attr->u.num); 4070 //dbg(1, "path_time %d\n", attr->u.num);
3653 } 4071 }
3654 else 4072 else
3655 ret=0; 4073 ret = 0;
3656 break; 4074 break;
3657 case attr_destination_length: 4075 case attr_destination_length:
3658 if (this_->path2 && (this_->route_status == route_status_path_done_new || this_->route_status == route_status_path_done_incremental)) 4076 if (this_->path2 && (this_->route_status
4077 == route_status_path_done_new || this_->route_status
4078 == route_status_path_done_incremental))
3659 attr->u.num=this_->path2->path_len; 4079 attr->u.num = this_->path2->path_len;
3660 else 4080 else
3661 ret=0; 4081 ret = 0;
3662 break; 4082 break;
3663 default: 4083 default:
3664 return 0; 4084 return 0;
3665 } 4085 }
3666 attr->type=type; 4086 attr->type = type;
3667 return ret; 4087 return ret;
3668} 4088}
3669 4089
3670struct attr_iter * 4090struct attr_iter *
3671route_attr_iter_new(void) 4091route_attr_iter_new(void)
3672{ 4092{
3673 return g_new0(struct attr_iter, 1); 4093return g_new0(struct attr_iter, 1);
3674} 4094}
3675 4095
3676void
3677route_attr_iter_destroy(struct attr_iter *iter) 4096void route_attr_iter_destroy(struct attr_iter *iter)
3678{ 4097{
3679 g_free(iter); 4098 g_free(iter);
3680} 4099}
3681 4100
3682void
3683route_init(void) 4101void route_init(void)
3684{ 4102{
3685 plugin_register_map_type("route", route_map_new); 4103 plugin_register_map_type("route", route_map_new);
3686 plugin_register_map_type("route_graph", route_graph_map_new); 4104 plugin_register_map_type("route_graph", route_graph_map_new);
3687} 4105}
3688 4106
3689void
3690route_destroy(struct route *this_) 4107void route_destroy(struct route *this_)
3691{ 4108{
3692 route_path_destroy(this_->path2,1); 4109 route_path_destroy(this_->path2, 1);
3693 route_graph_destroy(this_->graph); 4110 route_graph_destroy(this_->graph);
3694 route_clear_destinations(this_); 4111 route_clear_destinations(this_);
3695 route_info_free(this_->pos); 4112 route_info_free(this_->pos);
3696 map_destroy(this_->map); 4113 map_destroy(this_->map);
3697 map_destroy(this_->graph_map); 4114 map_destroy(this_->graph_map);

Legend:
Removed from v.26  
changed lines
  Added in v.27

   
Visit the ZANavi Wiki