// checks if a positions is on the same street as a segment static int check_same_street(const PluginLine *line, const RoadMapPosition *point_position) { const char *street_name; const char *city_name; char current_street_name[512]; char current_city_name[512]; int point_res; int square_current = roadmap_square_active (); get_street_from_line (line->square, line->line_id, &street_name, &city_name); strncpy_safe (current_street_name, street_name, sizeof (current_street_name)); strncpy_safe (current_city_name, city_name, sizeof (current_city_name)); point_res = get_street(point_position, &street_name, &city_name); roadmap_square_set_current (square_current); if (point_res == -1) return FALSE; if (strcmp (current_street_name, street_name) == 0 && strcmp (current_city_name, city_name) == 0) return TRUE; else return FALSE; }
//return the street name given a GPS position static int get_street(const RoadMapPosition *position, const char **street_name, const char **city_name) { int count = 0; int layers[128]; int layers_count; RoadMapNeighbour neighbours; layers_count = roadmap_layer_all_roads (layers, 128); if (layers_count > 0) { count = roadmap_street_get_closest (position, 0, layers, layers_count, &neighbours, 1); if (count > 0) { get_street_from_line (neighbours.line.square, neighbours.line.line_id, street_name, city_name); return 0; } else return -1; } return -1; }
//checks whether an alert is within range static int is_alert_in_range(const RoadMapGpsPosition *gps_position, const PluginLine *line){ int i; int j; unsigned int speed; int distance; // will hold the distance of the alert RoadMapPosition gps_pos; int square; int squares[9]; int count_squares; const char * street_name; // the current street name. char current_street_name[512]; RoadMapPosition context_save_pos; int context_save_zoom; int alert_index; // will hold the index in the provider of the alert int priorities [] = {ALERTER_PRIORITY_HIGH,ALERTER_PRIORITY_MEDIUM,ALERTER_PRIORITY_LOW}; int num_priorities = sizeof(priorities)/sizeof(int); int alert_providor_ind; int square_ind; BOOL found_alert = FALSE; gps_pos.latitude = gps_position->latitude; gps_pos.longitude = gps_position->longitude; roadmap_math_get_context(&context_save_pos, &context_save_zoom); roadmap_math_set_context((RoadMapPosition *)&gps_pos, 20); count_squares = roadmap_square_find_neighbours (&gps_pos, 0, squares); // get the street infromation of the current position. get_street_from_line(line->square,line->line_id, &street_name); strncpy_safe (current_street_name, street_name, sizeof (current_street_name)); // go over priorities one by one from highest to lowest. for (j=0; (j< num_priorities); j++){ if ( found_alert ) // Removed from the "for" condition due to some problem in android gcc AGA break; // loop all the providers for an alert for (i = 0 ; ((i < RoadMapAlertProviders.count)&&(!found_alert)); i++){ // if provider doesn't have a high enough priority skip him, we'll get to him later. if(RoadMapAlertProviders.provider[i]->get_priority()!=priorities[j]) continue; /* * If not enough distance has been passed from last check, provider can order to ignore * if alert is active, always perform check, so distance will be updated */ if(!alert_should_be_visible){ if(!(* (RoadMapAlertProviders.provider[i]->distance_check))(gps_pos)) continue; } if ((* (RoadMapAlertProviders.provider[i]->is_square_dependent))()){ /* * This provider has different alerts for each square, so we need to loop over all * these squares and check. (Speed cams in tiles for example, as opposed to RealTimeAlerts). */ for (square = 0; ((square < count_squares)&&(!found_alert)); square++) { roadmap_square_set_current(squares[square]); if(is_alert_in_range_provider(RoadMapAlertProviders.provider[i], gps_position, line, &alert_index,&distance, current_street_name)) { square_ind = square; alert_providor_ind = i; found_alert = TRUE; } } } else { if(is_alert_in_range_provider(RoadMapAlertProviders.provider[i], gps_position, line, &alert_index,&distance,current_street_name)) { square_ind = square; alert_providor_ind = i; found_alert = TRUE; } } } } if(found_alert){ speed = (* (RoadMapAlertProviders.provider[alert_providor_ind]->get_speed))(alert_index); // if driving speed is over the speed limit - it's an ALERT, otherwise it's a WARNING if ((unsigned int)roadmap_math_to_speed_unit(gps_position->speed) < speed) { the_active_alert.alert_type = WARN; the_active_alert.distance_to_alert = distance; the_active_alert.active_alert_id = (* (RoadMapAlertProviders.provider[alert_providor_ind]->get_id))(alert_index); the_active_alert.alert_provider = alert_providor_ind; the_active_alert.square = squares[square_ind]; roadmap_math_set_context(&context_save_pos, context_save_zoom); return TRUE; } else{ the_active_alert.alert_type = ALERT; the_active_alert.distance_to_alert = distance; the_active_alert.active_alert_id = (* (RoadMapAlertProviders.provider[alert_providor_ind]->get_id))(alert_index); the_active_alert.alert_provider = alert_providor_ind; the_active_alert.square = squares[square_ind]; roadmap_math_set_context(&context_save_pos, context_save_zoom); return TRUE; } } roadmap_math_set_context(&context_save_pos, context_save_zoom); return FALSE; }
/* * searches for relevant alerts in the given param provider - D.F. */ static BOOL is_alert_in_range_provider(roadmap_alert_provider* provider, const RoadMapGpsPosition *gps_position, const PluginLine* line, int * pAlert_index, int * pDistance, const char* cur_street_name){ int i; int steering; RoadMapPosition pos; int azymuth; int delta; int square_current; int count = 0; const char *street_name; roadmap_alerter_location_info location_info; roadmap_alerter_location_info * pAlert_location_info = NULL; RoadMapPosition gps_pos; gps_pos.latitude = gps_position->latitude; gps_pos.longitude = gps_position->longitude; square_current = roadmap_square_active (); count = (* (provider->count)) (); // no alerts for this provider if (count == 0) { return FALSE; } for (i=0; i<count; i++) { roadmap_square_set_current (square_current); // if the alert is not alertable, continue. (dummy speed cams, etc.) if (!(* (provider->is_alertable))(i)) { continue; } (* (provider->get_position)) (i, &pos, &steering); // check that the alert is within alert distance * pDistance = roadmap_math_distance(&pos, &gps_pos); if (*pDistance > (*(provider->get_distance))(i)) continue; // Let the provider handle the Alert. if ((* (provider->handle_event))((* (provider->get_id))(i))) continue; // get this alerts cached location info pAlert_location_info = (*(provider->get_location_info))(i); // retrieve the current location info for this alert ( square id, line id... ) if(!get_alert_location_info(&pos,&location_info,pAlert_location_info)) continue; // could not find relevant location. // check if the alert is on the navigation route if (!alert_is_on_route (&location_info, steering)) { roadmap_square_set_current (square_current); if ((* (provider->check_same_street))(i)){ // check that the alert is in the direction of driving delta = azymuth_delta(gps_position->steering, steering); if (delta > AZYMUTH_DELTA || delta < (0-AZYMUTH_DELTA)) { continue; } // check that we didnt pass the alert azymuth = roadmap_math_azymuth (&gps_pos, &pos); delta = azymuth_delta(azymuth, steering); if (delta > 90|| delta < (-90)) continue; // get the street name of the alert get_street_from_line(location_info.square_id,location_info.line_id, &street_name); // if same street found an alert infront of us if(strcmp(street_name,cur_street_name)) continue; // not the same street. } } // if we got until here, then we found a valid alert * pAlert_index = i; roadmap_square_set_current (square_current); return TRUE; } roadmap_square_set_current (square_current); return FALSE; }