Ticket #905: navit_route_guard.diff

File navit_route_guard.diff, 8.8 KB (added by tegzed, 10 years ago)

added support for imperial units

  • attr_def.h

     
    172172ATTR(update_period)
    173173ATTR(tunnel_extrapolation)
    174174ATTR(street_count)
     175ATTR(min_dist)
     176ATTR(max_dist)
    175177ATTR2(0x00027500,type_rel_abs_begin)
    176178/* These attributes are int that can either hold relative               *
    177179 * or absolute values. A relative value is indicated by                 *
     
    348350ATTR(dbus_method)
    349351ATTR(osm_is_in)
    350352ATTR(event_loop_system)
     353ATTR(map_name)
     354ATTR(item_name)
    351355ATTR2(0x0003ffff,type_string_end)
    352356ATTR2(0x00040000,type_special_begin)
    353357ATTR(order)
  • osd/core/osd_core.c

     
    261261        }
    262262        return 0;
    263263}
     264
     265
     266struct route_guard {
     267        int coord_num;
     268        struct coord *coords;
     269        double min_dist;        //distance treshold, exceeding this distance will trigger announcement
     270        double max_dist;        //out of range distance, farther than this distance no warning will be given
     271        char*item_name;
     272        char*map_name;
     273        int warned;
     274        double last_time;
     275        int update_period;
     276        struct color active_color;
     277        struct graphics_gc *red;
     278        struct graphics_gc *white;
     279        int width;
     280};
     281
     282static void osd_route_guard_draw(struct osd_priv_common *opc, struct navit *nav, struct vehicle *v)
     283{
     284        int i=0;
     285        struct vehicle* curr_vehicle = v;
     286        struct attr position_attr, vehicle_attr, imperial_attr;
     287        struct coord curr_coord;
     288        struct route_guard *this = (struct route_guard *)opc->data;
     289        double curr_time;
     290        struct timeval tv;
     291        struct point p;
     292        struct point bbox[4];
     293        char* dist_str;
     294        struct graphics_gc *curr_color;
     295        int imperial=0;
     296     
     297      //do not execute for each gps update
     298        gettimeofday(&tv,NULL);
     299        curr_time = (double)(tv.tv_usec)/1000000.0+tv.tv_sec;
     300        if ( this->last_time+this->update_period > curr_time) {
     301                this->last_time = curr_time;
     302                return;
     303        }
     304        if(nav) {
     305                navit_get_attr(nav, attr_vehicle, &vehicle_attr, NULL);
     306                if (vehicle_attr.u.vehicle) {
     307                        curr_vehicle = vehicle_attr.u.vehicle;
     308                }
     309                if (navit_get_attr(nav, attr_imperial, &imperial_attr, NULL)) {
     310                        imperial=imperial_attr.u.num;
     311                }
     312        }
     313
     314        if(0==curr_vehicle)
     315                return;
     316
     317        if(!vehicle_get_attr(curr_vehicle, attr_position_coord_geo,&position_attr, NULL)) {
     318                return;
     319        }
     320        transform_from_geo(projection_mg, position_attr.u.coord_geo, &curr_coord);
     321
     322        double min_dist = 1000000;
     323        //calculate min dist
     324        if(this->coord_num > 1) {
     325                double scale = transform_scale(curr_coord.y);
     326                for( i=1 ; i<this->coord_num ; ++i ) {
     327                        struct coord proj_coord;
     328                        double curr_dist = sqrt(transform_distance_line_sq(&this->coords[i-1], &this->coords[i], &curr_coord, &proj_coord));
     329                        curr_dist /= scale;
     330                        if (curr_dist<min_dist) {
     331                                min_dist = curr_dist;
     332                        }
     333                }
     334                if ( this->warned == 0 && this->min_dist < min_dist && min_dist < this->max_dist) {
     335                        navit_say(nav, _("Return to route!"));
     336                        this->warned = 1;
     337                } else if( min_dist < this->min_dist ) {
     338                        this->warned = 0;
     339                }
     340        }
     341        osd_std_draw(&opc->osd_item);
     342
     343        dist_str = format_distance(min_dist, "", imperial);
     344
     345        graphics_get_text_bbox(opc->osd_item.gr, opc->osd_item.font, dist_str, 0x10000, 0, bbox, 0);
     346        p.x=(opc->osd_item.w-bbox[2].x)/2;
     347        p.y = opc->osd_item.h-opc->osd_item.h/10;
     348
     349        curr_color = (this->min_dist < min_dist && min_dist < this->max_dist) ? this->red : this->white;
     350        graphics_draw_text(opc->osd_item.gr, curr_color, NULL, opc->osd_item.font, dist_str, &p, 0x10000, 0);
     351
     352        g_free(dist_str);
     353
     354        graphics_draw_mode(opc->osd_item.gr, draw_mode_end);
     355}
     356
     357static void
     358osd_route_guard_init(struct osd_priv_common *opc, struct navit *nav)
     359{
     360        struct color red_color={0xffff,0x0000,0x0000,0xffff};
     361        struct route_guard *this = (struct route_guard *)opc->data;
     362        osd_set_std_graphic(nav, &opc->osd_item, (struct osd_priv *)opc);
     363        //load coord data
     364        if (this->map_name && this->item_name) {
     365                struct mapset* ms;
     366                struct map_rect *mr;
     367                struct mapset_handle *msh;
     368                struct map *map = NULL;
     369                struct item *item = NULL;
     370                if(!(ms=navit_get_mapset(nav))) {
     371                        return;
     372                }
     373                msh=mapset_open(ms);
     374                while ((map=mapset_next(msh, 1))) {
     375                        struct attr attr;
     376                        if(map_get_attr(map, attr_name, &attr, NULL)) {
     377                                if( ! strcmp(this->map_name, attr.u.str) ) {
     378                                mr=map_rect_new(map, NULL);
     379                                        if (mr) {
     380                                                while ((item=map_rect_get_item(mr))) {
     381                                                        struct attr item_attr;
     382                                                        if(item_attr_get(item, attr_name, &item_attr)) {
     383                                                                if (!strcmp(item_attr.u.str,this->item_name)) {
     384                                                                        //item found, get coords
     385                                                                        struct coord c;
     386                                                                        this->coord_num=0;
     387                                                                        while (item_coord_get(item,&c,1)) {
     388                                                                                this->coords = g_renew(struct coord,this->coords,this->coord_num+1);
     389                                                                                this->coords[this->coord_num] = c;
     390                                                                                ++this->coord_num;
     391                                                                        }
     392                                                                }
     393                                                        }
     394                                                }
     395                                        }
     396                                } else {
     397                                        continue;
     398                                }
     399                        } else {
     400                                continue;
     401                        }
     402                }
     403                mapset_close(msh);
     404        }
     405
     406        this->red = graphics_gc_new(opc->osd_item.gr);
     407        graphics_gc_set_foreground(this->red, &red_color);
     408        graphics_gc_set_linewidth(this->red, this->width);
     409
     410        this->white = graphics_gc_new(opc->osd_item.gr);
     411        graphics_gc_set_foreground(this->white, &opc->osd_item.text_color);
     412        graphics_gc_set_linewidth(this->white, this->width);
     413
     414        //setup draw callback
     415        navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_route_guard_draw), attr_position_coord_geo, opc));
     416}
     417
     418static void
     419osd_route_guard_destroy(struct navit* nav)
     420{
     421}
     422
     423static struct osd_priv *
     424osd_route_guard_new(struct navit *nav, struct osd_methods *meth,
     425                struct attr **attrs)
     426{
     427        //get min_dist and max_dist from attrs
     428        //get map name and item name
     429        //read coord list
     430
     431        struct route_guard *this = g_new0(struct route_guard, 1);
     432        struct osd_priv_common *opc = g_new0(struct osd_priv_common,1);
     433        opc->data = (void*)this;
     434
     435        struct attr *attr;
     436        opc->osd_item.p.x = 120;
     437        opc->osd_item.p.y = 20;
     438        opc->osd_item.w = 60;
     439        opc->osd_item.h = 80;
     440        opc->osd_item.navit = nav;
     441        opc->osd_item.font_size = 200;
     442        opc->osd_item.meth.draw = osd_draw_cast(osd_route_guard_draw);
     443        meth->set_attr = (void (*)(struct osd_priv *osd, struct attr* attr)) set_std_osd_attr;
     444        osd_set_std_attr(attrs, &opc->osd_item, 2);
     445
     446        attr = attr_search(attrs, NULL, attr_min_dist);
     447        if (attr) {
     448                this->min_dist = attr->u.num;
     449        }
     450        else
     451                this->min_dist = 30;    //default tolerance is 30m
     452
     453        attr = attr_search(attrs, NULL, attr_max_dist);
     454        if (attr) {
     455                this->max_dist = attr->u.num;
     456        }
     457        else
     458                this->max_dist = 500;   //default
     459
     460        attr = attr_search(attrs, NULL, attr_item_name);
     461        if (attr) {
     462                this->item_name = g_strdup(attr->u.str);
     463        }
     464        else
     465                this->item_name = NULL; 
     466
     467        attr = attr_search(attrs, NULL, attr_map_name);
     468        if (attr) {
     469                this->map_name = g_strdup(attr->u.str);
     470        }
     471        else
     472                this->map_name = NULL;   
     473
     474        attr = attr_search(attrs, NULL, attr_update_period);
     475        this->update_period=attr ? attr->u.num : 10;
     476
     477        attr = attr_search(attrs, NULL, attr_width);
     478        this->width=attr ? attr->u.num : 2;
     479
     480        navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_route_guard_init), attr_graphics_ready, opc));
     481        navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_route_guard_destroy), attr_destroy, nav));
     482
     483        return (struct osd_priv *) opc;
     484}
     485
     486
    264487 
    265488static int odometers_saved = 0;
    266489static GList* odometer_list = NULL;
     
    33293552        plugin_register_osd_type("compass", osd_compass_new);
    33303553        plugin_register_osd_type("navigation_next_turn", osd_nav_next_turn_new);
    33313554        plugin_register_osd_type("button", osd_button_new);
    3332         plugin_register_osd_type("toggle_announcer", osd_nav_toggle_announcer_new);
    3333         plugin_register_osd_type("speed_warner", osd_speed_warner_new);
    3334         plugin_register_osd_type("speed_cam", osd_speed_cam_new);
    3335         plugin_register_osd_type("text", osd_text_new);
    3336         plugin_register_osd_type("gps_status", osd_gps_status_new);
    3337         plugin_register_osd_type("volume", osd_volume_new);
    3338         plugin_register_osd_type("scale", osd_scale_new);
     3555    plugin_register_osd_type("toggle_announcer", osd_nav_toggle_announcer_new);
     3556    plugin_register_osd_type("speed_warner", osd_speed_warner_new);
     3557    plugin_register_osd_type("speed_cam", osd_speed_cam_new);
     3558    plugin_register_osd_type("text", osd_text_new);
     3559    plugin_register_osd_type("gps_status", osd_gps_status_new);
     3560    plugin_register_osd_type("volume", osd_volume_new);
     3561    plugin_register_osd_type("scale", osd_scale_new);
    33393562        plugin_register_osd_type("image", osd_image_new);
    33403563        plugin_register_osd_type("stopwatch", osd_stopwatch_new);
    33413564        plugin_register_osd_type("odometer", osd_odometer_new);
    33423565        plugin_register_osd_type("auxmap", osd_auxmap_new);
    33433566        plugin_register_osd_type("cmd_interface", osd_cmd_interface_new);
     3567        plugin_register_osd_type("route_guard", osd_route_guard_new);
    33443568}