summaryrefslogtreecommitdiff
path: root/navit/track.c
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2008-05-18 10:01:53 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2008-05-18 10:01:53 +0000
commit0b74d7f4ee6d448ac811e2741e8cb1ed04f5ce76 (patch)
treebe7bb1cb1020f4022e41c004e2fa9d561ea3580d /navit/track.c
parentf46eb419c46011d6d103b7f06cb2c842a2cbe6c9 (diff)
downloadnavit-0b74d7f4ee6d448ac811e2741e8cb1ed04f5ce76.tar.gz
Fix:Core:Renamed src to navit for cleanup of includes
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@1059 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/track.c')
-rw-r--r--navit/track.c318
1 files changed, 318 insertions, 0 deletions
diff --git a/navit/track.c b/navit/track.c
new file mode 100644
index 000000000..3f08b9a08
--- /dev/null
+++ b/navit/track.c
@@ -0,0 +1,318 @@
+#include <glib.h>
+#include <string.h>
+#include "item.h"
+#include "attr.h"
+#include "track.h"
+#include "debug.h"
+#include "transform.h"
+#include "coord.h"
+#include "route.h"
+#include "projection.h"
+#include "map.h"
+#include "mapset.h"
+
+struct tracking_line
+{
+ struct street_data *street;
+#if 0
+ long segid;
+ int linenum;
+ struct coord c[2];
+ struct coord lpnt;
+ int value;
+ int dir;
+#endif
+ struct tracking_line *next;
+ int angle[0];
+};
+
+
+struct tracking {
+ struct mapset *ms;
+#if 0
+ struct transformation t;
+#endif
+ struct coord last_updated;
+ struct tracking_line *lines;
+#if 0
+ struct tracking_line **last_ptr;
+#endif
+ struct tracking_line *curr_line;
+ int pos;
+ struct coord curr[2];
+ struct coord last_in;
+ struct coord last_out;
+};
+
+
+int angle_factor=30;
+int connected_pref=-10;
+int nostop_pref=10;
+int offroad_limit_pref=5000;
+
+
+struct coord *
+tracking_get_pos(struct tracking *tr)
+{
+ return &tr->last_out;
+}
+
+int
+tracking_get_segment_pos(struct tracking *tr)
+{
+ return tr->pos;
+}
+
+struct street_data *
+tracking_get_street_data(struct tracking *tr)
+{
+ return tr->curr_line->street;
+}
+
+int
+tracking_get_current_attr(struct tracking *_this, enum attr_type type, struct attr *attr)
+{
+ struct item *item;
+ struct map_rect *mr;
+ int result=0;
+ if (! _this->curr_line || ! _this->curr_line->street)
+ return 0;
+ item=&_this->curr_line->street->item;
+ mr=map_rect_new(item->map,NULL);
+ item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
+ if (item_attr_get(item, type, attr))
+ result=1;
+ map_rect_destroy(mr);
+ return result;
+}
+
+struct item *
+tracking_get_current_item(struct tracking *_this)
+{
+ if (! _this->curr_line || ! _this->curr_line->street)
+ return NULL;
+ return &_this->curr_line->street->item;
+}
+
+static void
+tracking_get_angles(struct tracking_line *tl)
+{
+ int i;
+ struct street_data *sd=tl->street;
+ for (i = 0 ; i < sd->count-1 ; i++)
+ tl->angle[i]=transform_get_angle_delta(&sd->c[i], &sd->c[i+1], 0);
+}
+
+static void
+tracking_doupdate_lines(struct tracking *tr, struct coord *cc)
+{
+ int max_dist=1000;
+ struct map_selection *sel=route_rect(18, cc, cc, 0, max_dist);
+ struct mapset_handle *h;
+ struct map *m;
+ struct map_rect *mr;
+ struct item *item;
+ struct street_data *street;
+ struct tracking_line *tl;
+#if 0
+ struct coord c;
+#endif
+
+ dbg(1,"enter\n");
+ h=mapset_open(tr->ms);
+ while ((m=mapset_next(h,1))) {
+ mr=map_rect_new(m, sel);
+ if (! mr)
+ continue;
+ while ((item=map_rect_get_item(mr))) {
+ if (item->type >= type_street_0 && item->type <= type_ferry) {
+ street=street_get_data(item);
+ tl=g_malloc(sizeof(struct tracking_line)+(street->count-1)*sizeof(int));
+ tl->street=street;
+ tracking_get_angles(tl);
+ tl->next=tr->lines;
+ tr->lines=tl;
+ }
+ }
+ map_rect_destroy(mr);
+ }
+ mapset_close(h);
+ map_selection_destroy(sel);
+ dbg(1, "exit\n");
+#if 0
+
+ struct transformation t;
+
+ tr->last_ptr=&tr->lines;
+ transform_setup_source_rect_limit(&t,c,1000);
+ transform_setup_source_rect_limit(&tr->t,c,1000);
+
+
+ profile_timer(NULL);
+ street_get_block(tr->ma,&t,tst_callback,tr);
+ profile_timer("end");
+#endif
+}
+
+
+static void
+tracking_free_lines(struct tracking *tr)
+{
+ struct tracking_line *tl=tr->lines,*next;
+ dbg(1,"enter(tr=%p)\n", tr);
+
+ while (tl) {
+ next=tl->next;
+ street_data_free(tl->street);
+ g_free(tl);
+ tl=next;
+ }
+ tr->lines=NULL;
+}
+
+static int
+tracking_angle_abs_diff(int a1, int a2, int full)
+{
+ int ret;
+
+ if (a2 > a1)
+ ret=(a2-a1)%full;
+ else
+ ret=(a1-a2)%full;
+ if (ret > full/2)
+ ret=full-ret;
+ return ret;
+}
+
+static int
+tracking_angle_delta(int vehicle_angle, int street_angle, int dir)
+{
+ int full=180;
+ int ret;
+ if (dir) {
+ full=360;
+ if (dir < 0)
+ street_angle=(street_angle+180)%360;
+ }
+ ret=tracking_angle_abs_diff(vehicle_angle, street_angle, full);
+
+ return ret*ret;
+}
+
+static int
+tracking_is_connected(struct coord *c1, struct coord *c2)
+{
+ if (c1[0].x == c2[0].x && c1[0].y == c2[0].y)
+ return 1;
+ if (c1[0].x == c2[1].x && c1[0].y == c2[1].y)
+ return 1;
+ if (c1[1].x == c2[0].x && c1[1].y == c2[0].y)
+ return 1;
+ if (c1[1].x == c2[1].x && c1[1].y == c2[1].y)
+ return 1;
+ return 0;
+}
+
+int
+tracking_update(struct tracking *tr, struct coord *c, int angle)
+{
+ struct tracking_line *t;
+ int i,value,min=0;
+ struct coord lpnt;
+#if 0
+ int min,dist;
+ int debug=0;
+#endif
+ dbg(1,"enter(%p,%p,%d)\n", tr, c, angle);
+ dbg(1,"c=0x%x,0x%x\n", c->x, c->y);
+
+ if (c->x == tr->last_in.x && c->y == tr->last_in.y) {
+ *c=tr->last_out;
+ return 0;
+ }
+ tr->last_in=*c;
+ if (!tr->lines || transform_distance_sq(&tr->last_updated, c) > 250000) {
+ dbg(1, "update\n");
+ tracking_free_lines(tr);
+ tracking_doupdate_lines(tr, c);
+ tr->last_updated=*c;
+ dbg(1,"update end\n");
+ }
+
+ t=tr->lines;
+ if (! t)
+ return 0;
+ tr->curr_line=NULL;
+ while (t) {
+ struct street_data *sd=t->street;
+ int dir = 0;
+ switch(sd->flags & AF_ONEWAYMASK) {
+ case 0:
+ dir=0;
+ break;
+ case 1:
+ dir=1;
+ break;
+ case 2:
+ dir=-1;
+ break;
+ case 3:
+ t=t->next;
+ continue;
+ }
+ for (i = 0; i < sd->count-1 ; i++) {
+ dbg(2, "%d: (0x%x,0x%x)-(0x%x,0x%x)\n", i, sd->c[i].x, sd->c[i].y, sd->c[i+1].x, sd->c[i+1].y);
+ value=transform_distance_line_sq(&sd->c[i], &sd->c[i+1], c, &lpnt);
+ if (value < INT_MAX/2)
+ value += tracking_angle_delta(angle, t->angle[i], dir)*angle_factor>>4;
+ if (tracking_is_connected(tr->curr, &sd->c[i]))
+ value += connected_pref;
+ if (lpnt.x == tr->last_out.x && lpnt.y == tr->last_out.y)
+ value += nostop_pref;
+ if (! tr->curr_line || value < min) {
+ tr->curr_line=t;
+ tr->pos=i;
+ tr->curr[0]=sd->c[i];
+ tr->curr[1]=sd->c[i+1];
+ dbg(1,"lpnt.x=0x%x,lpnt.y=0x%x pos=%d %d+%d+%d+%d=%d\n", lpnt.x, lpnt.y, i,
+ transform_distance_line_sq(&sd->c[i], &sd->c[i+1], c, &lpnt),
+ tracking_angle_delta(angle, t->angle[i], 0)*angle_factor,
+ tracking_is_connected(tr->curr, &sd->c[i]) ? connected_pref : 0,
+ lpnt.x == tr->last_out.x && lpnt.y == tr->last_out.y ? nostop_pref : 0,
+ value
+ );
+ tr->last_out=lpnt;
+ min=value;
+ }
+ }
+ t=t->next;
+ }
+ dbg(1,"tr->curr_line=%p min=%d\n", tr->curr_line, min);
+ if (!tr->curr_line || min > offroad_limit_pref)
+ return 0;
+ dbg(1,"found 0x%x,0x%x\n", tr->last_out.x, tr->last_out.y);
+ *c=tr->last_out;
+ return 1;
+}
+
+struct tracking *
+tracking_new(struct mapset *ms)
+{
+ struct tracking *this=g_new0(struct tracking, 1);
+ this->ms=ms;
+
+ return this;
+}
+
+void
+tracking_set_mapset(struct tracking *this, struct mapset *ms)
+{
+ this->ms=ms;
+}
+
+void
+tracking_destroy(struct tracking *tr)
+{
+ tracking_free_lines(tr);
+ g_free(tr);
+}