Add:Core:Support for position_coord_geo parsing
[navit-package] / src / vehicle / demo / vehicle_demo.c
1 #include <glib.h>
2 #include "debug.h"
3 #include "coord.h"
4 #include "item.h"
5 #include "navit.h"
6 #include "route.h"
7 #include "callback.h"
8 #include "transform.h"
9 #include "plugin.h"
10 #include "vehicle.h"
11
12 struct vehicle_priv {
13         int interval;
14         int position_set;
15         struct callback_list *cbl;
16         struct navit *navit;
17         struct coord_geo geo;
18         struct coord last;
19         double speed;
20         double direction;
21 };
22
23 static void
24 vehicle_demo_destroy(struct vehicle_priv *priv)
25 {
26         g_free(priv);
27 }
28
29 static int
30 vehicle_demo_position_attr_get(struct vehicle_priv *priv,
31                                enum attr_type type, struct attr *attr)
32 {
33         switch (type) {
34         case attr_position_speed:
35                 attr->u.numd = &priv->speed;
36                 break;
37         case attr_position_direction:
38                 attr->u.numd = &priv->direction;
39                 break;
40         case attr_position_coord_geo:
41                 attr->u.coord_geo = &priv->geo;
42                 break;
43         default:
44                 return 0;
45         }
46         attr->type = type;
47         return 1;
48 }
49
50 static int
51 vehicle_demo_set_attr(struct vehicle_priv *priv, struct attr *attr,
52                       struct attr **attrs)
53 {
54         if (attr->type == attr_navit) {
55                 priv->navit = attr->u.navit;
56                 return 1;
57         }
58         return 0;
59 }
60
61 struct vehicle_methods vehicle_demo_methods = {
62         vehicle_demo_destroy,
63         vehicle_demo_position_attr_get,
64         vehicle_demo_set_attr,
65 };
66
67 static int
68 vehicle_demo_timer(struct vehicle_priv *priv)
69 {
70         struct route_path_coord_handle *h=NULL;
71         struct coord *c, *pos=NULL, ci;
72         int slen, len, dx, dy;
73
74         len = (priv->speed * priv->interval / 1000)/ 3.6;
75         dbg(1, "###### Entering simulation loop\n");
76         if (!priv->navit) {
77                 dbg(1, "vehicle->navit is not set. Can't simulate\n");
78                 return 1;
79         }
80         struct route *vehicle_route = navit_get_route(priv->navit);
81         if (vehicle_route) 
82                 h = route_path_coord_open(vehicle_route);
83         if (h) 
84                 pos = route_path_coord_get(h);
85         dbg(1, "current pos=%p\n", pos);
86         if (pos) {
87                 priv->position_set=0;
88                 dbg(1, "current pos=0x%x,0x%x\n", pos->x, pos->y);
89                 dbg(1, "last pos=0x%x,0x%x\n", priv->last.x, priv->last.y);
90                 if (priv->last.x == pos->x && priv->last.y == pos->y) {
91                         dbg(1, "endless loop\n");
92                 }
93                 priv->last = *pos;
94                 for (;;) {
95                         c = route_path_coord_get(h);
96                         dbg(1, "next pos=%p\n", c);
97                         if (!c)
98                                 break;
99                         dbg(1, "next pos=0x%x,0x%x\n", c->x, c->y);
100                         slen = transform_distance(projection_mg, pos, c);
101                         dbg(1, "len=%d slen=%d\n", len, slen);
102                         if (slen < len) {
103                                 len -= slen;
104                                 pos = c;
105                         } else {
106                                 dx = c->x - pos->x;
107                                 dy = c->y - pos->y;
108                                 ci.x = pos->x + dx * len / slen;
109                                 ci.y = pos->y + dy * len / slen;
110                                 priv->direction =
111                                     transform_get_angle_delta(pos, c, 0);
112                                 dbg(1, "ci=0x%x,0x%x\n", ci.x, ci.y);
113                                 transform_to_geo(projection_mg, &ci,
114                                                  &priv->geo);
115                                 callback_list_call_0(priv->cbl);
116                                 break;
117                         }
118                 }
119         } else {
120                 if (priv->position_set) 
121                         callback_list_call_0(priv->cbl);
122         }
123         return 1;
124 }
125
126
127
128 static struct vehicle_priv *
129 vehicle_demo_new(struct vehicle_methods
130                  *meth, struct callback_list
131                  *cbl, struct attr **attrs)
132 {
133         struct vehicle_priv *ret;
134         struct attr *interval,*speed,*position_coord_geo;
135
136         dbg(1, "enter\n");
137         ret = g_new0(struct vehicle_priv, 1);
138         ret->cbl = cbl;
139         ret->interval=1000;
140         ret->speed=40;
141         if ((speed=attr_search(attrs, NULL, attr_speed)))
142                 ret->speed=speed->u.num;
143         if ((interval=attr_search(attrs, NULL, attr_interval)))
144                 ret->interval=speed->u.num;
145         if ((position_coord_geo=attr_search(attrs, NULL, attr_position_coord_geo))) {
146                 ret->geo=*(position_coord_geo->u.coord_geo);
147                 ret->position_set=1;
148                 dbg(0,"position_set %f %f\n", ret->geo.lat, ret->geo.lng);
149         }
150         *meth = vehicle_demo_methods;
151         g_timeout_add(ret->interval, (GSourceFunc) vehicle_demo_timer, ret);
152         return ret;
153 }
154
155 void
156 plugin_init(void)
157 {
158         dbg(1, "enter\n");
159         plugin_register_vehicle_type("demo", vehicle_demo_new);
160 }