19 struct track_line *next;
24 struct transformation t;
25 struct coord last_updated;
26 struct track_line *lines;
27 struct track_line **last_ptr;
30 struct coord last_out;
34 int connected_pref=-10;
38 struct track_line **last;
41 tst_callback(struct street_str *str, void *handle, void *data)
44 int visible=0,count=0;
45 struct track *tr=data;
46 struct track_line *lines;
50 /* printf("tst_callback id=0x%x ",str->segid < 0 ? -str->segid : str->segid); */
51 if (street_coord_handle_get(handle, &c[0], 1)) {
52 if (str->segid == debug_segid)
53 printf("0x%lx,0x%lx ", c->x, c->y);
55 while (street_coord_handle_get(handle, &c[0], 1)) {
56 if (is_line_visible(&tr->t, c)) {
61 if (str->segid == debug_segid)
62 printf("0x%lx,0x%lx ", c->x, c->y);
66 lines=g_new(struct track_line, count);
67 street_coord_handle_rewind(handle);
68 street_coord_handle_get(handle, &c[0], 1);
70 while (street_coord_handle_get(handle, &c[1], 1)) {
71 *(tr->last_ptr)=lines;
72 tr->last_ptr=&lines->next;
73 lines->segid=str->segid;
77 lines->angle=transform_get_angle(c,0);
84 printf("%d lines\n", count);
90 track_doupdate_lines(struct track *tr, struct coord *c)
93 struct transformation t;
95 tr->last_ptr=&tr->lines;
96 transform_setup_source_rect_limit(&t,c,1000);
97 transform_setup_source_rect_limit(&tr->t,c,1000);
101 street_get_block(tr->ma,&t,tst_callback,tr);
102 profile_timer("end");
106 track_free_lines(struct track *tr)
108 struct track_line *tl=tr->lines,*next;
110 printf("track_free_lines(tr=%p)\n", tr);
123 track_angle_abs_diff(int a1, int a2, int full)
137 track_angle_delta(int a1, int a2, int dir)
140 return track_angle_abs_diff(a1, a2, 180);
142 return track_angle_abs_diff(a1, a2, 360);
146 track_is_connected(struct coord *c1, struct coord *c2)
148 if (c1[0].x == c2[0].x && c1[0].y == c2[0].y)
150 if (c1[0].x == c2[1].x && c1[0].y == c2[1].y)
152 if (c1[1].x == c2[0].x && c1[1].y == c2[0].y)
154 if (c1[1].x == c2[1].x && c1[1].y == c2[1].y)
160 track_update(struct track *tr, struct coord *c, int angle)
162 struct track_line *t,*tm;
166 if (c->x == tr->last_in.x && c->y == tr->last_in.y) {
170 if (transform_distance_sq(&tr->last_updated, c) > 250000 || !tr->lines) {
172 track_free_lines(tr);
173 track_doupdate_lines(tr, c);
181 if (debug) printf("0x%lx,0x%lx (%d deg)\n", c->x, c->y, angle);
183 if (debug) printf("0x%lx 0x%lx,0x%lx - 0x%lx,0x%lx (%d deg) ", -t->segid, t->c[0].x, t->c[0].y, t->c[1].x, t->c[1].y, t->angle);
184 t->value=transform_distance_line_sq(&t->c[0], &t->c[1], c, &t->lpnt);
185 if (t->value < INT_MAX/2)
186 t->value += track_angle_delta(angle, t->angle, 0)*angle_factor;
187 if (track_is_connected(tr->curr, t->c))
188 t->value += connected_pref;
189 if (t->lpnt.x == tr->last_out.x && t->lpnt.y == tr->last_out.y)
190 t->value += nostop_pref;
191 if (debug) printf(" %d\n", t->value);
198 if (t->value < min) {
204 dist=transform_distance_sq(&tm->lpnt, c);
205 if (debug) printf("dist=%d id=0x%lx\n", dist, tm->segid);
207 tr->curr[0]=tm->c[0];
208 tr->curr[1]=tm->c[1];
209 tr->last_out=tm->lpnt;
211 // printf("pos 0x%lx,0x%lx value %d dist %d angle %d vs %d (%d)\n", c->x, c->y, tm->value, dist, angle, tm->angle, track_angle_delta(angle, tm->angle, 0));
212 g_assert(dist < 10000);
214 profile_timer("track_update end");
220 track_new(struct map_data *ma)
222 struct track *this=g_new0(struct track, 1);
229 track_destroy(struct track *tr)
231 track_free_lines(tr);