15 #include "projection.h"
23 #include "transform.h"
34 struct route_graph_point {
35 struct route_graph_point *next;
36 struct route_graph_point *hash_next;
37 struct route_graph_segment *start;
38 struct route_graph_segment *end;
39 struct route_graph_segment *seg;
40 struct fibheap_el *el;
45 struct route_graph_segment {
46 struct route_graph_segment *next;
47 struct route_graph_segment *start_next;
48 struct route_graph_segment *end_next;
49 struct route_graph_point *start;
50 struct route_graph_point *end;
57 struct route_path_segment {
58 struct route_path_segment *next;
78 struct street_data *street;
82 struct route_path_segment *path;
83 struct route_path_segment *path_last;
84 /* XXX: path_hash is not necessery now */
85 struct item_hash *path_hash;
88 #define RF_FASTEST (1<<0)
89 #define RF_SHORTEST (1<<1)
90 #define RF_AVOIDHW (1<<2)
91 #define RF_AVOIDPAID (1<<3)
92 #define RF_LOCKONROAD (1<<4)
93 #define RF_SHOWGRAPH (1<<5)
99 struct route_info *pos;
100 struct route_info *dst;
102 struct route_graph *graph;
103 struct route_path *path2;
105 struct map *graph_map;
106 int speedlist[route_item_last-route_item_first+1];
110 struct route_graph_point *route_points;
111 struct route_graph_segment *route_segments;
112 #define HASH_SIZE 8192
113 struct route_graph_point *hash[HASH_SIZE];
116 #define HASHCOORD(c) ((((c)->x +(c)->y) * 2654435761UL) & (HASH_SIZE-1))
118 static struct route_info * route_find_nearest_street(struct mapset *ms, struct pcoord *c);
119 static struct route_graph_point *route_graph_get_point(struct route_graph *this, struct coord *c);
120 static void route_graph_update(struct route *this);
121 static struct route_path *route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, int *speedlist);
122 static void route_process_street_graph(struct route_graph *this, struct item *item);
123 static void route_graph_destroy(struct route_graph *this);
124 static void route_path_update(struct route *this);
126 static enum projection route_projection(struct route *route)
128 struct street_data *street;
129 street = route->pos ? route->pos->street : route->dst->street;
130 return map_projection(street->item.map);
134 route_path_destroy(struct route_path *this)
136 struct route_path_segment *c,*n;
139 if (this->path_hash) {
140 item_hash_destroy(this->path_hash);
141 this->path_hash=NULL;
153 route_new(struct attr **attrs)
155 struct route *this=g_new0(struct route, 1);
157 printf("%s:Out of memory\n", __FUNCTION__);
164 route_set_mapset(struct route *this, struct mapset *ms)
170 route_get_mapset(struct route *this)
176 route_get_pos(struct route *this)
182 route_get_dst(struct route *this)
188 route_get_speedlist(struct route *this)
190 return this->speedlist;
194 route_get_path_set(struct route *this)
196 return this->path2 != NULL;
200 route_set_speed(struct route *this, enum item_type type, int value)
202 if (type < route_item_first || type > route_item_last) {
203 dbg(0,"street type %d out of range [%d,%d]", type, route_item_first, route_item_last);
206 this->speedlist[type-route_item_first]=value;
211 route_contains(struct route *this, struct item *item)
213 if (! this->path2 || !this->path2->path_hash)
215 return (int)item_hash_lookup(this->path2->path_hash, item);
219 route_path_update(struct route *this)
221 struct route_path *oldpath = NULL;
222 if (! this->pos || ! this->dst) {
223 route_path_destroy(this->path2);
227 /* the graph is destroyed when setting the destination */
228 if (this->graph && this->pos && this->dst && this->path2) {
229 // we can try to update
230 oldpath = this->path2;
233 if (! this->graph || !(this->path2=route_path_new(this->graph, oldpath, this->pos, this->dst, this->speedlist))) {
235 route_graph_update(this);
236 this->path2=route_path_new(this->graph, oldpath, this->pos, this->dst, this->speedlist);
237 profile(1,"route_path_new");
241 /* Destroy what's left */
242 route_path_destroy(oldpath);
247 route_set_position(struct route *this, struct pcoord *pos)
250 route_info_free(this->pos);
252 this->pos=route_find_nearest_street(this->ms, pos);
253 dbg(1,"this->pos=%p\n", this->pos);
257 route_path_update(this);
261 route_set_position_from_tracking(struct route *this, struct tracking *tracking)
264 struct route_info *ret;
267 c=tracking_get_pos(tracking);
268 ret=g_new0(struct route_info, 1);
270 printf("%s:Out of memory\n", __FUNCTION__);
274 route_info_free(this->pos);
278 ret->pos=tracking_get_segment_pos(tracking);
281 ret->street=street_data_dup(tracking_get_street_data(tracking));
282 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->item.id_hi, ret->street->item.id_lo);
283 dbg(3,"street 0=(0x%x,0x%x) %d=(0x%x,0x%x)\n", ret->street->c[0].x, ret->street->c[0].y, ret->street->count-1, ret->street->c[ret->street->count-1].x, ret->street->c[ret->street->count-1].y);
286 route_path_update(this);
290 /* Used for debuging of route_rect, what routing sees */
291 struct map_selection *route_selection;
293 struct map_selection *
294 route_rect(int order, struct coord *c1, struct coord *c2, int rel, int abs)
296 int dx,dy,sx=1,sy=1,d,m;
297 struct map_selection *sel=g_new(struct map_selection, 1);
299 printf("%s:Out of memory\n", __FUNCTION__);
302 sel->order[layer_town]=0;
303 sel->order[layer_poly]=0;
304 sel->order[layer_street]=order;
305 dbg(1,"%p %p\n", c1, c2);
310 sel->u.c_rect.lu.x=c1->x;
311 sel->u.c_rect.rl.x=c2->x;
313 sel->u.c_rect.lu.x=c2->x;
314 sel->u.c_rect.rl.x=c1->x;
318 sel->u.c_rect.lu.y=c2->y;
319 sel->u.c_rect.rl.y=c1->y;
321 sel->u.c_rect.lu.y=c1->y;
322 sel->u.c_rect.rl.y=c2->y;
329 sel->u.c_rect.lu.x-=m;
330 sel->u.c_rect.rl.x+=m;
331 sel->u.c_rect.lu.y+=m;
332 sel->u.c_rect.rl.y-=m;
337 static struct map_selection *
338 route_calc_selection(struct coord *c1, struct coord *c2)
340 struct map_selection *ret,*sel;
341 sel=route_rect(4, c1, c2, 25, 0);
343 sel->next=route_rect(8, c1, c1, 0, 40000);
345 sel->next=route_rect(18, c1, c1, 0, 10000);
347 sel->next=route_rect(8, c2, c2, 0, 40000);
349 sel->next=route_rect(18, c2, c2, 0, 10000);
350 /* route_selection=ret; */
355 route_free_selection(struct map_selection *sel)
357 struct map_selection *next;
368 route_set_destination(struct route *this, struct pcoord *dst)
372 route_info_free(this->dst);
375 this->dst=route_find_nearest_street(this->ms, dst);
376 profile(1,"find_nearest_street");
377 route_graph_destroy(this->graph);
379 route_path_update(this);
383 static struct route_graph_point *
384 route_graph_get_point(struct route_graph *this, struct coord *c)
386 struct route_graph_point *p;
387 int hashval=HASHCOORD(c);
388 p=this->hash[hashval];
390 if (p->c.x == c->x && p->c.y == c->y)
398 static struct route_graph_point *
399 route_graph_add_point(struct route_graph *this, struct coord *f)
402 struct route_graph_point *p;
404 p=route_graph_get_point(this,f);
406 hashval=HASHCOORD(f);
408 printf("p (0x%x,0x%x)\n", f->x, f->y);
409 p=g_new(struct route_graph_point,1);
411 printf("%s:Out of memory\n", __FUNCTION__);
414 p->hash_next=this->hash[hashval];
415 this->hash[hashval]=p;
416 p->next=this->route_points;
423 this->route_points=p;
430 route_graph_free_points(struct route_graph *this)
432 struct route_graph_point *curr,*next;
433 curr=this->route_points;
439 this->route_points=NULL;
440 memset(this->hash, 0, sizeof(this->hash));
444 route_graph_add_segment(struct route_graph *this, struct route_graph_point *start,
445 struct route_graph_point *end, int len, struct item *item,
446 int flags, int offset)
448 struct route_graph_segment *s;
449 s = g_new0(struct route_graph_segment, 1);
451 printf("%s:Out of memory\n", __FUNCTION__);
455 s->start_next=start->start;
458 s->end_next=end->end;
465 s->next=this->route_segments;
466 this->route_segments=s;
468 printf("l (0x%x,0x%x)-(0x%x,0x%x)\n", start->c.x, start->c.y, end->c.x, end->c.y);
471 static int get_item_seg_coords(struct item *i, struct coord *c, int max,
472 struct route_graph_segment *rgs)
476 int rc = 0, fs = 0, p = 0;
478 mr=map_rect_new(i->map, NULL);
481 item = map_rect_get_item_byid(mr, i->id_hi, i->id_lo);
484 rc = item_coord_get(item, &c1, 1);
487 if (c1.x == rgs->start->c.x &&
488 c1.y == rgs->start->c.y)
493 if (c1.x == rgs->end->c.x &&
494 c1.y == rgs->end->c.y)
500 map_rect_destroy(mr);
504 static struct route_path_segment *
505 route_extract_segment_from_path(struct route_path *path, struct item *item,
508 struct route_path_segment *sp = NULL, *s;
511 if (s->offset == offset && item_is_equal(s->item,*item)) {
516 path->path = s->next;
524 item_hash_remove(path->path_hash, item);
529 route_path_add_item(struct route_path *this, struct route_path *oldpath,
530 struct route_graph_segment *rgs, int len, int offset, int dir)
532 struct route_path_segment *segment;
534 struct coord ca[2048];
537 ccnt = (int)item_hash_lookup(oldpath->path_hash, &rgs->item);
539 segment = route_extract_segment_from_path(oldpath,
546 ccnt = get_item_seg_coords(&rgs->item, ca, 2047, rgs);
547 segment= g_malloc0(sizeof(*segment) + sizeof(struct coord) * ccnt);
549 printf("%s:Out of memory\n", __FUNCTION__);
552 memcpy(segment->c, ca, ccnt * sizeof(struct coord));
553 segment->ncoords = ccnt;
554 segment->item=rgs->item;
555 segment->offset = offset;
560 item_hash_insert(this->path_hash, &rgs->item, (void *)offset);
564 this->path_last->next=segment;
565 this->path_last=segment;
568 struct route_path_handle {
569 struct route_path_segment *s;
572 struct route_path_handle *
573 route_path_open(struct route *this)
575 struct route_path_handle *ret;
577 if (! this->path2 || ! this->path2->path)
580 ret=g_new(struct route_path_handle, 1);
582 printf("%s:Out of memory\n", __FUNCTION__);
585 ret->s=this->path2->path;
589 struct route_path_segment *
590 route_path_get_segment(struct route_path_handle *h)
592 struct route_path_segment *ret=h->s;
600 static struct coord *
601 route_path_segment_get_helper(struct route_path_segment *s, int dir)
606 return &s->c[s->ncoords-1];
610 route_path_segment_get_start(struct route_path_segment *s)
612 return route_path_segment_get_helper(s, 1);
616 route_path_segment_get_end(struct route_path_segment *s)
618 return route_path_segment_get_helper(s, -1);
622 route_path_segment_get_item(struct route_path_segment *s)
628 route_path_close(struct route_path_handle *h)
634 route_graph_free_segments(struct route_graph *this)
636 struct route_graph_segment *curr,*next;
637 curr=this->route_segments;
643 this->route_segments=NULL;
647 route_graph_destroy(struct route_graph *this)
650 route_graph_free_points(this);
651 route_graph_free_segments(this);
657 route_time(int *speedlist, struct item *item, int len)
659 if (item->type < route_item_first || item->type > route_item_last) {
660 dbg(0,"street type %d out of range [%d,%d]", item->type, route_item_first, route_item_last);
663 return len*36/speedlist[item->type-route_item_first];
668 route_value(int *speedlist, struct item *item, int len)
672 printf("len=%d\n", len);
675 ret=route_time(speedlist, item, len);
676 dbg(1, "route_value(0x%x, %d)=%d\n", item->type, len, ret);
681 route_process_street_graph(struct route_graph *this, struct item *item)
688 struct route_graph_point *s_pnt,*e_pnt;
695 if (item_coord_get(item, &l, 1)) {
696 if (item_attr_get(item, attr_flags, &attr)) {
698 if (flags & AF_SEGMENTED)
701 s_pnt=route_graph_add_point(this,&l);
703 while (item_coord_get(item, &c, 1)) {
704 len+=transform_distance(map_projection(item->map), &l, &c);
707 e_pnt=route_graph_add_point(this,&l);
709 route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset);
714 isseg = item_coord_is_segment(item);
715 rc = item_coord_get(item, &c, 1);
717 len+=transform_distance(map_projection(item->map), &l, &c);
720 e_pnt=route_graph_add_point(this,&l);
721 route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset);
723 s_pnt=route_graph_add_point(this,&l);
728 e_pnt=route_graph_add_point(this,&l);
731 route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset);
737 compare(void *v1, void *v2)
739 struct route_graph_point *p1=v1;
740 struct route_graph_point *p2=v2;
743 printf("compare %d (%p) vs %d (%p)\n", p1->value,p1,p2->value,p2);
745 return p1->value-p2->value;
749 route_info_length(struct route_info *pos, struct route_info *dst, int dir)
751 struct route_info_handle *h;
754 struct street_data *street;
756 dbg(2,"enter pos=%p dst=%p dir=%d\n", pos, dst, dir);
757 h=route_info_open(pos, dst, dir);
762 street = pos ? pos->street : dst->street;
764 while ((c=route_info_get(h))) {
766 ret+=transform_distance(map_projection(street->item.map), c, l);
769 dbg(2,"ret=%d\n", ret);
774 route_graph_flood(struct route_graph *this, struct route_info *dst, int *speedlist)
776 struct route_graph_point *p_min,*end=NULL;
777 struct route_graph_segment *s;
779 struct fibheap *heap;
780 struct street_data *sd=dst->street;
782 heap = fh_makeheap();
783 fh_setcmp(heap, compare);
785 if (! (sd->flags & AF_ONEWAYREV)) {
786 end=route_graph_get_point(this, &sd->c[0]);
788 end->value=route_value(speedlist, &sd->item, route_info_length(NULL, dst, -1));
789 end->el=fh_insert(heap, end);
792 if (! (sd->flags & AF_ONEWAY)) {
793 end=route_graph_get_point(this, &sd->c[sd->count-1]);
795 end->value=route_value(speedlist, &sd->item, route_info_length(NULL, dst, 1));
796 end->el=fh_insert(heap, end);
799 dbg(1,"0x%x,0x%x\n", end->c.x, end->c.y);
801 p_min=fh_extractmin(heap);
806 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);
810 val=route_value(speedlist, &s->item, s->len);
812 val+=val*2*street_route_contained(s->str->segid);
816 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);
817 if (new < s->end->value && !(s->flags & AF_ONEWAY)) {
822 printf("insert_end p=%p el=%p val=%d ", s->end, s->end->el, s->end->value);
823 s->end->el=fh_insert(heap, s->end);
825 printf("el new=%p\n", s->end->el);
829 printf("replace_end p=%p el=%p val=%d\n", s->end, s->end->el, s->end->value);
830 fh_replacedata(heap, s->end->el, s->end);
839 val=route_value(speedlist, &s->item, s->len);
842 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);
843 if (new < s->start->value && !(s->flags & AF_ONEWAYREV)) {
847 if (! s->start->el) {
849 printf("insert_start p=%p el=%p val=%d ", s->start, s->start->el, s->start->value);
850 s->start->el=fh_insert(heap, s->start);
852 printf("el new=%p\n", s->start->el);
856 printf("replace_start p=%p el=%p val=%d\n", s->start, s->start->el, s->start->value);
857 fh_replacedata(heap, s->start->el, s->start);
868 static struct route_path *
869 route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, int *speedlist)
871 struct route_graph_point *start1=NULL,*start2=NULL,*start;
872 struct route_graph_segment *s=NULL;
876 int time=0,hr,min,sec
878 unsigned int val1=0xffffffff,val2=0xffffffff;
879 struct street_data *sd=pos->street;
880 struct route_path *ret;
882 if (! (sd->flags & AF_ONEWAY)) {
883 start1=route_graph_get_point(this, &sd->c[0]);
886 val1=start1->value+route_value(speedlist, &sd->item, route_info_length(pos, NULL, -1));
887 dbg(1,"start1: %d(route)+%d=%d\n", start1->value, val1-start1->value, val1);
889 if (! (sd->flags & AF_ONEWAYREV)) {
890 start2=route_graph_get_point(this, &sd->c[sd->count-1]);
893 val2=start2->value+route_value(speedlist, &sd->item, route_info_length(pos, NULL, 1));
894 dbg(1,"start2: %d(route)+%d=%d\n", start2->value, val2-start2->value, val2);
896 dbg(1,"val1=%d val2=%d\n", val1, val2);
898 val1=start1->start->start->value;
899 val2=start2->end->end->value;
901 if (start1 && (val1 < val2)) {
909 printf("no route found, pos blocked\n");
913 ret=g_new0(struct route_path, 1);
915 printf("%s:Out of memory\n", __FUNCTION__);
918 ret->path_hash=item_hash_new();
919 dbg(1,"dir=%d\n", pos->dir);
920 while ((s=start->seg)) {
923 printf("start->value=%d 0x%x,0x%x\n", start->value, start->c.x, start->c.y);
927 if (s->start == start) {
928 route_path_add_item(ret, oldpath, s, seg_len, s->offset, 1);
931 route_path_add_item(ret, oldpath, s, seg_len, s->offset, -1);
936 dbg(1,"start->value=%d 0x%x,0x%x\n", start->value, start->c.x, start->c.y);
937 dbg(1,"dst sd->flags=%d sd->c[0]=0x%x,0x%x sd->c[sd->count-1]=0x%x,0x%x\n", sd->flags, sd->c[0].x,sd->c[0].y, sd->c[sd->count-1].x, sd->c[sd->count-1].y);
938 if (start->c.x == sd->c[0].x && start->c.y == sd->c[0].y)
940 else if (start->c.x == sd->c[sd->count-1].x && start->c.y == sd->c[sd->count-1].y)
943 printf("no route found\n");
944 route_path_destroy(ret);
947 ilen=route_info_length(pos, NULL, 0);
950 ilen=route_info_length(NULL, dst, 0);
953 dbg(1, "%d segments\n", segs);
957 static struct route_graph *
958 route_graph_build(struct mapset *ms, struct coord *c1, struct coord *c2)
960 struct route_graph *ret=g_new0(struct route_graph, 1);
961 struct map_selection *sel;
962 struct mapset_handle *h;
968 printf("%s:Out of memory\n", __FUNCTION__);
971 sel=route_calc_selection(c1, c2);
973 while ((m=mapset_next(h,1))) {
974 mr=map_rect_new(m, sel);
977 while ((item=map_rect_get_item(mr))) {
978 if (item->type >= type_street_0 && item->type <= type_ferry) {
979 route_process_street_graph(ret, item);
982 map_rect_destroy(mr);
985 route_free_selection(sel);
991 route_graph_update(struct route *this)
993 route_graph_destroy(this->graph);
994 profile(1,"graph_free");
995 this->graph=route_graph_build(this->ms, &this->pos->c, &this->dst->c);
996 profile(1,"route_graph_build");
997 route_graph_flood(this->graph, this->dst, this->speedlist);
998 profile(1,"route_graph_flood");
1002 struct street_data *
1003 street_get_data (struct item *item)
1006 struct coord c[maxcount];
1008 struct street_data *ret;
1011 while (count < maxcount) {
1012 if (!item_coord_get(item, &c[count], 1))
1016 if (count >= maxcount) {
1017 dbg(0, "count=%d maxcount=%d id_hi=0x%x id_lo=0x%x\n", count, maxcount, item->id_hi, item->id_lo);
1018 if (item_attr_get(item, attr_debug, &attr))
1019 dbg(0,"debug='%s'\n", attr.u.str);
1021 g_assert(count < maxcount);
1022 ret=g_malloc(sizeof(struct street_data)+count*sizeof(struct coord));
1025 if (item_attr_get(item, attr_flags, &attr))
1026 ret->flags=attr.u.num;
1029 memcpy(ret->c, c, count*sizeof(struct coord));
1034 struct street_data *
1035 street_data_dup(struct street_data *orig)
1037 struct street_data *ret;
1038 int size=sizeof(struct street_data)+orig->count*sizeof(struct coord);
1041 memcpy(ret, orig, size);
1047 street_data_free(struct street_data *sd)
1052 static struct route_info *
1053 route_find_nearest_street(struct mapset *ms, struct pcoord *pc)
1055 struct route_info *ret=NULL;
1057 struct map_selection *sel;
1059 struct mapset_handle *h;
1061 struct map_rect *mr;
1064 struct street_data *sd;
1071 * This is not correct for two reasons:
1072 * - You may need to go back first
1073 * - Currently we allow mixing of mapsets
1075 sel = route_rect(18, &c, &c, 0, max_dist);
1077 while ((m=mapset_next(h,1))) {
1080 if (map_projection(m) != pc->pro) {
1081 transform_to_geo(pc->pro, &c, &g);
1082 transform_from_geo(map_projection(m), &g, &c);
1084 mr=map_rect_new(m, sel);
1087 while ((item=map_rect_get_item(mr))) {
1088 if (item->type >= type_street_0 && item->type <= type_ferry) {
1089 sd=street_get_data(item);
1090 dist=transform_distance_polyline_sq(sd->c, sd->count, &c, &lp, &pos);
1091 if (!ret || dist < ret->dist) {
1093 street_data_free(ret->street);
1096 ret=g_new(struct route_info, 1);
1098 printf("%s:Out of memory\n", __FUNCTION__);
1107 dbg(1,"dist=%d id 0x%x 0x%x pos=%d\n", dist, item->id_hi, item->id_lo, pos);
1109 street_data_free(sd);
1112 map_rect_destroy(mr);
1115 map_selection_destroy(sel);
1121 route_info_free(struct route_info *inf)
1124 street_data_free(inf->street);
1131 struct street_data *
1132 route_info_street(struct route_info *rinf)
1134 return rinf->street;
1138 route_info_point(struct route_info *rinf, int point)
1140 struct street_data *sd=rinf->street;
1146 dir=(point == 2) ? rinf->dir : -rinf->dir;
1148 return &sd->c[sd->count-1];
1160 struct route_info_handle {
1161 struct route_info *start;
1162 struct route_info *curr;
1163 struct route_info *end;
1172 struct route_info_handle *
1173 route_info_open(struct route_info *start, struct route_info *end, int dir)
1175 struct route_info_handle *ret=g_new0(struct route_info_handle, 1);
1176 struct route_info *curr;
1177 dbg(2,"enter start=%p end=%p dir=%d\n", start, end, dir);
1179 printf("%s:Out of memory\n", __FUNCTION__);
1190 if (start->street->item.map != end->street->item.map || start->street->item.id_hi != end->street->item.id_hi || start->street->item.id_lo != end->street->item.id_lo) {
1191 dbg(1,"return NULL\n");
1194 printf("trivial start=%d end=%d start dir %d end dir %d\n", start->pos, end->pos, start->dir, end->dir);
1195 if (start->pos == end->pos) {
1200 if (start->pos > end->pos) {
1205 if (start->pos < end->pos) {
1210 printf("trivial now start=%d end=%d start dir %d end dir %d\n", start->pos, end->pos, start->dir, end->dir);
1211 ret->endpos=end->pos;
1216 dbg(2,"dir=%d\n", dir);
1224 dbg(2,"ret=%p\n",ret);
1229 route_info_get(struct route_info_handle *h)
1234 dbg(1,"iter=%d\n", h->iter);
1250 dbg(1,"h->pos=%d\n", h->pos);
1251 if (h->dir && h->pos >= 0 && h->pos < h->curr->street->count && (h->end == NULL || h->endpos!=h->pos)) {
1252 new=&h->curr->street->c[h->pos];
1273 dbg(1,"new=%p (0x%x,0x%x) last=%p\n", new, new->x, new->y, h->last);
1274 if (h->last && new->x == h->last->x && new->y == h->last->y)
1284 route_info_close(struct route_info_handle *h)
1291 struct route_crossings *
1292 route_crossings_get(struct route *this, struct coord *c)
1294 struct route_point *pnt;
1295 struct route_segment *seg;
1297 struct route_crossings *ret;
1299 pnt=route_graph_get_point(this, c);
1302 printf("start: 0x%x 0x%x\n", seg->item.id_hi, seg->item.id_lo);
1304 seg=seg->start_next;
1308 printf("end: 0x%x 0x%x\n", seg->item.id_hi, seg->item.id_lo);
1312 ret=g_malloc(sizeof(struct route_crossings)+crossings*sizeof(struct route_crossing));
1313 ret->count=crossings;
1319 struct map_rect_priv {
1320 struct route_info_handle *ri;
1321 enum attr_type attr_next;
1324 struct map_priv *mpriv;
1328 unsigned int last_coord;
1329 struct route_path_segment *seg;
1330 struct route_graph_point *point;
1331 struct route_graph_segment *rseg;
1336 rm_coord_rewind(void *priv_data)
1338 struct map_rect_priv *mr = priv_data;
1343 rm_attr_rewind(void *priv_data)
1345 struct map_rect_priv *mr = priv_data;
1346 mr->attr_next = attr_street_item;
1350 rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
1352 struct map_rect_priv *mr = priv_data;
1353 struct route_path_segment *seg=mr->seg;
1354 struct route *route=mr->mpriv->route;
1355 attr->type=attr_type;
1356 switch (attr_type) {
1358 while (mr->attr_next != attr_none) {
1359 if (rm_attr_get(priv_data, mr->attr_next, attr))
1363 case attr_street_item:
1365 attr->u.item=&seg->item;
1367 attr->u.item=mr->sitem;
1368 mr->attr_next=attr_length;
1372 attr->u.num=seg->length;
1374 attr->u.num=mr->length;
1375 mr->attr_next=attr_time;
1379 attr->u.num=route_time(route->speedlist, &seg->item, seg->length);
1381 attr->u.num=route_time(route->speedlist, mr->sitem, mr->length);
1382 mr->attr_next=attr_none;
1385 attr->type=attr_none;
1392 rm_coord_get(void *priv_data, struct coord *c, int count)
1394 struct map_rect_priv *mr = priv_data;
1395 struct route_path_segment *seg = mr->seg;
1398 dbg(1,"pos=%d seg=%p\n", mr->pos, seg);
1401 for (i=0; i < count; i++) {
1402 if ((c1=route_info_get(mr->ri))) {
1409 for (i=0; i < count; i++) {
1410 if (mr->last_coord >= seg->ncoords)
1412 if (i >= seg->ncoords)
1415 c[i] = seg->c[seg->ncoords-++mr->last_coord];
1417 c[i] = seg->c[mr->last_coord++];
1422 for (i=0; i < count; i++) {
1423 if ((c1=route_info_get(mr->ri))) {
1432 dbg(1,"return %d\n",rc);
1436 static struct item_methods methods_route_item = {
1444 rp_attr_rewind(void *priv_data)
1446 struct map_rect_priv *mr = priv_data;
1447 mr->attr_next = attr_label;
1451 rp_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
1453 struct map_rect_priv *mr = priv_data;
1454 struct route_graph_point *p = mr->point;
1455 if (mr->item.type != type_rg_point)
1457 switch (attr_type) {
1459 while (mr->attr_next != attr_none) {
1460 if (rm_attr_get(priv_data, mr->attr_next, attr))
1464 attr->type = attr_label;
1467 if (p->value != INT_MAX)
1468 mr->str=g_strdup_printf("%d", p->value);
1470 mr->str=g_strdup("-");
1471 attr->u.str = mr->str;
1472 mr->attr_next=attr_none;
1475 attr->type = attr_debug;
1478 mr->str=g_strdup_printf("x=%d y=%d", p->c.x, p->c.y);
1479 attr->u.str = mr->str;
1480 mr->attr_next=attr_none;
1488 rp_coord_get(void *priv_data, struct coord *c, int count)
1490 struct map_rect_priv *mr = priv_data;
1491 struct route_graph_point *p = mr->point;
1492 struct route_graph_segment *seg = mr->rseg;
1494 for (i=0; i < count; i++) {
1495 if (mr->item.type == type_rg_point) {
1496 if (mr->last_coord >= 1)
1500 if (mr->last_coord >= 2)
1505 c[i] = seg->start->c;
1513 static struct item_methods methods_point_item = {
1521 rm_destroy(struct map_priv *priv)
1526 static struct map_rect_priv *
1527 rm_rect_new(struct map_priv *priv, struct map_selection *sel)
1529 struct map_rect_priv * mr;
1531 if (! route_get_pos(priv->route))
1533 if (! route_get_dst(priv->route))
1535 if (! priv->route->path2)
1537 mr=g_new0(struct map_rect_priv, 1);
1539 mr->ri=route_info_open(route_get_pos(priv->route), route_get_dst(priv->route), 0);
1541 mr->sitem=&(route_get_pos(priv->route)->street->item);
1542 mr->item.priv_data = mr;
1543 mr->item.type = type_street_route;
1544 mr->item.meth = &methods_route_item;
1546 mr->length=route_info_length(route_get_pos(priv->route), route_get_dst(priv->route), 0);
1548 mr->ri=route_info_open(route_get_pos(priv->route), NULL, 0);
1549 mr->length=route_info_length(route_get_pos(priv->route), NULL, 0);
1555 static struct map_rect_priv *
1556 rp_rect_new(struct map_priv *priv, struct map_selection *sel)
1558 struct map_rect_priv * mr;
1560 if (! priv->route->graph || ! priv->route->graph->route_points)
1562 mr=g_new0(struct map_rect_priv, 1);
1564 mr->item.priv_data = mr;
1565 mr->item.type = type_rg_point;
1566 mr->item.meth = &methods_point_item;
1571 rm_rect_destroy(struct map_rect_priv *mr)
1574 route_info_close(mr->ri);
1580 static struct item *
1581 rp_get_item(struct map_rect_priv *mr)
1583 struct route *r = mr->mpriv->route;
1584 struct route_graph_point *p = mr->point;
1585 struct route_graph_segment *seg = mr->rseg;
1587 if (mr->item.type == type_rg_point) {
1589 p = r->graph->route_points;
1595 rm_coord_rewind(mr);
1599 mr->item.type = type_rg_segment;
1602 seg=r->graph->route_segments;
1608 rm_coord_rewind(mr);
1616 static struct item *
1617 rp_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
1619 struct item *ret=NULL;
1621 ret=rp_get_item(mr);
1626 static struct item *
1627 rm_get_item(struct map_rect_priv *mr)
1629 struct route *r = mr->mpriv->route;
1630 struct route_path_segment *seg = mr->seg;
1631 dbg(1,"enter\n", mr->pos);
1633 mr->pos=mr->pos_next;
1640 seg = r->path2->path;
1644 mr->sitem = &seg->item;
1648 route_info_close(mr->ri);
1649 mr->ri=route_info_open(NULL, route_get_dst(r), 0);
1650 mr->sitem=&(route_get_dst(r)->street->item);
1651 mr->length=route_info_length(NULL, route_get_dst(r), 0);
1665 static struct item *
1666 rm_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
1668 struct item *ret=NULL;
1670 ret=rm_get_item(mr);
1674 static struct map_methods route_meth = {
1687 static struct map_methods route_graph_meth = {
1701 route_toggle_routegraph_display(struct route *route)
1703 if (route->flags & RF_SHOWGRAPH) {
1704 route->flags &= ~RF_SHOWGRAPH;
1706 route->flags |= RF_SHOWGRAPH;
1710 static struct map_priv *
1711 route_map_new_helper(struct map_methods *meth, struct attr **attrs, int graph)
1713 struct map_priv *ret;
1714 struct attr *route_attr;
1716 route_attr=attr_search(attrs, NULL, attr_route);
1719 ret=g_new0(struct map_priv, 1);
1721 *meth=route_graph_meth;
1724 ret->route=route_attr->u.route;
1729 static struct map_priv *
1730 route_map_new(struct map_methods *meth, struct attr **attrs)
1732 return route_map_new_helper(meth, attrs, 0);
1735 static struct map_priv *
1736 route_graph_map_new(struct map_methods *meth, struct attr **attrs)
1738 return route_map_new_helper(meth, attrs, 1);
1742 route_get_map_helper(struct route *this_, struct map **map, char *type)
1744 struct attr route_attr;
1745 struct attr data_attr;
1746 struct attr *attrs_route[]={&route_attr, &data_attr, NULL};
1747 route_attr.type=attr_route;
1748 route_attr.u.route=this_;
1749 data_attr.type=attr_data;
1753 *map=map_new(type,attrs_route);
1758 route_get_map(struct route *this_)
1760 return route_get_map_helper(this_, &this_->map, "route");
1765 route_get_graph_map(struct route *this_)
1767 return route_get_map_helper(this_, &this_->graph_map, "route_graph");
1771 route_set_projection(struct route *this_, enum projection pro)
1778 plugin_register_map_type("route", route_map_new);
1779 plugin_register_map_type("route_graph", route_graph_map_new);